From: Theodore Ts'o tytso@mit.edu
mainline inclusion from mainline-5.15-rc1 commit 308c57ccf4318236be75dfa251c84713e694457b category: bugfix bugzilla: 109297 CVE: NA ---------------------------
If the underlying storage device is using thin-provisioning, it's possible for a zeroout operation to return ENOSPC.
Commit df22291ff0fd ("ext4: Retry block allocation if we have free blocks left") added logic to retry block allocation since we might get free block after we commit a transaction. But the ENOSPC from thin-provisioning will confuse ext4, and lead to an infinite loop.
Since using zeroout instead of splitting the extent node is an optimization, if it fails, we might as well fall back to splitting the extent node.
Reported-by: yangerkun yangerkun@huawei.com Signed-off-by: Theodore Ts'o tytso@mit.edu Signed-off-by: yangerkun yangerkun@huawei.com Reviewed-by: Zhang Yi yi.zhang@huawei.com Signed-off-by: Yang Yingliang yangyingliang@huawei.com --- fs/ext4/extents.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/fs/ext4/extents.c b/fs/ext4/extents.c index fc00a78163117..10298c13a67d7 100644 --- a/fs/ext4/extents.c +++ b/fs/ext4/extents.c @@ -3696,7 +3696,7 @@ static int ext4_ext_convert_to_initialized(handle_t *handle, split_map.m_len - ee_block); err = ext4_ext_zeroout(inode, &zero_ex1); if (err) - goto out; + goto fallback; split_map.m_len = allocated; } if (split_map.m_lblk - ee_block + split_map.m_len < @@ -3710,7 +3710,7 @@ static int ext4_ext_convert_to_initialized(handle_t *handle, ext4_ext_pblock(ex)); err = ext4_ext_zeroout(inode, &zero_ex2); if (err) - goto out; + goto fallback; }
split_map.m_len += split_map.m_lblk - ee_block; @@ -3719,6 +3719,7 @@ static int ext4_ext_convert_to_initialized(handle_t *handle, } }
+fallback: err = ext4_split_extent(handle, inode, ppath, &split_map, split_flag, flags); if (err > 0)