mirror of
https://github.com/tbsdtv/linux_media.git
synced 2025-07-23 04:33:26 +02:00
vfs: Add a single-or-reconfig keying to vfs_get_super()
Add an additional keying mode to vfs_get_super() to indicate that only a single superblock should exist in the system, and that, if it does, further mounts should invoke reconfiguration upon it. This allows mount_single() to be replaced. [Fix by Eric Biggers folded in] Signed-off-by: David Howells <dhowells@redhat.com> Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
This commit is contained in:
35
fs/super.c
35
fs/super.c
@@ -1160,9 +1160,11 @@ int vfs_get_super(struct fs_context *fc,
|
||||
{
|
||||
int (*test)(struct super_block *, struct fs_context *);
|
||||
struct super_block *sb;
|
||||
int err;
|
||||
|
||||
switch (keying) {
|
||||
case vfs_get_single_super:
|
||||
case vfs_get_single_reconf_super:
|
||||
test = test_single_super;
|
||||
break;
|
||||
case vfs_get_keyed_super:
|
||||
@@ -1180,18 +1182,29 @@ int vfs_get_super(struct fs_context *fc,
|
||||
return PTR_ERR(sb);
|
||||
|
||||
if (!sb->s_root) {
|
||||
int err = fill_super(sb, fc);
|
||||
if (err) {
|
||||
deactivate_locked_super(sb);
|
||||
return err;
|
||||
}
|
||||
err = fill_super(sb, fc);
|
||||
if (err)
|
||||
goto error;
|
||||
|
||||
sb->s_flags |= SB_ACTIVE;
|
||||
fc->root = dget(sb->s_root);
|
||||
} else {
|
||||
fc->root = dget(sb->s_root);
|
||||
if (keying == vfs_get_single_reconf_super) {
|
||||
err = reconfigure_super(fc);
|
||||
if (err < 0) {
|
||||
dput(fc->root);
|
||||
fc->root = NULL;
|
||||
goto error;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
BUG_ON(fc->root);
|
||||
fc->root = dget(sb->s_root);
|
||||
return 0;
|
||||
|
||||
error:
|
||||
deactivate_locked_super(sb);
|
||||
return err;
|
||||
}
|
||||
EXPORT_SYMBOL(vfs_get_super);
|
||||
|
||||
@@ -1211,6 +1224,14 @@ int get_tree_single(struct fs_context *fc,
|
||||
}
|
||||
EXPORT_SYMBOL(get_tree_single);
|
||||
|
||||
int get_tree_single_reconf(struct fs_context *fc,
|
||||
int (*fill_super)(struct super_block *sb,
|
||||
struct fs_context *fc))
|
||||
{
|
||||
return vfs_get_super(fc, vfs_get_single_reconf_super, fill_super);
|
||||
}
|
||||
EXPORT_SYMBOL(get_tree_single_reconf);
|
||||
|
||||
int get_tree_keyed(struct fs_context *fc,
|
||||
int (*fill_super)(struct super_block *sb,
|
||||
struct fs_context *fc),
|
||||
|
Reference in New Issue
Block a user