xfs: fix missing KM_NOFS tags to keep lockdep happy
[firefly-linux-kernel-4.4.55.git] / fs / ceph / dir.c
index 6d797f46d77219572998a057db726b2b01d5faae..f02d82b7933e4399abd235a2527403df3364a2fa 100644 (file)
@@ -107,7 +107,7 @@ static unsigned fpos_off(loff_t p)
  * falling back to a "normal" sync readdir if any dentries in the dir
  * are dropped.
  *
- * D_COMPLETE tells indicates we have all dentries in the dir.  It is
+ * Complete dir indicates that we have all dentries in the dir.  It is
  * defined IFF we hold CEPH_CAP_FILE_SHARED (which will be revoked by
  * the MDS if/when the directory is modified).
  */
@@ -198,8 +198,8 @@ more:
        filp->f_pos++;
 
        /* make sure a dentry wasn't dropped while we didn't have parent lock */
-       if (!ceph_dir_test_complete(dir)) {
-               dout(" lost D_COMPLETE on %p; falling back to mds\n", dir);
+       if (!ceph_dir_is_complete(dir)) {
+               dout(" lost dir complete on %p; falling back to mds\n", dir);
                err = -EAGAIN;
                goto out;
        }
@@ -258,7 +258,7 @@ static int ceph_readdir(struct file *filp, void *dirent, filldir_t filldir)
        if (filp->f_pos == 0) {
                /* note dir version at start of readdir so we can tell
                 * if any dentries get dropped */
-               fi->dir_release_count = ci->i_release_count;
+               fi->dir_release_count = atomic_read(&ci->i_release_count);
 
                dout("readdir off 0 -> '.'\n");
                if (filldir(dirent, ".", 1, ceph_make_fpos(0, 0),
@@ -284,7 +284,7 @@ static int ceph_readdir(struct file *filp, void *dirent, filldir_t filldir)
        if ((filp->f_pos == 2 || fi->dentry) &&
            !ceph_test_mount_opt(fsc, NOASYNCREADDIR) &&
            ceph_snap(inode) != CEPH_SNAPDIR &&
-           ceph_dir_test_complete(inode) &&
+           __ceph_dir_is_complete(ci) &&
            __ceph_caps_issued_mask(ci, CEPH_CAP_FILE_SHARED, 1)) {
                spin_unlock(&ci->i_ceph_lock);
                err = __dcache_readdir(filp, dirent, filldir);
@@ -350,7 +350,8 @@ more:
 
                if (!req->r_did_prepopulate) {
                        dout("readdir !did_prepopulate");
-                       fi->dir_release_count--;    /* preclude D_COMPLETE */
+                       /* preclude from marking dir complete */
+                       fi->dir_release_count--;
                }
 
                /* note next offset and last dentry name */
@@ -428,8 +429,9 @@ more:
         * the complete dir contents in our cache.
         */
        spin_lock(&ci->i_ceph_lock);
-       if (ci->i_release_count == fi->dir_release_count) {
-               ceph_dir_set_complete(inode);
+       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);
                ci->i_max_offset = filp->f_pos;
        }
        spin_unlock(&ci->i_ceph_lock);
@@ -604,7 +606,7 @@ static struct dentry *ceph_lookup(struct inode *dir, struct dentry *dentry,
                            fsc->mount_options->snapdir_name,
                            dentry->d_name.len) &&
                    !is_root_ceph_dentry(dir, dentry) &&
-                   ceph_dir_test_complete(dir) &&
+                   __ceph_dir_is_complete(ci) &&
                    (__ceph_caps_issued_mask(ci, CEPH_CAP_FILE_SHARED, 1))) {
                        spin_unlock(&ci->i_ceph_lock);
                        dout(" dir %p complete, -ENOENT\n", dir);
@@ -1064,44 +1066,6 @@ static int ceph_snapdir_d_revalidate(struct dentry *dentry,
        return 1;
 }
 
-/*
- * Set/clear/test dir complete flag on the dir's dentry.
- */
-void ceph_dir_set_complete(struct inode *inode)
-{
-       struct dentry *dentry = d_find_any_alias(inode);
-       
-       if (dentry && ceph_dentry(dentry) &&
-           ceph_test_mount_opt(ceph_sb_to_client(dentry->d_sb), DCACHE)) {
-               dout(" marking %p (%p) complete\n", inode, dentry);
-               set_bit(CEPH_D_COMPLETE, &ceph_dentry(dentry)->flags);
-       }
-       dput(dentry);
-}
-
-void ceph_dir_clear_complete(struct inode *inode)
-{
-       struct dentry *dentry = d_find_any_alias(inode);
-
-       if (dentry && ceph_dentry(dentry)) {
-               dout(" marking %p (%p) complete\n", inode, dentry);
-               set_bit(CEPH_D_COMPLETE, &ceph_dentry(dentry)->flags);
-       }
-       dput(dentry);
-}
-
-bool ceph_dir_test_complete(struct inode *inode)
-{
-       struct dentry *dentry = d_find_any_alias(inode);
-
-       if (dentry && ceph_dentry(dentry)) {
-               dout(" marking %p (%p) NOT complete\n", inode, dentry);
-               clear_bit(CEPH_D_COMPLETE, &ceph_dentry(dentry)->flags);
-       }
-       dput(dentry);
-       return false;
-}
-
 /*
  * When the VFS prunes a dentry from the cache, we need to clear the
  * complete flag on the parent directory.
@@ -1110,15 +1074,13 @@ bool ceph_dir_test_complete(struct inode *inode)
  */
 static void ceph_d_prune(struct dentry *dentry)
 {
-       struct ceph_dentry_info *di;
-
        dout("ceph_d_prune %p\n", dentry);
 
        /* do we have a valid parent? */
        if (IS_ROOT(dentry))
                return;
 
-       /* if we are not hashed, we don't affect D_COMPLETE */
+       /* if we are not hashed, we don't affect dir's completeness */
        if (d_unhashed(dentry))
                return;
 
@@ -1126,8 +1088,7 @@ static void ceph_d_prune(struct dentry *dentry)
         * we hold d_lock, so d_parent is stable, and d_fsdata is never
         * cleared until d_release
         */
-       di = ceph_dentry(dentry->d_parent);
-       clear_bit(CEPH_D_COMPLETE, &di->flags);
+       ceph_dir_clear_complete(dentry->d_parent->d_inode);
 }
 
 /*