clk: rockchip: support setting ddr clock via SCPI APIs
[firefly-linux-kernel-4.4.55.git] / fs / namespace.c
index 7df3d406d3e00f8e96060193df1c48aed53ed848..c1477882a8537094ea5ee2b5470b3be0d68c2994 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);
@@ -968,11 +969,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);
+       root = mount_fs(type, flags, name, &mnt->mnt, data);
        if (IS_ERR(root)) {
+               kfree(mnt->mnt.data);
                mnt_free_id(mnt);
                free_vfsmnt(mnt);
                return ERR_CAST(root);
@@ -1000,6 +1011,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
@@ -1068,6 +1087,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);
@@ -2243,8 +2263,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
-               err = do_remount_sb(sb, flags, data, 0);
+       else {
+               err = do_remount_sb2(path->mnt, 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;