diff options
Diffstat (limited to 'fs/ceph/dir.c')
-rw-r--r-- | fs/ceph/dir.c | 23 |
1 files changed, 15 insertions, 8 deletions
diff --git a/fs/ceph/dir.c b/fs/ceph/dir.c index e6d63f8f98c0..652619950fa9 100644 --- a/fs/ceph/dir.c +++ b/fs/ceph/dir.c | |||
@@ -183,7 +183,7 @@ more: | |||
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 */ | 185 | /* make sure a dentry wasn't dropped while we didn't have parent lock */ |
186 | if (!ceph_dir_is_complete(dir)) { | 186 | if (!ceph_dir_is_complete_ordered(dir)) { |
187 | dout(" lost dir complete on %p; falling back to mds\n", dir); | 187 | dout(" lost dir complete on %p; falling back to mds\n", dir); |
188 | dput(dentry); | 188 | dput(dentry); |
189 | err = -EAGAIN; | 189 | err = -EAGAIN; |
@@ -261,10 +261,6 @@ static int ceph_readdir(struct file *file, struct dir_context *ctx) | |||
261 | 261 | ||
262 | /* always start with . and .. */ | 262 | /* always start with . and .. */ |
263 | if (ctx->pos == 0) { | 263 | if (ctx->pos == 0) { |
264 | /* note dir version at start of readdir so we can tell | ||
265 | * if any dentries get dropped */ | ||
266 | fi->dir_release_count = atomic_read(&ci->i_release_count); | ||
267 | |||
268 | dout("readdir off 0 -> '.'\n"); | 264 | dout("readdir off 0 -> '.'\n"); |
269 | if (!dir_emit(ctx, ".", 1, | 265 | if (!dir_emit(ctx, ".", 1, |
270 | ceph_translate_ino(inode->i_sb, inode->i_ino), | 266 | ceph_translate_ino(inode->i_sb, inode->i_ino), |
@@ -289,7 +285,7 @@ static int ceph_readdir(struct file *file, struct dir_context *ctx) | |||
289 | if ((ctx->pos == 2 || fi->dentry) && | 285 | if ((ctx->pos == 2 || fi->dentry) && |
290 | !ceph_test_mount_opt(fsc, NOASYNCREADDIR) && | 286 | !ceph_test_mount_opt(fsc, NOASYNCREADDIR) && |
291 | ceph_snap(inode) != CEPH_SNAPDIR && | 287 | ceph_snap(inode) != CEPH_SNAPDIR && |
292 | __ceph_dir_is_complete(ci) && | 288 | __ceph_dir_is_complete_ordered(ci) && |
293 | __ceph_caps_issued_mask(ci, CEPH_CAP_FILE_SHARED, 1)) { | 289 | __ceph_caps_issued_mask(ci, CEPH_CAP_FILE_SHARED, 1)) { |
294 | u32 shared_gen = ci->i_shared_gen; | 290 | u32 shared_gen = ci->i_shared_gen; |
295 | spin_unlock(&ci->i_ceph_lock); | 291 | spin_unlock(&ci->i_ceph_lock); |
@@ -312,6 +308,13 @@ static int ceph_readdir(struct file *file, struct dir_context *ctx) | |||
312 | 308 | ||
313 | /* proceed with a normal readdir */ | 309 | /* proceed with a normal readdir */ |
314 | 310 | ||
311 | if (ctx->pos == 2) { | ||
312 | /* note dir version at start of readdir so we can tell | ||
313 | * if any dentries get dropped */ | ||
314 | fi->dir_release_count = atomic_read(&ci->i_release_count); | ||
315 | fi->dir_ordered_count = ci->i_ordered_count; | ||
316 | } | ||
317 | |||
315 | more: | 318 | more: |
316 | /* do we have the correct frag content buffered? */ | 319 | /* do we have the correct frag content buffered? */ |
317 | if (fi->frag != frag || fi->last_readdir == NULL) { | 320 | if (fi->frag != frag || fi->last_readdir == NULL) { |
@@ -446,8 +449,12 @@ more: | |||
446 | */ | 449 | */ |
447 | spin_lock(&ci->i_ceph_lock); | 450 | spin_lock(&ci->i_ceph_lock); |
448 | if (atomic_read(&ci->i_release_count) == fi->dir_release_count) { | 451 | if (atomic_read(&ci->i_release_count) == fi->dir_release_count) { |
449 | dout(" marking %p complete\n", inode); | 452 | if (ci->i_ordered_count == fi->dir_ordered_count) |
450 | __ceph_dir_set_complete(ci, fi->dir_release_count); | 453 | dout(" marking %p complete and ordered\n", inode); |
454 | else | ||
455 | dout(" marking %p complete\n", inode); | ||
456 | __ceph_dir_set_complete(ci, fi->dir_release_count, | ||
457 | fi->dir_ordered_count); | ||
451 | } | 458 | } |
452 | spin_unlock(&ci->i_ceph_lock); | 459 | spin_unlock(&ci->i_ceph_lock); |
453 | 460 | ||