summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--fs/fs_context.c8
-rw-r--r--fs/internal.h1
-rw-r--r--fs/namespace.c12
-rw-r--r--fs/super.c15
4 files changed, 19 insertions, 17 deletions
diff --git a/fs/fs_context.c b/fs/fs_context.c
index 4294091b689d..857cd46a687b 100644
--- a/fs/fs_context.c
+++ b/fs/fs_context.c
@@ -90,6 +90,14 @@ struct fs_context *fs_context_for_mount(struct file_system_type *fs_type,
}
EXPORT_SYMBOL(fs_context_for_mount);
+void fc_drop_locked(struct fs_context *fc)
+{
+ struct super_block *sb = fc->root->d_sb;
+ dput(fc->root);
+ fc->root = NULL;
+ deactivate_locked_super(sb);
+}
+
static void legacy_fs_context_free(struct fs_context *fc);
/**
* put_fs_context - Dispose of a superblock configuration context.
diff --git a/fs/internal.h b/fs/internal.h
index f85c3212d25d..6af26d897034 100644
--- a/fs/internal.h
+++ b/fs/internal.h
@@ -57,6 +57,7 @@ extern void __init chrdev_init(void);
*/
extern int legacy_get_tree(struct fs_context *fc);
extern int parse_monolithic_mount_data(struct fs_context *, void *);
+extern void fc_drop_locked(struct fs_context *);
/*
* namei.c
diff --git a/fs/namespace.c b/fs/namespace.c
index f629e1c7f3cc..750500c6c33d 100644
--- a/fs/namespace.c
+++ b/fs/namespace.c
@@ -2536,11 +2536,13 @@ static int do_new_mount_fc(struct fs_context *fc, struct path *mountpoint,
struct super_block *sb = fc->root->d_sb;
int error;
- if (mount_too_revealing(sb, &mnt_flags)) {
- dput(fc->root);
- fc->root = NULL;
- deactivate_locked_super(sb);
- return -EPERM;
+ error = security_sb_kern_mount(sb);
+ if (!error && mount_too_revealing(sb, &mnt_flags))
+ error = -EPERM;
+
+ if (unlikely(error)) {
+ fc_drop_locked(fc);
+ return error;
}
up_write(&sb->s_umount);
diff --git a/fs/super.c b/fs/super.c
index b91b6df05b67..11e2a6cb3baf 100644
--- a/fs/super.c
+++ b/fs/super.c
@@ -1277,13 +1277,9 @@ int vfs_get_tree(struct fs_context *fc)
sb->s_flags |= SB_BORN;
error = security_sb_set_mnt_opts(sb, fc->security, 0, NULL);
- if (error)
- goto out_sb;
-
- if (!(fc->sb_flags & (MS_KERNMOUNT|MS_SUBMOUNT))) {
- error = security_sb_kern_mount(sb);
- if (error)
- goto out_sb;
+ if (unlikely(error)) {
+ fc_drop_locked(fc);
+ return error;
}
/*
@@ -1296,11 +1292,6 @@ int vfs_get_tree(struct fs_context *fc)
"negative value (%lld)\n", fc->fs_type->name, sb->s_maxbytes);
return 0;
-out_sb:
- dput(fc->root);
- fc->root = NULL;
- deactivate_locked_super(sb);
- return error;
}
EXPORT_SYMBOL(vfs_get_tree);