diff options
author | Miklos Szeredi <mszeredi@suse.cz> | 2013-09-05 05:44:34 -0400 |
---|---|---|
committer | Al Viro <viro@zeniv.linux.org.uk> | 2013-09-05 16:22:43 -0400 |
commit | 01ddc4ede5f09cdaed015d49ab66eec179085a2e (patch) | |
tree | 360acfdd63f30ca9a52d1d46d39d7cbea044c98a /fs | |
parent | a09e9a7a4b907f2dfa9bdb2b98a1828ab4b340b2 (diff) |
vfs: restructure d_genocide()
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>
Diffstat (limited to 'fs')
-rw-r--r-- | fs/dcache.c | 12 |
1 files changed, 4 insertions, 8 deletions
diff --git a/fs/dcache.c b/fs/dcache.c index 5aa53bc056ba..f792e9f20eca 100644 --- a/fs/dcache.c +++ b/fs/dcache.c | |||
@@ -2952,6 +2952,10 @@ resume: | |||
2952 | spin_unlock(&dentry->d_lock); | 2952 | spin_unlock(&dentry->d_lock); |
2953 | continue; | 2953 | continue; |
2954 | } | 2954 | } |
2955 | if (!(dentry->d_flags & DCACHE_GENOCIDE)) { | ||
2956 | dentry->d_flags |= DCACHE_GENOCIDE; | ||
2957 | dentry->d_lockref.count--; | ||
2958 | } | ||
2955 | if (!list_empty(&dentry->d_subdirs)) { | 2959 | if (!list_empty(&dentry->d_subdirs)) { |
2956 | spin_unlock(&this_parent->d_lock); | 2960 | spin_unlock(&this_parent->d_lock); |
2957 | spin_release(&dentry->d_lock.dep_map, 1, _RET_IP_); | 2961 | spin_release(&dentry->d_lock.dep_map, 1, _RET_IP_); |
@@ -2959,18 +2963,10 @@ resume: | |||
2959 | spin_acquire(&this_parent->d_lock.dep_map, 0, 1, _RET_IP_); | 2963 | spin_acquire(&this_parent->d_lock.dep_map, 0, 1, _RET_IP_); |
2960 | goto repeat; | 2964 | goto repeat; |
2961 | } | 2965 | } |
2962 | if (!(dentry->d_flags & DCACHE_GENOCIDE)) { | ||
2963 | dentry->d_flags |= DCACHE_GENOCIDE; | ||
2964 | dentry->d_lockref.count--; | ||
2965 | } | ||
2966 | spin_unlock(&dentry->d_lock); | 2966 | spin_unlock(&dentry->d_lock); |
2967 | } | 2967 | } |
2968 | if (this_parent != root) { | 2968 | if (this_parent != root) { |
2969 | struct dentry *child = this_parent; | 2969 | struct dentry *child = this_parent; |
2970 | if (!(this_parent->d_flags & DCACHE_GENOCIDE)) { | ||
2971 | this_parent->d_flags |= DCACHE_GENOCIDE; | ||
2972 | this_parent->d_lockref.count--; | ||
2973 | } | ||
2974 | this_parent = try_to_ascend(this_parent, locked, seq); | 2970 | this_parent = try_to_ascend(this_parent, locked, seq); |
2975 | if (!this_parent) | 2971 | if (!this_parent) |
2976 | goto rename_retry; | 2972 | goto rename_retry; |