mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
From: Edward Adam Davis <eadavis@qq.com>
To: jack@suse.cz
Cc: brauner@kernel.org, eadavis@qq.com, linux-ext4@vger.kernel.org,
	linux-fsdevel@vger.kernel.org, linux-kernel@vger.kernel.org,
	syzbot+1659aaaaa8d9d11265d7@syzkaller.appspotmail.com,
	syzkaller-bugs@googlegroups.com, viro@zeniv.linux.org.uk
Subject: [PATCH v4] ext4: avoid infinite loops caused by residual data
Date: Thu,  5 Mar 2026 22:12:03 +0800	[thread overview]
Message-ID: <tencent_3ADDAE194DCFFD8DC925858DC11278DDA907@qq.com> (raw)
In-Reply-To: <uweckkartekmwpzpt2kt34bbjyn3a2a4tc3lw7qyyghkxhfl5l@st7yfcuu73f4>

On the mkdir/mknod path, when mapping logical blocks to physical blocks,
if inserting a new extent into the extent tree fails (in this example,
because the file system disabled the huge file feature when marking the
inode as dirty), ext4_ext_map_blocks() only calls ext4_free_blocks() to
reclaim the physical block without deleting the corresponding data in
the extent tree. This causes subsequent mkdir operations to reference
the previously reclaimed physical block number again, even though this
physical block is already being used by the xattr block. Therefore, a
situation arises where both the directory and xattr are using the same
buffer head block in memory simultaneously.

The above causes ext4_xattr_block_set() to enter an infinite loop about
"inserted" and cannot release the inode lock, ultimately leading to the
143s blocking problem mentioned in [1].

By using ext4_ext_remove_space() to delete the inserted logical block
and reclaim the physical block when inserting a new extent fails during
extent block mapping, either delete both as described above, or retain
the data completely (i.e., neither delete the physical block nor the
data in the extent tree), residual extent data can be prevented from
affecting subsequent logical block physical mappings. 

Besides the errors ENOSPC or EDQUOT, this means metadata is corrupted.
We should strive to do as few modifications as possible to limit damage.
So just skip freeing of allocated blocks.

[1]
INFO: task syz.0.17:5995 blocked for more than 143 seconds.
Call Trace:
 inode_lock_nested include/linux/fs.h:1073 [inline]
 __start_dirop fs/namei.c:2923 [inline]
 start_dirop fs/namei.c:2934 [inline]

Reported-by: syzbot+512459401510e2a9a39f@syzkaller.appspotmail.com
Closes: https://syzkaller.appspot.com/bug?extid=1659aaaaa8d9d11265d7
Tested-by: syzbot+1659aaaaa8d9d11265d7@syzkaller.appspotmail.com
Reported-by: syzbot+1659aaaaa8d9d11265d7@syzkaller.appspotmail.com
Closes: https://syzkaller.appspot.com/bug?extid=512459401510e2a9a39f
Tested-by: syzbot+1659aaaaa8d9d11265d7@syzkaller.appspotmail.com
Signed-off-by: Edward Adam Davis <eadavis@qq.com>
---
v1 -> v2: fix ci reported issues
v2 -> v3: new fix for removing residual data and update subject and coments
v3 -> v4: filtering already allocated blocks and update comments

 fs/ext4/extents.c | 15 +++++++--------
 1 file changed, 7 insertions(+), 8 deletions(-)

diff --git a/fs/ext4/extents.c b/fs/ext4/extents.c
index ae3804f36535..56b7398a0b40 100644
--- a/fs/ext4/extents.c
+++ b/fs/ext4/extents.c
@@ -4457,20 +4457,19 @@ int ext4_ext_map_blocks(handle_t *handle, struct inode *inode,
 	path = ext4_ext_insert_extent(handle, inode, path, &newex, flags);
 	if (IS_ERR(path)) {
 		err = PTR_ERR(path);
-		if (allocated_clusters) {
-			int fb_flags = 0;
-
+		/*
+		 * Gracefully handle out of space conditions. If the filesystem
+		 * is inconsistent, we'll just leak allocated blocks to avoid
+		 * causing even more damage.
+		 */
+		if (allocated_clusters && (err == -EDQUOT || err == -ENOSPC)) {
 			/*
 			 * free data blocks we just allocated.
 			 * not a good idea to call discard here directly,
 			 * but otherwise we'd need to call it every free().
 			 */
 			ext4_discard_preallocations(inode);
-			if (flags & EXT4_GET_BLOCKS_DELALLOC_RESERVE)
-				fb_flags = EXT4_FREE_BLOCKS_NO_QUOT_UPDATE;
-			ext4_free_blocks(handle, inode, NULL, newblock,
-					 EXT4_C2B(sbi, allocated_clusters),
-					 fb_flags);
+			ext4_ext_remove_space(inode, newex.ee_block, newex.ee_block);
 		}
 		goto out;
 	}
-- 
2.43.0


  parent reply	other threads:[~2026-03-05 14:12 UTC|newest]

Thread overview: 24+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-02-25  9:12 [syzbot] [ext4?] INFO: task hung in filename_unlinkat syzbot
2026-03-01  8:32 ` Edward Adam Davis
2026-03-01  8:57   ` syzbot
2026-03-01 10:12 ` [PATCH] ext4: avoid infinite loops caused by data conflicts Edward Adam Davis
2026-03-02 10:52   ` [syzbot ci] " syzbot ci
2026-03-02 12:51     ` [PATCH v2] " Edward Adam Davis
2026-03-03  7:47       ` [syzbot ci] " syzbot ci
2026-03-02 13:01   ` [PATCH] " Jan Kara
2026-03-05  7:25     ` [PATCH v3] ext4: avoid infinite loops caused by residual data Edward Adam Davis
2026-03-05 10:38       ` Jan Kara
2026-03-05 12:10         ` Edward Adam Davis
2026-03-05 14:12         ` Edward Adam Davis [this message]
2026-03-05 15:41           ` [PATCH v4] " Jan Kara
2026-03-06  1:31             ` [PATCH v5] " Edward Adam Davis
2026-03-06 15:25               ` Jan Kara
2026-03-27  4:06               ` Theodore Ts'o
2026-03-05  4:51 ` [syzbot] [ext4?] INFO: task hung in filename_unlinkat Edward Adam Davis
2026-03-05  5:20   ` syzbot
2026-03-05  6:33 ` Edward Adam Davis
2026-03-05  6:56   ` syzbot
2026-03-05 12:20 ` Edward Adam Davis
2026-03-05 13:59   ` syzbot
2026-03-06  1:18 ` Edward Adam Davis
2026-03-06  2:07   ` syzbot

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=tencent_3ADDAE194DCFFD8DC925858DC11278DDA907@qq.com \
    --to=eadavis@qq.com \
    --cc=brauner@kernel.org \
    --cc=jack@suse.cz \
    --cc=linux-ext4@vger.kernel.org \
    --cc=linux-fsdevel@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=syzbot+1659aaaaa8d9d11265d7@syzkaller.appspotmail.com \
    --cc=syzkaller-bugs@googlegroups.com \
    --cc=viro@zeniv.linux.org.uk \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox

all inboxes | Powered by JetHome®