diff options
Diffstat (limited to 'fs/super.c')
| -rw-r--r-- | fs/super.c | 27 | 
1 files changed, 27 insertions, 0 deletions
diff --git a/fs/super.c b/fs/super.c index 8341e4e1d73..5260d620c55 100644 --- a/fs/super.c +++ b/fs/super.c @@ -107,6 +107,7 @@ out:  static inline void destroy_super(struct super_block *s)  {  	security_sb_free(s); +	kfree(s->s_subtype);  	kfree(s);  } @@ -907,6 +908,29 @@ out:  EXPORT_SYMBOL_GPL(vfs_kern_mount); +static struct vfsmount *fs_set_subtype(struct vfsmount *mnt, const char *fstype) +{ +	int err; +	const char *subtype = strchr(fstype, '.'); +	if (subtype) { +		subtype++; +		err = -EINVAL; +		if (!subtype[0]) +			goto err; +	} else +		subtype = ""; + +	mnt->mnt_sb->s_subtype = kstrdup(subtype, GFP_KERNEL); +	err = -ENOMEM; +	if (!mnt->mnt_sb->s_subtype) +		goto err; +	return mnt; + + err: +	mntput(mnt); +	return ERR_PTR(err); +} +  struct vfsmount *  do_kern_mount(const char *fstype, int flags, const char *name, void *data)  { @@ -915,6 +939,9 @@ do_kern_mount(const char *fstype, int flags, const char *name, void *data)  	if (!type)  		return ERR_PTR(-ENODEV);  	mnt = vfs_kern_mount(type, flags, name, data); +	if (!IS_ERR(mnt) && (type->fs_flags & FS_HAS_SUBTYPE) && +	    !mnt->mnt_sb->s_subtype) +		mnt = fs_set_subtype(mnt, fstype);  	put_filesystem(type);  	return mnt;  }  | 
