From: Darrick J. Wong Date: Mon, 7 Jul 2025 16:05:25 +0000 (-0700) Subject: fuse2fs: fix relatime comparisons X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=5cd55fe0aca3fed5a7ca6f0b4976f0e7b1e4a972;p=thirdparty%2Fe2fsprogs.git fuse2fs: fix relatime comparisons 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@vger.kernel.org # v1.43 Fixes: 81cbf1ef4f5dab ("misc: add fuse2fs, a FUSE server for e2fsprogs") Signed-off-by: Darrick J. Wong Link: https://lore.kernel.org/r/20250707160525.GC2672022@frogsfrogsfrogs Signed-off-by: Theodore Ts'o --- diff --git a/misc/fuse2fs.c b/misc/fuse2fs.c index ab3efea6..b7201f7c 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);