ceph: stop on-going cached readdir if mds revokes FILE_SHARED cap

If directory's FILE_SHARED cap get revoked, dentry in the directory
can get spliced into other directory (Eg, other client move the
dentry into directory B, then we do readdir on directory B). So we
should stop on-going cached readdir. this can be achieved by marking
dir not complete, because __dcache_readdir() checks dir completeness
before emitting each dentry.

Signed-off-by: "Yan, Zheng" <zyan@redhat.com>
Signed-off-by: Ilya Dryomov <idryomov@gmail.com>

authored by

Yan, Zheng and committed by
Ilya Dryomov
15b51bd6 f275635e

+7 -6
+7 -6
fs/ceph/caps.c
··· 490 } 491 492 /* 493 - * if we are newly issued FILE_SHARED, mark dir not complete; we 494 - * don't know what happened to this directory while we didn't 495 - * have the cap. 496 */ 497 - if ((issued & CEPH_CAP_FILE_SHARED) && 498 - (had & CEPH_CAP_FILE_SHARED) == 0) { 499 - ci->i_shared_gen++; 500 if (S_ISDIR(ci->vfs_inode.i_mode)) { 501 dout(" marking %p NOT complete\n", &ci->vfs_inode); 502 __ceph_dir_clear_complete(ci);
··· 490 } 491 492 /* 493 + * If FILE_SHARED is newly issued, mark dir not complete. We don't 494 + * know what happened to this directory while we didn't have the cap. 495 + * If FILE_SHARED is being revoked, also mark dir not complete. It 496 + * stops on-going cached readdir. 497 */ 498 + if ((issued & CEPH_CAP_FILE_SHARED) != (had & CEPH_CAP_FILE_SHARED)) { 499 + if (issued & CEPH_CAP_FILE_SHARED) 500 + ci->i_shared_gen++; 501 if (S_ISDIR(ci->vfs_inode.i_mode)) { 502 dout(" marking %p NOT complete\n", &ci->vfs_inode); 503 __ceph_dir_clear_complete(ci);