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>
This commit is contained in:
49
fs/dcache.c
49
fs/dcache.c
@@ -438,7 +438,7 @@ static struct dentry *d_kill(struct dentry *dentry, struct dentry *parent)
|
|||||||
{
|
{
|
||||||
list_del(&dentry->d_u.d_child);
|
list_del(&dentry->d_u.d_child);
|
||||||
/*
|
/*
|
||||||
* Inform try_to_ascend() that we are no longer attached to the
|
* Inform d_walk() that we are no longer attached to the
|
||||||
* dentry tree
|
* dentry tree
|
||||||
*/
|
*/
|
||||||
dentry->d_flags |= DCACHE_DENTRY_KILLED;
|
dentry->d_flags |= DCACHE_DENTRY_KILLED;
|
||||||
@@ -1038,34 +1038,6 @@ void shrink_dcache_sb(struct super_block *sb)
|
|||||||
}
|
}
|
||||||
EXPORT_SYMBOL(shrink_dcache_sb);
|
EXPORT_SYMBOL(shrink_dcache_sb);
|
||||||
|
|
||||||
/*
|
|
||||||
* This tries to ascend one level of parenthood, but
|
|
||||||
* we can race with renaming, so we need to re-check
|
|
||||||
* the parenthood after dropping the lock and check
|
|
||||||
* that the sequence number still matches.
|
|
||||||
*/
|
|
||||||
static struct dentry *try_to_ascend(struct dentry *old, unsigned seq)
|
|
||||||
{
|
|
||||||
struct dentry *new = old->d_parent;
|
|
||||||
|
|
||||||
rcu_read_lock();
|
|
||||||
spin_unlock(&old->d_lock);
|
|
||||||
spin_lock(&new->d_lock);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* might go back up the wrong parent if we have had a rename
|
|
||||||
* or deletion
|
|
||||||
*/
|
|
||||||
if (new != old->d_parent ||
|
|
||||||
(old->d_flags & DCACHE_DENTRY_KILLED) ||
|
|
||||||
need_seqretry(&rename_lock, seq)) {
|
|
||||||
spin_unlock(&new->d_lock);
|
|
||||||
new = NULL;
|
|
||||||
}
|
|
||||||
rcu_read_unlock();
|
|
||||||
return new;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* enum d_walk_ret - action to talke during tree walk
|
* enum d_walk_ret - action to talke during tree walk
|
||||||
* @D_WALK_CONTINUE: contrinue walk
|
* @D_WALK_CONTINUE: contrinue walk
|
||||||
@@ -1154,9 +1126,24 @@ resume:
|
|||||||
*/
|
*/
|
||||||
if (this_parent != parent) {
|
if (this_parent != parent) {
|
||||||
struct dentry *child = this_parent;
|
struct dentry *child = this_parent;
|
||||||
this_parent = try_to_ascend(this_parent, seq);
|
this_parent = child->d_parent;
|
||||||
if (!this_parent)
|
|
||||||
|
rcu_read_lock();
|
||||||
|
spin_unlock(&child->d_lock);
|
||||||
|
spin_lock(&this_parent->d_lock);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* might go back up the wrong parent if we have had a rename
|
||||||
|
* or deletion
|
||||||
|
*/
|
||||||
|
if (this_parent != child->d_parent ||
|
||||||
|
(child->d_flags & DCACHE_DENTRY_KILLED) ||
|
||||||
|
need_seqretry(&rename_lock, seq)) {
|
||||||
|
spin_unlock(&this_parent->d_lock);
|
||||||
|
rcu_read_unlock();
|
||||||
goto rename_retry;
|
goto rename_retry;
|
||||||
|
}
|
||||||
|
rcu_read_unlock();
|
||||||
next = child->d_u.d_child.next;
|
next = child->d_u.d_child.next;
|
||||||
goto resume;
|
goto resume;
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user