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

Commit 6ac08709 authored by Al Viro's avatar Al Viro
Browse files

path_openat(): take O_PATH handling out of do_last()



do_last() and lookup_open() simpler that way and so does O_PATH
itself.  As it bloody well should: we find what the pathname
resolves to, same way as in stat() et.al. and associate it with
FMODE_PATH struct file.

Signed-off-by: default avatarAl Viro <viro@zeniv.linux.org.uk>
parent 3b0a3c1a
Loading
Loading
Loading
Loading
+24 −7
Original line number Original line Diff line number Diff line
@@ -3019,7 +3019,7 @@ static int lookup_open(struct nameidata *nd, struct path *path,
		goto out_no_open;
		goto out_no_open;
	}
	}


	if ((nd->flags & LOOKUP_OPEN) && dir_inode->i_op->atomic_open) {
	if (dir_inode->i_op->atomic_open) {
		return atomic_open(nd, dentry, path, file, op, got_write,
		return atomic_open(nd, dentry, path, file, op, got_write,
				   need_lookup, opened);
				   need_lookup, opened);
	}
	}
@@ -3219,7 +3219,7 @@ static int do_last(struct nameidata *nd,
		return error;
		return error;
	}
	}
	audit_inode(nd->name, nd->path.dentry, 0);
	audit_inode(nd->name, nd->path.dentry, 0);
	if (unlikely(d_is_symlink(nd->path.dentry)) && !(open_flag & O_PATH)) {
	if (unlikely(d_is_symlink(nd->path.dentry))) {
		error = -ELOOP;
		error = -ELOOP;
		goto out;
		goto out;
	}
	}
@@ -3239,11 +3239,9 @@ static int do_last(struct nameidata *nd,
		got_write = true;
		got_write = true;
	}
	}
finish_open_created:
finish_open_created:
	if (likely(!(open_flag & O_PATH))) {
	error = may_open(&nd->path, acc_mode, open_flag);
	error = may_open(&nd->path, acc_mode, open_flag);
	if (error)
	if (error)
		goto out;
		goto out;
	}
	BUG_ON(*opened & FILE_OPENED); /* once it's opened, it's opened */
	BUG_ON(*opened & FILE_OPENED); /* once it's opened, it's opened */
	error = vfs_open(&nd->path, file, current_cred());
	error = vfs_open(&nd->path, file, current_cred());
	if (!error) {
	if (!error) {
@@ -3357,6 +3355,18 @@ static int do_tmpfile(struct nameidata *nd, unsigned flags,
	return error;
	return error;
}
}


static int do_o_path(struct nameidata *nd, unsigned flags, struct file *file)
{
	struct path path;
	int error = path_lookupat(nd, flags, &path);
	if (!error) {
		audit_inode(nd->name, path.dentry, 0);
		error = vfs_open(&path, file, current_cred());
		path_put(&path);
	}
	return error;
}

static struct file *path_openat(struct nameidata *nd,
static struct file *path_openat(struct nameidata *nd,
			const struct open_flags *op, unsigned flags)
			const struct open_flags *op, unsigned flags)
{
{
@@ -3376,6 +3386,13 @@ static struct file *path_openat(struct nameidata *nd,
		goto out2;
		goto out2;
	}
	}


	if (unlikely(file->f_flags & O_PATH)) {
		error = do_o_path(nd, flags, file);
		if (!error)
			opened |= FILE_OPENED;
		goto out2;
	}

	s = path_init(nd, flags);
	s = path_init(nd, flags);
	if (IS_ERR(s)) {
	if (IS_ERR(s)) {
		put_filp(file);
		put_filp(file);