@@ -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.
@@ -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
@@ -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);
@@ -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);