diff options
author | Yan, Zheng <zheng.z.yan@intel.com> | 2014-04-08 09:42:59 -0400 |
---|---|---|
committer | Sage Weil <sage@inktank.com> | 2014-04-28 15:53:43 -0400 |
commit | 0081bd83c089ef3d0c9a4e4e869e2ab75f2cb379 (patch) | |
tree | 0405653138dd561f7f8d61b0e927384528f7438e /fs/ceph | |
parent | a30be7cb2ccb995ad5e67fd4b548f11fe37fc8b1 (diff) |
ceph: check directory's completeness before emitting directory entry
Signed-off-by: Yan, Zheng <zheng.z.yan@intel.com>
Reviewed-by: Sage Weil <sage@inktank.com>
Diffstat (limited to 'fs/ceph')
-rw-r--r-- | fs/ceph/dir.c | 22 |
1 files changed, 12 insertions, 10 deletions
diff --git a/fs/ceph/dir.c b/fs/ceph/dir.c index 766410a12c2c..8c7f90b96913 100644 --- a/fs/ceph/dir.c +++ b/fs/ceph/dir.c | |||
@@ -182,9 +182,16 @@ more: | |||
182 | spin_unlock(&dentry->d_lock); | 182 | spin_unlock(&dentry->d_lock); |
183 | spin_unlock(&parent->d_lock); | 183 | spin_unlock(&parent->d_lock); |
184 | 184 | ||
185 | /* make sure a dentry wasn't dropped while we didn't have parent lock */ | ||
186 | if (!ceph_dir_is_complete(dir)) { | ||
187 | dout(" lost dir complete on %p; falling back to mds\n", dir); | ||
188 | dput(dentry); | ||
189 | err = -EAGAIN; | ||
190 | goto out; | ||
191 | } | ||
192 | |||
185 | dout(" %llu (%llu) dentry %p %.*s %p\n", di->offset, ctx->pos, | 193 | dout(" %llu (%llu) dentry %p %.*s %p\n", di->offset, ctx->pos, |
186 | dentry, dentry->d_name.len, dentry->d_name.name, dentry->d_inode); | 194 | dentry, dentry->d_name.len, dentry->d_name.name, dentry->d_inode); |
187 | ctx->pos = di->offset; | ||
188 | if (!dir_emit(ctx, dentry->d_name.name, | 195 | if (!dir_emit(ctx, dentry->d_name.name, |
189 | dentry->d_name.len, | 196 | dentry->d_name.len, |
190 | ceph_translate_ino(dentry->d_sb, dentry->d_inode->i_ino), | 197 | ceph_translate_ino(dentry->d_sb, dentry->d_inode->i_ino), |
@@ -198,19 +205,12 @@ more: | |||
198 | return 0; | 205 | return 0; |
199 | } | 206 | } |
200 | 207 | ||
208 | ctx->pos = di->offset + 1; | ||
209 | |||
201 | if (last) | 210 | if (last) |
202 | dput(last); | 211 | dput(last); |
203 | last = dentry; | 212 | last = dentry; |
204 | 213 | ||
205 | ctx->pos++; | ||
206 | |||
207 | /* make sure a dentry wasn't dropped while we didn't have parent lock */ | ||
208 | if (!ceph_dir_is_complete(dir)) { | ||
209 | dout(" lost dir complete on %p; falling back to mds\n", dir); | ||
210 | err = -EAGAIN; | ||
211 | goto out; | ||
212 | } | ||
213 | |||
214 | spin_lock(&parent->d_lock); | 214 | spin_lock(&parent->d_lock); |
215 | p = p->prev; /* advance to next dentry */ | 215 | p = p->prev; /* advance to next dentry */ |
216 | goto more; | 216 | goto more; |
@@ -296,6 +296,8 @@ static int ceph_readdir(struct file *file, struct dir_context *ctx) | |||
296 | err = __dcache_readdir(file, ctx, shared_gen); | 296 | err = __dcache_readdir(file, ctx, shared_gen); |
297 | if (err != -EAGAIN) | 297 | if (err != -EAGAIN) |
298 | return err; | 298 | return err; |
299 | frag = fpos_frag(ctx->pos); | ||
300 | off = fpos_off(ctx->pos); | ||
299 | } else { | 301 | } else { |
300 | spin_unlock(&ci->i_ceph_lock); | 302 | spin_unlock(&ci->i_ceph_lock); |
301 | } | 303 | } |