path_mount() wants the mount data if not NULL to be a whole page. Expanding a string onto an allocated page was done in do_mount_root(); move it instead into init_mount() so other users of init_mount() can leverage this same code.
Signed-off-by: H. Peter Anvin (Intel) <[email protected]> --- fs/init.c | 23 ++++++++++++++++++++--- include/linux/init_syscalls.h | 3 ++- init/do_mounts.c | 17 ++--------------- 3 files changed, 24 insertions(+), 19 deletions(-) diff --git a/fs/init.c b/fs/init.c index e0f5429c0a49..1253bcc73e26 100644 --- a/fs/init.c +++ b/fs/init.c @@ -14,16 +14,33 @@ #include "internal.h" int __init init_mount(const char *dev_name, const char *dir_name, - const char *type_page, unsigned long flags, void *data_page) + const char *type_page, unsigned long flags, + const char *data_str) { + struct page *data_page = NULL; + char *data_buf = NULL; struct path path; int ret; + /* path_mount() wants a proper page for data */ + if (data_str && data_str[0]) { + data_page = alloc_page(GFP_KERNEL); + if (!data_page) + return -ENOMEM; + data_buf = page_address(data_page); + strscpy_pad(data_buf, data_str, PAGE_SIZE); + } + ret = kern_path(dir_name, LOOKUP_FOLLOW, &path); if (ret) - return ret; - ret = path_mount(dev_name, &path, type_page, flags, data_page); + goto out; + + ret = path_mount(dev_name, &path, type_page, flags, data_buf); path_put(&path); + +out: + if (data_page) + put_page(data_page); return ret; } diff --git a/include/linux/init_syscalls.h b/include/linux/init_syscalls.h index 92045d18cbfc..804d3070ce73 100644 --- a/include/linux/init_syscalls.h +++ b/include/linux/init_syscalls.h @@ -1,7 +1,8 @@ /* SPDX-License-Identifier: GPL-2.0 */ int __init init_mount(const char *dev_name, const char *dir_name, - const char *type_page, unsigned long flags, void *data_page); + const char *type_page, unsigned long flags, + const char *data_str); int __init init_umount(const char *name, int flags); int __init init_chdir(const char *filename); int __init init_chroot(const char *filename); diff --git a/init/do_mounts.c b/init/do_mounts.c index defbbf1d55f7..87cf110a48e6 100644 --- a/init/do_mounts.c +++ b/init/do_mounts.c @@ -147,23 +147,12 @@ static int __init split_fs_names(char *page, size_t size) } static int __init do_mount_root(const char *name, const char *fs, - const int flags, const void *data) + const int flags, const char *data) { struct super_block *s; - struct page *p = NULL; - char *data_page = NULL; int ret; - if (data) { - /* init_mount() requires a full page as fifth argument */ - p = alloc_page(GFP_KERNEL); - if (!p) - return -ENOMEM; - data_page = page_address(p); - strscpy_pad(data_page, data, PAGE_SIZE); - } - - ret = init_mount(name, "/root", fs, flags, data_page); + ret = init_mount(name, "/root", fs, flags, data); if (ret) goto out; @@ -177,8 +166,6 @@ static int __init do_mount_root(const char *name, const char *fs, MAJOR(ROOT_DEV), MINOR(ROOT_DEV)); out: - if (p) - put_page(p); return ret; } -- 2.52.0
