|
@@ -183,7 +183,7 @@ more:
|
|
spin_unlock(&parent->d_lock);
|
|
spin_unlock(&parent->d_lock);
|
|
|
|
|
|
/* make sure a dentry wasn't dropped while we didn't have parent lock */
|
|
/* make sure a dentry wasn't dropped while we didn't have parent lock */
|
|
- if (!ceph_dir_is_complete(dir)) {
|
|
|
|
|
|
+ if (!ceph_dir_is_complete_ordered(dir)) {
|
|
dout(" lost dir complete on %p; falling back to mds\n", dir);
|
|
dout(" lost dir complete on %p; falling back to mds\n", dir);
|
|
dput(dentry);
|
|
dput(dentry);
|
|
err = -EAGAIN;
|
|
err = -EAGAIN;
|
|
@@ -261,10 +261,6 @@ static int ceph_readdir(struct file *file, struct dir_context *ctx)
|
|
|
|
|
|
/* always start with . and .. */
|
|
/* always start with . and .. */
|
|
if (ctx->pos == 0) {
|
|
if (ctx->pos == 0) {
|
|
- /* note dir version at start of readdir so we can tell
|
|
|
|
- * if any dentries get dropped */
|
|
|
|
- fi->dir_release_count = atomic_read(&ci->i_release_count);
|
|
|
|
-
|
|
|
|
dout("readdir off 0 -> '.'\n");
|
|
dout("readdir off 0 -> '.'\n");
|
|
if (!dir_emit(ctx, ".", 1,
|
|
if (!dir_emit(ctx, ".", 1,
|
|
ceph_translate_ino(inode->i_sb, inode->i_ino),
|
|
ceph_translate_ino(inode->i_sb, inode->i_ino),
|
|
@@ -289,7 +285,7 @@ static int ceph_readdir(struct file *file, struct dir_context *ctx)
|
|
if ((ctx->pos == 2 || fi->dentry) &&
|
|
if ((ctx->pos == 2 || fi->dentry) &&
|
|
!ceph_test_mount_opt(fsc, NOASYNCREADDIR) &&
|
|
!ceph_test_mount_opt(fsc, NOASYNCREADDIR) &&
|
|
ceph_snap(inode) != CEPH_SNAPDIR &&
|
|
ceph_snap(inode) != CEPH_SNAPDIR &&
|
|
- __ceph_dir_is_complete(ci) &&
|
|
|
|
|
|
+ __ceph_dir_is_complete_ordered(ci) &&
|
|
__ceph_caps_issued_mask(ci, CEPH_CAP_FILE_SHARED, 1)) {
|
|
__ceph_caps_issued_mask(ci, CEPH_CAP_FILE_SHARED, 1)) {
|
|
u32 shared_gen = ci->i_shared_gen;
|
|
u32 shared_gen = ci->i_shared_gen;
|
|
spin_unlock(&ci->i_ceph_lock);
|
|
spin_unlock(&ci->i_ceph_lock);
|
|
@@ -312,6 +308,13 @@ static int ceph_readdir(struct file *file, struct dir_context *ctx)
|
|
|
|
|
|
/* proceed with a normal readdir */
|
|
/* proceed with a normal readdir */
|
|
|
|
|
|
|
|
+ if (ctx->pos == 2) {
|
|
|
|
+ /* note dir version at start of readdir so we can tell
|
|
|
|
+ * if any dentries get dropped */
|
|
|
|
+ fi->dir_release_count = atomic_read(&ci->i_release_count);
|
|
|
|
+ fi->dir_ordered_count = ci->i_ordered_count;
|
|
|
|
+ }
|
|
|
|
+
|
|
more:
|
|
more:
|
|
/* do we have the correct frag content buffered? */
|
|
/* do we have the correct frag content buffered? */
|
|
if (fi->frag != frag || fi->last_readdir == NULL) {
|
|
if (fi->frag != frag || fi->last_readdir == NULL) {
|
|
@@ -446,8 +449,12 @@ more:
|
|
*/
|
|
*/
|
|
spin_lock(&ci->i_ceph_lock);
|
|
spin_lock(&ci->i_ceph_lock);
|
|
if (atomic_read(&ci->i_release_count) == fi->dir_release_count) {
|
|
if (atomic_read(&ci->i_release_count) == fi->dir_release_count) {
|
|
- dout(" marking %p complete\n", inode);
|
|
|
|
- __ceph_dir_set_complete(ci, fi->dir_release_count);
|
|
|
|
|
|
+ if (ci->i_ordered_count == fi->dir_ordered_count)
|
|
|
|
+ dout(" marking %p complete and ordered\n", inode);
|
|
|
|
+ else
|
|
|
|
+ dout(" marking %p complete\n", inode);
|
|
|
|
+ __ceph_dir_set_complete(ci, fi->dir_release_count,
|
|
|
|
+ fi->dir_ordered_count);
|
|
}
|
|
}
|
|
spin_unlock(&ci->i_ceph_lock);
|
|
spin_unlock(&ci->i_ceph_lock);
|
|
|
|
|