Received: by 2002:ac0:a594:0:0:0:0:0 with SMTP id m20-v6csp2953564imm; Thu, 24 May 2018 19:48:17 -0700 (PDT) X-Google-Smtp-Source: AB8JxZpGeWVMQXqLVgmPp75ewqOlV37dcbWS+6Eu2N0HJxyCCTvbt3vyRVd+dedkUDDlvuypuvfC X-Received: by 2002:a17:902:c6b:: with SMTP id 98-v6mr660126pls.270.1527216497903; Thu, 24 May 2018 19:48:17 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1527216497; cv=none; d=google.com; s=arc-20160816; b=Y4bPF+c1E093sM3A57dLZxzD2Ljk4Po4mVI6HI+PQR9D2HxqqZP2r1/LBgInr7LoGF u/jT4+excTWlJlYLJaG8FKOJFc2BasA9+pjbkwpdZwzdsk0ZQ8NomnBCTWa4T2UZoe12 waiQgTGmuNAX0D0dSIKeShO9DWHGY5KCyxcmqsLAoKVv1FE2I0coV8fbrXFYuaaPjAMG FHnM+u8NR12XIYCMVjWy9dm3Zml3GiBNyUpY6jraHo+M0JbCEqPF2WJeSPcukBX09l5B iQqQmV+HXrfoymrdWGJI10MHdOFNt9A84YzAM73vhOhnkyBQtqWjEh3fX+KueKb8GOpp 2gZw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:content-transfer-encoding:mime-version :user-agent:references:in-reply-to:message-id:date:cc:to:from :subject:organization:arc-authentication-results; bh=ToWvaq1mTymbzJRf/MCIXFaTub5VMC19Sx/IqMyCAnA=; b=CP11Xlz3isG+cjsLUt0q85lVf8jBOcHX7t8VF76p8dYHAhJET1d5/joHCYZevdA625 rjg/bEMpCpvO448rZCBwY/zBWLo5cdp6j+mUVZYE9Ntpz4NBqsipyyHJx7CoEUWooxBM cW8Q0DfO7aTbSnOsYmrYZwAvt8ZEPmKwwWrWFcKSgIW4lhNYH5qftbTEgq7vTkR8ZZSC GJKl8o3YrJqwsyMmSAF7NBfOHcVv4tU++zWyf4Ut2yQidmY0Xutg20lknGnt51YzaYcg YZVAajS9TJiCpNjOe2rknBgU3LEtjcHWNKqsZMlmZUG2Nl/MlUsi3+LAHcTsJRyaefh8 MnEA== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=redhat.com Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id u5-v6si10320350pgc.335.2018.05.24.19.48.03; Thu, 24 May 2018 19:48:17 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=redhat.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S971854AbeEYAH4 (ORCPT + 99 others); Thu, 24 May 2018 20:07:56 -0400 Received: from mx3-rdu2.redhat.com ([66.187.233.73]:58568 "EHLO mx1.redhat.com" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1161655AbeEYAHs (ORCPT ); Thu, 24 May 2018 20:07:48 -0400 Received: from smtp.corp.redhat.com (int-mx06.intmail.prod.int.rdu2.redhat.com [10.11.54.6]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 1E28A80825A5; Fri, 25 May 2018 00:07:48 +0000 (UTC) Received: from warthog.procyon.org.uk (ovpn-120-255.rdu2.redhat.com [10.10.120.255]) by smtp.corp.redhat.com (Postfix) with ESMTP id 50A2721411BD; Fri, 25 May 2018 00:07:47 +0000 (UTC) Organization: Red Hat UK Ltd. Registered Address: Red Hat UK Ltd, Amberley Place, 107-111 Peascod Street, Windsor, Berkshire, SI4 1TE, United Kingdom. Registered in England and Wales under Company Registration No. 3798903 Subject: [PATCH 22/32] vfs: Provide an fspick() system call [ver #8] From: David Howells To: viro@zeniv.linux.org.uk Cc: dhowells@redhat.com, linux-fsdevel@vger.kernel.org, linux-afs@lists.infradead.org, linux-kernel@vger.kernel.org Date: Fri, 25 May 2018 01:07:46 +0100 Message-ID: <152720686681.9073.2993011607682983090.stgit@warthog.procyon.org.uk> In-Reply-To: <152720672288.9073.9868393448836301272.stgit@warthog.procyon.org.uk> References: <152720672288.9073.9868393448836301272.stgit@warthog.procyon.org.uk> User-Agent: StGit/0.17.1-dirty MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: 7bit X-Scanned-By: MIMEDefang 2.78 on 10.11.54.6 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.11.55.8]); Fri, 25 May 2018 00:07:48 +0000 (UTC) X-Greylist: inspected by milter-greylist-4.5.16 (mx1.redhat.com [10.11.55.8]); Fri, 25 May 2018 00:07:48 +0000 (UTC) for IP:'10.11.54.6' DOMAIN:'int-mx06.intmail.prod.int.rdu2.redhat.com' HELO:'smtp.corp.redhat.com' FROM:'dhowells@redhat.com' RCPT:'' Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org 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); write(fd, "o intr"); write(fd, "o noac"); write(fd, "x reconfigure"); 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 --- arch/x86/entry/syscalls/syscall_32.tbl | 1 arch/x86/entry/syscalls/syscall_64.tbl | 1 fs/fsopen.c | 94 +++++++++++++++++++++++++------- include/linux/syscalls.h | 1 include/uapi/linux/fs.h | 5 ++ kernel/sys_ni.c | 1 6 files changed, 83 insertions(+), 20 deletions(-) diff --git a/arch/x86/entry/syscalls/syscall_32.tbl b/arch/x86/entry/syscalls/syscall_32.tbl index bdcb0c4a0491..b7e2adda092c 100644 --- a/arch/x86/entry/syscalls/syscall_32.tbl +++ b/arch/x86/entry/syscalls/syscall_32.tbl @@ -399,3 +399,4 @@ 385 i386 io_pgetevents sys_io_pgetevents __ia32_compat_sys_io_pgetevents 386 i386 fsopen sys_fsopen __ia32_sys_fsopen 387 i386 fsmount sys_fsmount __ia32_sys_fsmount +388 i386 fspick sys_fspick __ia32_sys_fspick diff --git a/arch/x86/entry/syscalls/syscall_64.tbl b/arch/x86/entry/syscalls/syscall_64.tbl index 7d932d3897fa..fd322986974b 100644 --- a/arch/x86/entry/syscalls/syscall_64.tbl +++ b/arch/x86/entry/syscalls/syscall_64.tbl @@ -344,6 +344,7 @@ 333 common io_pgetevents __x64_sys_io_pgetevents 334 common fsopen __x64_sys_fsopen 335 common fsmount __x64_sys_fsmount +336 common fspick __x64_sys_fspick # # x32-specific system call numbers start at 512 to avoid cache impact diff --git a/fs/fsopen.c b/fs/fsopen.c index 26565ddd7c9e..d69155b9303e 100644 --- a/fs/fsopen.c +++ b/fs/fsopen.c @@ -17,6 +17,7 @@ #include #include #include +#include #include "mount.h" static struct vfsmount *fscontext_fs_mnt __read_mostly; @@ -286,6 +287,36 @@ static int __init init_fscontext_fs(void) fs_initcall(init_fscontext_fs); +/* + * Attach a filesystem context to a file and an fd. + */ +static int fsopen_create_fd(struct fs_context *fc, bool cloexec) +{ + struct file *file; + int ret; + + file = create_fscontext_file(fc); + if (IS_ERR(file)) { + ret = PTR_ERR(file); + goto err_fc; + } + + ret = get_unused_fd_flags(cloexec); + if (ret < 0) + goto err_file; + + fd_install(ret, file); + return ret; + +err_fc: + put_fs_context(fc); + goto err; +err_file: + fput(file); +err: + return ret; +} + /* * Open a filesystem by name so that it can be configured for mounting. * @@ -298,9 +329,7 @@ SYSCALL_DEFINE5(fsopen, const char __user *, _fs_name, unsigned int, flags, { struct file_system_type *fs_type; struct fs_context *fc; - struct file *file; const char *fs_name; - int fd, ret; if (!ns_capable(current->nsproxy->mnt_ns->user_ns, CAP_SYS_ADMIN)) return -EPERM; @@ -324,29 +353,54 @@ SYSCALL_DEFINE5(fsopen, const char __user *, _fs_name, unsigned int, flags, fc->phase = FS_CONTEXT_CREATE_PARAMS; - ret = -EOPNOTSUPP; - if (!fc->ops) - goto err_fc; + return fsopen_create_fd(fc, flags & FSOPEN_CLOEXEC); +} - file = create_fscontext_file(fc); - if (IS_ERR(file)) { - ret = PTR_ERR(file); - goto err_fc; - } +/* + * Pick a superblock into a context for reconfiguration. + */ +SYSCALL_DEFINE3(fspick, int, dfd, const char *, path, unsigned int, flags) +{ + struct fs_context *fc; + struct path target; + unsigned int lookup_flags; + int ret; + + if ((flags & ~(FSPICK_CLOEXEC | + FSPICK_SYMLINK_NOFOLLOW | + FSPICK_NO_AUTOMOUNT | + FSPICK_EMPTY_PATH)) != 0) + return -EINVAL; - ret = get_unused_fd_flags(flags & O_CLOEXEC); + 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_file; + goto err; + + ret = -EOPNOTSUPP; + if (!target.dentry->d_sb->s_op->reconfigure) + goto err; + + fc = vfs_new_fs_context(target.dentry->d_sb->s_type, target.dentry, + 0, FS_CONTEXT_FOR_RECONFIGURE); + if (IS_ERR(fc)) { + ret = PTR_ERR(fc); + goto err_path; + } - fd = ret; - fd_install(fd, file); - return fd; + fc->phase = FS_CONTEXT_RECONF_PARAMS; -err_file: - fput(file); - return ret; + path_put(&target); + return fsopen_create_fd(fc, flags & FSPICK_CLOEXEC); -err_fc: - put_fs_context(fc); +err_path: + path_put(&target); +err: return ret; } diff --git a/include/linux/syscalls.h b/include/linux/syscalls.h index 178370cad1dd..5130fd687a85 100644 --- a/include/linux/syscalls.h +++ b/include/linux/syscalls.h @@ -900,6 +900,7 @@ asmlinkage long sys_fsopen(const char *fs_name, unsigned int flags, void *reserved3, void *reserved4, void *reserved5); asmlinkage long sys_fsmount(int fsfd, int dfd, const char *path, unsigned int at_flags, unsigned int flags); +asmlinkage long sys_fspick(int dfd, const char *path, unsigned int at_flags); /* diff --git a/include/uapi/linux/fs.h b/include/uapi/linux/fs.h index edb1983a9990..f3875a84349d 100644 --- a/include/uapi/linux/fs.h +++ b/include/uapi/linux/fs.h @@ -345,4 +345,9 @@ typedef int __bitwise __kernel_rwf_t; #define FSMOUNT_CLOEXEC 0x00000001 +#define FSPICK_CLOEXEC 0x00000001 +#define FSPICK_SYMLINK_NOFOLLOW 0x00000002 +#define FSPICK_NO_AUTOMOUNT 0x00000004 +#define FSPICK_EMPTY_PATH 0x00000008 + #endif /* _UAPI_LINUX_FS_H */ diff --git a/kernel/sys_ni.c b/kernel/sys_ni.c index 632a937ca09c..152fdc95d426 100644 --- a/kernel/sys_ni.c +++ b/kernel/sys_ni.c @@ -436,3 +436,4 @@ COND_SYSCALL(setuid16); /* fd-based mount */ COND_SYSCALL(sys_fsopen); COND_SYSCALL(sys_fsmount); +COND_SYSCALL(sys_fspick);