From: Darrick J. Wong <djwong@xxxxxxxxxx> generic/192 fails like this even before we start adding iomap code: --- tests/generic/192.out 2025-04-30 16:20:44.512675591 -0700 +++ tests/generic/192.out.bad 2025-07-06 22:26:11.666015735 -0700 @@ -1,5 +1,6 @@ QA output created by 192 sleep for 5 seconds test -delta1 is in range +delta1 has value of 0 +delta1 is NOT in range 5 .. 7 delta2 is in range The cause of this regression is that the timestamp comparisons account only for seconds, not nanoseconds. If a write came in 100ms after the last read but still in the same second, then we fail to update atime on a subsequent read. Fix this by converting the timespecs to doubles so that we can include the nanoseconds component, and then perform the comparison in floating point mode. Cc: <linux-ext4@xxxxxxxxxxxxxxx> # v1.43 Fixes: 81cbf1ef4f5dab ("misc: add fuse2fs, a FUSE server for e2fsprogs") Signed-off-by: "Darrick J. Wong" <djwong@xxxxxxxxxx> --- misc/fuse2fs.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/misc/fuse2fs.c b/misc/fuse2fs.c index ab3efea66d3def..b7201f7c8ed185 100644 --- a/misc/fuse2fs.c +++ b/misc/fuse2fs.c @@ -461,6 +461,7 @@ static int update_atime(ext2_filsys fs, ext2_ino_t ino) errcode_t err; struct ext2_inode_large inode, *pinode; struct timespec atime, mtime, now; + double datime, dmtime, dnow; if (!(fs->flags & EXT2_FLAG_RW)) return 0; @@ -472,11 +473,17 @@ static int update_atime(ext2_filsys fs, ext2_ino_t ino) EXT4_INODE_GET_XTIME(i_atime, &atime, pinode); EXT4_INODE_GET_XTIME(i_mtime, &mtime, pinode); get_now(&now); + + datime = atime.tv_sec + ((double)atime.tv_nsec / 1000000000); + dmtime = mtime.tv_sec + ((double)mtime.tv_nsec / 1000000000); + dnow = now.tv_sec + ((double)now.tv_nsec / 1000000000); + /* * If atime is newer than mtime and atime hasn't been updated in thirty - * seconds, skip the atime update. Same idea as Linux "relatime". + * seconds, skip the atime update. Same idea as Linux "relatime". Use + * doubles to account for nanosecond resolution. */ - if (atime.tv_sec >= mtime.tv_sec && atime.tv_sec >= now.tv_sec - 30) + if (datime >= dmtime && datime >= dnow - 30) return 0; EXT4_INODE_SET_XTIME(i_atime, &now, &inode);