]> git.proxmox.com Git - mirror_ubuntu-bionic-kernel.git/blobdiff - fs/ceph/dir.c
ceph: introduce a new inode flag indicating if cached dentries are ordered
[mirror_ubuntu-bionic-kernel.git] / fs / ceph / dir.c
index e6d63f8f98c0a79891396313c0b0d1252e1ef0fb..652619950fa92834ecb79580c46bcff7d2aa1a76 100644 (file)
@@ -183,7 +183,7 @@ more:
        spin_unlock(&parent->d_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);
                dput(dentry);
                err = -EAGAIN;
@@ -261,10 +261,6 @@ static int ceph_readdir(struct file *file, struct dir_context *ctx)
 
        /* always start with . and .. */
        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");
                if (!dir_emit(ctx, ".", 1, 
                            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) &&
            !ceph_test_mount_opt(fsc, NOASYNCREADDIR) &&
            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)) {
                u32 shared_gen = ci->i_shared_gen;
                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 */
 
+       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:
        /* do we have the correct frag content buffered? */
        if (fi->frag != frag || fi->last_readdir == NULL) {
@@ -446,8 +449,12 @@ more:
         */
        spin_lock(&ci->i_ceph_lock);
        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);