aboutsummaryrefslogtreecommitdiffstats
path: root/fs/super.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/super.c')
-rw-r--r--fs/super.c27
1 files changed, 27 insertions, 0 deletions
diff --git a/fs/super.c b/fs/super.c
index 8341e4e1d738..5260d620c555 100644
--- a/fs/super.c
+++ b/fs/super.c
@@ -107,6 +107,7 @@ out:
107static inline void destroy_super(struct super_block *s) 107static inline void destroy_super(struct super_block *s)
108{ 108{
109 security_sb_free(s); 109 security_sb_free(s);
110 kfree(s->s_subtype);
110 kfree(s); 111 kfree(s);
111} 112}
112 113
@@ -907,6 +908,29 @@ out:
907 908
908EXPORT_SYMBOL_GPL(vfs_kern_mount); 909EXPORT_SYMBOL_GPL(vfs_kern_mount);
909 910
911static struct vfsmount *fs_set_subtype(struct vfsmount *mnt, const char *fstype)
912{
913 int err;
914 const char *subtype = strchr(fstype, '.');
915 if (subtype) {
916 subtype++;
917 err = -EINVAL;
918 if (!subtype[0])
919 goto err;
920 } else
921 subtype = "";
922
923 mnt->mnt_sb->s_subtype = kstrdup(subtype, GFP_KERNEL);
924 err = -ENOMEM;
925 if (!mnt->mnt_sb->s_subtype)
926 goto err;
927 return mnt;
928
929 err:
930 mntput(mnt);
931 return ERR_PTR(err);
932}
933
910struct vfsmount * 934struct vfsmount *
911do_kern_mount(const char *fstype, int flags, const char *name, void *data) 935do_kern_mount(const char *fstype, int flags, const char *name, void *data)
912{ 936{
@@ -915,6 +939,9 @@ do_kern_mount(const char *fstype, int flags, const char *name, void *data)
915 if (!type) 939 if (!type)
916 return ERR_PTR(-ENODEV); 940 return ERR_PTR(-ENODEV);
917 mnt = vfs_kern_mount(type, flags, name, data); 941 mnt = vfs_kern_mount(type, flags, name, data);
942 if (!IS_ERR(mnt) && (type->fs_flags & FS_HAS_SUBTYPE) &&
943 !mnt->mnt_sb->s_subtype)
944 mnt = fs_set_subtype(mnt, fstype);
918 put_filesystem(type); 945 put_filesystem(type);
919 return mnt; 946 return mnt;
920} 947}