]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
init: do_mounts: use kmalloc() for allocations of temporary buffers
authorMike Rapoport (Microsoft) <rppt@kernel.org>
Wed, 20 May 2026 08:16:51 +0000 (11:16 +0300)
committerChristian Brauner <brauner@kernel.org>
Fri, 22 May 2026 10:12:20 +0000 (12:12 +0200)
Several places in init/do_mounts.c allocate temporary buffers for
filesystem names or options using __get_free_page() or alloc_page().

Usage of alloc_page() APIs is not required there and only creates
unnecessary noise with castings or conversion from struct page to void *.

kmalloc() is a better API for these uses and it also provides better
scalability and more debugging possibilities.

Replace use of __get_free_page() and alloc_page() with kmalloc().

While on it, add a check for -ENOMEM condition in mount_root_generic().

Link: https://lore.kernel.org/all/635405e4-9423-4a25-a6e7-e03c8ea0bcbe@redhat.com
Signed-off-by: Mike Rapoport (Microsoft) <rppt@kernel.org>
Link: https://patch.msgid.link/20260520-init-v1-1-aaf2ebac5ad9@kernel.org
Reviewed-by: David Disseldorp <ddiss@suse.de>
Reviewed-by: SeongJae Park <sj@kernel.org>
Signed-off-by: Christian Brauner (Amutable) <brauner@kernel.org>
init/do_mounts.c

index 55ed3ac0b70fd133e86649191de538fe119f4ef6..95e0b3a0f711bd72c76b8a6fc752414bdb049a7e 100644 (file)
@@ -143,16 +143,14 @@ static int __init do_mount_root(const char *name, const char *fs,
                                 const int flags, const void *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)
+               data_page = kmalloc(PAGE_SIZE, GFP_KERNEL);
+               if (!data_page)
                        return -ENOMEM;
-               data_page = page_address(p);
                strscpy_pad(data_page, data, PAGE_SIZE);
        }
 
@@ -170,19 +168,20 @@ static int __init do_mount_root(const char *name, const char *fs,
               MAJOR(ROOT_DEV), MINOR(ROOT_DEV));
 
 out:
-       if (p)
-               put_page(p);
+       kfree(data_page);
        return ret;
 }
 
 void __init mount_root_generic(char *name, char *pretty_name, int flags)
 {
-       struct page *page = alloc_page(GFP_KERNEL);
-       char *fs_names = page_address(page);
+       char *fs_names = kmalloc(PAGE_SIZE, GFP_KERNEL);
        char *p;
        char b[BDEVNAME_SIZE];
        int num_fs, i;
 
+       if (!fs_names)
+               panic("VFS: Unable to mount root fs: not enough memory");
+
        scnprintf(b, BDEVNAME_SIZE, "unknown-block(%u,%u)",
                  MAJOR(ROOT_DEV), MINOR(ROOT_DEV));
        if (root_fs_names)
@@ -242,7 +241,7 @@ retry:
        printk("\n");
        panic("VFS: Unable to mount root fs on \"%s\" or %s", pretty_name, b);
 out:
-       put_page(page);
+       kfree(fs_names);
 }
  
 #ifdef CONFIG_ROOT_NFS
@@ -343,7 +342,7 @@ static int __init mount_nodev_root(char *root_device_name)
        int err = -EINVAL;
        int num_fs, i;
 
-       fs_names = (void *)__get_free_page(GFP_KERNEL);
+       fs_names = kmalloc(PAGE_SIZE, GFP_KERNEL);
        if (!fs_names)
                return -EINVAL;
        num_fs = split_fs_names(fs_names, PAGE_SIZE);
@@ -360,7 +359,7 @@ static int __init mount_nodev_root(char *root_device_name)
                        break;
        }
 
-       free_page((unsigned long)fs_names);
+       kfree(fs_names);
        return err;
 }