Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 31dec132 authored by Al Viro's avatar Al Viro
Browse files

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: default avatarAl Viro <viro@zeniv.linux.org.uk>
parent 482db906
Loading
Loading
Loading
Loading
+18 −31
Original line number Diff line number Diff line
@@ -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;
@@ -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
@@ -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;
	}