summaryrefslogtreecommitdiffstats
path: root/fs/ceph/caps.c
diff options
context:
space:
mode:
authorYan, Zheng <zyan@redhat.com>2017-09-05 22:15:16 -0400
committerIlya Dryomov <idryomov@gmail.com>2017-09-06 13:57:00 -0400
commit15b51bd6badbb373c723aa019cf530c8263efd7e (patch)
treee5e9c111c77b05319364f241440b2d5edee77923 /fs/ceph/caps.c
parentf275635ee0b6641151dfaf07b901d7c8d4d8e987 (diff)
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>
Diffstat (limited to 'fs/ceph/caps.c')
-rw-r--r--fs/ceph/caps.c13
1 files changed, 7 insertions, 6 deletions
diff --git a/fs/ceph/caps.c b/fs/ceph/caps.c
index 7a7945032802..157fe59fbabe 100644
--- a/fs/ceph/caps.c
+++ b/fs/ceph/caps.c
@@ -490,13 +490,14 @@ static void __check_cap_issue(struct ceph_inode_info *ci, struct ceph_cap *cap,
490 } 490 }
491 491
492 /* 492 /*
493 * if we are newly issued FILE_SHARED, mark dir not complete; we 493 * If FILE_SHARED is newly issued, mark dir not complete. We don't
494 * don't know what happened to this directory while we didn't 494 * know what happened to this directory while we didn't have the cap.
495 * have the cap. 495 * If FILE_SHARED is being revoked, also mark dir not complete. It
496 * stops on-going cached readdir.
496 */ 497 */
497 if ((issued & CEPH_CAP_FILE_SHARED) && 498 if ((issued & CEPH_CAP_FILE_SHARED) != (had & CEPH_CAP_FILE_SHARED)) {
498 (had & CEPH_CAP_FILE_SHARED) == 0) { 499 if (issued & CEPH_CAP_FILE_SHARED)
499 ci->i_shared_gen++; 500 ci->i_shared_gen++;
500 if (S_ISDIR(ci->vfs_inode.i_mode)) { 501 if (S_ISDIR(ci->vfs_inode.i_mode)) {
501 dout(" marking %p NOT complete\n", &ci->vfs_inode); 502 dout(" marking %p NOT complete\n", &ci->vfs_inode);
502 __ceph_dir_clear_complete(ci); 503 __ceph_dir_clear_complete(ci);