OSDN Git Service

Merge 4.9.120 into android-4.9
[android-x86/kernel.git] / fs / namespace.c
index 0a9e766..c2a51a8 100644 (file)
@@ -227,6 +227,7 @@ static struct mount *alloc_vfsmnt(const char *name)
                mnt->mnt_count = 1;
                mnt->mnt_writers = 0;
 #endif
+               mnt->mnt.data = NULL;
 
                INIT_HLIST_NODE(&mnt->mnt_hash);
                INIT_LIST_HEAD(&mnt->mnt_child);
@@ -581,6 +582,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);
@@ -984,10 +986,18 @@ vfs_kern_mount(struct file_system_type *type, int flags, const char *name, void
        if (!mnt)
                return ERR_PTR(-ENOMEM);
 
+       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)) {
                mnt_free_id(mnt);
                free_vfsmnt(mnt);
@@ -1031,6 +1041,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
@@ -2330,8 +2348,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;