summaryrefslogtreecommitdiff
path: root/fs/fsopen.c
diff options
context:
space:
mode:
authorChristian Brauner <brauner@kernel.org>2023-08-02 13:57:05 +0200
committerChristian Brauner <brauner@kernel.org>2023-08-14 18:48:02 +0200
commit11a51d8c13a75f6b24cffeda8e5e11fc8a749f1e (patch)
treee1f9ebd3d6b724dcc6c05f44a790ff5d2c9655aa /fs/fsopen.c
parentdae8b08d5d83b7550917af06cfba76f0b908bf15 (diff)
downloadlwn-11a51d8c13a75f6b24cffeda8e5e11fc8a749f1e.tar.gz
lwn-11a51d8c13a75f6b24cffeda8e5e11fc8a749f1e.zip
fs: add vfs_cmd_reconfigure()
Split the steps to reconfigure a superblock into a tiny helper instead of open-coding it in the switch. Reviewed-by: Christoph Hellwig <hch@lst.de> Reviewed-by: Jan Kara <jack@suse.cz> Reviewed-by: Aleksa Sarai <cyphar@cyphar.com> Message-Id: <20230802-vfs-super-exclusive-v2-3-95dc4e41b870@kernel.org> Signed-off-by: Christian Brauner <brauner@kernel.org>
Diffstat (limited to 'fs/fsopen.c')
-rw-r--r--fs/fsopen.c47
1 files changed, 29 insertions, 18 deletions
diff --git a/fs/fsopen.c b/fs/fsopen.c
index 1de2b3576958..a69b7c9cc59c 100644
--- a/fs/fsopen.c
+++ b/fs/fsopen.c
@@ -242,6 +242,34 @@ static int vfs_cmd_create(struct fs_context *fc)
return 0;
}
+static int vfs_cmd_reconfigure(struct fs_context *fc)
+{
+ struct super_block *sb;
+ int ret;
+
+ if (fc->phase != FS_CONTEXT_RECONF_PARAMS)
+ return -EBUSY;
+
+ fc->phase = FS_CONTEXT_RECONFIGURING;
+
+ sb = fc->root->d_sb;
+ if (!ns_capable(sb->s_user_ns, CAP_SYS_ADMIN)) {
+ fc->phase = FS_CONTEXT_FAILED;
+ return -EPERM;
+ }
+
+ down_write(&sb->s_umount);
+ ret = reconfigure_super(fc);
+ up_write(&sb->s_umount);
+ if (ret) {
+ fc->phase = FS_CONTEXT_FAILED;
+ return ret;
+ }
+
+ vfs_clean_context(fc);
+ return 0;
+}
+
/*
* 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.
@@ -249,7 +277,6 @@ static int vfs_cmd_create(struct fs_context *fc)
static int vfs_fsconfig_locked(struct fs_context *fc, int cmd,
struct fs_parameter *param)
{
- struct super_block *sb;
int ret;
ret = finish_clean_context(fc);
@@ -259,21 +286,7 @@ static int vfs_fsconfig_locked(struct fs_context *fc, int cmd,
case FSCONFIG_CMD_CREATE:
return vfs_cmd_create(fc);
case FSCONFIG_CMD_RECONFIGURE:
- if (fc->phase != FS_CONTEXT_RECONF_PARAMS)
- return -EBUSY;
- fc->phase = FS_CONTEXT_RECONFIGURING;
- sb = fc->root->d_sb;
- if (!ns_capable(sb->s_user_ns, CAP_SYS_ADMIN)) {
- ret = -EPERM;
- break;
- }
- down_write(&sb->s_umount);
- ret = reconfigure_super(fc);
- up_write(&sb->s_umount);
- if (ret)
- break;
- vfs_clean_context(fc);
- return 0;
+ return vfs_cmd_reconfigure(fc);
default:
if (fc->phase != FS_CONTEXT_CREATE_PARAMS &&
fc->phase != FS_CONTEXT_RECONF_PARAMS)
@@ -281,8 +294,6 @@ static int vfs_fsconfig_locked(struct fs_context *fc, int cmd,
return vfs_parse_fs_param(fc, param);
}
- fc->phase = FS_CONTEXT_FAILED;
- return ret;
}
/**