diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2017-09-14 21:54:01 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2017-09-14 21:54:01 -0400 |
commit | 0f0d12728e56c94d3289c6831243b6faeae8a19d (patch) | |
tree | bd52fd4ed6fba2a0d8bb95e7fc33f51ac299001d /fs/namespace.c | |
parent | 581bfce969cbfc7ce43ee92273be9cb7c3fdfa61 (diff) | |
parent | e462ec50cb5fad19f6003a3d8087f4a0945dd2b1 (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.c | 62 |
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 | } |
1066 | EXPORT_SYMBOL_GPL(vfs_submount); | 1066 | EXPORT_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 | ||
2118 | static int graft_tree(struct mount *mnt, struct mount *p, struct mountpoint *mp) | 2118 | static 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 | ||
2134 | static int flags_to_propagation_type(int flags) | 2134 | static 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 | */ |
2150 | static int do_change_type(struct path *path, int flag) | 2150 | static 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 | */ |
2283 | static int do_remount(struct path *path, int flags, int mnt_flags, | 2283 | static 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 | */ |
2498 | static int do_new_mount(struct path *path, const char *fstype, int flags, | 2498 | static 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); |
2836 | dput_out: | 2842 | dput_out: |
2837 | path_put(&path); | 2843 | path_put(&path); |
@@ -3281,7 +3287,7 @@ void put_mnt_ns(struct mnt_namespace *ns) | |||
3281 | struct vfsmount *kern_mount_data(struct file_system_type *type, void *data) | 3287 | struct 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 |