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

Commit e8bb73df authored by Al Viro's avatar Al Viro
Browse files

namei: fold put_link() into the failure case of complete_walk()



... and don't open-code unlazy_walk() in there - the only reason
for that is to avoid verfication of cached nd->root, which is
trivially avoided by discarding said cached nd->root first.

Signed-off-by: default avatarAl Viro <viro@zeniv.linux.org.uk>
parent fab51e8a
Loading
Loading
Loading
Loading
+6 −23
Original line number Diff line number Diff line
@@ -567,6 +567,8 @@ static inline int nd_alloc_stack(struct nameidata *nd)
 * to restart the path walk from the beginning in ref-walk mode.
 */

static void terminate_walk(struct nameidata *nd);

/**
 * unlazy_walk - try to switch to ref-walk mode.
 * @nd: nameidata pathwalk data
@@ -673,26 +675,12 @@ static int complete_walk(struct nameidata *nd)
	int status;

	if (nd->flags & LOOKUP_RCU) {
		nd->flags &= ~LOOKUP_RCU;
		if (!(nd->flags & LOOKUP_ROOT))
			nd->root.mnt = NULL;

		if (!legitimize_mnt(nd->path.mnt, nd->m_seq)) {
			rcu_read_unlock();
			return -ECHILD;
		}
		if (unlikely(!lockref_get_not_dead(&dentry->d_lockref))) {
			rcu_read_unlock();
			mntput(nd->path.mnt);
			return -ECHILD;
		}
		if (read_seqcount_retry(&dentry->d_seq, nd->seq)) {
			rcu_read_unlock();
			dput(dentry);
			mntput(nd->path.mnt);
		if (unlikely(unlazy_walk(nd, NULL))) {
			terminate_walk(nd);
			return -ECHILD;
		}
		rcu_read_unlock();
	}

	if (likely(!(nd->flags & LOOKUP_JUMPED)))
@@ -708,7 +696,7 @@ static int complete_walk(struct nameidata *nd)
	if (!status)
		status = -ESTALE;

	path_put(&nd->path);
	terminate_walk(nd);
	return status;
}

@@ -3008,11 +2996,8 @@ static int do_last(struct nameidata *nd,
		 * about to look up
		 */
		error = complete_walk(nd);
		if (error) {
			if (nd->depth)
				put_link(nd);
		if (error)
			return error;
		}

		audit_inode(name, dir, LOOKUP_PARENT);
		error = -EISDIR;
@@ -3117,8 +3102,6 @@ static int do_last(struct nameidata *nd,
finish_open:
	error = complete_walk(nd);
	if (error) {
		if (nd->depth)
			put_link(nd);
		path_put(&save_parent);
		return error;
	}