Skip to content

Commit

Permalink
fold try_to_ascend() into the sole remaining caller
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Al Viro committed Nov 16, 2013
1 parent 482db90 commit 31dec13
Showing 1 changed file with 18 additions and 31 deletions.
49 changes: 18 additions & 31 deletions fs/dcache.c
Original file line number Diff line number Diff line change
Expand Up @@ -438,7 +438,7 @@ static struct dentry *d_kill(struct dentry *dentry, struct dentry *parent)
{
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->d_flags |= DCACHE_DENTRY_KILLED;
Expand Down Expand Up @@ -1038,34 +1038,6 @@ void shrink_dcache_sb(struct super_block *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
* @D_WALK_CONTINUE: contrinue walk
Expand Down Expand Up @@ -1154,9 +1126,24 @@ static void d_walk(struct dentry *parent, void *data,
*/
if (this_parent != parent) {
struct dentry *child = this_parent;
this_parent = try_to_ascend(this_parent, seq);
if (!this_parent)
this_parent = child->d_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;
}
rcu_read_unlock();
next = child->d_u.d_child.next;
goto resume;
}
Expand Down

0 comments on commit 31dec13

Please sign in to comment.