Commit a1e6aaa3 authored by Christoph Hellwig's avatar Christoph Hellwig

fs: refactor do_mount

Factor out a path_mount helper that takes a struct path * instead of the
actual file name.  This will allow to convert the init and devtmpfs code
to properly mount based on a kernel pointer instead of relying on the
implicit set_fs(KERNEL_DS) during early init.
Signed-off-by: default avatarChristoph Hellwig <hch@lst.de>
parent 38b08223
...@@ -3115,12 +3115,11 @@ char *copy_mount_string(const void __user *data) ...@@ -3115,12 +3115,11 @@ char *copy_mount_string(const void __user *data)
* Therefore, if this magic number is present, it carries no information * Therefore, if this magic number is present, it carries no information
* and must be discarded. * and must be discarded.
*/ */
long do_mount(const char *dev_name, const char __user *dir_name, static int path_mount(const char *dev_name, struct path *path,
const char *type_page, unsigned long flags, void *data_page) const char *type_page, unsigned long flags, void *data_page)
{ {
struct path path;
unsigned int mnt_flags = 0, sb_flags; unsigned int mnt_flags = 0, sb_flags;
int retval = 0; int ret;
/* Discard magic */ /* Discard magic */
if ((flags & MS_MGC_MSK) == MS_MGC_VAL) if ((flags & MS_MGC_MSK) == MS_MGC_VAL)
...@@ -3133,19 +3132,13 @@ long do_mount(const char *dev_name, const char __user *dir_name, ...@@ -3133,19 +3132,13 @@ long do_mount(const char *dev_name, const char __user *dir_name,
if (flags & MS_NOUSER) if (flags & MS_NOUSER)
return -EINVAL; return -EINVAL;
/* ... and get the mountpoint */ ret = security_sb_mount(dev_name, path, type_page, flags, data_page);
retval = user_path_at(AT_FDCWD, dir_name, LOOKUP_FOLLOW, &path); if (ret)
if (retval) return ret;
return retval; if (!may_mount())
return -EPERM;
retval = security_sb_mount(dev_name, &path, if ((flags & SB_MANDLOCK) && !may_mandlock())
type_page, flags, data_page); return -EPERM;
if (!retval && !may_mount())
retval = -EPERM;
if (!retval && (flags & SB_MANDLOCK) && !may_mandlock())
retval = -EPERM;
if (retval)
goto dput_out;
/* Default to relatime unless overriden */ /* Default to relatime unless overriden */
if (!(flags & MS_NOATIME)) if (!(flags & MS_NOATIME))
...@@ -3172,7 +3165,7 @@ long do_mount(const char *dev_name, const char __user *dir_name, ...@@ -3172,7 +3165,7 @@ long do_mount(const char *dev_name, const char __user *dir_name,
((flags & (MS_NOATIME | MS_NODIRATIME | MS_RELATIME | ((flags & (MS_NOATIME | MS_NODIRATIME | MS_RELATIME |
MS_STRICTATIME)) == 0)) { MS_STRICTATIME)) == 0)) {
mnt_flags &= ~MNT_ATIME_MASK; mnt_flags &= ~MNT_ATIME_MASK;
mnt_flags |= path.mnt->mnt_flags & MNT_ATIME_MASK; mnt_flags |= path->mnt->mnt_flags & MNT_ATIME_MASK;
} }
sb_flags = flags & (SB_RDONLY | sb_flags = flags & (SB_RDONLY |
...@@ -3185,22 +3178,32 @@ long do_mount(const char *dev_name, const char __user *dir_name, ...@@ -3185,22 +3178,32 @@ long do_mount(const char *dev_name, const char __user *dir_name,
SB_I_VERSION); SB_I_VERSION);
if ((flags & (MS_REMOUNT | MS_BIND)) == (MS_REMOUNT | MS_BIND)) if ((flags & (MS_REMOUNT | MS_BIND)) == (MS_REMOUNT | MS_BIND))
retval = do_reconfigure_mnt(&path, mnt_flags); return do_reconfigure_mnt(path, mnt_flags);
else if (flags & MS_REMOUNT) if (flags & MS_REMOUNT)
retval = do_remount(&path, flags, sb_flags, mnt_flags, return do_remount(path, flags, sb_flags, mnt_flags, data_page);
data_page); if (flags & MS_BIND)
else if (flags & MS_BIND) return do_loopback(path, dev_name, flags & MS_REC);
retval = do_loopback(&path, dev_name, flags & MS_REC); if (flags & (MS_SHARED | MS_PRIVATE | MS_SLAVE | MS_UNBINDABLE))
else if (flags & (MS_SHARED | MS_PRIVATE | MS_SLAVE | MS_UNBINDABLE)) return do_change_type(path, flags);
retval = do_change_type(&path, flags); if (flags & MS_MOVE)
else if (flags & MS_MOVE) return do_move_mount_old(path, dev_name);
retval = do_move_mount_old(&path, dev_name);
else return do_new_mount(path, type_page, sb_flags, mnt_flags, dev_name,
retval = do_new_mount(&path, type_page, sb_flags, mnt_flags, data_page);
dev_name, data_page); }
dput_out:
long do_mount(const char *dev_name, const char __user *dir_name,
const char *type_page, unsigned long flags, void *data_page)
{
struct path path;
int ret;
ret = user_path_at(AT_FDCWD, dir_name, LOOKUP_FOLLOW, &path);
if (ret)
return ret;
ret = path_mount(dev_name, &path, type_page, flags, data_page);
path_put(&path); path_put(&path);
return retval; return ret;
} }
static struct ucounts *inc_mnt_namespaces(struct user_namespace *ns) static struct ucounts *inc_mnt_namespaces(struct user_namespace *ns)
......
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