From: Viacheslav Dubeyko Date: Thu, 14 May 2026 19:56:31 +0000 (-0700) Subject: hfs: disable the updating of file access times (atime) X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=f14ccd7baf7793020c9d1bc34ae7a8e048546f2c;p=thirdparty%2Flinux.git hfs: disable the updating of file access times (atime) The xfstests' test-case generic/003 fails with errors: sudo ./check generic/003 FSTYP -- hfs PLATFORM -- Linux/x86_64 hfsplus-testing-0001 7.0.0-rc1+ #18 SMP PREEMPT_DYNAMIC Fri Mar 13 17:54:19 PDT 2026 MKFS_OPTIONS -- /dev/loop51 MOUNT_OPTIONS -- /dev/loop51 /mnt/scratch output mismatch QA output created by 003 ERROR: access time has changed for file1 after remount ERROR: access time has changed after modifying file1 ERROR: change time has not been updated after changing file1 ERROR: access time has changed for file in read-only filesystem Silence is golden This patch fixes the issue with change time by adding inode_set_ctime_current() and mark_inode_dirty() in hfs_rename(). Also, it reworks hfs_inode_setattr() by changing simple_inode_init_ts() on inode_set_mtime_to_ts() and inode_set_ctime_current() calls. HFS hasn't any field in on-disk layout that can keep the file/folder access times (atime). It was added setting of SB_NOATIME in SB_NOATIME. Finally, we have only atime related errors in generic/003 output: sudo ./check generic/003 FSTYP -- hfs PLATFORM -- Linux/x86_64 hfsplus-testing-0001 7.1.0-rc1+ #52 SMP PREEMPT_DYNAMIC Wed May 13 15:04:37 PDT 2026 MKFS_OPTIONS -- /dev/loop51 MOUNT_OPTIONS -- /dev/loop51 /mnt/scratch QA output created by 003 ERROR: access time has not been updated after accessing file1 first time ERROR: access time has not been updated after accessing file2 ERROR: access time has not been updated after accessing file3 second time ERROR: access time has not been updated after accessing file3 third time Silence is golden The generic/003 test-case needs to be disabled for HFS case because it cannot support the file/folder access times (atime). Closes: https://github.com/hfs-linux-kernel/hfs-linux-kernel/issues/3 cc: John Paul Adrian Glaubitz cc: Yangtao Li cc: linux-fsdevel@vger.kernel.org Signed-off-by: Viacheslav Dubeyko Link: https://lore.kernel.org/r/20260514195630.354206-2-slava@dubeyko.com Signed-off-by: Viacheslav Dubeyko --- diff --git a/fs/hfs/dir.c b/fs/hfs/dir.c index f5e7efe924e78..702c16ea954bf 100644 --- a/fs/hfs/dir.c +++ b/fs/hfs/dir.c @@ -306,10 +306,15 @@ static int hfs_rename(struct mnt_idmap *idmap, struct inode *old_dir, res = hfs_cat_move(d_inode(old_dentry)->i_ino, old_dir, &old_dentry->d_name, new_dir, &new_dentry->d_name); - if (!res) + if (!res) { + struct inode *inode = d_inode(old_dentry); + hfs_cat_build_key(old_dir->i_sb, - (btree_key *)&HFS_I(d_inode(old_dentry))->cat_key, + (btree_key *)&HFS_I(inode)->cat_key, new_dir->i_ino, &new_dentry->d_name); + inode_set_ctime_current(inode); + mark_inode_dirty(inode); + } return res; } diff --git a/fs/hfs/inode.c b/fs/hfs/inode.c index 1cbba73450389..b2329de151eca 100644 --- a/fs/hfs/inode.c +++ b/fs/hfs/inode.c @@ -348,6 +348,7 @@ static int hfs_read_inode(struct inode *inode, void *data) struct hfs_iget_data *idata = data; struct hfs_sb_info *hsb = HFS_SB(inode->i_sb); hfs_cat_rec *rec; + struct timespec64 mtime; HFS_I(inode)->flags = 0; HFS_I(inode)->rsrc_inode = NULL; @@ -383,8 +384,10 @@ static int hfs_read_inode(struct inode *inode, void *data) inode->i_mode |= S_IWUGO; inode->i_mode &= ~hsb->s_file_umask; inode->i_mode |= S_IFREG; - inode_set_mtime_to_ts(inode, - inode_set_atime_to_ts(inode, inode_set_ctime_to_ts(inode, hfs_m_to_utime(rec->file.MdDat)))); + mtime = hfs_m_to_utime(rec->file.MdDat); + inode_set_ctime_to_ts(inode, mtime); + inode_set_atime_to_ts(inode, mtime); + inode_set_mtime_to_ts(inode, mtime); inode->i_op = &hfs_file_inode_operations; inode->i_fop = &hfs_file_operations; inode->i_mapping->a_ops = &hfs_aops; @@ -394,8 +397,10 @@ static int hfs_read_inode(struct inode *inode, void *data) inode->i_size = be16_to_cpu(rec->dir.Val) + 2; HFS_I(inode)->fs_blocks = 0; inode->i_mode = S_IFDIR | (S_IRWXUGO & ~hsb->s_dir_umask); - inode_set_mtime_to_ts(inode, - inode_set_atime_to_ts(inode, inode_set_ctime_to_ts(inode, hfs_m_to_utime(rec->dir.MdDat)))); + mtime = hfs_m_to_utime(rec->dir.MdDat); + inode_set_ctime_to_ts(inode, mtime); + inode_set_atime_to_ts(inode, mtime); + inode_set_mtime_to_ts(inode, mtime); inode->i_op = &hfs_dir_inode_operations; inode->i_fop = &hfs_dir_operations; break; @@ -665,7 +670,7 @@ int hfs_inode_setattr(struct mnt_idmap *idmap, struct dentry *dentry, truncate_setsize(inode, attr->ia_size); hfs_file_truncate(inode); - simple_inode_init_ts(inode); + inode_set_mtime_to_ts(inode, inode_set_ctime_current(inode)); } setattr_copy(&nop_mnt_idmap, inode, attr); diff --git a/fs/hfs/super.c b/fs/hfs/super.c index a4f2a2bfa6d30..a466c401f6bb2 100644 --- a/fs/hfs/super.c +++ b/fs/hfs/super.c @@ -338,7 +338,7 @@ static int hfs_fill_super(struct super_block *sb, struct fs_context *fc) sbi->sb = sb; sb->s_op = &hfs_super_operations; sb->s_xattr = hfs_xattr_handlers; - sb->s_flags |= SB_NODIRATIME; + sb->s_flags |= SB_NOATIME | SB_NODIRATIME; mutex_init(&sbi->bitmap_lock); res = hfs_mdb_get(sb);