From nobody Sun Feb 8 18:35:27 2026 Received: from mail.zytor.com (terminus.zytor.com [198.137.202.136]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 88D6C1465B4; Sat, 24 Jan 2026 00:40:23 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=198.137.202.136 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1769215224; cv=none; b=rUSZnP/GWvdqpeQ2vJ/jd4ZEMXj40zsL5EWEi8ILtsGcxcVV0+Wm56vYUFlLfOaJiIOmhJYsThss/pfVk3HF6JJ190Vvz1TbmNDyPjvM0Tcvo4e3LUvKDatiCh3gprM6MXJWf+y4UMXssE7dXRvbMXTAP23rfXALZVQLv1vZbRs= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1769215224; c=relaxed/simple; bh=VIIxrbHBSOZTQZmk6RThUD6/XbYBdxSTBSmfqc2iAFA=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=pAJLw2ZApL1eQMX0VGJ4By1jkTr7oQSfRimkyeJicYc9ftMqIyhq9v/ltrBm1eNQOXDVaNGM/2U6VpuhNY6PE1aIWoXYYkMzxzhORB7elyGCy/Z5AzwoGsTeSbLHETXN7asJ2dxL3GnZ8ff1ZOw2JzkGU7L5VOJiyhXTiISswN4= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=zytor.com; spf=pass smtp.mailfrom=zytor.com; dkim=pass (2048-bit key) header.d=zytor.com header.i=@zytor.com header.b=b2ZyWQEn; arc=none smtp.client-ip=198.137.202.136 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=zytor.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=zytor.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=zytor.com header.i=@zytor.com header.b="b2ZyWQEn" Received: from mail.zytor.com (c-76-133-66-138.hsd1.ca.comcast.net [76.133.66.138]) (authenticated bits=0) by mail.zytor.com (8.18.1/8.17.1) with ESMTPSA id 60O0dnvW1194278 (version=TLSv1.3 cipher=TLS_AES_256_GCM_SHA384 bits=256 verify=NO); Fri, 23 Jan 2026 16:39:59 -0800 DKIM-Filter: OpenDKIM Filter v2.11.0 mail.zytor.com 60O0dnvW1194278 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=zytor.com; s=2025122301; t=1769215199; bh=3gvBwig0hzF7NIxzN91ZTmQDDoHaKk76XYdPUXtLHtQ=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=b2ZyWQEnLPMG+1UJZWR/Ow1pjzS/Djnc00LiKj1d8h1eCCB0mvoGq/eMeskUGvKmR i+L0UzZ9MF9M/AEZrKR4khIlkezkbOh6ureJXZPQFdkmFL/S5kyFUZzTsOWjuLPSAM wRhUm7ZLqGy7866RoXPT3inwZaUaIFjm1FADRY/0weXQmO6+dTCgWXqoiS9mKo0DZ2 uvPc6pDsaSvbXEOnQnEuwtLYDby2QHhnHSNe5i2lCyubnw5EAaLWKLa9cHaQhR1hUm d0N9/aeQpWIvLiJI93yaJnBeEdhIWwImjbYMJ5App+xp2wtK/YDZhHtXe4q0mu7Wiw tv+TPgIMj/Ayw== From: "H. Peter Anvin" To: Alexander Viro , Christian Brauner , Jan Kara , Jonathan Corbet , "H. Peter Anvin" Cc: linux-fsdevel@vger.kernel.org, linux-doc@vger.kernel.org, linux-kernel@vger.kernel.org, Lennart Poettering , systemd-devel@lists.freedesktop.org Subject: [RFC PATCH 1/3] fs/init: move creating the mount data_page into init_mount() Date: Fri, 23 Jan 2026 16:39:34 -0800 Message-ID: <20260124003939.426931-2-hpa@zytor.com> X-Mailer: git-send-email 2.52.0 In-Reply-To: <20260124003939.426931-1-hpa@zytor.com> References: <20260124003939.426931-1-hpa@zytor.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" 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) --- 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" =20 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 =3D NULL; + char *data_buf =3D NULL; struct path path; int ret; =20 + /* path_mount() wants a proper page for data */ + if (data_str && data_str[0]) { + data_page =3D alloc_page(GFP_KERNEL); + if (!data_page) + return -ENOMEM; + data_buf =3D page_address(data_page); + strscpy_pad(data_buf, data_str, PAGE_SIZE); + } + ret =3D kern_path(dir_name, LOOKUP_FOLLOW, &path); if (ret) - return ret; - ret =3D path_mount(dev_name, &path, type_page, flags, data_page); + goto out; + + ret =3D path_mount(dev_name, &path, type_page, flags, data_buf); path_put(&path); + +out: + if (data_page) + put_page(data_page); return ret; } =20 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 */ =20 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 s= ize) } =20 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 =3D NULL; - char *data_page =3D NULL; int ret; =20 - if (data) { - /* init_mount() requires a full page as fifth argument */ - p =3D alloc_page(GFP_KERNEL); - if (!p) - return -ENOMEM; - data_page =3D page_address(p); - strscpy_pad(data_page, data, PAGE_SIZE); - } - - ret =3D init_mount(name, "/root", fs, flags, data_page); + ret =3D init_mount(name, "/root", fs, flags, data); if (ret) goto out; =20 @@ -177,8 +166,6 @@ static int __init do_mount_root(const char *name, const= char *fs, MAJOR(ROOT_DEV), MINOR(ROOT_DEV)); =20 out: - if (p) - put_page(p); return ret; } =20 --=20 2.52.0 From nobody Sun Feb 8 18:35:27 2026 Received: from mail.zytor.com (terminus.zytor.com [198.137.202.136]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 70F3A1B983F; Sat, 24 Jan 2026 00:40:22 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=198.137.202.136 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1769215224; cv=none; b=C0b8JHbaNyn9GVFl+QeqN0uDvhVAXFyICK7IYRJXFaS7IqBuK/qLQFU4mbguU3z+cQaUYHDa7zk400L05vvjxVuxVXB8+l+2QoC3ADmYODah92IwiIRaGxnRKeA6aoqeGpMSH5aZsl08wSAnQkyVs+D83a8kOBO7VX6xMlbMfQ4= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1769215224; c=relaxed/simple; bh=qB+IOSkyKBdATauosJ5Yg0X7FjCJjLgE0oiXuqsG6lk=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=E3tLG3r7xRS4/RYfFK8ko5UIxHsyZtkL4eyY4Z6cPlDmovoV/hwsuvQfWFQlFh1scm7KQ3Z/RoCKBpRrvRQmDwddlWNbHQiJZOyA4wNydbJsvncRV2B0mCbnw0BUlgXHmkUjKTAZkBXeVtvU6ogn94k6oGFvnvWuaKFe2JTcw50= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=zytor.com; spf=pass smtp.mailfrom=zytor.com; dkim=pass (2048-bit key) header.d=zytor.com header.i=@zytor.com header.b=O/rAv7sy; arc=none smtp.client-ip=198.137.202.136 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=zytor.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=zytor.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=zytor.com header.i=@zytor.com header.b="O/rAv7sy" Received: from mail.zytor.com (c-76-133-66-138.hsd1.ca.comcast.net [76.133.66.138]) (authenticated bits=0) by mail.zytor.com (8.18.1/8.17.1) with ESMTPSA id 60O0dnvX1194278 (version=TLSv1.3 cipher=TLS_AES_256_GCM_SHA384 bits=256 verify=NO); Fri, 23 Jan 2026 16:39:59 -0800 DKIM-Filter: OpenDKIM Filter v2.11.0 mail.zytor.com 60O0dnvX1194278 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=zytor.com; s=2025122301; t=1769215200; bh=qgqCVVYC4g8IPodTRYXQvgyAgGlYYA2s0aoJDPH/JY0=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=O/rAv7sy3ru6J+JaF1sIVvws6airJxj4RycIDOdMTaZm1o1CrAV+azzYRmcnf583A fE6C7+MwwqMKhbHRAq3qcjVWWa/ivc3XrJNH9fWW8q07EzFjG3fW/kkMGiSXjKMbnx 2P43FVDwKUImNjB7ZI//maLsdnyfH4ghcsDcV1yslNO9GyWKhnMbwNF9jW8ca0KQkD ozFJOX4KeS8Lc+DCwsCGQKZg1kckbmzGefKP6vB1jR5QmrhqsiDR88ieKhRi4kBIRd hajCas16yk7deyUIk7JEQRfJOlZZpVsvt+JSABgYrSylfP1kHH8kJcMIJ+TXOMXPI9 9JFgM1LoaASWQ== From: "H. Peter Anvin" To: Alexander Viro , Christian Brauner , Jan Kara , Jonathan Corbet , "H. Peter Anvin" Cc: linux-fsdevel@vger.kernel.org, linux-doc@vger.kernel.org, linux-kernel@vger.kernel.org, Lennart Poettering , systemd-devel@lists.freedesktop.org Subject: [RFC PATCH 2/3] initramfs: support mounting filesystems during initramfs expansion Date: Fri, 23 Jan 2026 16:39:35 -0800 Message-ID: <20260124003939.426931-3-hpa@zytor.com> X-Mailer: git-send-email 2.52.0 In-Reply-To: <20260124003939.426931-1-hpa@zytor.com> References: <20260124003939.426931-1-hpa@zytor.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Expanding the initramfs contents directly into the rootfs is not always desirable. Allow the initramfs to contain instructions to mount additional filesystems before continuing processing. This is done by a magic filename !!!MOUNT!!! which, instead of being expanded as a file, is processed as a simplified fstab(5) mount specification (see following documentation patch.) Some reasons this may be desirable: 1. The early init code may wish to expand into a separate tmpfs so it can be pivoted, remounted, or efficiently garbage collected on umount. 2. The early init code may which to pass some content, but not all, to the main userspace. This allows mounting a second tmpfs that can then be mounted underneath somewhere the main root without having to copy the contents. 3. The main userspace can retain the rootfs as the only root. In that case, the initramfs contents can be expanded into a tmpfs that is mounted at a different path. One use case for that might be /lib/modules. 4. It may be convenient for the early init code to have /dev, /proc and /sys pre-mounted. Signed-off-by: H. Peter Anvin (Intel) --- init/initramfs.c | 98 ++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 95 insertions(+), 3 deletions(-) diff --git a/init/initramfs.c b/init/initramfs.c index 6ddbfb17fb8f..681ab59ab6cd 100644 --- a/init/initramfs.c +++ b/init/initramfs.c @@ -222,6 +222,7 @@ static __initdata enum state { GotName, CopyFile, GotSymlink, + GotMountpoint, Reset } state, next_state; =20 @@ -254,6 +255,9 @@ static void __init read_into(char *buf, unsigned size, = enum state next) } } =20 +#define SYMLINK_BUF_SIZE (PATH_MAX + N_ALIGN(PATH_MAX) + 1) +#define NAME_BUF_SIZE N_ALIGN(PATH_MAX) + static __initdata char *header_buf, *symlink_buf, *name_buf; =20 static int __init do_start(void) @@ -355,6 +359,37 @@ static int __init maybe_link(void) return 0; } =20 +static int __init maybe_mountpoint(void) +{ + static const char mount_magic_name[] __initconst =3D "!!!MOUNT!!!"; + const unsigned long mount_magic_len =3D sizeof(mount_magic_name)-1; + unsigned long len =3D name_len-1; + const char *name =3D collected; + + if (!S_ISREG(mode)) + return 0; + if (len < mount_magic_len) + return 0; + if (len > mount_magic_len && name[len-mount_magic_len] !=3D '/') + return 0; + if (memcmp(name+len-mount_magic_len, mount_magic_name, mount_magic_len)) + return 0; + + /* Factor out the parent directory name and save it in name_buf */ + len -=3D mount_magic_len; + if (!len) + name_buf[len++] =3D '.'; + else + memmove(name_buf, name, len); + name_buf[len] =3D '\0'; + + if (body_len >=3D SYMLINK_BUF_SIZE) + return 1; /* Option file too large */ + + read_into(symlink_buf, body_len, GotMountpoint); + return 1; +} + static __initdata struct file *wfile; static __initdata loff_t wfile_pos; =20 @@ -375,6 +410,10 @@ static int __init do_name(void) free_hash(); return 0; } + + if (maybe_mountpoint()) + return 0; + clean_path(collected, mode); if (S_ISREG(mode)) { int ml =3D maybe_link(); @@ -392,6 +431,7 @@ static int __init do_name(void) vfs_fchmod(wfile, mode); if (body_len) vfs_truncate(&wfile->f_path, body_len); + state =3D CopyFile; } } else if (S_ISDIR(mode)) { @@ -451,6 +491,56 @@ static int __init do_symlink(void) return 0; } =20 +static int __init do_mountpoint(void) +{ + int ret; + char *p, *ep; + const char *opts[3]; + const char *opstart; + unsigned long n; + + state =3D SkipIt; + next_state =3D Reset; + + memset(opts, 0, sizeof(opts)); + + /* Default filesystem type */ + opts[0] =3D IS_ENABLED(CONFIG_TMPFS) ? "tmpfs" : "ramfs"; + + p =3D collected; + ep =3D p + body_len; + n =3D 0; + opstart =3D NULL; + while (p < ep && n < 3) { + char c =3D *p; + if (c <=3D ' ') { + if (opstart) { + *p =3D '\0'; + opts[n++] =3D opstart; + opstart =3D NULL; + } + } else { + if (!opstart) + opstart =3D p; + } + p++; + } + + if (!opts[1]) + opts[1] =3D opts[0]; + + ret =3D init_mount(opts[0], name_buf, opts[1], 0, opts[2]); + if (!ret) { + init_chown(name_buf, uid, gid, 0); + init_chmod(name_buf, mode); /* S_IFMT is ignored by chmod() */ + dir_add(name_buf, name_len, mtime); + } else { + pr_err("initramfs mount %s %s %s failed, error %d\n", + opts[0], name_buf, opts[1], ret); + } + return 0; +} + static __initdata int (*actions[])(void) =3D { [Start] =3D do_start, [Collect] =3D do_collect, @@ -459,6 +549,7 @@ static __initdata int (*actions[])(void) =3D { [GotName] =3D do_name, [CopyFile] =3D do_copy, [GotSymlink] =3D do_symlink, + [GotMountpoint] =3D do_mountpoint, [Reset] =3D do_reset, }; =20 @@ -515,8 +606,8 @@ char * __init unpack_to_rootfs(char *buf, unsigned long= len) const char *compress_name; struct { char header[CPIO_HDRLEN]; - char symlink[PATH_MAX + N_ALIGN(PATH_MAX) + 1]; - char name[N_ALIGN(PATH_MAX)]; + char symlink[SYMLINK_BUF_SIZE]; + char name[NAME_BUF_SIZE]; } *bufs =3D kmalloc(sizeof(*bufs), GFP_KERNEL); =20 if (!bufs) From nobody Sun Feb 8 18:35:27 2026 Received: from mail.zytor.com (terminus.zytor.com [198.137.202.136]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 70EAF192590; Sat, 24 Jan 2026 00:40:22 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=198.137.202.136 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1769215224; cv=none; b=dUbEolHMJ6fBjqXPEhiXwTOEnZNnH9ZHCsYam4js6MCc6Hl+mv5dW3Tf7srjNeevixanun6f8FmcKYnQdJtEcNHYoCdipmV5rzztoUFVioacbAPpCwoYMNcoaBAnbVbQkW80u8kw+jR3tiyTN8C7tRzJp/6Cn1paCvI9LdIgBCY= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1769215224; c=relaxed/simple; bh=sxCYWInGWcJQzA2I9jwBu6cloSbClI3rKDeIROS8Aoc=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=Jb9mvGmglyeenR0HFz9ZuWbwanq6LWOHlHCCpezJnOilAYCOErm6+9HaAbi/YlOPivQ0jN2L7TYAW35K+cKZP/xo5HgLUNIQl+OBj7U4ydaJnwVO9myJdWpoc5Bf2Ryh7oHupuaO923xA6b0IgpDo/bcCo5KXIzX12kvZAKfKA4= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=zytor.com; spf=pass smtp.mailfrom=zytor.com; dkim=pass (2048-bit key) header.d=zytor.com header.i=@zytor.com header.b=bn/0m0OP; arc=none smtp.client-ip=198.137.202.136 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=zytor.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=zytor.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=zytor.com header.i=@zytor.com header.b="bn/0m0OP" Received: from mail.zytor.com (c-76-133-66-138.hsd1.ca.comcast.net [76.133.66.138]) (authenticated bits=0) by mail.zytor.com (8.18.1/8.17.1) with ESMTPSA id 60O0dnvY1194278 (version=TLSv1.3 cipher=TLS_AES_256_GCM_SHA384 bits=256 verify=NO); Fri, 23 Jan 2026 16:40:00 -0800 DKIM-Filter: OpenDKIM Filter v2.11.0 mail.zytor.com 60O0dnvY1194278 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=zytor.com; s=2025122301; t=1769215201; bh=4va4Vi1oM4mVPAzSfh+07TIDR6BSUY4QxzNfUhSYeE8=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=bn/0m0OP6ydBZerJ5bYNgIWvCw9jmD6sMeXonaQ5WDZLoLQ15pxI7MFpGS2SaU85Z gAEg+wjx8R5V9kgu6LFGiioqN5RdDkBk5eBJMMwoLdA8Sxg6MYQeGWuqjOeKJMe5UI IGrvwG5uJWTPAArLOf3MDuw7LCtjJCl23CT+QsUIzehyoO8v79/cv1FXDeDjopX4UA 29xh4rGJxZZq6V1QqqquGHEfR+E9/6ZGhDgPelcdf34JWSYWcPKefNrZQGKxzg66ry 37MVPar7XVevksRnGoMnBb17rScoElQx+5RqtfUbf02CxO59Lp+Wl46MLmyJSWgchq y+envHmh7lA/A== From: "H. Peter Anvin" To: Alexander Viro , Christian Brauner , Jan Kara , Jonathan Corbet , "H. Peter Anvin" Cc: linux-fsdevel@vger.kernel.org, linux-doc@vger.kernel.org, linux-kernel@vger.kernel.org, Lennart Poettering , systemd-devel@lists.freedesktop.org Subject: [RFC PATCH 3/3] Documentation/initramfs: document mount points in initramfs Date: Fri, 23 Jan 2026 16:39:36 -0800 Message-ID: <20260124003939.426931-4-hpa@zytor.com> X-Mailer: git-send-email 2.52.0 In-Reply-To: <20260124003939.426931-1-hpa@zytor.com> References: <20260124003939.426931-1-hpa@zytor.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Document how to create mount points in initramfs, using magic "!!!MOUNT!!!" file entries, the format the kernel expects for these files, and their exact semantics. Signed-off-by: H. Peter Anvin (Intel) --- .../early-userspace/buffer-format.rst | 60 ++++++++++++++++++- 1 file changed, 58 insertions(+), 2 deletions(-) diff --git a/Documentation/driver-api/early-userspace/buffer-format.rst b/D= ocumentation/driver-api/early-userspace/buffer-format.rst index 4597a91100b7..40f86b9eec75 100644 --- a/Documentation/driver-api/early-userspace/buffer-format.rst +++ b/Documentation/driver-api/early-userspace/buffer-format.rst @@ -8,8 +8,8 @@ With kernel 2.5.x, the old "initial ramdisk" protocol was c= omplemented with an "initial ramfs" protocol. The initramfs content is passed using the same memory buffer protocol used by initrd, but the content is different. The initramfs buffer contains an archive which is -expanded into a ramfs filesystem; this document details the initramfs -buffer format. +expanded into a tmpfs or ramfs filesystem; this document details the +initramfs buffer format. =20 The initramfs buffer format is based around the "newc" or "crc" CPIO formats, and can be created with the cpio(1) utility. The cpio @@ -17,6 +17,9 @@ archive can be compressed using gzip(1), or any other alg= orithm provided via CONFIG_DECOMPRESS_*. One valid version of an initramfs buffer is thus a single .cpio.gz file. =20 +In kernel version XXXX the feature to mount additional filesystems +during initramfs expansion was introduced, see below. + The full format of the initramfs buffer is defined by the following grammar, where:: =20 @@ -130,3 +133,56 @@ a) Separate the different file data sources with a "TR= AILER!!!" end-of-archive marker, or =20 b) Make sure c_nlink =3D=3D 1 for all nondirectory entries. + + +Mounting additional filesystems +=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D + +If a regular file with the special name "!!!MOUNT!!!" is encountered +during initramfs processing, the file contents is parsed as a mount +specification in format similar to fstab(5). It should contain of a +single line in one of the following formats:: + + fs_spec fs_vfstype fs_mntops + fs_spec fs_vfstype + fs_vfstype + + +Comment or blank lines are NOT allowed, and the terminating newline is +required. + +The specified filesystem is then mounted onto the directory in which +the !!!MOUNT!!! file is located, for example, if the file is named:: + + dev/!!!MOUNT!!! + + +then the filesystem will be mounted onto the /dev directory, which +must already exist. + +The mount is performed immediately, before processing any further +initramfs entries. + +The c_mode, c_uid, c_gid, and c_mtime (with CONFIG_INITRAMFS_PRESERVE_MTIM= E) +values for the file are applied to the root directory of the newly +mounted filesystem, if that filesystem is writable and allows those +operations. Therefore, the !!!MOUNT!!! file should typically have the +x permission bit set, as a directory would. + +fs_spec or fs_mntops values that require user space support, such as +LABEL=3D or UUID=3D, are not supported. To mount a filesystem that +requires a block device, the appropriate /dev entry need to have +been created, or devtmpfs have been mounted, earlier in the initramfs +image. + +A !!!MOUNT!!! entry in the cpio archive root, or multiple !!!MOUNT!!! +entries for the same path, will cause overmounts. This allows the +initramfs to be expanded into a tmpfs that is separate from the +rootfs, and which therefore, unlike the rootfs, can be unmounted. + +The special name !!!MOUNT!!! was chosen because the sequence !!! +already has special meaning in cpio (the TRAILER!!! entry) and because +! is the lowest-numbered non-blank character in ASCII. Therefore +creating a sorted cpio archive will naturally end up with the +!!!MOUNT!!! entry immediately after the directory itself and before +its contents. --=20 2.52.0