FAILED: patch "[PATCH] btrfs: populate otime when logging an inode item" failed to apply to 6.6-stable tree
Subsystems (2)
[email protected]
maintainerThe patch below does not apply to the 6.6-stable tree.
If someone wants it applied there, or to any other stable or longterm tree, then please email the backport, including the original git commit id to <[email protected]>.
To reproduce the conflict and resubmit, you may use the following commands:
git fetch https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/ linux-6.6.y
git checkout FETCH_HEAD
git cherry-pick -x 1ef94169db0958d6de39f9ea6e063ce887342e2d
# <resolve conflicts, build, test, etc.>
git commit -s
git send-email --to '<[email protected]>' --in-reply-to '2025081854-eject-aloft-03ff@gregkh' --subject-prefix 'PATCH 6.6.y' HEAD^..
Possible dependencies:
thanks,
greg k-h
------------------ original commit in Linus's tree ------------------
From 1ef94169db0958d6de39f9ea6e063ce887342e2d Mon Sep 17 00:00:00 2001
From: Qu Wenruo <[email protected]>
Date: Wed, 2 Jul 2025 15:08:13 +0930
Subject: [PATCH] btrfs: populate otime when logging an inode item
[TEST FAILURE WITH EXPERIMENTAL FEATURES]
When running test case generic/508, the test case will fail with the new btrfs shutdown support:
generic/508 - output mismatch (see /home/adam/xfstests/results//generic/508.out.bad)
--- tests/generic/508.out 2022-05-11 11:25:30.806666664 +0930
+++ /home/adam/xfstests/results//generic/508.out.bad 2025-07-02 14:53:22.401824212 +0930
@@ -1,2 +1,6 @@
QA output created by 508
Silence is golden
+Before:
+After : stat.btime = Thu Jan 1 09:30:00 1970
+Before:
+After : stat.btime = Wed Jul 2 14:53:22 2025
...
(Run 'diff -u /home/adam/xfstests/tests/generic/508.out /home/adam/xfstests/results//generic/508.out.bad' to see the entire diff)Ran: generic/508
Failures: generic/508
Failed 1 of 1 tests
Please note that the test case requires shutdown support, thus the test case will be skipped using the current upstream kernel, as it doesn't have shutdown ioctl support.
[CAUSE]
The direct cause the 0 time stamp in the log tree:
leaf 30507008 items 2 free space 16057 generation 9 owner TREE_LOG leaf 30507008 flags 0x1(WRITTEN) backref revision 1 checksum stored e522548d
checksum calced e522548d
fs uuid 57d45451-481e-43e4-aa93-289ad707a3a0
chunk uuid d52bd3fd-5163-4337-98a7-7986993ad398
item 0 key (257 INODE_ITEM 0) itemoff 16123 itemsize 160 generation 9 transid 9 size 0 nbytes 0 block group 0 mode 100644 links 1 uid 0 gid 0 rdev 0 sequence 1 flags 0x0(none) atime 1751432947.492000000 (2025-07-02 14:39:07) ctime 1751432947.492000000 (2025-07-02 14:39:07) mtime 1751432947.492000000 (2025-07-02 14:39:07) otime 0.0 (1970-01-01 09:30:00) <<<
But the old fs tree has all the correct time stamp:
btrfs-progs v6.12
fs tree key (FS_TREE ROOT_ITEM 0)
leaf 30425088 items 2 free space 16061 generation 5 owner FS_TREE leaf 30425088 flags 0x1(WRITTEN) backref revision 1 checksum stored 48f6c57e
checksum calced 48f6c57e
fs uuid 57d45451-481e-43e4-aa93-289ad707a3a0
chunk uuid d52bd3fd-5163-4337-98a7-7986993ad398
item 0 key (256 INODE_ITEM 0) itemoff 16123 itemsize 160 generation 3 transid 0 size 0 nbytes 16384 block group 0 mode 40755 links 1 uid 0 gid 0 rdev 0 sequence 0 flags 0x0(none) atime 1751432947.0 (2025-07-02 14:39:07) ctime 1751432947.0 (2025-07-02 14:39:07) mtime 1751432947.0 (2025-07-02 14:39:07) otime 1751432947.0 (2025-07-02 14:39:07) <<<
The root cause is that fill_inode_item() in tree-log.c is only populating a/c/m time, not the otime (or btime in statx output).
Part of the reason is that, the vfs inode only has a/c/m time, no native btime support yet.
[FIX]
Thankfully btrfs has its otime stored in btrfs_inode::i_otime_sec and btrfs_inode::i_otime_nsec.
So what we really need is just fill the otime time stamp in fill_inode_item() of tree-log.c
There is another fill_inode_item() in inode.c, which is doing the proper otime population.
fs/btrfs/tree-log.c +3 -0
@@ -4233,6 +4233,9 @@ static void fill_inode_item(struct btrfs_trans_handle *trans,btrfs_set_timespec_sec (leaf, &item->ctime,inode_get_ctime_sec (inode));btrfs_set_timespec_nsec (leaf, &item->ctime,inode_get_ctime_nsec (inode)); +btrfs_set_timespec_sec (leaf, &item->otime,BTRFS_I (inode)->i_otime_sec); +btrfs_set_timespec_nsec (leaf, &item->otime,BTRFS_I (inode)->i_otime_nsec); +/* * We do not need to set the nbytes field, in fact during a fast fsync * its value may not even be correct, since a fast fsync does not wait
Sasha Levin
maintainerPATCH 1/2 btrfs: open code timespec64 in struct btrfs_inode
From: David Sterba <[email protected]>
[ Upstream commit c6e8f898f56fae2cb5bc4396bec480f23cd8b066 ]
The type of timespec64::tv_nsec is 'unsigned long', while we have only u32 for on-disk and in-memory. This wastes a few bytes in btrfs_inode. Add separate members for sec and nsec with the corresponding type width. This creates a 4 byte hole in btrfs_inode which can be utilized in the future.
Stable-dep-of: 1ef94169db09 ("btrfs: populate otime when logging an inode item")
--- fs/btrfs/btrfs_inode.h | 3 ++- fs/btrfs/delayed-inode.c | 12 ++++-------- fs/btrfs/inode.c | 26 ++++++++++++-------------- 3 files changed, 18 insertions(+), 23 deletions(-)
fs/btrfs/btrfs_inode.h +2 -1
@@ -251,7 +251,8 @@ struct btrfs_inode {struct btrfs_delayed_node *delayed_node;/* File creation time. */ -struct timespec64 i_otime; +u64 i_otime_sec; +u32 i_otime_nsec;/* Hook into fs_info->delayed_iputs */ struct list_head delayed_iput;
fs/btrfs/delayed-inode.c +4 -8
@@ -1849,10 +1849,8 @@ static void fill_stack_inode_item(struct btrfs_trans_handle *trans,btrfs_set_stack_timespec_nsec (&inode_item->ctime,inode_get_ctime (inode).tv_nsec); -btrfs_set_stack_timespec_sec (&inode_item->otime, -BTRFS_I (inode)->i_otime.tv_sec); -btrfs_set_stack_timespec_nsec (&inode_item->otime, -BTRFS_I (inode)->i_otime.tv_nsec); +btrfs_set_stack_timespec_sec (&inode_item->otime,BTRFS_I (inode)->i_otime_sec); +btrfs_set_stack_timespec_nsec (&inode_item->otime,BTRFS_I (inode)->i_otime_nsec); }int btrfs_fill_inode (struct inode *inode,u32 *rdev)
@@ -1901,10 +1899,8 @@ int btrfs_fill_inode(struct inode *inode, u32 *rdev)inode_set_ctime (inode,btrfs_stack_timespec_sec (&inode_item->ctime),btrfs_stack_timespec_nsec (&inode_item->ctime)); -BTRFS_I (inode)->i_otime.tv_sec = -btrfs_stack_timespec_sec (&inode_item->otime); -BTRFS_I (inode)->i_otime.tv_nsec = -btrfs_stack_timespec_nsec (&inode_item->otime); +BTRFS_I (inode)->i_otime_sec =btrfs_stack_timespec_sec (&inode_item->otime); +BTRFS_I (inode)->i_otime_nsec =btrfs_stack_timespec_nsec (&inode_item->otime); inode->i_generation =BTRFS_I (inode)->generation;BTRFS_I (inode)->index_cnt = (u64)-1 ;
fs/btrfs/inode.c +12 -14
@@ -3785,10 +3785,8 @@ static int btrfs_read_locked_inode(struct inode *inode,inode_set_ctime (inode,btrfs_timespec_sec (leaf, &inode_item->ctime),btrfs_timespec_nsec (leaf, &inode_item->ctime)); -BTRFS_I (inode)->i_otime.tv_sec = -btrfs_timespec_sec (leaf, &inode_item->otime); -BTRFS_I (inode)->i_otime.tv_nsec = -btrfs_timespec_nsec (leaf, &inode_item->otime); +BTRFS_I (inode)->i_otime_sec =btrfs_timespec_sec (leaf, &inode_item->otime); +BTRFS_I (inode)->i_otime_nsec =btrfs_timespec_nsec (leaf, &inode_item->otime);inode_set_bytes (inode,btrfs_inode_nbytes (leaf, inode_item));BTRFS_I (inode)->generation =btrfs_inode_generation (leaf, inode_item);
@@ -3958,10 +3956,8 @@ static void fill_inode_item(struct btrfs_trans_handle *trans,btrfs_set_token_timespec_nsec (&token, &item->ctime,inode_get_ctime (inode).tv_nsec); -btrfs_set_token_timespec_sec (&token, &item->otime, -BTRFS_I (inode)->i_otime.tv_sec); -btrfs_set_token_timespec_nsec (&token, &item->otime, -BTRFS_I (inode)->i_otime.tv_nsec); +btrfs_set_token_timespec_sec (&token, &item->otime,BTRFS_I (inode)->i_otime_sec); +btrfs_set_token_timespec_nsec (&token, &item->otime,BTRFS_I (inode)->i_otime_nsec);btrfs_set_token_inode_nbytes (&token, item,inode_get_bytes (inode)); btrfs_set_token_inode_generation(&token, item,
@@ -5644,7 +5640,8 @@ static struct inode *new_simple_dir(struct inode *dir, inode->i_mode =S_IFDIR |S_IRUGO |S_IWUSR |S_IXUGO ; inode->i_mtime =inode_set_ctime_current (inode); inode->i_atime = dir->i_atime; -BTRFS_I (inode)->i_otime = inode->i_mtime; +BTRFS_I (inode)->i_otime_sec = inode->i_mtime.tv_sec; +BTRFS_I (inode)->i_otime_nsec = inode->i_mtime.tv_nsec; inode->i_uid = dir->i_uid; inode->i_gid = dir->i_gid;
@@ -6321,7 +6318,8 @@ int btrfs_create_new_inode(struct btrfs_trans_handle *trans, inode->i_mtime =inode_set_ctime_current (inode); inode->i_atime = inode->i_mtime; -BTRFS_I (inode)->i_otime = inode->i_mtime; +BTRFS_I (inode)->i_otime_sec = inode->i_mtime.tv_sec; +BTRFS_I (inode)->i_otime_nsec = inode->i_mtime.tv_nsec;/* * We're going to fill the inode item now, so at this point the inode
@@ -8550,8 +8548,8 @@ struct inode *btrfs_alloc_inode(struct super_block *sb) ei->delayed_node =NULL ; - ei->i_otime.tv_sec =0 ; - ei->i_otime.tv_nsec =0 ; + ei->i_otime_sec =0 ; + ei->i_otime_nsec =0 ; inode = &ei->vfs_inode;extent_map_tree_init (&ei->extent_tree);
@@ -8703,8 +8701,8 @@ static int btrfs_getattr(struct mnt_idmap *idmap,u32 bi_ro_flags =BTRFS_I (inode)->ro_flags; stat->result_mask |=STATX_BTIME ; - stat->btime.tv_sec =BTRFS_I (inode)->i_otime.tv_sec; - stat->btime.tv_nsec =BTRFS_I (inode)->i_otime.tv_nsec; + stat->btime.tv_sec =BTRFS_I (inode)->i_otime_sec; + stat->btime.tv_nsec =BTRFS_I (inode)->i_otime_nsec;if (bi_flags &BTRFS_INODE_APPEND ) stat->attributes |=STATX_ATTR_APPEND ;if (bi_flags &BTRFS_INODE_COMPRESS )
Signature · 1 line
2.50.1
Sasha Levin
maintainerPATCH 2/2 btrfs: populate otime when logging an inode item
From: Qu Wenruo <[email protected]>
[ Upstream commit 1ef94169db0958d6de39f9ea6e063ce887342e2d ]
[TEST FAILURE WITH EXPERIMENTAL FEATURES]
When running test case generic/508, the test case will fail with the new btrfs shutdown support:
generic/508 - output mismatch (see /home/adam/xfstests/results//generic/508.out.bad)
--- tests/generic/508.out 2022-05-11 11:25:30.806666664 +0930
+++ /home/adam/xfstests/results//generic/508.out.bad 2025-07-02 14:53:22.401824212 +0930
@@ -1,2 +1,6 @@
QA output created by 508
Silence is golden
+Before:
+After : stat.btime = Thu Jan 1 09:30:00 1970
+Before:
+After : stat.btime = Wed Jul 2 14:53:22 2025
...
(Run 'diff -u /home/adam/xfstests/tests/generic/508.out /home/adam/xfstests/results//generic/508.out.bad' to see the entire diff)Ran: generic/508
Failures: generic/508
Failed 1 of 1 tests
Please note that the test case requires shutdown support, thus the test case will be skipped using the current upstream kernel, as it doesn't have shutdown ioctl support.
[CAUSE]
The direct cause the 0 time stamp in the log tree:
leaf 30507008 items 2 free space 16057 generation 9 owner TREE_LOG leaf 30507008 flags 0x1(WRITTEN) backref revision 1 checksum stored e522548d
checksum calced e522548d
fs uuid 57d45451-481e-43e4-aa93-289ad707a3a0
chunk uuid d52bd3fd-5163-4337-98a7-7986993ad398
item 0 key (257 INODE_ITEM 0) itemoff 16123 itemsize 160 generation 9 transid 9 size 0 nbytes 0 block group 0 mode 100644 links 1 uid 0 gid 0 rdev 0 sequence 1 flags 0x0(none) atime 1751432947.492000000 (2025-07-02 14:39:07) ctime 1751432947.492000000 (2025-07-02 14:39:07) mtime 1751432947.492000000 (2025-07-02 14:39:07) otime 0.0 (1970-01-01 09:30:00) <<<
But the old fs tree has all the correct time stamp:
btrfs-progs v6.12
fs tree key (FS_TREE ROOT_ITEM 0)
leaf 30425088 items 2 free space 16061 generation 5 owner FS_TREE leaf 30425088 flags 0x1(WRITTEN) backref revision 1 checksum stored 48f6c57e
checksum calced 48f6c57e
fs uuid 57d45451-481e-43e4-aa93-289ad707a3a0
chunk uuid d52bd3fd-5163-4337-98a7-7986993ad398
item 0 key (256 INODE_ITEM 0) itemoff 16123 itemsize 160 generation 3 transid 0 size 0 nbytes 16384 block group 0 mode 40755 links 1 uid 0 gid 0 rdev 0 sequence 0 flags 0x0(none) atime 1751432947.0 (2025-07-02 14:39:07) ctime 1751432947.0 (2025-07-02 14:39:07) mtime 1751432947.0 (2025-07-02 14:39:07) otime 1751432947.0 (2025-07-02 14:39:07) <<<
The root cause is that fill_inode_item() in tree-log.c is only populating a/c/m time, not the otime (or btime in statx output).
Part of the reason is that, the vfs inode only has a/c/m time, no native btime support yet.
[FIX]
Thankfully btrfs has its otime stored in btrfs_inode::i_otime_sec and btrfs_inode::i_otime_nsec.
So what we really need is just fill the otime time stamp in fill_inode_item() of tree-log.c
There is another fill_inode_item() in inode.c, which is doing the proper otime population.
--- fs/btrfs/tree-log.c | 3 +++ 1 file changed, 3 insertions(+)
fs/btrfs/tree-log.c +3 -0
@@ -4243,6 +4243,9 @@ static void fill_inode_item(struct btrfs_trans_handle *trans,btrfs_set_token_timespec_nsec (&token, &item->ctime,inode_get_ctime (inode).tv_nsec); +btrfs_set_timespec_sec (leaf, &item->otime,BTRFS_I (inode)->i_otime_sec); +btrfs_set_timespec_nsec (leaf, &item->otime,BTRFS_I (inode)->i_otime_nsec); +/* * We do not need to set the nbytes field, in fact during a fast fsync * its value may not even be correct, since a fast fsync does not wait
Signature · 1 line
2.50.1