Linux filesystem development
 help / color / mirror / Atom feed
From: Collin Funk <collin.funk1@gmail.com>
To: bug-gnulib@gnu.org,
Cc: Christoph Hellwig <hch@lst.de>,
	linux-kernel@vger.kernel.org, linux-btrfs@vger.kernel.org,
	linux-fsdevel@vger.kernel.org, Jan Kara <jack@suse.cz>,
	Christian Brauner <brauner@kernel.org>
Subject: test-fdutimensat failures after 7.0.6-200.fc44.x86_64 kernel update
Date: Fri, 15 May 2026 22:14:28 -0700	[thread overview]
Message-ID: <8733zsj5qj.fsf@gmail.com> (raw)

Hi,

After updating my Fedora system to kernel version 7.0.6-200.fc44.x86_64,
I noticed that the Gnulib 'test-fdutimensat' test fails a majority of
the time in my GNU coreutils checkout:

    $ seq 100 | xargs -n 1 sh -c '
      ./test-fdutimensat >/dev/null 2>&1
      echo $?
      ' | LC_ALL=C sort | LC_ALL=C uniq -c
         14 0
         86 134

Here is the section of code where it fails [1]:

  /* Play with UTIME_OMIT, UTIME_NOW.  */
  {
    struct stat st3;
    struct timespec ts[2];
    ts[0].tv_sec = BILLION;
    ts[0].tv_nsec = UTIME_OMIT;
    ts[1].tv_sec = 0;
    ts[1].tv_nsec = UTIME_NOW;
    nap ();
    ASSERT (func (BASE "link", ts) == 0);
    ASSERT (lstat (BASE "link", &st3) == 0);
    if (check_atime_on_symlinks)
      {
        /* The first assertion fails.  */
        ASSERT (st3.st_atime == Y2K);
        ASSERT (0 <= get_stat_atime_ns (&st3));
        ASSERT (get_stat_atime_ns (&st3) < BILLION / 2);
      }

Adding some print statements in place of the comment:

        fprintf (stderr, "%jd\n", (intmax_t) st3.st_atime);
        fprintf (stderr, "%jd\n", (intmax_t) Y2K);
        fprintf (stderr, "----------------\n");

Here is an example of what is seen when the test fails:

    $ ./test-fdutimensat 
    ----------------
    1778905091
    946684800
    test-lutimens.h:192: assertion 'st3.st_atime == Y2K' failed

Here is an example of what is seen when the test passes:

    $ ./test-fdutimensat 
    ----------------
    946684800
    946684800
    ----------------
    946684800
    946684800
    ----------------
    946684800
    946684800

So, it looks like the atime is being updated sometimes despite the use
of UTIME_OMIT.

Interestingly, in my Gnulib checkout residing in a separate directory
the test passes:

    $ git clone https://github.com/coreutils/gnulib.git
    $ cd gnulib
    $ ./gnulib-tool --create-testdir --dir testdir1 fdutimensat
    $ cd testdir1
    $ ./configure && make -j $(nproc)
    $ cd gltests
    $ seq 100 | xargs -n 1 sh -c '
          ./test-fdutimensat >/dev/null 2>&1
          echo $?
          ' | LC_ALL=C sort | LC_ALL=C uniq -c
        100 0

All of this testing was performed on the same BTRFS subvolume:

    /dev/mapper/nvme0n1p3_encrypted on /home type btrfs (rw,relatime,seclabel,ssd,space_cache=v2,subvolid=257,subvol=/root/home)

I could only find one commit since 6.19.14-300.fc44, which I never
experienced this error on, that looked like it may be related [2]. I am
very much unfamiliar with this code, so anything after this sentence
should be taken with a grain of salt.

Looking at the new inode_update_atime function that was added in that
commit:

> +static int inode_update_atime(struct inode *inode)
> +{
> +	struct timespec64 atime = inode_get_atime(inode);
> +	struct timespec64 now = current_time(inode);
> +
> +	if (timespec64_equal(&now, &atime))
> +		return 0;
> +
> +	inode_set_atime_to_ts(inode, now);
> +	return inode_time_dirty_flag(inode);
> +}

Compared to the old inode_update_timestamps function:

> -int inode_update_timestamps(struct inode *inode, int flags)
> +int inode_update_time(struct inode *inode, enum fs_update_time type,
> +		unsigned int flags)
>  {
> -	int updated = 0;
> -	struct timespec64 now;
> -
> -	if (flags & (S_MTIME|S_CTIME|S_VERSION)) {
> -		struct timespec64 ctime = inode_get_ctime(inode);
> -		struct timespec64 mtime = inode_get_mtime(inode);
> -
> -		now = inode_set_ctime_current(inode);
> -		if (!timespec64_equal(&now, &ctime))
> -			updated |= S_CTIME;
> -		if (!timespec64_equal(&now, &mtime)) {
> -			inode_set_mtime_to_ts(inode, now);
> -			updated |= S_MTIME;
> -		}
> -		if (IS_I_VERSION(inode) && inode_maybe_inc_iversion(inode, updated))
> -			updated |= S_VERSION;
> -	} else {
> -		now = current_time(inode);
> -	}
> -
> -	if (flags & S_ATIME) {
> -		struct timespec64 atime = inode_get_atime(inode);
> -
> -		if (!timespec64_equal(&now, &atime)) {
> -			inode_set_atime_to_ts(inode, now);
> -			updated |= S_ATIME;
> -		}
> +	switch (type) {
> +	case FS_UPD_ATIME:
> +		return inode_update_atime(inode);
> +	case FS_UPD_CMTIME:
> +		return inode_update_cmtime(inode);
> +	default:
> +		WARN_ON_ONCE(1);
> +		return -EIO;
>  	}
> -	return updated;
>  }

The behavior looks a bit different in the case of flags having S_MTIME,
S_CTIME, and S_VERSION being set. Before that commit it would use the
following to compare to atime:

    now = inode_set_ctime_current(inode);

However, now it will always use:

    struct timespec64 now = current_time(inode);

Could that be the cause of this behavior?

Let me know if there is any other useful information that I can share.

Thanks,
Collin

[1] https://github.com/coreutils/gnulib/blob/master/tests/test-lutimens.h#L176-L192
[2] https://github.com/torvalds/linux/commit/761475268fa8e322fe6b80bcf557dc65517df71e#diff-325e7194d6fde054508f3ab689c05b774e0755b85d5639dc92c19a2230bbcc2f

                 reply	other threads:[~2026-05-16  5:14 UTC|newest]

Thread overview: [no followups] expand[flat|nested]  mbox.gz  Atom feed

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=8733zsj5qj.fsf@gmail.com \
    --to=collin.funk1@gmail.com \
    --cc=brauner@kernel.org \
    --cc=bug-gnulib@gnu.org \
    --cc=hch@lst.de \
    --cc=jack@suse.cz \
    --cc=linux-btrfs@vger.kernel.org \
    --cc=linux-fsdevel@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.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