linux-fsdevel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: David Disseldorp <ddiss@suse.de>
To: linux-fsdevel@vger.kernel.org, Andrew Morton <akpm@linux-foundation.org>
Cc: Martin Wilck <mwilck@suse.com>,
	viro@zeniv.linux.org.uk, willy@infradead.org
Subject: Re: [PATCH v6 3/6] initramfs: add INITRAMFS_PRESERVE_MTIME Kconfig option
Date: Tue, 8 Mar 2022 14:09:42 +0100	[thread overview]
Message-ID: <20220308140942.47dcb97c@suse.de> (raw)
In-Reply-To: <20220107133814.32655-4-ddiss@suse.de>

Ping on this patchset again...

@Andrew: while looking through lkml archives from a lifetime ago at
https://lkml.org/lkml/2008/8/16/59 , it appears that your preference at
the time was to drop the scattered INITRAMFS_PRESERVE_MTIME ifdefs prior
to merge.
I'd much appreciate your thoughts on the reintroduction of the option
based on the microbenchmark results below.

On Fri,  7 Jan 2022 14:38:11 +0100, David Disseldorp wrote:

> initramfs cpio mtime preservation, as implemented in commit 889d51a10712
> ("initramfs: add option to preserve mtime from initramfs cpio images"),
> uses a linked list to defer directory mtime processing until after all
> other items in the cpio archive have been processed. This is done to
> ensure that parent directory mtimes aren't overwritten via subsequent
> child creation. Contrary to the 889d51a10712 commit message, the mtime
> preservation behaviour is unconditional.
> 
> This change adds a new INITRAMFS_PRESERVE_MTIME Kconfig option, which
> can be used to disable on-by-default mtime retention and in turn
> speed up initramfs extraction, particularly for cpio archives with large
> directory counts.
> 
> Benchmarks with a one million directory cpio archive extracted 20 times
> demonstrated:
> 				mean extraction time (s)	std dev
> INITRAMFS_PRESERVE_MTIME=y		3.808			 0.006
> INITRAMFS_PRESERVE_MTIME unset		3.056			 0.004
> 
> The above extraction times were measured using ftrace
> (initcall_finish - initcall_start) values for populate_rootfs() with
> initramfs_async disabled.
> 
> Signed-off-by: David Disseldorp <ddiss@suse.de>
> Reviewed-by: Martin Wilck <mwilck@suse.com>
> [ddiss: rebase atop dir_entry.name flexible array member]
> ---
>  init/Kconfig           | 10 ++++++++
>  init/initramfs.c       | 50 +++-------------------------------------
>  init/initramfs_mtime.h | 52 ++++++++++++++++++++++++++++++++++++++++++
>  3 files changed, 65 insertions(+), 47 deletions(-)
>  create mode 100644 init/initramfs_mtime.h
> 
> diff --git a/init/Kconfig b/init/Kconfig
> index 4b7bac10c72d..a98f63d3c366 100644
> --- a/init/Kconfig
> +++ b/init/Kconfig
> @@ -1357,6 +1357,16 @@ config BOOT_CONFIG
>  
>  	  If unsure, say Y.
>  
> +config INITRAMFS_PRESERVE_MTIME
> +	bool "Preserve cpio archive mtimes in initramfs"
> +	default y
> +	help
> +	  Each entry in an initramfs cpio archive carries an mtime value. When
> +	  enabled, extracted cpio items take this mtime, with directory mtime
> +	  setting deferred until after creation of any child entries.
> +
> +	  If unsure, say Y.
> +
>  choice
>  	prompt "Compiler optimization level"
>  	default CC_OPTIMIZE_FOR_PERFORMANCE
> diff --git a/init/initramfs.c b/init/initramfs.c
> index 656d2d71349f..5b4ca8ecadb5 100644
> --- a/init/initramfs.c
> +++ b/init/initramfs.c
> @@ -17,6 +17,8 @@
>  #include <linux/init_syscalls.h>
>  #include <linux/umh.h>
>  
> +#include "initramfs_mtime.h"
> +
>  static ssize_t __init xwrite(struct file *file, const char *p, size_t count,
>  		loff_t *pos)
>  {
> @@ -116,48 +118,6 @@ static void __init free_hash(void)
>  	}
>  }
>  
> -static long __init do_utime(char *filename, time64_t mtime)
> -{
> -	struct timespec64 t[2];
> -
> -	t[0].tv_sec = mtime;
> -	t[0].tv_nsec = 0;
> -	t[1].tv_sec = mtime;
> -	t[1].tv_nsec = 0;
> -	return init_utimes(filename, t);
> -}
> -
> -static __initdata LIST_HEAD(dir_list);
> -struct dir_entry {
> -	struct list_head list;
> -	time64_t mtime;
> -	char name[];
> -};
> -
> -static void __init dir_add(const char *name, time64_t mtime)
> -{
> -	size_t nlen = strlen(name) + 1;
> -	struct dir_entry *de;
> -
> -	de = kmalloc(sizeof(struct dir_entry) + nlen, GFP_KERNEL);
> -	if (!de)
> -		panic_show_mem("can't allocate dir_entry buffer");
> -	INIT_LIST_HEAD(&de->list);
> -	strscpy(de->name, name, nlen);
> -	de->mtime = mtime;
> -	list_add(&de->list, &dir_list);
> -}
> -
> -static void __init dir_utime(void)
> -{
> -	struct dir_entry *de, *tmp;
> -	list_for_each_entry_safe(de, tmp, &dir_list, list) {
> -		list_del(&de->list);
> -		do_utime(de->name, de->mtime);
> -		kfree(de);
> -	}
> -}
> -
>  static __initdata time64_t mtime;
>  
>  /* cpio header parsing */
> @@ -381,14 +341,10 @@ static int __init do_name(void)
>  static int __init do_copy(void)
>  {
>  	if (byte_count >= body_len) {
> -		struct timespec64 t[2] = { };
>  		if (xwrite(wfile, victim, body_len, &wfile_pos) != body_len)
>  			error("write error");
>  
> -		t[0].tv_sec = mtime;
> -		t[1].tv_sec = mtime;
> -		vfs_utimes(&wfile->f_path, t);
> -
> +		do_utime_path(&wfile->f_path, mtime);
>  		fput(wfile);
>  		eat(body_len);
>  		state = SkipIt;
> diff --git a/init/initramfs_mtime.h b/init/initramfs_mtime.h
> new file mode 100644
> index 000000000000..688ed4b6f327
> --- /dev/null
> +++ b/init/initramfs_mtime.h
> @@ -0,0 +1,52 @@
> +/* SPDX-License-Identifier: GPL-2.0 */
> +
> +#ifdef CONFIG_INITRAMFS_PRESERVE_MTIME
> +static void __init do_utime(char *filename, time64_t mtime)
> +{
> +	struct timespec64 t[2] = { { .tv_sec = mtime }, { .tv_sec = mtime } };
> +	init_utimes(filename, t);
> +}
> +
> +static void __init do_utime_path(const struct path *path, time64_t mtime)
> +{
> +	struct timespec64 t[2] = { { .tv_sec = mtime }, { .tv_sec = mtime } };
> +	vfs_utimes(path, t);
> +}
> +
> +static __initdata LIST_HEAD(dir_list);
> +struct dir_entry {
> +	struct list_head list;
> +	time64_t mtime;
> +	char name[];
> +};
> +
> +static void __init dir_add(const char *name, time64_t mtime)
> +{
> +	size_t nlen = strlen(name) + 1;
> +	struct dir_entry *de;
> +
> +	de = kmalloc(sizeof(struct dir_entry) + nlen, GFP_KERNEL);
> +	if (!de)
> +		panic("can't allocate dir_entry buffer");
> +	INIT_LIST_HEAD(&de->list);
> +	strscpy(de->name, name, nlen);
> +	de->mtime = mtime;
> +	list_add(&de->list, &dir_list);
> +}
> +
> +static void __init dir_utime(void)
> +{
> +	struct dir_entry *de, *tmp;
> +
> +	list_for_each_entry_safe(de, tmp, &dir_list, list) {
> +		list_del(&de->list);
> +		do_utime(de->name, de->mtime);
> +		kfree(de);
> +	}
> +}
> +#else
> +static void __init do_utime(char *filename, time64_t mtime) {}
> +static void __init do_utime_path(const struct path *path, time64_t mtime) {}
> +static void __init dir_add(const char *name, time64_t mtime) {}
> +static void __init dir_utime(void) {}
> +#endif


  reply	other threads:[~2022-03-08 13:09 UTC|newest]

Thread overview: 13+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-01-07 13:38 [PATCH v6 0/6] initramfs: "crc" cpio format and INITRAMFS_PRESERVE_MTIME David Disseldorp
2022-01-07 13:38 ` [PATCH v6 1/6] initramfs: refactor do_header() cpio magic checks David Disseldorp
2022-01-07 13:52   ` Christian Brauner
2022-01-07 13:38 ` [PATCH v6 2/6] initramfs: make dir_entry.name a flexible array member David Disseldorp
2022-01-07 13:46   ` Christian Brauner
2022-01-07 13:38 ` [PATCH v6 3/6] initramfs: add INITRAMFS_PRESERVE_MTIME Kconfig option David Disseldorp
2022-03-08 13:09   ` David Disseldorp [this message]
2022-03-10  3:41     ` Andrew Morton
2022-01-07 13:38 ` [PATCH v6 4/6] gen_init_cpio: fix short read file handling David Disseldorp
2022-01-12 15:38   ` Martin Wilck
2022-01-07 13:38 ` [PATCH v6 5/6] gen_init_cpio: support file checksum archiving David Disseldorp
2022-01-07 13:38 ` [PATCH v6 6/6] initramfs: support cpio extraction with file checksums David Disseldorp
2022-01-18 17:25 ` [PATCH v6 0/6] initramfs: "crc" cpio format and INITRAMFS_PRESERVE_MTIME David Disseldorp

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20220308140942.47dcb97c@suse.de \
    --to=ddiss@suse.de \
    --cc=akpm@linux-foundation.org \
    --cc=linux-fsdevel@vger.kernel.org \
    --cc=mwilck@suse.com \
    --cc=viro@zeniv.linux.org.uk \
    --cc=willy@infradead.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).