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