ANDROID: mnt: Add filesystem private data to mount points
[GitHub/exynos8895/android_kernel_samsung_universal8895.git] / fs / namespace.c
index 0570729c87fd22dd299c50ee0303f43c384e4932..c38f318eb9df133b0e87e88abb84505123195ec1 100644 (file)
@@ -577,6 +577,7 @@ int sb_prepare_remount_readonly(struct super_block *sb)
 
 static void free_vfsmnt(struct mount *mnt)
 {
+       kfree(mnt->mnt.data);
        kfree_const(mnt->mnt_devname);
 #ifdef CONFIG_SMP
        free_percpu(mnt->mnt_pcp);
@@ -942,11 +943,21 @@ vfs_kern_mount(struct file_system_type *type, int flags, const char *name, void
        if (!mnt)
                return ERR_PTR(-ENOMEM);
 
+       mnt->mnt.data = NULL;
+       if (type->alloc_mnt_data) {
+               mnt->mnt.data = type->alloc_mnt_data();
+               if (!mnt->mnt.data) {
+                       mnt_free_id(mnt);
+                       free_vfsmnt(mnt);
+                       return ERR_PTR(-ENOMEM);
+               }
+       }
        if (flags & MS_KERNMOUNT)
                mnt->mnt.mnt_flags = MNT_INTERNAL;
 
        root = mount_fs(type, flags, name, data);
        if (IS_ERR(root)) {
+               kfree(mnt->mnt.data);
                mnt_free_id(mnt);
                free_vfsmnt(mnt);
                return ERR_CAST(root);
@@ -974,6 +985,14 @@ static struct mount *clone_mnt(struct mount *old, struct dentry *root,
        if (!mnt)
                return ERR_PTR(-ENOMEM);
 
+       if (sb->s_op->clone_mnt_data) {
+               mnt->mnt.data = sb->s_op->clone_mnt_data(old->mnt.data);
+               if (!mnt->mnt.data) {
+                       err = -ENOMEM;
+                       goto out_free;
+               }
+       }
+
        if (flag & (CL_SLAVE | CL_PRIVATE | CL_SHARED_TO_SLAVE))
                mnt->mnt_group_id = 0; /* not a peer of original */
        else
@@ -1042,6 +1061,7 @@ static struct mount *clone_mnt(struct mount *old, struct dentry *root,
        return mnt;
 
  out_free:
+       kfree(mnt->mnt.data);
        mnt_free_id(mnt);
        free_vfsmnt(mnt);
        return ERR_PTR(err);
@@ -2207,8 +2227,14 @@ static int do_remount(struct path *path, int flags, int mnt_flags,
                err = change_mount_flags(path->mnt, flags);
        else if (!capable(CAP_SYS_ADMIN))
                err = -EPERM;
-       else
+       else {
                err = do_remount_sb(sb, flags, data, 0);
+               namespace_lock();
+               lock_mount_hash();
+               propagate_remount(mnt);
+               unlock_mount_hash();
+               namespace_unlock();
+       }
        if (!err) {
                lock_mount_hash();
                mnt_flags |= mnt->mnt.mnt_flags & ~MNT_USER_SETTABLE_MASK;