* [PATCH] initramfs: Reduce hardlink hash allocation sizes
@ 2026-09-19 21:39 Thorsten Blum
2026-09-22 9:45 ` Jan Kara
2026-09-25 15:17 ` Christian Brauner
0 siblings, 2 replies; 5+ messages in thread
From: Thorsten Blum @ 2026-09-19 21:39 UTC (permalink / raw)
To: Alexander Viro, Christian Brauner, Jan Kara
Cc: Thorsten Blum, linux-fsdevel, linux-kernel
Each hardlink hash entry reserves N_ALIGN(PATH_MAX) bytes for its name.
This makes every allocation larger than 4 KiB, placing it in the
kmalloc-8k bucket even for short names.
Use a flexible array with the already validated cpio name_len to reduce
allocation sizes.
Also use const for the read-only name parameter.
Signed-off-by: Thorsten Blum <blum@kernel.org>
---
Tested with initramfs KUnit suite: all 9 tests pass.
---
init/initramfs.c | 11 ++++++-----
1 file changed, 6 insertions(+), 5 deletions(-)
diff --git a/init/initramfs.c b/init/initramfs.c
index 3cee8b50ad82..ebddde9c8f0d 100644
--- a/init/initramfs.c
+++ b/init/initramfs.c
@@ -80,7 +80,7 @@ static __initdata struct hash {
int ino, minor, major;
umode_t mode;
struct hash *next;
- char name[N_ALIGN(PATH_MAX)];
+ char name[];
} *head[32];
static __initdata bool hardlink_seen;
@@ -92,7 +92,7 @@ static inline int hash(int major, int minor, int ino)
}
static char __init *find_link(int major, int minor, int ino,
- umode_t mode, char *name)
+ umode_t mode, const char *name, size_t nlen)
{
struct hash **p, *q;
for (p = head + hash(major, minor, ino); *p; p = &(*p)->next) {
@@ -106,14 +106,15 @@ static char __init *find_link(int major, int minor, int ino,
continue;
return (*p)->name;
}
- q = kmalloc_obj(struct hash);
+
+ q = kmalloc_flex(struct hash, name, nlen);
if (!q)
panic_show_mem("can't allocate link hash entry");
q->major = major;
q->minor = minor;
q->ino = ino;
q->mode = mode;
- strscpy(q->name, name);
+ strscpy(q->name, name, nlen);
q->next = NULL;
*p = q;
hardlink_seen = true;
@@ -355,7 +356,7 @@ static void __init clean_path(char *path, umode_t fmode)
static int __init maybe_link(void)
{
if (nlink >= 2) {
- char *old = find_link(major, minor, ino, mode, collected);
+ char *old = find_link(major, minor, ino, mode, collected, name_len);
if (old) {
clean_path(collected, 0);
return (init_link(old, collected) < 0) ? -1 : 1;
^ permalink raw reply [flat|nested] 5+ messages in thread* Re: [PATCH] initramfs: Reduce hardlink hash allocation sizes
2026-09-19 21:39 [PATCH] initramfs: Reduce hardlink hash allocation sizes Thorsten Blum
@ 2026-09-22 9:45 ` Jan Kara
2026-09-22 10:08 ` Thorsten Blum
2026-09-25 15:17 ` Christian Brauner
1 sibling, 1 reply; 5+ messages in thread
From: Jan Kara @ 2026-09-22 9:45 UTC (permalink / raw)
To: Thorsten Blum
Cc: Alexander Viro, Christian Brauner, Jan Kara, linux-fsdevel, linux-kernel
On Sat 19-09-26 23:39:00, Thorsten Blum wrote:
> Each hardlink hash entry reserves N_ALIGN(PATH_MAX) bytes for its name.
> This makes every allocation larger than 4 KiB, placing it in the
> kmalloc-8k bucket even for short names.
>
> Use a flexible array with the already validated cpio name_len to reduce
> allocation sizes.
>
> Also use const for the read-only name parameter.
>
> Signed-off-by: Thorsten Blum <blum@kernel.org>
...
> @@ -106,14 +106,15 @@ static char __init *find_link(int major, int minor, int ino,
> continue;
> return (*p)->name;
> }
> - q = kmalloc_obj(struct hash);
> +
> + q = kmalloc_flex(struct hash, name, nlen);
> if (!q)
> panic_show_mem("can't allocate link hash entry");
> q->major = major;
> q->minor = minor;
> q->ino = ino;
> q->mode = mode;
> - strscpy(q->name, name);
> + strscpy(q->name, name, nlen);
> q->next = NULL;
> *p = q;
> hardlink_seen = true;
What about the space for terminating \0 ? This way the stored 'name' will
be actually one character shorter because strscpy() will overwrite the last
character by \0. Or do I miss something?
Honza
> @@ -355,7 +356,7 @@ static void __init clean_path(char *path, umode_t fmode)
> static int __init maybe_link(void)
> {
> if (nlink >= 2) {
> - char *old = find_link(major, minor, ino, mode, collected);
> + char *old = find_link(major, minor, ino, mode, collected, name_len);
> if (old) {
> clean_path(collected, 0);
> return (init_link(old, collected) < 0) ? -1 : 1;
--
Jan Kara <jack@suse.com>
SUSE Labs, CR
^ permalink raw reply [flat|nested] 5+ messages in thread* Re: [PATCH] initramfs: Reduce hardlink hash allocation sizes
2026-09-22 9:45 ` Jan Kara
@ 2026-09-22 10:08 ` Thorsten Blum
2026-09-23 10:38 ` Jan Kara
0 siblings, 1 reply; 5+ messages in thread
From: Thorsten Blum @ 2026-09-22 10:08 UTC (permalink / raw)
To: Jan Kara; +Cc: Alexander Viro, Christian Brauner, linux-fsdevel, linux-kernel
On Tue, Sep 22, 2026 at 11:45:37AM +0200, Jan Kara wrote:
> On Sat 19-09-26 23:39:00, Thorsten Blum wrote:
> > Each hardlink hash entry reserves N_ALIGN(PATH_MAX) bytes for its name.
> > This makes every allocation larger than 4 KiB, placing it in the
> > kmalloc-8k bucket even for short names.
> >
> > Use a flexible array with the already validated cpio name_len to reduce
> > allocation sizes.
> >
> > Also use const for the read-only name parameter.
> >
> > Signed-off-by: Thorsten Blum <blum@kernel.org>
>
> ...
>
> > @@ -106,14 +106,15 @@ static char __init *find_link(int major, int minor, int ino,
> > continue;
> > return (*p)->name;
> > }
> > - q = kmalloc_obj(struct hash);
> > +
> > + q = kmalloc_flex(struct hash, name, nlen);
> > if (!q)
> > panic_show_mem("can't allocate link hash entry");
> > q->major = major;
> > q->minor = minor;
> > q->ino = ino;
> > q->mode = mode;
> > - strscpy(q->name, name);
> > + strscpy(q->name, name, nlen);
> > q->next = NULL;
> > *p = q;
> > hardlink_seen = true;
>
> What about the space for terminating \0 ? This way the stored 'name' will
> be actually one character shorter because strscpy() will overwrite the last
> character by \0. Or do I miss something?
do_name() guarantees that collected[name_len - 1] == '\0' before calling
maybe_link(), so name_len already includes the NUL terminator and no
character is overwritten.
^ permalink raw reply [flat|nested] 5+ messages in thread* Re: [PATCH] initramfs: Reduce hardlink hash allocation sizes
2026-09-22 10:08 ` Thorsten Blum
@ 2026-09-23 10:38 ` Jan Kara
0 siblings, 0 replies; 5+ messages in thread
From: Jan Kara @ 2026-09-23 10:38 UTC (permalink / raw)
To: Thorsten Blum
Cc: Jan Kara, Alexander Viro, Christian Brauner, linux-fsdevel, linux-kernel
On Tue 22-09-26 12:08:43, Thorsten Blum wrote:
> On Tue, Sep 22, 2026 at 11:45:37AM +0200, Jan Kara wrote:
> > On Sat 19-09-26 23:39:00, Thorsten Blum wrote:
> > > Each hardlink hash entry reserves N_ALIGN(PATH_MAX) bytes for its name.
> > > This makes every allocation larger than 4 KiB, placing it in the
> > > kmalloc-8k bucket even for short names.
> > >
> > > Use a flexible array with the already validated cpio name_len to reduce
> > > allocation sizes.
> > >
> > > Also use const for the read-only name parameter.
> > >
> > > Signed-off-by: Thorsten Blum <blum@kernel.org>
> >
> > ...
> >
> > > @@ -106,14 +106,15 @@ static char __init *find_link(int major, int minor, int ino,
> > > continue;
> > > return (*p)->name;
> > > }
> > > - q = kmalloc_obj(struct hash);
> > > +
> > > + q = kmalloc_flex(struct hash, name, nlen);
> > > if (!q)
> > > panic_show_mem("can't allocate link hash entry");
> > > q->major = major;
> > > q->minor = minor;
> > > q->ino = ino;
> > > q->mode = mode;
> > > - strscpy(q->name, name);
> > > + strscpy(q->name, name, nlen);
> > > q->next = NULL;
> > > *p = q;
> > > hardlink_seen = true;
> >
> > What about the space for terminating \0 ? This way the stored 'name' will
> > be actually one character shorter because strscpy() will overwrite the last
> > character by \0. Or do I miss something?
>
> do_name() guarantees that collected[name_len - 1] == '\0' before calling
> maybe_link(), so name_len already includes the NUL terminator and no
> character is overwritten.
Ah, indeed. Thanks for explanation. Feel free to add:
Reviewed-by: Jan Kara <jack@suse.cz>
Honza
--
Jan Kara <jack@suse.com>
SUSE Labs, CR
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [PATCH] initramfs: Reduce hardlink hash allocation sizes
2026-09-19 21:39 [PATCH] initramfs: Reduce hardlink hash allocation sizes Thorsten Blum
2026-09-22 9:45 ` Jan Kara
@ 2026-09-25 15:17 ` Christian Brauner
1 sibling, 0 replies; 5+ messages in thread
From: Christian Brauner @ 2026-09-25 15:17 UTC (permalink / raw)
To: Alexander Viro, Jan Kara, Thorsten Blum; +Cc: linux-fsdevel, linux-kernel
On Sat, 19 Sep 2026 23:39:00 +0200, Thorsten Blum wrote:
> initramfs: Reduce hardlink hash allocation sizes
Applied to the vfs-7.4.misc branch of the vfs/vfs.git tree.
Patches in the vfs-7.4.misc branch should appear in linux-next soon.
Please report any outstanding bugs that were missed during review in a
new review to the original patch series allowing us to drop it.
It's encouraged to provide Acked-bys and Reviewed-bys even though the
patch has now been applied. If possible patch trailers will be updated.
Note that commit hashes shown below are subject to change due to rebase,
trailer updates or similar. If in doubt, please check the listed branch.
tree: https://git.kernel.org/pub/scm/linux/kernel/git/vfs/vfs.git
branch: vfs-7.4.misc
[1/1] initramfs: Reduce hardlink hash allocation sizes
https://git.kernel.org/vfs/vfs/c/b53f422491af
^ permalink raw reply [flat|nested] 5+ messages in thread
end of thread, other threads:[~2026-09-25 15:17 UTC | newest]
Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2026-09-19 21:39 [PATCH] initramfs: Reduce hardlink hash allocation sizes Thorsten Blum
2026-09-22 9:45 ` Jan Kara
2026-09-22 10:08 ` Thorsten Blum
2026-09-23 10:38 ` Jan Kara
2026-09-25 15:17 ` Christian Brauner
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®