Commit 191d7f73 authored by Al Viro's avatar Al Viro
Browse files

namei: take put_link() into {lookup,mountpoint,do}_last()



rationale: we'll need to have terminate_walk() do put_link() on
everything, which will mean that in some cases ..._last() will do
put_link() anyway.  Easier to have them do it in all cases.

Signed-off-by: default avatarAl Viro <viro@zeniv.linux.org.uk>
parent 1bc4b813
Loading
Loading
Loading
Loading
+21 −13
Original line number Diff line number Diff line
@@ -2018,6 +2018,8 @@ static inline int lookup_last(struct nameidata *nd)

	nd->flags &= ~LOOKUP_PARENT;
	err = walk_component(nd, nd->flags & LOOKUP_FOLLOW);
	if (nd->depth)
		put_link(nd);
	if (err < 0)
		terminate_walk(nd);
	return err;
@@ -2045,13 +2047,10 @@ static int path_lookupat(int dfd, const struct filename *name,
	 */
	err = path_init(dfd, name, flags, nd);
	if (!err && !(flags & LOOKUP_PARENT)) {
		err = lookup_last(nd);
		while (err > 0) {
		while ((err = lookup_last(nd)) > 0) {
			err = trailing_symlink(nd);
			if (err)
				break;
			err = lookup_last(nd);
			put_link(nd);
		}
	}

@@ -2362,6 +2361,8 @@ done:
		dput(dentry);
		goto out;
	}
	if (nd->depth)
		put_link(nd);
	path->dentry = dentry;
	path->mnt = nd->path.mnt;
	if (should_follow_link(dentry, nd->flags & LOOKUP_FOLLOW)) {
@@ -2373,6 +2374,8 @@ done:
	error = 0;
out:
	terminate_walk(nd);
	if (nd->depth)
		put_link(nd);
	return error;
}

@@ -2394,13 +2397,10 @@ path_mountpoint(int dfd, const struct filename *name, struct path *path,
	if (unlikely(err))
		goto out;

	err = mountpoint_last(nd, path);
	while (err > 0) {
	while ((err = mountpoint_last(nd, path)) > 0) {
		err = trailing_symlink(nd);
		if (err)
			break;
		err = mountpoint_last(nd, path);
		put_link(nd);
	}
out:
	path_cleanup(nd);
@@ -2978,6 +2978,8 @@ static int do_last(struct nameidata *nd,
		error = handle_dots(nd, nd->last_type);
		if (unlikely(error)) {
			terminate_walk(nd);
			if (nd->depth)
				put_link(nd);
			return error;
		}
		goto finish_open;
@@ -3003,8 +3005,11 @@ static int do_last(struct nameidata *nd,
		 * about to look up
		 */
		error = complete_walk(nd);
		if (error)
		if (error) {
			if (nd->depth)
				put_link(nd);
			return error;
		}

		audit_inode(name, dir, LOOKUP_PARENT);
		error = -EISDIR;
@@ -3093,6 +3098,8 @@ finish_lookup:
			}
		}
		BUG_ON(inode != path.dentry->d_inode);
		if (nd->depth)
			put_link(nd);
		nd->link = path;
		return 1;
	}
@@ -3116,6 +3123,8 @@ finish_lookup:
finish_open:
	error = complete_walk(nd);
	if (error) {
		if (nd->depth)
			put_link(nd);
		path_put(&save_parent);
		return error;
	}
@@ -3167,6 +3176,8 @@ out:
		mnt_drop_write(nd->path.mnt);
	path_put(&save_parent);
	terminate_walk(nd);
	if (nd->depth)
		put_link(nd);
	return error;

exit_dput:
@@ -3279,14 +3290,11 @@ static struct file *path_openat(int dfd, struct filename *pathname,
	if (unlikely(error))
		goto out;

	error = do_last(nd, file, op, &opened, pathname);
	while (unlikely(error > 0)) { /* trailing symlink */
	while ((error = do_last(nd, file, op, &opened, pathname)) > 0) {
		nd->flags &= ~(LOOKUP_OPEN|LOOKUP_CREATE|LOOKUP_EXCL);
		error = trailing_symlink(nd);
		if (unlikely(error))
			break;
		error = do_last(nd, file, op, &opened, pathname);
		put_link(nd);
	}
out:
	path_cleanup(nd);