aboutsummaryrefslogtreecommitdiffstats
path: root/fs/namespace.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2017-09-14 21:54:01 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2017-09-14 21:54:01 -0400
commit0f0d12728e56c94d3289c6831243b6faeae8a19d (patch)
treebd52fd4ed6fba2a0d8bb95e7fc33f51ac299001d /fs/namespace.c
parent581bfce969cbfc7ce43ee92273be9cb7c3fdfa61 (diff)
parente462ec50cb5fad19f6003a3d8087f4a0945dd2b1 (diff)
Merge branch 'work.mount' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs
Pull mount flag updates from Al Viro: "Another chunk of fmount preparations from dhowells; only trivial conflicts for that part. It separates MS_... bits (very grotty mount(2) ABI) from the struct super_block ->s_flags (kernel-internal, only a small subset of MS_... stuff). This does *not* convert the filesystems to new constants; only the infrastructure is done here. The next step in that series is where the conflicts would be; that's the conversion of filesystems. It's purely mechanical and it's better done after the merge, so if you could run something like list=$(for i in MS_RDONLY MS_NOSUID MS_NODEV MS_NOEXEC MS_SYNCHRONOUS MS_MANDLOCK MS_DIRSYNC MS_NOATIME MS_NODIRATIME MS_SILENT MS_POSIXACL MS_KERNMOUNT MS_I_VERSION MS_LAZYTIME; do git grep -l $i fs drivers/staging/lustre drivers/mtd ipc mm include/linux; done|sort|uniq|grep -v '^fs/namespace.c$') sed -i -e 's/\<MS_RDONLY\>/SB_RDONLY/g' \ -e 's/\<MS_NOSUID\>/SB_NOSUID/g' \ -e 's/\<MS_NODEV\>/SB_NODEV/g' \ -e 's/\<MS_NOEXEC\>/SB_NOEXEC/g' \ -e 's/\<MS_SYNCHRONOUS\>/SB_SYNCHRONOUS/g' \ -e 's/\<MS_MANDLOCK\>/SB_MANDLOCK/g' \ -e 's/\<MS_DIRSYNC\>/SB_DIRSYNC/g' \ -e 's/\<MS_NOATIME\>/SB_NOATIME/g' \ -e 's/\<MS_NODIRATIME\>/SB_NODIRATIME/g' \ -e 's/\<MS_SILENT\>/SB_SILENT/g' \ -e 's/\<MS_POSIXACL\>/SB_POSIXACL/g' \ -e 's/\<MS_KERNMOUNT\>/SB_KERNMOUNT/g' \ -e 's/\<MS_I_VERSION\>/SB_I_VERSION/g' \ -e 's/\<MS_LAZYTIME\>/SB_LAZYTIME/g' \ $list and commit it with something along the lines of 'convert filesystems away from use of MS_... constants' as commit message, it would save a quite a bit of headache next cycle" * 'work.mount' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs: VFS: Differentiate mount flags (MS_*) from internal superblock flags VFS: Convert sb->s_flags & MS_RDONLY to sb_rdonly(sb) vfs: Add sb_rdonly(sb) to query the MS_RDONLY flag on s_flags
Diffstat (limited to 'fs/namespace.c')
-rw-r--r--fs/namespace.c62
1 files changed, 34 insertions, 28 deletions
diff --git a/fs/namespace.c b/fs/namespace.c
index df0f7521979a..e48ad0192d81 100644
--- a/fs/namespace.c
+++ b/fs/namespace.c
@@ -275,7 +275,7 @@ int __mnt_is_readonly(struct vfsmount *mnt)
275{ 275{
276 if (mnt->mnt_flags & MNT_READONLY) 276 if (mnt->mnt_flags & MNT_READONLY)
277 return 1; 277 return 1;
278 if (mnt->mnt_sb->s_flags & MS_RDONLY) 278 if (sb_rdonly(mnt->mnt_sb))
279 return 1; 279 return 1;
280 return 0; 280 return 0;
281} 281}
@@ -1029,7 +1029,7 @@ vfs_kern_mount(struct file_system_type *type, int flags, const char *name, void
1029 if (!mnt) 1029 if (!mnt)
1030 return ERR_PTR(-ENOMEM); 1030 return ERR_PTR(-ENOMEM);
1031 1031
1032 if (flags & MS_KERNMOUNT) 1032 if (flags & SB_KERNMOUNT)
1033 mnt->mnt.mnt_flags = MNT_INTERNAL; 1033 mnt->mnt.mnt_flags = MNT_INTERNAL;
1034 1034
1035 root = mount_fs(type, flags, name, data); 1035 root = mount_fs(type, flags, name, data);
@@ -1061,7 +1061,7 @@ vfs_submount(const struct dentry *mountpoint, struct file_system_type *type,
1061 if (mountpoint->d_sb->s_user_ns != &init_user_ns) 1061 if (mountpoint->d_sb->s_user_ns != &init_user_ns)
1062 return ERR_PTR(-EPERM); 1062 return ERR_PTR(-EPERM);
1063 1063
1064 return vfs_kern_mount(type, MS_SUBMOUNT, name, data); 1064 return vfs_kern_mount(type, SB_SUBMOUNT, name, data);
1065} 1065}
1066EXPORT_SYMBOL_GPL(vfs_submount); 1066EXPORT_SYMBOL_GPL(vfs_submount);
1067 1067
@@ -1592,8 +1592,8 @@ static int do_umount(struct mount *mnt, int flags)
1592 if (!capable(CAP_SYS_ADMIN)) 1592 if (!capable(CAP_SYS_ADMIN))
1593 return -EPERM; 1593 return -EPERM;
1594 down_write(&sb->s_umount); 1594 down_write(&sb->s_umount);
1595 if (!(sb->s_flags & MS_RDONLY)) 1595 if (!sb_rdonly(sb))
1596 retval = do_remount_sb(sb, MS_RDONLY, NULL, 0); 1596 retval = do_remount_sb(sb, SB_RDONLY, NULL, 0);
1597 up_write(&sb->s_umount); 1597 up_write(&sb->s_umount);
1598 return retval; 1598 return retval;
1599 } 1599 }
@@ -2117,7 +2117,7 @@ static void unlock_mount(struct mountpoint *where)
2117 2117
2118static int graft_tree(struct mount *mnt, struct mount *p, struct mountpoint *mp) 2118static int graft_tree(struct mount *mnt, struct mount *p, struct mountpoint *mp)
2119{ 2119{
2120 if (mnt->mnt.mnt_sb->s_flags & MS_NOUSER) 2120 if (mnt->mnt.mnt_sb->s_flags & SB_NOUSER)
2121 return -EINVAL; 2121 return -EINVAL;
2122 2122
2123 if (d_is_dir(mp->m_dentry) != 2123 if (d_is_dir(mp->m_dentry) !=
@@ -2131,9 +2131,9 @@ static int graft_tree(struct mount *mnt, struct mount *p, struct mountpoint *mp)
2131 * Sanity check the flags to change_mnt_propagation. 2131 * Sanity check the flags to change_mnt_propagation.
2132 */ 2132 */
2133 2133
2134static int flags_to_propagation_type(int flags) 2134static int flags_to_propagation_type(int ms_flags)
2135{ 2135{
2136 int type = flags & ~(MS_REC | MS_SILENT); 2136 int type = ms_flags & ~(MS_REC | MS_SILENT);
2137 2137
2138 /* Fail if any non-propagation flags are set */ 2138 /* Fail if any non-propagation flags are set */
2139 if (type & ~(MS_SHARED | MS_PRIVATE | MS_SLAVE | MS_UNBINDABLE)) 2139 if (type & ~(MS_SHARED | MS_PRIVATE | MS_SLAVE | MS_UNBINDABLE))
@@ -2147,18 +2147,18 @@ static int flags_to_propagation_type(int flags)
2147/* 2147/*
2148 * recursively change the type of the mountpoint. 2148 * recursively change the type of the mountpoint.
2149 */ 2149 */
2150static int do_change_type(struct path *path, int flag) 2150static int do_change_type(struct path *path, int ms_flags)
2151{ 2151{
2152 struct mount *m; 2152 struct mount *m;
2153 struct mount *mnt = real_mount(path->mnt); 2153 struct mount *mnt = real_mount(path->mnt);
2154 int recurse = flag & MS_REC; 2154 int recurse = ms_flags & MS_REC;
2155 int type; 2155 int type;
2156 int err = 0; 2156 int err = 0;
2157 2157
2158 if (path->dentry != path->mnt->mnt_root) 2158 if (path->dentry != path->mnt->mnt_root)
2159 return -EINVAL; 2159 return -EINVAL;
2160 2160
2161 type = flags_to_propagation_type(flag); 2161 type = flags_to_propagation_type(ms_flags);
2162 if (!type) 2162 if (!type)
2163 return -EINVAL; 2163 return -EINVAL;
2164 2164
@@ -2280,8 +2280,8 @@ static int change_mount_flags(struct vfsmount *mnt, int ms_flags)
2280 * If you've mounted a non-root directory somewhere and want to do remount 2280 * If you've mounted a non-root directory somewhere and want to do remount
2281 * on it - tough luck. 2281 * on it - tough luck.
2282 */ 2282 */
2283static int do_remount(struct path *path, int flags, int mnt_flags, 2283static int do_remount(struct path *path, int ms_flags, int sb_flags,
2284 void *data) 2284 int mnt_flags, void *data)
2285{ 2285{
2286 int err; 2286 int err;
2287 struct super_block *sb = path->mnt->mnt_sb; 2287 struct super_block *sb = path->mnt->mnt_sb;
@@ -2325,12 +2325,12 @@ static int do_remount(struct path *path, int flags, int mnt_flags,
2325 return err; 2325 return err;
2326 2326
2327 down_write(&sb->s_umount); 2327 down_write(&sb->s_umount);
2328 if (flags & MS_BIND) 2328 if (ms_flags & MS_BIND)
2329 err = change_mount_flags(path->mnt, flags); 2329 err = change_mount_flags(path->mnt, ms_flags);
2330 else if (!capable(CAP_SYS_ADMIN)) 2330 else if (!capable(CAP_SYS_ADMIN))
2331 err = -EPERM; 2331 err = -EPERM;
2332 else 2332 else
2333 err = do_remount_sb(sb, flags, data, 0); 2333 err = do_remount_sb(sb, sb_flags, data, 0);
2334 if (!err) { 2334 if (!err) {
2335 lock_mount_hash(); 2335 lock_mount_hash();
2336 mnt_flags |= mnt->mnt.mnt_flags & ~MNT_USER_SETTABLE_MASK; 2336 mnt_flags |= mnt->mnt.mnt_flags & ~MNT_USER_SETTABLE_MASK;
@@ -2495,7 +2495,7 @@ static bool mount_too_revealing(struct vfsmount *mnt, int *new_mnt_flags);
2495 * create a new mount for userspace and request it to be added into the 2495 * create a new mount for userspace and request it to be added into the
2496 * namespace's tree 2496 * namespace's tree
2497 */ 2497 */
2498static int do_new_mount(struct path *path, const char *fstype, int flags, 2498static int do_new_mount(struct path *path, const char *fstype, int sb_flags,
2499 int mnt_flags, const char *name, void *data) 2499 int mnt_flags, const char *name, void *data)
2500{ 2500{
2501 struct file_system_type *type; 2501 struct file_system_type *type;
@@ -2509,7 +2509,7 @@ static int do_new_mount(struct path *path, const char *fstype, int flags,
2509 if (!type) 2509 if (!type)
2510 return -ENODEV; 2510 return -ENODEV;
2511 2511
2512 mnt = vfs_kern_mount(type, flags, name, data); 2512 mnt = vfs_kern_mount(type, sb_flags, name, data);
2513 if (!IS_ERR(mnt) && (type->fs_flags & FS_HAS_SUBTYPE) && 2513 if (!IS_ERR(mnt) && (type->fs_flags & FS_HAS_SUBTYPE) &&
2514 !mnt->mnt_sb->s_subtype) 2514 !mnt->mnt_sb->s_subtype)
2515 mnt = fs_set_subtype(mnt, fstype); 2515 mnt = fs_set_subtype(mnt, fstype);
@@ -2764,8 +2764,8 @@ long do_mount(const char *dev_name, const char __user *dir_name,
2764 const char *type_page, unsigned long flags, void *data_page) 2764 const char *type_page, unsigned long flags, void *data_page)
2765{ 2765{
2766 struct path path; 2766 struct path path;
2767 unsigned int mnt_flags = 0, sb_flags;
2767 int retval = 0; 2768 int retval = 0;
2768 int mnt_flags = 0;
2769 2769
2770 /* Discard magic */ 2770 /* Discard magic */
2771 if ((flags & MS_MGC_MSK) == MS_MGC_VAL) 2771 if ((flags & MS_MGC_MSK) == MS_MGC_VAL)
@@ -2775,6 +2775,9 @@ long do_mount(const char *dev_name, const char __user *dir_name,
2775 if (data_page) 2775 if (data_page)
2776 ((char *)data_page)[PAGE_SIZE - 1] = 0; 2776 ((char *)data_page)[PAGE_SIZE - 1] = 0;
2777 2777
2778 if (flags & MS_NOUSER)
2779 return -EINVAL;
2780
2778 /* ... and get the mountpoint */ 2781 /* ... and get the mountpoint */
2779 retval = user_path(dir_name, &path); 2782 retval = user_path(dir_name, &path);
2780 if (retval) 2783 if (retval)
@@ -2784,7 +2787,7 @@ long do_mount(const char *dev_name, const char __user *dir_name,
2784 type_page, flags, data_page); 2787 type_page, flags, data_page);
2785 if (!retval && !may_mount()) 2788 if (!retval && !may_mount())
2786 retval = -EPERM; 2789 retval = -EPERM;
2787 if (!retval && (flags & MS_MANDLOCK) && !may_mandlock()) 2790 if (!retval && (flags & SB_MANDLOCK) && !may_mandlock())
2788 retval = -EPERM; 2791 retval = -EPERM;
2789 if (retval) 2792 if (retval)
2790 goto dput_out; 2793 goto dput_out;
@@ -2806,7 +2809,7 @@ long do_mount(const char *dev_name, const char __user *dir_name,
2806 mnt_flags |= MNT_NODIRATIME; 2809 mnt_flags |= MNT_NODIRATIME;
2807 if (flags & MS_STRICTATIME) 2810 if (flags & MS_STRICTATIME)
2808 mnt_flags &= ~(MNT_RELATIME | MNT_NOATIME); 2811 mnt_flags &= ~(MNT_RELATIME | MNT_NOATIME);
2809 if (flags & MS_RDONLY) 2812 if (flags & SB_RDONLY)
2810 mnt_flags |= MNT_READONLY; 2813 mnt_flags |= MNT_READONLY;
2811 2814
2812 /* The default atime for remount is preservation */ 2815 /* The default atime for remount is preservation */
@@ -2817,12 +2820,15 @@ long do_mount(const char *dev_name, const char __user *dir_name,
2817 mnt_flags |= path.mnt->mnt_flags & MNT_ATIME_MASK; 2820 mnt_flags |= path.mnt->mnt_flags & MNT_ATIME_MASK;
2818 } 2821 }
2819 2822
2820 flags &= ~(MS_NOSUID | MS_NOEXEC | MS_NODEV | MS_ACTIVE | MS_BORN | 2823 sb_flags = flags & (SB_RDONLY |
2821 MS_NOATIME | MS_NODIRATIME | MS_RELATIME| MS_KERNMOUNT | 2824 SB_SYNCHRONOUS |
2822 MS_STRICTATIME | MS_NOREMOTELOCK | MS_SUBMOUNT); 2825 SB_MANDLOCK |
2826 SB_DIRSYNC |
2827 SB_SILENT |
2828 SB_POSIXACL);
2823 2829
2824 if (flags & MS_REMOUNT) 2830 if (flags & MS_REMOUNT)
2825 retval = do_remount(&path, flags & ~MS_REMOUNT, mnt_flags, 2831 retval = do_remount(&path, flags, sb_flags, mnt_flags,
2826 data_page); 2832 data_page);
2827 else if (flags & MS_BIND) 2833 else if (flags & MS_BIND)
2828 retval = do_loopback(&path, dev_name, flags & MS_REC); 2834 retval = do_loopback(&path, dev_name, flags & MS_REC);
@@ -2831,7 +2837,7 @@ long do_mount(const char *dev_name, const char __user *dir_name,
2831 else if (flags & MS_MOVE) 2837 else if (flags & MS_MOVE)
2832 retval = do_move_mount(&path, dev_name); 2838 retval = do_move_mount(&path, dev_name);
2833 else 2839 else
2834 retval = do_new_mount(&path, type_page, flags, mnt_flags, 2840 retval = do_new_mount(&path, type_page, sb_flags, mnt_flags,
2835 dev_name, data_page); 2841 dev_name, data_page);
2836dput_out: 2842dput_out:
2837 path_put(&path); 2843 path_put(&path);
@@ -3281,7 +3287,7 @@ void put_mnt_ns(struct mnt_namespace *ns)
3281struct vfsmount *kern_mount_data(struct file_system_type *type, void *data) 3287struct vfsmount *kern_mount_data(struct file_system_type *type, void *data)
3282{ 3288{
3283 struct vfsmount *mnt; 3289 struct vfsmount *mnt;
3284 mnt = vfs_kern_mount(type, MS_KERNMOUNT, type->name, data); 3290 mnt = vfs_kern_mount(type, SB_KERNMOUNT, type->name, data);
3285 if (!IS_ERR(mnt)) { 3291 if (!IS_ERR(mnt)) {
3286 /* 3292 /*
3287 * it is a longterm mount, don't release mnt until 3293 * it is a longterm mount, don't release mnt until
@@ -3358,7 +3364,7 @@ static bool mnt_already_visible(struct mnt_namespace *ns, struct vfsmount *new,
3358 mnt_flags = mnt->mnt.mnt_flags; 3364 mnt_flags = mnt->mnt.mnt_flags;
3359 3365
3360 /* Don't miss readonly hidden in the superblock flags */ 3366 /* Don't miss readonly hidden in the superblock flags */
3361 if (mnt->mnt.mnt_sb->s_flags & MS_RDONLY) 3367 if (sb_rdonly(mnt->mnt.mnt_sb))
3362 mnt_flags |= MNT_LOCK_READONLY; 3368 mnt_flags |= MNT_LOCK_READONLY;
3363 3369
3364 /* Verify the mount flags are equal to or more permissive 3370 /* Verify the mount flags are equal to or more permissive