aboutsummaryrefslogtreecommitdiffstats
path: root/fs/dcache.c
diff options
context:
space:
mode:
authorAl Viro <viro@zeniv.linux.org.uk>2013-10-25 17:04:27 -0400
committerAl Viro <viro@zeniv.linux.org.uk>2013-11-15 22:04:17 -0500
commit31dec1327e377b6d91a8a6c92b5cd8513939a233 (patch)
tree575b1aa7e37ab0fd8b00c9b756d107232e5aca7e /fs/dcache.c
parent482db9066199813d6b999b65a3171afdbec040b6 (diff)
fold try_to_ascend() into the sole remaining caller
There used to be a bunch of tree-walkers in dcache.c, all alike. try_to_ascend() had been introduced to abstract a piece of logics duplicated in all of them. These days all these tree-walkers are implemented via the same iterator (d_walk()), which is the only remaining caller of try_to_ascend(), so let's fold it back... Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Diffstat (limited to 'fs/dcache.c')
-rw-r--r--fs/dcache.c49
1 files changed, 18 insertions, 31 deletions
diff --git a/fs/dcache.c b/fs/dcache.c
index 7f079d00475a..4bdb300b16e2 100644
--- a/fs/dcache.c
+++ b/fs/dcache.c
@@ -438,7 +438,7 @@ static struct dentry *d_kill(struct dentry *dentry, struct dentry *parent)
438{ 438{
439 list_del(&dentry->d_u.d_child); 439 list_del(&dentry->d_u.d_child);
440 /* 440 /*
441 * Inform try_to_ascend() that we are no longer attached to the 441 * Inform d_walk() that we are no longer attached to the
442 * dentry tree 442 * dentry tree
443 */ 443 */
444 dentry->d_flags |= DCACHE_DENTRY_KILLED; 444 dentry->d_flags |= DCACHE_DENTRY_KILLED;
@@ -1038,34 +1038,6 @@ void shrink_dcache_sb(struct super_block *sb)
1038} 1038}
1039EXPORT_SYMBOL(shrink_dcache_sb); 1039EXPORT_SYMBOL(shrink_dcache_sb);
1040 1040
1041/*
1042 * This tries to ascend one level of parenthood, but
1043 * we can race with renaming, so we need to re-check
1044 * the parenthood after dropping the lock and check
1045 * that the sequence number still matches.
1046 */
1047static struct dentry *try_to_ascend(struct dentry *old, unsigned seq)
1048{
1049 struct dentry *new = old->d_parent;
1050
1051 rcu_read_lock();
1052 spin_unlock(&old->d_lock);
1053 spin_lock(&new->d_lock);
1054
1055 /*
1056 * might go back up the wrong parent if we have had a rename
1057 * or deletion
1058 */
1059 if (new != old->d_parent ||
1060 (old->d_flags & DCACHE_DENTRY_KILLED) ||
1061 need_seqretry(&rename_lock, seq)) {
1062 spin_unlock(&new->d_lock);
1063 new = NULL;
1064 }
1065 rcu_read_unlock();
1066 return new;
1067}
1068
1069/** 1041/**
1070 * enum d_walk_ret - action to talke during tree walk 1042 * enum d_walk_ret - action to talke during tree walk
1071 * @D_WALK_CONTINUE: contrinue walk 1043 * @D_WALK_CONTINUE: contrinue walk
@@ -1154,9 +1126,24 @@ resume:
1154 */ 1126 */
1155 if (this_parent != parent) { 1127 if (this_parent != parent) {
1156 struct dentry *child = this_parent; 1128 struct dentry *child = this_parent;
1157 this_parent = try_to_ascend(this_parent, seq); 1129 this_parent = child->d_parent;
1158 if (!this_parent) 1130
1131 rcu_read_lock();
1132 spin_unlock(&child->d_lock);
1133 spin_lock(&this_parent->d_lock);
1134
1135 /*
1136 * might go back up the wrong parent if we have had a rename
1137 * or deletion
1138 */
1139 if (this_parent != child->d_parent ||
1140 (child->d_flags & DCACHE_DENTRY_KILLED) ||
1141 need_seqretry(&rename_lock, seq)) {
1142 spin_unlock(&this_parent->d_lock);
1143 rcu_read_unlock();
1159 goto rename_retry; 1144 goto rename_retry;
1145 }
1146 rcu_read_unlock();
1160 next = child->d_u.d_child.next; 1147 next = child->d_u.d_child.next;
1161 goto resume; 1148 goto resume;
1162 } 1149 }