vfs: restructure d_genocide()
authorMiklos Szeredi <mszeredi@suse.cz>
Thu, 5 Sep 2013 09:44:34 +0000 (11:44 +0200)
committerAl Viro <viro@zeniv.linux.org.uk>
Thu, 5 Sep 2013 20:22:43 +0000 (16:22 -0400)
It shouldn't matter when we decrement the refcount during the walk as long
as we do it exactly once.

Restructure d_genocide() to do the killing on entering the dentry instead
of when leaving it.  This helps creating a common helper for tree walking.

Signed-off-by: Miklos Szeredi <mszeredi@suse.cz>
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
fs/dcache.c

index 5aa53bc056bada2af9c3c6040498abcb9a3a3856..f792e9f20eca112eefebdd672c87fdf1001df6c3 100644 (file)
@@ -2952,6 +2952,10 @@ resume:
                        spin_unlock(&dentry->d_lock);
                        continue;
                }
+               if (!(dentry->d_flags & DCACHE_GENOCIDE)) {
+                       dentry->d_flags |= DCACHE_GENOCIDE;
+                       dentry->d_lockref.count--;
+               }
                if (!list_empty(&dentry->d_subdirs)) {
                        spin_unlock(&this_parent->d_lock);
                        spin_release(&dentry->d_lock.dep_map, 1, _RET_IP_);
@@ -2959,18 +2963,10 @@ resume:
                        spin_acquire(&this_parent->d_lock.dep_map, 0, 1, _RET_IP_);
                        goto repeat;
                }
-               if (!(dentry->d_flags & DCACHE_GENOCIDE)) {
-                       dentry->d_flags |= DCACHE_GENOCIDE;
-                       dentry->d_lockref.count--;
-               }
                spin_unlock(&dentry->d_lock);
        }
        if (this_parent != root) {
                struct dentry *child = this_parent;
-               if (!(this_parent->d_flags & DCACHE_GENOCIDE)) {
-                       this_parent->d_flags |= DCACHE_GENOCIDE;
-                       this_parent->d_lockref.count--;
-               }
                this_parent = try_to_ascend(this_parent, locked, seq);
                if (!this_parent)
                        goto rename_retry;