[<prev] [next>] [thread-next>] [day] [month] [year] [list]
Message-ID: <20210804125044.2480435-1-yangerkun@huawei.com>
Date: Wed, 4 Aug 2021 20:50:44 +0800
From: yangerkun <yangerkun@...wei.com>
To: <tytso@....edu>, <jack@...e.cz>, <adilger.kernel@...ger.ca>
CC: <linux-ext4@...r.kernel.org>, <yangerkun@...wei.com>,
<yukuai3@...wei.com>
Subject: [PATCH] ext4: stop return ENOSPC from ext4_issue_zeroout
Our testcase(briefly described as fsstress on dm thin-provisioning which
ext4 see volume size with 100G but actual size 10G) trigger a hungtask
bug since ext4_writepages fall into a infinite loop:
static int ext4_writepages(xxx)
{
...
while (!done && mpd.first_page <= mpd.last_page) {
...
ret = mpage_prepare_extent_to_map(&mpd);
if (!ret) {
...
ret = mpage_map_and_submit_extent(handle,
&mpd,&give_up_on_write);
<----- will return -ENOSPC
...
}
...
if (ret == -ENOSPC && sbi->s_journal) {
<------ we cannot break since we will get ENOSPC forever
jbd2_journal_force_commit_nested(sbi->s_journal);
ret = 0;
continue;
}
...
}
}
Got ENOSPC with follow stack:
...
ext4_ext_map_blocks
ext4_ext_convert_to_initialized
ext4_ext_zeroout
ext4_issue_zeroout
...
submit_bio_wait <-- bio to thinpool will return ENOSPC
'df22291ff0fd ("ext4: Retry block allocation if we have free blocks
left")' add the logic to retry block allcate since we may get free block
after we commit a transaction. But the ENOSPC from thin-provisioning
will confuse ext4, and lead the upper infinite loop. Fix it by convert
the err to EIO.
Signed-off-by: yangerkun <yangerkun@...wei.com>
---
fs/ext4/inode.c | 3 +++
1 file changed, 3 insertions(+)
diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c
index 038aebd7eb2f..d9ded699a88c 100644
--- a/fs/ext4/inode.c
+++ b/fs/ext4/inode.c
@@ -428,6 +428,9 @@ int ext4_issue_zeroout(struct inode *inode, ext4_lblk_t lblk, ext4_fsblk_t pblk,
if (ret > 0)
ret = 0;
+ if (ret == -ENOSPC)
+ ret = -EIO;
+
return ret;
}
--
2.31.1
Powered by blists - more mailing lists