]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph-client.git/commitdiff
DO NOT UPSTREAM. We can't make this change ourselves, but are testing it.
authorYan, Zheng <zheng.z.yan@intel.com>
Mon, 11 Mar 2013 12:42:45 +0000 (20:42 +0800)
committerGreg Farnum <greg@inktank.com>
Wed, 13 Mar 2013 00:49:10 +0000 (17:49 -0700)
fs: remove dentry_lru_prune()

When pruning a dentry, its ancestor dentry can also be pruned. But
the ancestor dentry does not go through dput(), so it does not get
put on the dentry LRU. Hence associating d_prune with removing the
dentry from the LRU is the wrong.

The fix is remove dentry_lru_prune(). Modify all its callers to use
dentry_lru_del() and call file system's d_prune() callback directly.

Signed-off-by: Yan, Zheng <zheng.z.yan@intel.com>
fs/dcache.c

index 19153a0a810c1d12de751d5d416a5c1b6fe8c9bb..ceedd045eea18e0a818126e65e5d40d874ceee86 100644 (file)
@@ -337,23 +337,6 @@ static void dentry_lru_del(struct dentry *dentry)
        }
 }
 
-/*
- * Remove a dentry that is unreferenced and about to be pruned
- * (unhashed and destroyed) from the LRU, and inform the file system.
- * This wrapper should be called _prior_ to unhashing a victim dentry.
- */
-static void dentry_lru_prune(struct dentry *dentry)
-{
-       if (!list_empty(&dentry->d_lru)) {
-               if (dentry->d_flags & DCACHE_OP_PRUNE)
-                       dentry->d_op->d_prune(dentry);
-
-               spin_lock(&dcache_lru_lock);
-               __dentry_lru_del(dentry);
-               spin_unlock(&dcache_lru_lock);
-       }
-}
-
 static void dentry_lru_move_list(struct dentry *dentry, struct list_head *list)
 {
        spin_lock(&dcache_lru_lock);
@@ -486,11 +469,13 @@ relock:
        if (ref)
                dentry->d_count--;
        /*
-        * if dentry was on the d_lru list delete it from there.
         * inform the fs via d_prune that this dentry is about to be
         * unhashed and destroyed.
         */
-       dentry_lru_prune(dentry);
+       if (dentry->d_flags & DCACHE_OP_PRUNE)
+               dentry->d_op->d_prune(dentry);
+
+       dentry_lru_del(dentry);
        /* if it was on the hash then remove it */
        __d_drop(dentry);
        return d_kill(dentry, parent);
@@ -921,11 +906,13 @@ static void shrink_dcache_for_umount_subtree(struct dentry *dentry)
                        struct inode *inode;
 
                        /*
-                        * remove the dentry from the lru, and inform
-                        * the fs that this dentry is about to be
+                        * inform the fs that this dentry is about to be
                         * unhashed and destroyed.
                         */
-                       dentry_lru_prune(dentry);
+                       if (dentry->d_flags & DCACHE_OP_PRUNE)
+                               dentry->d_op->d_prune(dentry);
+
+                       dentry_lru_del(dentry);
                        __d_shrink(dentry);
 
                        if (dentry->d_count != 0) {