diff options
author | Yan, Zheng <zheng.z.yan@intel.com> | 2014-04-06 02:10:04 -0400 |
---|---|---|
committer | Sage Weil <sage@inktank.com> | 2014-04-06 12:13:14 -0400 |
commit | a30be7cb2ccb995ad5e67fd4b548f11fe37fc8b1 (patch) | |
tree | 5f0927538f5e54ea9b6be1ec95e571d569975ca0 | |
parent | 8a53f23fcda355958a79774c6333a3a31c380ecf (diff) |
ceph: skip invalid dentry during dcache readdir
skip dentries that were added before MDS issued FILE_SHARED to
client.
Signed-off-by: Yan, Zheng <zheng.z.yan@intel.com>
Reviewed-by: Sage Weil <sage@inktank.com>
-rw-r--r-- | fs/ceph/dir.c | 13 |
1 files changed, 8 insertions, 5 deletions
diff --git a/fs/ceph/dir.c b/fs/ceph/dir.c index 46cd092cb013..766410a12c2c 100644 --- a/fs/ceph/dir.c +++ b/fs/ceph/dir.c | |||
@@ -119,7 +119,8 @@ static int fpos_cmp(loff_t l, loff_t r) | |||
119 | * defined IFF we hold CEPH_CAP_FILE_SHARED (which will be revoked by | 119 | * defined IFF we hold CEPH_CAP_FILE_SHARED (which will be revoked by |
120 | * the MDS if/when the directory is modified). | 120 | * the MDS if/when the directory is modified). |
121 | */ | 121 | */ |
122 | static int __dcache_readdir(struct file *file, struct dir_context *ctx) | 122 | static int __dcache_readdir(struct file *file, struct dir_context *ctx, |
123 | u32 shared_gen) | ||
123 | { | 124 | { |
124 | struct ceph_file_info *fi = file->private_data; | 125 | struct ceph_file_info *fi = file->private_data; |
125 | struct dentry *parent = file->f_dentry; | 126 | struct dentry *parent = file->f_dentry; |
@@ -133,8 +134,8 @@ static int __dcache_readdir(struct file *file, struct dir_context *ctx) | |||
133 | last = fi->dentry; | 134 | last = fi->dentry; |
134 | fi->dentry = NULL; | 135 | fi->dentry = NULL; |
135 | 136 | ||
136 | dout("__dcache_readdir %p at %llu (last %p)\n", dir, ctx->pos, | 137 | dout("__dcache_readdir %p v%u at %llu (last %p)\n", |
137 | last); | 138 | dir, shared_gen, ctx->pos, last); |
138 | 139 | ||
139 | spin_lock(&parent->d_lock); | 140 | spin_lock(&parent->d_lock); |
140 | 141 | ||
@@ -161,7 +162,8 @@ more: | |||
161 | goto out_unlock; | 162 | goto out_unlock; |
162 | } | 163 | } |
163 | spin_lock_nested(&dentry->d_lock, DENTRY_D_LOCK_NESTED); | 164 | spin_lock_nested(&dentry->d_lock, DENTRY_D_LOCK_NESTED); |
164 | if (!d_unhashed(dentry) && dentry->d_inode && | 165 | if (di->lease_shared_gen == shared_gen && |
166 | !d_unhashed(dentry) && dentry->d_inode && | ||
165 | ceph_snap(dentry->d_inode) != CEPH_SNAPDIR && | 167 | ceph_snap(dentry->d_inode) != CEPH_SNAPDIR && |
166 | ceph_ino(dentry->d_inode) != CEPH_INO_CEPH && | 168 | ceph_ino(dentry->d_inode) != CEPH_INO_CEPH && |
167 | fpos_cmp(ctx->pos, di->offset) <= 0) | 169 | fpos_cmp(ctx->pos, di->offset) <= 0) |
@@ -289,8 +291,9 @@ static int ceph_readdir(struct file *file, struct dir_context *ctx) | |||
289 | ceph_snap(inode) != CEPH_SNAPDIR && | 291 | ceph_snap(inode) != CEPH_SNAPDIR && |
290 | __ceph_dir_is_complete(ci) && | 292 | __ceph_dir_is_complete(ci) && |
291 | __ceph_caps_issued_mask(ci, CEPH_CAP_FILE_SHARED, 1)) { | 293 | __ceph_caps_issued_mask(ci, CEPH_CAP_FILE_SHARED, 1)) { |
294 | u32 shared_gen = ci->i_shared_gen; | ||
292 | spin_unlock(&ci->i_ceph_lock); | 295 | spin_unlock(&ci->i_ceph_lock); |
293 | err = __dcache_readdir(file, ctx); | 296 | err = __dcache_readdir(file, ctx, shared_gen); |
294 | if (err != -EAGAIN) | 297 | if (err != -EAGAIN) |
295 | return err; | 298 | return err; |
296 | } else { | 299 | } else { |