diff mbox series

[4/4] ocfs2: use coarse time for new created files

Message ID 20240331111744.7224-5-l@damenly.org (mailing list archive)
State New, archived
Headers show
Series ocfs2 bugs fixes exposed by fstests | expand

Commit Message

Su Yue March 31, 2024, 11:17 a.m. UTC
From: Su Yue <glass.su@suse.com>

The default atime related mount option is '-o realtime'
which means file atime should be updated if atime <= ctime
or atime <= mtime. atime should be updated in the
following scenario, but it is not:
==========================================================
$ rm /mnt/testfile;
$ echo test > /mnt/testfile
$ stat -c "%X %Y %Z" /mnt/testfile
1711881646 1711881646 1711881646
$ sleep 5
$ cat /mnt/testfile > /dev/null
$ stat -c "%X %Y %Z" /mnt/testfile
1711881646 1711881646 1711881646
==========================================================

And the reason the atime in the test is not updated is that
ocfs2 calls ktime_get_real_ts64() in __ocfs2_mknod_locked during
file creation. Then inode_set_ctime_current() is called in
inode_set_ctime_current() calls ktime_get_coarse_real_ts64() to
get current time.
ktime_get_real_ts64() is accurater than ktime_get_coarse_real_ts64().
In my test box, I saw ctime set by ktime_get_coarse_real_ts64() is
less than ktime_get_real_ts64() even ctime is set later.
The ctime of the new inode is smaller than atime.

The call trace is like:

ocfs2_create
  ocfs2_mknod
    __ocfs2_mknod_locked
    ....

      ktime_get_real_ts64 <------- set atime,ctime,mtime, more accurate
      ocfs2_populate_inode
    ...
    ocfs2_init_acl
      ocfs2_acl_set_mode
        inode_set_ctime_current
          current_time
            ktime_get_coarse_real_ts64 <-------less accurate

ocfs2_file_read_iter
  ocfs2_inode_lock_atime
    ocfs2_should_update_atime
      atime <= ctime ? <-------- false, ctime < atime due to accuracy

So here call ktime_get_coarse_real_ts64 to set inode time coarser while
creating new files. It may lower the accuracy of file times. But it's not
a big deal since we already use coarse time in other places like
ocfs2_update_inode_atime and inode_set_ctime_current.

Signed-off-by: Su Yue <glass.su@suse.com>
---
 fs/ocfs2/namei.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

Comments

Joseph Qi April 1, 2024, 2:02 a.m. UTC | #1
On 3/31/24 7:17 PM, Su Yue wrote:
> From: Su Yue <glass.su@suse.com>
> 
> The default atime related mount option is '-o realtime'
> which means file atime should be updated if atime <= ctime
> or atime <= mtime. atime should be updated in the
> following scenario, but it is not:
> ==========================================================
> $ rm /mnt/testfile;
> $ echo test > /mnt/testfile
> $ stat -c "%X %Y %Z" /mnt/testfile
> 1711881646 1711881646 1711881646
> $ sleep 5
> $ cat /mnt/testfile > /dev/null
> $ stat -c "%X %Y %Z" /mnt/testfile
> 1711881646 1711881646 1711881646
> ==========================================================
> 
> And the reason the atime in the test is not updated is that
> ocfs2 calls ktime_get_real_ts64() in __ocfs2_mknod_locked during
> file creation. Then inode_set_ctime_current() is called in
> inode_set_ctime_current() calls ktime_get_coarse_real_ts64() to
> get current time.
> ktime_get_real_ts64() is accurater than ktime_get_coarse_real_ts64().
> In my test box, I saw ctime set by ktime_get_coarse_real_ts64() is
> less than ktime_get_real_ts64() even ctime is set later.
> The ctime of the new inode is smaller than atime.
> 
> The call trace is like:
> 
> ocfs2_create
>   ocfs2_mknod
>     __ocfs2_mknod_locked
>     ....
> 
>       ktime_get_real_ts64 <------- set atime,ctime,mtime, more accurate
>       ocfs2_populate_inode
>     ...
>     ocfs2_init_acl
>       ocfs2_acl_set_mode
>         inode_set_ctime_current
>           current_time
>             ktime_get_coarse_real_ts64 <-------less accurate
> 
> ocfs2_file_read_iter
>   ocfs2_inode_lock_atime
>     ocfs2_should_update_atime
>       atime <= ctime ? <-------- false, ctime < atime due to accuracy
> 
> So here call ktime_get_coarse_real_ts64 to set inode time coarser while
> creating new files. It may lower the accuracy of file times. But it's not
> a big deal since we already use coarse time in other places like
> ocfs2_update_inode_atime and inode_set_ctime_current.
> 
> Signed-off-by: Su Yue <glass.su@suse.com>

Looks reasonable.
Reviewed-by: Joseph Qi <joseph.qi@linux.alibaba.com>

> ---
>  fs/ocfs2/namei.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/fs/ocfs2/namei.c b/fs/ocfs2/namei.c
> index 55c9d90caaaf..4d1ea8703fcd 100644
> --- a/fs/ocfs2/namei.c
> +++ b/fs/ocfs2/namei.c
> @@ -566,7 +566,7 @@ static int __ocfs2_mknod_locked(struct inode *dir,
>  	fe->i_last_eb_blk = 0;
>  	strcpy(fe->i_signature, OCFS2_INODE_SIGNATURE);
>  	fe->i_flags |= cpu_to_le32(OCFS2_VALID_FL);
> -	ktime_get_real_ts64(&ts);
> +	ktime_get_coarse_real_ts64(&ts);
>  	fe->i_atime = fe->i_ctime = fe->i_mtime =
>  		cpu_to_le64(ts.tv_sec);
>  	fe->i_mtime_nsec = fe->i_ctime_nsec = fe->i_atime_nsec =
diff mbox series

Patch

diff --git a/fs/ocfs2/namei.c b/fs/ocfs2/namei.c
index 55c9d90caaaf..4d1ea8703fcd 100644
--- a/fs/ocfs2/namei.c
+++ b/fs/ocfs2/namei.c
@@ -566,7 +566,7 @@  static int __ocfs2_mknod_locked(struct inode *dir,
 	fe->i_last_eb_blk = 0;
 	strcpy(fe->i_signature, OCFS2_INODE_SIGNATURE);
 	fe->i_flags |= cpu_to_le32(OCFS2_VALID_FL);
-	ktime_get_real_ts64(&ts);
+	ktime_get_coarse_real_ts64(&ts);
 	fe->i_atime = fe->i_ctime = fe->i_mtime =
 		cpu_to_le64(ts.tv_sec);
 	fe->i_mtime_nsec = fe->i_ctime_nsec = fe->i_atime_nsec =