Commit e462ec50 authored by David Howells's avatar David Howells

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: default avatarAl Viro <viro@ZenIV.linux.org.uk>
Signed-off-by: default avatarDavid Howells <dhowells@redhat.com>
parent bc98a42c
...@@ -228,7 +228,7 @@ anything from oops to silent memory corruption. ...@@ -228,7 +228,7 @@ anything from oops to silent memory corruption.
--- ---
[mandatory] [mandatory]
FS_NOMOUNT is gone. If you use it - just set MS_NOUSER in flags FS_NOMOUNT is gone. If you use it - just set SB_NOUSER in flags
(see rootfs for one kind of solution and bdev/socket/pipe for another). (see rootfs for one kind of solution and bdev/socket/pipe for another).
--- ---
......
...@@ -971,7 +971,7 @@ vfs_kern_mount(struct file_system_type *type, int flags, const char *name, void ...@@ -971,7 +971,7 @@ vfs_kern_mount(struct file_system_type *type, int flags, const char *name, void
if (!mnt) if (!mnt)
return ERR_PTR(-ENOMEM); return ERR_PTR(-ENOMEM);
if (flags & MS_KERNMOUNT) if (flags & SB_KERNMOUNT)
mnt->mnt.mnt_flags = MNT_INTERNAL; mnt->mnt.mnt_flags = MNT_INTERNAL;
root = mount_fs(type, flags, name, data); root = mount_fs(type, flags, name, data);
...@@ -1003,7 +1003,7 @@ vfs_submount(const struct dentry *mountpoint, struct file_system_type *type, ...@@ -1003,7 +1003,7 @@ vfs_submount(const struct dentry *mountpoint, struct file_system_type *type,
if (mountpoint->d_sb->s_user_ns != &init_user_ns) if (mountpoint->d_sb->s_user_ns != &init_user_ns)
return ERR_PTR(-EPERM); return ERR_PTR(-EPERM);
return vfs_kern_mount(type, MS_SUBMOUNT, name, data); return vfs_kern_mount(type, SB_SUBMOUNT, name, data);
} }
EXPORT_SYMBOL_GPL(vfs_submount); EXPORT_SYMBOL_GPL(vfs_submount);
...@@ -1535,7 +1535,7 @@ static int do_umount(struct mount *mnt, int flags) ...@@ -1535,7 +1535,7 @@ static int do_umount(struct mount *mnt, int flags)
return -EPERM; return -EPERM;
down_write(&sb->s_umount); down_write(&sb->s_umount);
if (!sb_rdonly(sb)) if (!sb_rdonly(sb))
retval = do_remount_sb(sb, MS_RDONLY, NULL, 0); retval = do_remount_sb(sb, SB_RDONLY, NULL, 0);
up_write(&sb->s_umount); up_write(&sb->s_umount);
return retval; return retval;
} }
...@@ -2059,7 +2059,7 @@ static void unlock_mount(struct mountpoint *where) ...@@ -2059,7 +2059,7 @@ static void unlock_mount(struct mountpoint *where)
static int graft_tree(struct mount *mnt, struct mount *p, struct mountpoint *mp) static int graft_tree(struct mount *mnt, struct mount *p, struct mountpoint *mp)
{ {
if (mnt->mnt.mnt_sb->s_flags & MS_NOUSER) if (mnt->mnt.mnt_sb->s_flags & SB_NOUSER)
return -EINVAL; return -EINVAL;
if (d_is_dir(mp->m_dentry) != if (d_is_dir(mp->m_dentry) !=
...@@ -2073,9 +2073,9 @@ static int graft_tree(struct mount *mnt, struct mount *p, struct mountpoint *mp) ...@@ -2073,9 +2073,9 @@ static int graft_tree(struct mount *mnt, struct mount *p, struct mountpoint *mp)
* Sanity check the flags to change_mnt_propagation. * Sanity check the flags to change_mnt_propagation.
*/ */
static int flags_to_propagation_type(int flags) static int flags_to_propagation_type(int ms_flags)
{ {
int type = flags & ~(MS_REC | MS_SILENT); int type = ms_flags & ~(MS_REC | MS_SILENT);
/* Fail if any non-propagation flags are set */ /* Fail if any non-propagation flags are set */
if (type & ~(MS_SHARED | MS_PRIVATE | MS_SLAVE | MS_UNBINDABLE)) if (type & ~(MS_SHARED | MS_PRIVATE | MS_SLAVE | MS_UNBINDABLE))
...@@ -2089,18 +2089,18 @@ static int flags_to_propagation_type(int flags) ...@@ -2089,18 +2089,18 @@ static int flags_to_propagation_type(int flags)
/* /*
* recursively change the type of the mountpoint. * recursively change the type of the mountpoint.
*/ */
static int do_change_type(struct path *path, int flag) static int do_change_type(struct path *path, int ms_flags)
{ {
struct mount *m; struct mount *m;
struct mount *mnt = real_mount(path->mnt); struct mount *mnt = real_mount(path->mnt);
int recurse = flag & MS_REC; int recurse = ms_flags & MS_REC;
int type; int type;
int err = 0; int err = 0;
if (path->dentry != path->mnt->mnt_root) if (path->dentry != path->mnt->mnt_root)
return -EINVAL; return -EINVAL;
type = flags_to_propagation_type(flag); type = flags_to_propagation_type(ms_flags);
if (!type) if (!type)
return -EINVAL; return -EINVAL;
...@@ -2222,8 +2222,8 @@ static int change_mount_flags(struct vfsmount *mnt, int ms_flags) ...@@ -2222,8 +2222,8 @@ static int change_mount_flags(struct vfsmount *mnt, int ms_flags)
* If you've mounted a non-root directory somewhere and want to do remount * If you've mounted a non-root directory somewhere and want to do remount
* on it - tough luck. * on it - tough luck.
*/ */
static int do_remount(struct path *path, int flags, int mnt_flags, static int do_remount(struct path *path, int ms_flags, int sb_flags,
void *data) int mnt_flags, void *data)
{ {
int err; int err;
struct super_block *sb = path->mnt->mnt_sb; struct super_block *sb = path->mnt->mnt_sb;
...@@ -2267,12 +2267,12 @@ static int do_remount(struct path *path, int flags, int mnt_flags, ...@@ -2267,12 +2267,12 @@ static int do_remount(struct path *path, int flags, int mnt_flags,
return err; return err;
down_write(&sb->s_umount); down_write(&sb->s_umount);
if (flags & MS_BIND) if (ms_flags & MS_BIND)
err = change_mount_flags(path->mnt, flags); err = change_mount_flags(path->mnt, ms_flags);
else if (!capable(CAP_SYS_ADMIN)) else if (!capable(CAP_SYS_ADMIN))
err = -EPERM; err = -EPERM;
else else
err = do_remount_sb(sb, flags, data, 0); err = do_remount_sb(sb, sb_flags, data, 0);
if (!err) { if (!err) {
lock_mount_hash(); lock_mount_hash();
mnt_flags |= mnt->mnt.mnt_flags & ~MNT_USER_SETTABLE_MASK; 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); ...@@ -2437,7 +2437,7 @@ static bool mount_too_revealing(struct vfsmount *mnt, int *new_mnt_flags);
* create a new mount for userspace and request it to be added into the * create a new mount for userspace and request it to be added into the
* namespace's tree * namespace's tree
*/ */
static int do_new_mount(struct path *path, const char *fstype, int flags, static int do_new_mount(struct path *path, const char *fstype, int sb_flags,
int mnt_flags, const char *name, void *data) int mnt_flags, const char *name, void *data)
{ {
struct file_system_type *type; struct file_system_type *type;
...@@ -2451,7 +2451,7 @@ static int do_new_mount(struct path *path, const char *fstype, int flags, ...@@ -2451,7 +2451,7 @@ static int do_new_mount(struct path *path, const char *fstype, int flags,
if (!type) if (!type)
return -ENODEV; return -ENODEV;
mnt = vfs_kern_mount(type, flags, name, data); mnt = vfs_kern_mount(type, sb_flags, name, data);
if (!IS_ERR(mnt) && (type->fs_flags & FS_HAS_SUBTYPE) && if (!IS_ERR(mnt) && (type->fs_flags & FS_HAS_SUBTYPE) &&
!mnt->mnt_sb->s_subtype) !mnt->mnt_sb->s_subtype)
mnt = fs_set_subtype(mnt, fstype); mnt = fs_set_subtype(mnt, fstype);
...@@ -2706,8 +2706,8 @@ long do_mount(const char *dev_name, const char __user *dir_name, ...@@ -2706,8 +2706,8 @@ long do_mount(const char *dev_name, const char __user *dir_name,
const char *type_page, unsigned long flags, void *data_page) const char *type_page, unsigned long flags, void *data_page)
{ {
struct path path; struct path path;
unsigned int mnt_flags = 0, sb_flags;
int retval = 0; int retval = 0;
int mnt_flags = 0;
/* Discard magic */ /* Discard magic */
if ((flags & MS_MGC_MSK) == MS_MGC_VAL) if ((flags & MS_MGC_MSK) == MS_MGC_VAL)
...@@ -2717,6 +2717,9 @@ long do_mount(const char *dev_name, const char __user *dir_name, ...@@ -2717,6 +2717,9 @@ long do_mount(const char *dev_name, const char __user *dir_name,
if (data_page) if (data_page)
((char *)data_page)[PAGE_SIZE - 1] = 0; ((char *)data_page)[PAGE_SIZE - 1] = 0;
if (flags & MS_NOUSER)
return -EINVAL;
/* ... and get the mountpoint */ /* ... and get the mountpoint */
retval = user_path(dir_name, &path); retval = user_path(dir_name, &path);
if (retval) if (retval)
...@@ -2726,7 +2729,7 @@ long do_mount(const char *dev_name, const char __user *dir_name, ...@@ -2726,7 +2729,7 @@ long do_mount(const char *dev_name, const char __user *dir_name,
type_page, flags, data_page); type_page, flags, data_page);
if (!retval && !may_mount()) if (!retval && !may_mount())
retval = -EPERM; retval = -EPERM;
if (!retval && (flags & MS_MANDLOCK) && !may_mandlock()) if (!retval && (flags & SB_MANDLOCK) && !may_mandlock())
retval = -EPERM; retval = -EPERM;
if (retval) if (retval)
goto dput_out; goto dput_out;
...@@ -2748,7 +2751,7 @@ long do_mount(const char *dev_name, const char __user *dir_name, ...@@ -2748,7 +2751,7 @@ long do_mount(const char *dev_name, const char __user *dir_name,
mnt_flags |= MNT_NODIRATIME; mnt_flags |= MNT_NODIRATIME;
if (flags & MS_STRICTATIME) if (flags & MS_STRICTATIME)
mnt_flags &= ~(MNT_RELATIME | MNT_NOATIME); mnt_flags &= ~(MNT_RELATIME | MNT_NOATIME);
if (flags & MS_RDONLY) if (flags & SB_RDONLY)
mnt_flags |= MNT_READONLY; mnt_flags |= MNT_READONLY;
/* The default atime for remount is preservation */ /* The default atime for remount is preservation */
...@@ -2759,12 +2762,15 @@ long do_mount(const char *dev_name, const char __user *dir_name, ...@@ -2759,12 +2762,15 @@ long do_mount(const char *dev_name, const char __user *dir_name,
mnt_flags |= path.mnt->mnt_flags & MNT_ATIME_MASK; mnt_flags |= path.mnt->mnt_flags & MNT_ATIME_MASK;
} }
flags &= ~(MS_NOSUID | MS_NOEXEC | MS_NODEV | MS_ACTIVE | MS_BORN | sb_flags = flags & (SB_RDONLY |
MS_NOATIME | MS_NODIRATIME | MS_RELATIME| MS_KERNMOUNT | SB_SYNCHRONOUS |
MS_STRICTATIME | MS_NOREMOTELOCK | MS_SUBMOUNT); SB_MANDLOCK |
SB_DIRSYNC |
SB_SILENT |
SB_POSIXACL);
if (flags & MS_REMOUNT) if (flags & MS_REMOUNT)
retval = do_remount(&path, flags & ~MS_REMOUNT, mnt_flags, retval = do_remount(&path, flags, sb_flags, mnt_flags,
data_page); data_page);
else if (flags & MS_BIND) else if (flags & MS_BIND)
retval = do_loopback(&path, dev_name, flags & MS_REC); 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, ...@@ -2773,7 +2779,7 @@ long do_mount(const char *dev_name, const char __user *dir_name,
else if (flags & MS_MOVE) else if (flags & MS_MOVE)
retval = do_move_mount(&path, dev_name); retval = do_move_mount(&path, dev_name);
else else
retval = do_new_mount(&path, type_page, flags, mnt_flags, retval = do_new_mount(&path, type_page, sb_flags, mnt_flags,
dev_name, data_page); dev_name, data_page);
dput_out: dput_out:
path_put(&path); path_put(&path);
...@@ -3223,7 +3229,7 @@ void put_mnt_ns(struct mnt_namespace *ns) ...@@ -3223,7 +3229,7 @@ void put_mnt_ns(struct mnt_namespace *ns)
struct vfsmount *kern_mount_data(struct file_system_type *type, void *data) struct vfsmount *kern_mount_data(struct file_system_type *type, void *data)
{ {
struct vfsmount *mnt; struct vfsmount *mnt;
mnt = vfs_kern_mount(type, MS_KERNMOUNT, type->name, data); mnt = vfs_kern_mount(type, SB_KERNMOUNT, type->name, data);
if (!IS_ERR(mnt)) { if (!IS_ERR(mnt)) {
/* /*
* it is a longterm mount, don't release mnt until * it is a longterm mount, don't release mnt until
......
...@@ -360,7 +360,7 @@ static int grab_super(struct super_block *s) __releases(sb_lock) ...@@ -360,7 +360,7 @@ static int grab_super(struct super_block *s) __releases(sb_lock)
s->s_count++; s->s_count++;
spin_unlock(&sb_lock); spin_unlock(&sb_lock);
down_write(&s->s_umount); down_write(&s->s_umount);
if ((s->s_flags & MS_BORN) && atomic_inc_not_zero(&s->s_active)) { if ((s->s_flags & SB_BORN) && atomic_inc_not_zero(&s->s_active)) {
put_super(s); put_super(s);
return 1; return 1;
} }
...@@ -390,7 +390,7 @@ bool trylock_super(struct super_block *sb) ...@@ -390,7 +390,7 @@ bool trylock_super(struct super_block *sb)
{ {
if (down_read_trylock(&sb->s_umount)) { if (down_read_trylock(&sb->s_umount)) {
if (!hlist_unhashed(&sb->s_instances) && if (!hlist_unhashed(&sb->s_instances) &&
sb->s_root && (sb->s_flags & MS_BORN)) sb->s_root && (sb->s_flags & SB_BORN))
return true; return true;
up_read(&sb->s_umount); up_read(&sb->s_umount);
} }
...@@ -419,7 +419,7 @@ void generic_shutdown_super(struct super_block *sb) ...@@ -419,7 +419,7 @@ void generic_shutdown_super(struct super_block *sb)
if (sb->s_root) { if (sb->s_root) {
shrink_dcache_for_umount(sb); shrink_dcache_for_umount(sb);
sync_filesystem(sb); sync_filesystem(sb);
sb->s_flags &= ~MS_ACTIVE; sb->s_flags &= ~SB_ACTIVE;
fsnotify_unmount_inodes(sb); fsnotify_unmount_inodes(sb);
cgroup_writeback_umount(); cgroup_writeback_umount();
...@@ -472,7 +472,7 @@ struct super_block *sget_userns(struct file_system_type *type, ...@@ -472,7 +472,7 @@ struct super_block *sget_userns(struct file_system_type *type,
struct super_block *old; struct super_block *old;
int err; int err;
if (!(flags & (MS_KERNMOUNT|MS_SUBMOUNT)) && if (!(flags & (SB_KERNMOUNT|SB_SUBMOUNT)) &&
!(type->fs_flags & FS_USERNS_MOUNT) && !(type->fs_flags & FS_USERNS_MOUNT) &&
!capable(CAP_SYS_ADMIN)) !capable(CAP_SYS_ADMIN))
return ERR_PTR(-EPERM); return ERR_PTR(-EPERM);
...@@ -502,7 +502,7 @@ struct super_block *sget_userns(struct file_system_type *type, ...@@ -502,7 +502,7 @@ struct super_block *sget_userns(struct file_system_type *type,
} }
if (!s) { if (!s) {
spin_unlock(&sb_lock); spin_unlock(&sb_lock);
s = alloc_super(type, (flags & ~MS_SUBMOUNT), user_ns); s = alloc_super(type, (flags & ~SB_SUBMOUNT), user_ns);
if (!s) if (!s)
return ERR_PTR(-ENOMEM); return ERR_PTR(-ENOMEM);
goto retry; goto retry;
...@@ -547,11 +547,11 @@ struct super_block *sget(struct file_system_type *type, ...@@ -547,11 +547,11 @@ struct super_block *sget(struct file_system_type *type,
* mount through to here so always use &init_user_ns * mount through to here so always use &init_user_ns
* until that changes. * until that changes.
*/ */
if (flags & MS_SUBMOUNT) if (flags & SB_SUBMOUNT)
user_ns = &init_user_ns; user_ns = &init_user_ns;
/* Ensure the requestor has permissions over the target filesystem */ /* Ensure the requestor has permissions over the target filesystem */
if (!(flags & (MS_KERNMOUNT|MS_SUBMOUNT)) && !ns_capable(user_ns, CAP_SYS_ADMIN)) if (!(flags & (SB_KERNMOUNT|SB_SUBMOUNT)) && !ns_capable(user_ns, CAP_SYS_ADMIN))
return ERR_PTR(-EPERM); return ERR_PTR(-EPERM);
return sget_userns(type, test, set, flags, user_ns, data); return sget_userns(type, test, set, flags, user_ns, data);
...@@ -594,7 +594,7 @@ void iterate_supers(void (*f)(struct super_block *, void *), void *arg) ...@@ -594,7 +594,7 @@ void iterate_supers(void (*f)(struct super_block *, void *), void *arg)
spin_unlock(&sb_lock); spin_unlock(&sb_lock);
down_read(&sb->s_umount); down_read(&sb->s_umount);
if (sb->s_root && (sb->s_flags & MS_BORN)) if (sb->s_root && (sb->s_flags & SB_BORN))
f(sb, arg); f(sb, arg);
up_read(&sb->s_umount); up_read(&sb->s_umount);
...@@ -628,7 +628,7 @@ void iterate_supers_type(struct file_system_type *type, ...@@ -628,7 +628,7 @@ void iterate_supers_type(struct file_system_type *type,
spin_unlock(&sb_lock); spin_unlock(&sb_lock);
down_read(&sb->s_umount); down_read(&sb->s_umount);
if (sb->s_root && (sb->s_flags & MS_BORN)) if (sb->s_root && (sb->s_flags & SB_BORN))
f(sb, arg); f(sb, arg);
up_read(&sb->s_umount); up_read(&sb->s_umount);
...@@ -664,7 +664,7 @@ static struct super_block *__get_super(struct block_device *bdev, bool excl) ...@@ -664,7 +664,7 @@ static struct super_block *__get_super(struct block_device *bdev, bool excl)
else else
down_write(&sb->s_umount); down_write(&sb->s_umount);
/* still alive? */ /* still alive? */
if (sb->s_root && (sb->s_flags & MS_BORN)) if (sb->s_root && (sb->s_flags & SB_BORN))
return sb; return sb;
if (!excl) if (!excl)
up_read(&sb->s_umount); up_read(&sb->s_umount);
...@@ -785,7 +785,7 @@ struct super_block *user_get_super(dev_t dev) ...@@ -785,7 +785,7 @@ struct super_block *user_get_super(dev_t dev)
spin_unlock(&sb_lock); spin_unlock(&sb_lock);
down_read(&sb->s_umount); down_read(&sb->s_umount);
/* still alive? */ /* still alive? */
if (sb->s_root && (sb->s_flags & MS_BORN)) if (sb->s_root && (sb->s_flags & SB_BORN))
return sb; return sb;
up_read(&sb->s_umount); up_read(&sb->s_umount);
/* nope, got unmounted */ /* nope, got unmounted */
...@@ -801,13 +801,13 @@ struct super_block *user_get_super(dev_t dev) ...@@ -801,13 +801,13 @@ struct super_block *user_get_super(dev_t dev)
/** /**
* do_remount_sb - asks filesystem to change mount options. * do_remount_sb - asks filesystem to change mount options.
* @sb: superblock in question * @sb: superblock in question
* @flags: numeric part of options * @sb_flags: revised superblock flags
* @data: the rest of options * @data: the rest of options
* @force: whether or not to force the change * @force: whether or not to force the change
* *
* Alters the mount options of a mounted file system. * Alters the mount options of a mounted file system.
*/ */
int do_remount_sb(struct super_block *sb, int flags, void *data, int force) int do_remount_sb(struct super_block *sb, int sb_flags, void *data, int force)
{ {
int retval; int retval;
int remount_ro; int remount_ro;
...@@ -816,11 +816,11 @@ int do_remount_sb(struct super_block *sb, int flags, void *data, int force) ...@@ -816,11 +816,11 @@ int do_remount_sb(struct super_block *sb, int flags, void *data, int force)
return -EBUSY; return -EBUSY;
#ifdef CONFIG_BLOCK #ifdef CONFIG_BLOCK
if (!(flags & MS_RDONLY) && bdev_read_only(sb->s_bdev)) if (!(sb_flags & SB_RDONLY) && bdev_read_only(sb->s_bdev))
return -EACCES; return -EACCES;
#endif #endif
remount_ro = (flags & MS_RDONLY) && !sb_rdonly(sb); remount_ro = (sb_flags & SB_RDONLY) && !sb_rdonly(sb);
if (remount_ro) { if (remount_ro) {
if (!hlist_empty(&sb->s_pins)) { if (!hlist_empty(&sb->s_pins)) {
...@@ -831,7 +831,7 @@ int do_remount_sb(struct super_block *sb, int flags, void *data, int force) ...@@ -831,7 +831,7 @@ int do_remount_sb(struct super_block *sb, int flags, void *data, int force)
return 0; return 0;
if (sb->s_writers.frozen != SB_UNFROZEN) if (sb->s_writers.frozen != SB_UNFROZEN)
return -EBUSY; return -EBUSY;
remount_ro = (flags & MS_RDONLY) && !sb_rdonly(sb); remount_ro = (sb_flags & SB_RDONLY) && !sb_rdonly(sb);
} }
} }
shrink_dcache_sb(sb); shrink_dcache_sb(sb);
...@@ -850,7 +850,7 @@ int do_remount_sb(struct super_block *sb, int flags, void *data, int force) ...@@ -850,7 +850,7 @@ int do_remount_sb(struct super_block *sb, int flags, void *data, int force)
} }
if (sb->s_op->remount_fs) { if (sb->s_op->remount_fs) {
retval = sb->s_op->remount_fs(sb, &flags, data); retval = sb->s_op->remount_fs(sb, &sb_flags, data);
if (retval) { if (retval) {
if (!force) if (!force)
goto cancel_readonly; goto cancel_readonly;
...@@ -859,7 +859,7 @@ int do_remount_sb(struct super_block *sb, int flags, void *data, int force) ...@@ -859,7 +859,7 @@ int do_remount_sb(struct super_block *sb, int flags, void *data, int force)
sb->s_type->name, retval); sb->s_type->name, retval);
} }
} }
sb->s_flags = (sb->s_flags & ~MS_RMT_MASK) | (flags & MS_RMT_MASK); sb->s_flags = (sb->s_flags & ~MS_RMT_MASK) | (sb_flags & MS_RMT_MASK);
/* Needs to be ordered wrt mnt_is_readonly() */ /* Needs to be ordered wrt mnt_is_readonly() */
smp_wmb(); smp_wmb();
sb->s_readonly_remount = 0; sb->s_readonly_remount = 0;
...@@ -892,12 +892,12 @@ static void do_emergency_remount(struct work_struct *work) ...@@ -892,12 +892,12 @@ static void do_emergency_remount(struct work_struct *work)
sb->s_count++; sb->s_count++;
spin_unlock(&sb_lock); spin_unlock(&sb_lock);
down_write(&sb->s_umount); down_write(&sb->s_umount);
if (sb->s_root && sb->s_bdev && (sb->s_flags & MS_BORN) && if (sb->s_root && sb->s_bdev && (sb->s_flags & SB_BORN) &&
!sb_rdonly(sb)) { !sb_rdonly(sb)) {
/* /*
* What lock protects sb->s_flags?? * What lock protects sb->s_flags??
*/ */
do_remount_sb(sb, MS_RDONLY, NULL, 1); do_remount_sb(sb, SB_RDONLY, NULL, 1);
} }
up_write(&sb->s_umount); up_write(&sb->s_umount);
spin_lock(&sb_lock); spin_lock(&sb_lock);
...@@ -1023,7 +1023,7 @@ struct dentry *mount_ns(struct file_system_type *fs_type, ...@@ -1023,7 +1023,7 @@ struct dentry *mount_ns(struct file_system_type *fs_type,
/* Don't allow mounting unless the caller has CAP_SYS_ADMIN /* Don't allow mounting unless the caller has CAP_SYS_ADMIN
* over the namespace. * over the namespace.
*/ */
if (!(flags & MS_KERNMOUNT) && !ns_capable(user_ns, CAP_SYS_ADMIN)) if (!(flags & SB_KERNMOUNT) && !ns_capable(user_ns, CAP_SYS_ADMIN))
return ERR_PTR(-EPERM); return ERR_PTR(-EPERM);
sb = sget_userns(fs_type, ns_test_super, ns_set_super, flags, sb = sget_userns(fs_type, ns_test_super, ns_set_super, flags,
...@@ -1033,13 +1033,13 @@ struct dentry *mount_ns(struct file_system_type *fs_type, ...@@ -1033,13 +1033,13 @@ struct dentry *mount_ns(struct file_system_type *fs_type,
if (!sb->s_root) { if (!sb->s_root) {
int err; int err;
err = fill_super(sb, data, flags & MS_SILENT ? 1 : 0); err = fill_super(sb, data, flags & SB_SILENT ? 1 : 0);
if (err) { if (err) {
deactivate_locked_super(sb); deactivate_locked_super(sb);
return ERR_PTR(err); return ERR_PTR(err);
} }
sb->s_flags |= MS_ACTIVE; sb->s_flags |= SB_ACTIVE;
} }
return dget(sb->s_root); return dget(sb->s_root);
...@@ -1071,7 +1071,7 @@ struct dentry *mount_bdev(struct file_system_type *fs_type, ...@@ -1071,7 +1071,7 @@ struct dentry *mount_bdev(struct file_system_type *fs_type,
fmode_t mode = FMODE_READ | FMODE_EXCL; fmode_t mode = FMODE_READ | FMODE_EXCL;
int error = 0; int error = 0;
if (!(flags & MS_RDONLY)) if (!(flags & SB_RDONLY))
mode |= FMODE_WRITE; mode |= FMODE_WRITE;
bdev = blkdev_get_by_path(dev_name, mode, fs_type); bdev = blkdev_get_by_path(dev_name, mode, fs_type);
...@@ -1089,14 +1089,14 @@ struct dentry *mount_bdev(struct file_system_type *fs_type, ...@@ -1089,14 +1089,14 @@ struct dentry *mount_bdev(struct file_system_type *fs_type,
error = -EBUSY; error = -EBUSY;
goto error_bdev; goto error_bdev;
} }
s = sget(fs_type, test_bdev_super, set_bdev_super, flags | MS_NOSEC, s = sget(fs_type, test_bdev_super, set_bdev_super, flags | SB_NOSEC,
bdev); bdev);
mutex_unlock(&bdev->bd_fsfreeze_mutex); mutex_unlock(&bdev->bd_fsfreeze_mutex);
if (IS_ERR(s)) if (IS_ERR(s))
goto error_s; goto error_s;
if (s->s_root) { if (s->s_root) {
if ((flags ^ s->s_flags) & MS_RDONLY) { if ((flags ^ s->s_flags) & SB_RDONLY) {
deactivate_locked_super(s); deactivate_locked_super(s);
error = -EBUSY; error = -EBUSY;
goto error_bdev; goto error_bdev;
...@@ -1116,13 +1116,13 @@ struct dentry *mount_bdev(struct file_system_type *fs_type, ...@@ -1116,13 +1116,13 @@ struct dentry *mount_bdev(struct file_system_type *fs_type,
s->s_mode = mode; s->s_mode = mode;
snprintf(s->s_id, sizeof(s->s_id), "%pg", bdev); snprintf(s->s_id, sizeof(s->s_id), "%pg", bdev);
sb_set_blocksize(s, block_size(bdev)); sb_set_blocksize(s, block_size(bdev));
error = fill_super(s, data, flags & MS_SILENT ? 1 : 0); error = fill_super(s, data, flags & SB_SILENT ? 1 : 0);
if (error) { if (error) {
deactivate_locked_super(s); deactivate_locked_super(s);
goto error; goto error;
} }
s->s_flags |= MS_ACTIVE; s->s_flags |= SB_ACTIVE;
bdev->bd_super = s; bdev->bd_super = s;
} }
...@@ -1162,12 +1162,12 @@ struct dentry *mount_nodev(struct file_system_type *fs_type, ...@@ -1162,12 +1162,12 @@ struct dentry *mount_nodev(struct file_system_type *fs_type,
if (IS_ERR(s)) if (IS_ERR(s))
return ERR_CAST(s); return ERR_CAST(s);
error = fill_super(s, data, flags & MS_SILENT ? 1 : 0); error = fill_super(s, data, flags & SB_SILENT ? 1 : 0);
if (error) { if (error) {
deactivate_locked_super(s); deactivate_locked_super(s);
return ERR_PTR(error); return ERR_PTR(error);
} }
s->s_flags |= MS_ACTIVE; s->s_flags |= SB_ACTIVE;
return dget(s->s_root); return dget(s->s_root);
} }
EXPORT_SYMBOL(mount_nodev); EXPORT_SYMBOL(mount_nodev);
...@@ -1188,12 +1188,12 @@ struct dentry *mount_single(struct file_system_type *fs_type, ...@@ -1188,12 +1188,12 @@ struct dentry *mount_single(struct file_system_type *fs_type,
if (IS_ERR(s)) if (IS_ERR(s))
return ERR_CAST(s); return ERR_CAST(s);
if (!s->s_root) { if (!s->s_root) {
error = fill_super(s, data, flags & MS_SILENT ? 1 : 0); error = fill_super(s, data, flags & SB_SILENT ? 1 : 0);
if (error) { if (error) {
deactivate_locked_super(s); deactivate_locked_super(s);
return ERR_PTR(error); return ERR_PTR(error);
} }
s->s_flags |= MS_ACTIVE; s->s_flags |= SB_ACTIVE;
} else { } else {
do_remount_sb(s, flags, data, 0); do_remount_sb(s, flags, data, 0);
} }
...@@ -1227,7 +1227,7 @@ mount_fs(struct file_system_type *type, int flags, const char *name, void *data) ...@@ -1227,7 +1227,7 @@ mount_fs(struct file_system_type *type, int flags, const char *name, void *data)
sb = root->d_sb; sb = root->d_sb;
BUG_ON(!sb); BUG_ON(!sb);
WARN_ON(!sb->s_bdi); WARN_ON(!sb->s_bdi);
sb->s_flags |= MS_BORN; sb->s_flags |= SB_BORN;
error = security_sb_kern_mount(sb, flags, secdata); error = security_sb_kern_mount(sb, flags, secdata);
if (error) if (error)
...@@ -1434,7 +1434,7 @@ int freeze_super(struct super_block *sb) ...@@ -1434,7 +1434,7 @@ int freeze_super(struct super_block *sb)
return -EBUSY; return -EBUSY;
} }
if (!(sb->s_flags & MS_BORN)) { if (!(sb->s_flags & SB_BORN)) {
up_write(&sb->s_umount); up_write(&sb->s_umount);
return 0; /* sic - it's "nothing to do" */ return 0; /* sic - it's "nothing to do" */
} }
......
...@@ -1269,6 +1269,33 @@ extern int send_sigurg(struct fown_struct *fown); ...@@ -1269,6 +1269,33 @@ extern int send_sigurg(struct fown_struct *fown);
struct mm_struct; struct mm_struct;
/*
* sb->s_flags. Note that these mirror the equivalent MS_* flags where
* represented in both.
*/
#define SB_RDONLY 1 /* Mount read-only */
#define SB_NOSUID 2 /* Ignore suid and sgid bits */
#define SB_NODEV 4 /* Disallow access to device special files */
#define SB_NOEXEC 8 /* Disallow program execution */
#define SB_SYNCHRONOUS 16 /* Writes are synced at once */
#define SB_MANDLOCK 64 /* Allow mandatory locks on an FS */
#define SB_DIRSYNC 128 /* Directory modifications are synchronous */
#define SB_NOATIME 1024 /* Do not update access times. */
#define SB_NODIRATIME 2048 /* Do not update directory access times */
#define SB_SILENT 32768
#define SB_POSIXACL (1<<16) /* VFS does not apply the umask */
#define SB_KERNMOUNT (1<<22) /* this is a kern_mount call */
#define SB_I_VERSION (1<<23) /* Update inode I_version field */
#define SB_LAZYTIME (1<<25) /* Update the on-disk [acm]times lazily */
/* These sb flags are internal to the kernel */
#define SB_SUBMOUNT (1<<26)
#define SB_NOREMOTELOCK (1<<27)
#define SB_NOSEC (1<<28)
#define SB_BORN (1<<29)
#define SB_ACTIVE (1<<30)
#define SB_NOUSER (1<<31)
/* /*
* Umount options * Umount options
*/ */
...@@ -1835,7 +1862,7 @@ struct super_operations { ...@@ -1835,7 +1862,7 @@ struct super_operations {
* possible to override it selectively if you really wanted to with some * possible to override it selectively if you really wanted to with some
* ioctl() that is not currently implemented. * ioctl() that is not currently implemented.
* *
* Exception: MS_RDONLY is always applied to the entire file system. * Exception: SB_RDONLY is always applied to the entire file system.
* *
* Unfortunately, it is possible to change a filesystems flags with it mounted * Unfortunately, it is possible to change a filesystems flags with it mounted
* with files in use. This means that all of the inodes will not have their * with files in use. This means that all of the inodes will not have their
...@@ -1846,18 +1873,18 @@ struct super_operations { ...@@ -1846,18 +1873,18 @@ struct super_operations {
static inline bool sb_rdonly(const struct super_block *sb) { return sb->s_flags & MS_RDONLY; } static inline bool sb_rdonly(const struct super_block *sb) { return sb->s_flags & MS_RDONLY; }
#define IS_RDONLY(inode) sb_rdonly((inode)->i_sb) #define IS_RDONLY(inode) sb_rdonly((inode)->i_sb)
#define IS_SYNC(inode) (__IS_FLG(inode, MS_SYNCHRONOUS) || \ #define IS_SYNC(inode) (__IS_FLG(inode, SB_SYNCHRONOUS) || \
((inode)->i_flags & S_SYNC)) ((inode)->i_flags & S_SYNC))
#define IS_DIRSYNC(inode) (__IS_FLG(inode, MS_SYNCHRONOUS|MS_DIRSYNC) || \ #define IS_DIRSYNC(inode) (__IS_FLG(inode, SB_SYNCHRONOUS|SB_DIRSYNC) || \
((inode)->i_flags & (S_SYNC|S_DIRSYNC))) ((inode)->i_flags & (S_SYNC|S_DIRSYNC)))
#define IS_MANDLOCK(inode) __IS_FLG(inode, MS_MANDLOCK) #define IS_MANDLOCK(inode) __IS_FLG(inode, SB_MANDLOCK)
#define IS_NOATIME(inode) __IS_FLG(inode, MS_RDONLY|MS_NOATIME) #define IS_NOATIME(inode) __IS_FLG(inode, SB_RDONLY|SB_NOATIME)
#define IS_I_VERSION(inode) __IS_FLG(inode, MS_I_VERSION) #define IS_I_VERSION(inode) __IS_FLG(inode, SB_I_VERSION)
#define IS_NOQUOTA(inode) ((inode)->i_flags & S_NOQUOTA) #define IS_NOQUOTA(inode) ((inode)->i_flags & S_NOQUOTA)
#define IS_APPEND(inode) ((inode)->i_flags & S_APPEND) #define IS_APPEND(inode) ((inode)->i_flags & S_APPEND)
#define IS_IMMUTABLE(inode) ((inode)->i_flags & S_IMMUTABLE) #define IS_IMMUTABLE(inode) ((inode)->i_flags & S_IMMUTABLE)
#define IS_POSIXACL(inode) __IS_FLG(inode, MS_POSIXACL) #define IS_POSIXACL(inode) __IS_FLG(inode, SB_POSIXACL)
#define IS_DEADDIR(inode) ((inode)->i_flags & S_DEAD) #define IS_DEADDIR(inode) ((inode)->i_flags & S_DEAD)
#define IS_NOCMTIME(inode) ((inode)->i_flags & S_NOCMTIME) #define IS_NOCMTIME(inode) ((inode)->i_flags & S_NOCMTIME)
...@@ -2178,7 +2205,7 @@ static inline int __mandatory_lock(struct inode *ino) ...@@ -2178,7 +2205,7 @@ static inline int __mandatory_lock(struct inode *ino)
} }
/* /*
* ... and these candidates should be on MS_MANDLOCK mounted fs, * ... and these candidates should be on SB_MANDLOCK mounted fs,
* otherwise these will be advisory locks * otherwise these will be advisory locks
*/ */
...@@ -3274,7 +3301,7 @@ static inline int check_sticky(struct inode *dir, struct inode *inode) ...@@ -3274,7 +3301,7 @@ static inline int check_sticky(struct inode *dir, struct inode *inode)
static inline void inode_has_no_xattr(struct inode *inode) static inline void inode_has_no_xattr(struct inode *inode)
{ {
if (!is_sxid(inode->i_mode) && (inode->i_sb->s_flags & MS_NOSEC)) if (!is_sxid(inode->i_mode) && (inode->i_sb->s_flags & SB_NOSEC))
inode->i_flags |= S_NOSEC; inode->i_flags |= S_NOSEC;
} }
......
...@@ -420,8 +420,8 @@ void __init mount_block_root(char *name, int flags) ...@@ -420,8 +420,8 @@ void __init mount_block_root(char *name, int flags)
#endif #endif
panic("VFS: Unable to mount root fs on %s", b); panic("VFS: Unable to mount root fs on %s", b);
} }
if (!(flags & MS_RDONLY)) { if (!(flags & SB_RDONLY)) {
flags |= MS_RDONLY; flags |= SB_RDONLY;
goto retry; goto retry;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment