Skip to contentSkip to conversation

FAILED: patch "[PATCH] ext4: propagate errors from fast commit range replay" failed to apply to 5.10-stable tree

PATCH New [email protected] 2 participants 2 messages Aug 24 – Aug 26

Subsystems (2)
lore
Share & tools
lore

[email protected]

author maintainer
#0 lore raw

The patch below does not apply to the 5.10-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-5.10.y
git checkout FETCH_HEAD
git cherry-pick -x d8b8dd3530bf41e14b118702cdaf9de64bb96885
# <resolve conflicts, build, test, etc.>
git commit -s
git send-email --to '<[email protected]>' --in-reply-to '2026082456-backache-routing-3aa7@gregkh' --subject-prefix 'PATCH 5.10.y' 'HEAD^..'

Possible dependencies:

thanks,

greg k-h

------------------ original commit in Linus's tree ------------------

From d8b8dd3530bf41e14b118702cdaf9de64bb96885 Mon Sep 17 00:00:00 2001
From: Guanghui Yang <[email protected]>
Date: Wed, 8 Jul 2026 08:12:04 +0000
Subject: [PATCH] ext4: propagate errors from fast commit range replay

ext4_fc_replay() stops replaying fast commit tags only when a tag handler returns a negative error. However, ext4_fc_replay_add_range() and ext4_fc_replay_del_range() currently return 0 from their common exit paths even after internal failures.

This hides errors from ext4_fc_record_modified_inode(), ext4_map_blocks(), ext4_find_extent(), ext4_ext_insert_extent(), ext4_ext_replay_update_ex(), and ext4_ext_remove_space(). As a result, a failed ADD_RANGE or DEL_RANGE replay can be treated as successful and the replay code may continue with subsequent fast commit tags.

This is particularly problematic for DEL_RANGE because it may already have marked blocks as free before ext4_ext_remove_space() fails. If the error is swallowed, replay may continue from a partially applied range operation.

Return the saved error from the common exit paths and make the ERR_PTR() cases in ADD_RANGE store PTR_ERR() before jumping to out.

fs/ext4/fast_commit.c +12 -4
index ca72a52f8cc9..062103e42cd8 100644
@@ -2177,8 +2177,11 @@ static int ext4_fc_replay_add_range(struct super_block *sb, u8 *val)
 		if (ret == 0) {
 			/* Range is not mapped */
 			path = ext4_find_extent(inode, cur, path, 0);
-			if (IS_ERR(path))
+			if (IS_ERR(path)) {
+				ret = PTR_ERR(path);
+				path = NULL;
 				goto out;
+			}
 			memset(&newex, 0, sizeof(newex));
 			newex.ee_block = cpu_to_le32(cur);
 			ext4_ext_store_pblock(
@@ -2190,8 +2193,11 @@ static int ext4_fc_replay_add_range(struct super_block *sb, u8 *val)
 			path = ext4_ext_insert_extent(NULL, inode,
 						      path, &newex, 0);
 			up_write((&EXT4_I(inode)->i_data_sem));
-			if (IS_ERR(path))
+			if (IS_ERR(path)) {
+				ret = PTR_ERR(path);
+				path = NULL;
 				goto out;
+			}
 			goto next;
 		}
 
@@ -2238,10 +2244,11 @@ static int ext4_fc_replay_add_range(struct super_block *sb, u8 *val)
 	}
 	ext4_ext_replay_shrink_inode(inode, i_size_read(inode) >>
 					sb->s_blocksize_bits);
+	ret = 0;
 out:
 	ext4_free_ext_path(path);
 	iput(inode);
-	return 0;
+	return ret;
 }
 
 /* Replay DEL_RANGE tag */
@@ -2301,9 +2308,10 @@ ext4_fc_replay_del_range(struct super_block *sb, u8 *val)
 	ext4_ext_replay_shrink_inode(inode,
 		i_size_read(inode) >> sb->s_blocksize_bits);
 	ext4_mark_inode_dirty(NULL, inode);
+	ret = 0;
 out:
 	iput(inode);
-	return 0;
+	return ret;
 }
 
 static void ext4_fc_set_bitmaps_and_counters(struct super_block *sb)
maintainer
#1 lore raw

PATCH 1/1 ext4: propagate errors from fast commit range replay

From: Guanghui Yang <[email protected]>

[ Upstream commit d8b8dd3530bf41e14b118702cdaf9de64bb96885 ]

ext4_fc_replay() stops replaying fast commit tags only when a tag handler returns a negative error. However, ext4_fc_replay_add_range() and ext4_fc_replay_del_range() currently return 0 from their common exit paths even after internal failures.

This hides errors from ext4_fc_record_modified_inode(), ext4_map_blocks(), ext4_find_extent(), ext4_ext_insert_extent(), ext4_ext_replay_update_ex(), and ext4_ext_remove_space(). As a result, a failed ADD_RANGE or DEL_RANGE replay can be treated as successful and the replay code may continue with subsequent fast commit tags.

This is particularly problematic for DEL_RANGE because it may already have marked blocks as free before ext4_ext_remove_space() fails. If the error is swallowed, replay may continue from a partially applied range operation.

Return the saved error from the common exit paths and make the ERR_PTR() cases in ADD_RANGE store PTR_ERR() before jumping to out.

---
 fs/ext4/fast_commit.c | 10 +++++++---
 1 file changed, 7 insertions(+), 3 deletions(-)
fs/ext4/fast_commit.c +7 -3
index 26b7782b03f40..4f73f0ad6c85c 100644
@@ -1678,8 +1678,10 @@ static int ext4_fc_replay_add_range(struct super_block *sb,
 		if (ret == 0) {
 			/* Range is not mapped */
 			path = ext4_find_extent(inode, cur, NULL, 0);
-			if (IS_ERR(path))
+			if (IS_ERR(path)) {
+				ret = PTR_ERR(path);
 				goto out;
+			}
 			memset(&newex, 0, sizeof(newex));
 			newex.ee_block = cpu_to_le32(cur);
 			ext4_ext_store_pblock(
@@ -1741,9 +1743,10 @@ static int ext4_fc_replay_add_range(struct super_block *sb,
 	}
 	ext4_ext_replay_shrink_inode(inode, i_size_read(inode) >>
 					sb->s_blocksize_bits);
+	ret = 0;
 out:
 	iput(inode);
-	return 0;
+	return ret;
 }
 
 /* Replay DEL_RANGE tag */
@@ -1804,9 +1807,10 @@ ext4_fc_replay_del_range(struct super_block *sb, struct ext4_fc_tl *tl,
 	ext4_ext_replay_shrink_inode(inode,
 		i_size_read(inode) >> sb->s_blocksize_bits);
 	ext4_mark_inode_dirty(NULL, inode);
+	ret = 0;
 out:
 	iput(inode);
-	return 0;
+	return ret;
 }
 
 static inline const char *tag2str(u16 tag)
Signature · 1 line
2.53.0