mirror of
https://github.com/Fishwaldo/Star64_linux.git
synced 2025-06-20 21:51:05 +00:00
vfs: syscall: Add fspick() to select a superblock for reconfiguration
Provide an fspick() system call that can be used to pick an existing mountpoint into an fs_context which can thereafter be used to reconfigure a superblock (equivalent of the superblock side of -o remount). This looks like: int fd = fspick(AT_FDCWD, "/mnt", FSPICK_CLOEXEC | FSPICK_NO_AUTOMOUNT); fsconfig(fd, FSCONFIG_SET_FLAG, "intr", NULL, 0); fsconfig(fd, FSCONFIG_SET_FLAG, "noac", NULL, 0); fsconfig(fd, FSCONFIG_CMD_RECONFIGURE, NULL, NULL, 0); At the point of fspick being called, the file descriptor referring to the filesystem context is in exactly the same state as the one that was created by fsopen() after fsmount() has been successfully called. Signed-off-by: David Howells <dhowells@redhat.com> cc: linux-api@vger.kernel.org Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
This commit is contained in:
parent
93766fbd26
commit
cf3cba4a42
5 changed files with 68 additions and 1 deletions
57
fs/fsopen.c
57
fs/fsopen.c
|
@ -156,6 +156,63 @@ err_fc:
|
|||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* Pick a superblock into a context for reconfiguration.
|
||||
*/
|
||||
SYSCALL_DEFINE3(fspick, int, dfd, const char __user *, path, unsigned int, flags)
|
||||
{
|
||||
struct fs_context *fc;
|
||||
struct path target;
|
||||
unsigned int lookup_flags;
|
||||
int ret;
|
||||
|
||||
if (!ns_capable(current->nsproxy->mnt_ns->user_ns, CAP_SYS_ADMIN))
|
||||
return -EPERM;
|
||||
|
||||
if ((flags & ~(FSPICK_CLOEXEC |
|
||||
FSPICK_SYMLINK_NOFOLLOW |
|
||||
FSPICK_NO_AUTOMOUNT |
|
||||
FSPICK_EMPTY_PATH)) != 0)
|
||||
return -EINVAL;
|
||||
|
||||
lookup_flags = LOOKUP_FOLLOW | LOOKUP_AUTOMOUNT;
|
||||
if (flags & FSPICK_SYMLINK_NOFOLLOW)
|
||||
lookup_flags &= ~LOOKUP_FOLLOW;
|
||||
if (flags & FSPICK_NO_AUTOMOUNT)
|
||||
lookup_flags &= ~LOOKUP_AUTOMOUNT;
|
||||
if (flags & FSPICK_EMPTY_PATH)
|
||||
lookup_flags |= LOOKUP_EMPTY;
|
||||
ret = user_path_at(dfd, path, lookup_flags, &target);
|
||||
if (ret < 0)
|
||||
goto err;
|
||||
|
||||
ret = -EINVAL;
|
||||
if (target.mnt->mnt_root != target.dentry)
|
||||
goto err_path;
|
||||
|
||||
fc = fs_context_for_reconfigure(target.dentry, 0, 0);
|
||||
if (IS_ERR(fc)) {
|
||||
ret = PTR_ERR(fc);
|
||||
goto err_path;
|
||||
}
|
||||
|
||||
fc->phase = FS_CONTEXT_RECONF_PARAMS;
|
||||
|
||||
ret = fscontext_alloc_log(fc);
|
||||
if (ret < 0)
|
||||
goto err_fc;
|
||||
|
||||
path_put(&target);
|
||||
return fscontext_create_fd(fc, flags & FSPICK_CLOEXEC ? O_CLOEXEC : 0);
|
||||
|
||||
err_fc:
|
||||
put_fs_context(fc);
|
||||
err_path:
|
||||
path_put(&target);
|
||||
err:
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* Check the state and apply the configuration. Note that this function is
|
||||
* allowed to 'steal' the value by setting param->xxx to NULL before returning.
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue