aboutsummaryrefslogtreecommitdiffstats
path: root/fs/ceph
diff options
context:
space:
mode:
authorYan, Zheng <zheng.z.yan@intel.com>2014-04-08 09:42:59 -0400
committerSage Weil <sage@inktank.com>2014-04-28 15:53:43 -0400
commit0081bd83c089ef3d0c9a4e4e869e2ab75f2cb379 (patch)
tree0405653138dd561f7f8d61b0e927384528f7438e /fs/ceph
parenta30be7cb2ccb995ad5e67fd4b548f11fe37fc8b1 (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.c22
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 }