[PATCH 9/8] fuse2fs: fix relatime comparisons

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



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);
 




[Index of Archives]     [Reiser Filesystem Development]     [Ceph FS]     [Kernel Newbies]     [Security]     [Netfilter]     [Bugtraq]     [Linux FS]     [Yosemite National Park]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Samba]     [Device Mapper]     [Linux Media]

  Powered by Linux