Skip to content

Commit e462ec5

Browse files
committed
VFS: Differentiate mount flags (MS_*) from internal superblock flags
Differentiate the MS_* flags passed to mount(2) from the internal flags set in the super_block's s_flags. s_flags are now called SB_*, with the names and the values for the moment mirroring the MS_* flags that they're equivalent to. In this patch, just the headers are altered and some kernel code where blind automated conversion isn't necessarily correct. Note that this shows up some interesting issues: (1) Some MS_* flags get translated to MNT_* flags (such as MS_NODEV -> MNT_NODEV) without passing this on to the filesystem, but some filesystems set such flags anyway. (2) The ->remount_fs() methods of some filesystems adjust the *flags argument by setting MS_* flags in it, such as MS_NOATIME - but these flags are then scrubbed by do_remount_sb() (only the occupants of MS_RMT_MASK are permitted: MS_RDONLY, MS_SYNCHRONOUS, MS_MANDLOCK, MS_I_VERSION and MS_LAZYTIME) I'm not sure what's the best way to solve all these cases. Suggested-by: Al Viro <viro@ZenIV.linux.org.uk> Signed-off-by: David Howells <dhowells@redhat.com>
1 parent bc98a42 commit e462ec5

File tree

5 files changed

+104
-71
lines changed

5 files changed

+104
-71
lines changed

Documentation/filesystems/porting

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -228,7 +228,7 @@ anything from oops to silent memory corruption.
228228
---
229229
[mandatory]
230230

231-
FS_NOMOUNT is gone. If you use it - just set MS_NOUSER in flags
231+
FS_NOMOUNT is gone. If you use it - just set SB_NOUSER in flags
232232
(see rootfs for one kind of solution and bdev/socket/pipe for another).
233233

234234
---

fs/namespace.c

Lines changed: 31 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -971,7 +971,7 @@ vfs_kern_mount(struct file_system_type *type, int flags, const char *name, void
971971
if (!mnt)
972972
return ERR_PTR(-ENOMEM);
973973

974-
if (flags & MS_KERNMOUNT)
974+
if (flags & SB_KERNMOUNT)
975975
mnt->mnt.mnt_flags = MNT_INTERNAL;
976976

977977
root = mount_fs(type, flags, name, data);
@@ -1003,7 +1003,7 @@ vfs_submount(const struct dentry *mountpoint, struct file_system_type *type,
10031003
if (mountpoint->d_sb->s_user_ns != &init_user_ns)
10041004
return ERR_PTR(-EPERM);
10051005

1006-
return vfs_kern_mount(type, MS_SUBMOUNT, name, data);
1006+
return vfs_kern_mount(type, SB_SUBMOUNT, name, data);
10071007
}
10081008
EXPORT_SYMBOL_GPL(vfs_submount);
10091009

@@ -1535,7 +1535,7 @@ static int do_umount(struct mount *mnt, int flags)
15351535
return -EPERM;
15361536
down_write(&sb->s_umount);
15371537
if (!sb_rdonly(sb))
1538-
retval = do_remount_sb(sb, MS_RDONLY, NULL, 0);
1538+
retval = do_remount_sb(sb, SB_RDONLY, NULL, 0);
15391539
up_write(&sb->s_umount);
15401540
return retval;
15411541
}
@@ -2059,7 +2059,7 @@ static void unlock_mount(struct mountpoint *where)
20592059

20602060
static int graft_tree(struct mount *mnt, struct mount *p, struct mountpoint *mp)
20612061
{
2062-
if (mnt->mnt.mnt_sb->s_flags & MS_NOUSER)
2062+
if (mnt->mnt.mnt_sb->s_flags & SB_NOUSER)
20632063
return -EINVAL;
20642064

20652065
if (d_is_dir(mp->m_dentry) !=
@@ -2073,9 +2073,9 @@ static int graft_tree(struct mount *mnt, struct mount *p, struct mountpoint *mp)
20732073
* Sanity check the flags to change_mnt_propagation.
20742074
*/
20752075

2076-
static int flags_to_propagation_type(int flags)
2076+
static int flags_to_propagation_type(int ms_flags)
20772077
{
2078-
int type = flags & ~(MS_REC | MS_SILENT);
2078+
int type = ms_flags & ~(MS_REC | MS_SILENT);
20792079

20802080
/* Fail if any non-propagation flags are set */
20812081
if (type & ~(MS_SHARED | MS_PRIVATE | MS_SLAVE | MS_UNBINDABLE))
@@ -2089,18 +2089,18 @@ static int flags_to_propagation_type(int flags)
20892089
/*
20902090
* recursively change the type of the mountpoint.
20912091
*/
2092-
static int do_change_type(struct path *path, int flag)
2092+
static int do_change_type(struct path *path, int ms_flags)
20932093
{
20942094
struct mount *m;
20952095
struct mount *mnt = real_mount(path->mnt);
2096-
int recurse = flag & MS_REC;
2096+
int recurse = ms_flags & MS_REC;
20972097
int type;
20982098
int err = 0;
20992099

21002100
if (path->dentry != path->mnt->mnt_root)
21012101
return -EINVAL;
21022102

2103-
type = flags_to_propagation_type(flag);
2103+
type = flags_to_propagation_type(ms_flags);
21042104
if (!type)
21052105
return -EINVAL;
21062106

@@ -2222,8 +2222,8 @@ static int change_mount_flags(struct vfsmount *mnt, int ms_flags)
22222222
* If you've mounted a non-root directory somewhere and want to do remount
22232223
* on it - tough luck.
22242224
*/
2225-
static int do_remount(struct path *path, int flags, int mnt_flags,
2226-
void *data)
2225+
static int do_remount(struct path *path, int ms_flags, int sb_flags,
2226+
int mnt_flags, void *data)
22272227
{
22282228
int err;
22292229
struct super_block *sb = path->mnt->mnt_sb;
@@ -2267,12 +2267,12 @@ static int do_remount(struct path *path, int flags, int mnt_flags,
22672267
return err;
22682268

22692269
down_write(&sb->s_umount);
2270-
if (flags & MS_BIND)
2271-
err = change_mount_flags(path->mnt, flags);
2270+
if (ms_flags & MS_BIND)
2271+
err = change_mount_flags(path->mnt, ms_flags);
22722272
else if (!capable(CAP_SYS_ADMIN))
22732273
err = -EPERM;
22742274
else
2275-
err = do_remount_sb(sb, flags, data, 0);
2275+
err = do_remount_sb(sb, sb_flags, data, 0);
22762276
if (!err) {
22772277
lock_mount_hash();
22782278
mnt_flags |= mnt->mnt.mnt_flags & ~MNT_USER_SETTABLE_MASK;
@@ -2437,7 +2437,7 @@ static bool mount_too_revealing(struct vfsmount *mnt, int *new_mnt_flags);
24372437
* create a new mount for userspace and request it to be added into the
24382438
* namespace's tree
24392439
*/
2440-
static int do_new_mount(struct path *path, const char *fstype, int flags,
2440+
static int do_new_mount(struct path *path, const char *fstype, int sb_flags,
24412441
int mnt_flags, const char *name, void *data)
24422442
{
24432443
struct file_system_type *type;
@@ -2451,7 +2451,7 @@ static int do_new_mount(struct path *path, const char *fstype, int flags,
24512451
if (!type)
24522452
return -ENODEV;
24532453

2454-
mnt = vfs_kern_mount(type, flags, name, data);
2454+
mnt = vfs_kern_mount(type, sb_flags, name, data);
24552455
if (!IS_ERR(mnt) && (type->fs_flags & FS_HAS_SUBTYPE) &&
24562456
!mnt->mnt_sb->s_subtype)
24572457
mnt = fs_set_subtype(mnt, fstype);
@@ -2706,8 +2706,8 @@ long do_mount(const char *dev_name, const char __user *dir_name,
27062706
const char *type_page, unsigned long flags, void *data_page)
27072707
{
27082708
struct path path;
2709+
unsigned int mnt_flags = 0, sb_flags;
27092710
int retval = 0;
2710-
int mnt_flags = 0;
27112711

27122712
/* Discard magic */
27132713
if ((flags & MS_MGC_MSK) == MS_MGC_VAL)
@@ -2717,6 +2717,9 @@ long do_mount(const char *dev_name, const char __user *dir_name,
27172717
if (data_page)
27182718
((char *)data_page)[PAGE_SIZE - 1] = 0;
27192719

2720+
if (flags & MS_NOUSER)
2721+
return -EINVAL;
2722+
27202723
/* ... and get the mountpoint */
27212724
retval = user_path(dir_name, &path);
27222725
if (retval)
@@ -2726,7 +2729,7 @@ long do_mount(const char *dev_name, const char __user *dir_name,
27262729
type_page, flags, data_page);
27272730
if (!retval && !may_mount())
27282731
retval = -EPERM;
2729-
if (!retval && (flags & MS_MANDLOCK) && !may_mandlock())
2732+
if (!retval && (flags & SB_MANDLOCK) && !may_mandlock())
27302733
retval = -EPERM;
27312734
if (retval)
27322735
goto dput_out;
@@ -2748,7 +2751,7 @@ long do_mount(const char *dev_name, const char __user *dir_name,
27482751
mnt_flags |= MNT_NODIRATIME;
27492752
if (flags & MS_STRICTATIME)
27502753
mnt_flags &= ~(MNT_RELATIME | MNT_NOATIME);
2751-
if (flags & MS_RDONLY)
2754+
if (flags & SB_RDONLY)
27522755
mnt_flags |= MNT_READONLY;
27532756

27542757
/* The default atime for remount is preservation */
@@ -2759,12 +2762,15 @@ long do_mount(const char *dev_name, const char __user *dir_name,
27592762
mnt_flags |= path.mnt->mnt_flags & MNT_ATIME_MASK;
27602763
}
27612764

2762-
flags &= ~(MS_NOSUID | MS_NOEXEC | MS_NODEV | MS_ACTIVE | MS_BORN |
2763-
MS_NOATIME | MS_NODIRATIME | MS_RELATIME| MS_KERNMOUNT |
2764-
MS_STRICTATIME | MS_NOREMOTELOCK | MS_SUBMOUNT);
2765+
sb_flags = flags & (SB_RDONLY |
2766+
SB_SYNCHRONOUS |
2767+
SB_MANDLOCK |
2768+
SB_DIRSYNC |
2769+
SB_SILENT |
2770+
SB_POSIXACL);
27652771

27662772
if (flags & MS_REMOUNT)
2767-
retval = do_remount(&path, flags & ~MS_REMOUNT, mnt_flags,
2773+
retval = do_remount(&path, flags, sb_flags, mnt_flags,
27682774
data_page);
27692775
else if (flags & MS_BIND)
27702776
retval = do_loopback(&path, dev_name, flags & MS_REC);
@@ -2773,7 +2779,7 @@ long do_mount(const char *dev_name, const char __user *dir_name,
27732779
else if (flags & MS_MOVE)
27742780
retval = do_move_mount(&path, dev_name);
27752781
else
2776-
retval = do_new_mount(&path, type_page, flags, mnt_flags,
2782+
retval = do_new_mount(&path, type_page, sb_flags, mnt_flags,
27772783
dev_name, data_page);
27782784
dput_out:
27792785
path_put(&path);
@@ -3223,7 +3229,7 @@ void put_mnt_ns(struct mnt_namespace *ns)
32233229
struct vfsmount *kern_mount_data(struct file_system_type *type, void *data)
32243230
{
32253231
struct vfsmount *mnt;
3226-
mnt = vfs_kern_mount(type, MS_KERNMOUNT, type->name, data);
3232+
mnt = vfs_kern_mount(type, SB_KERNMOUNT, type->name, data);
32273233
if (!IS_ERR(mnt)) {
32283234
/*
32293235
* it is a longterm mount, don't release mnt until

0 commit comments

Comments
 (0)