Commit 308c57cc authored by Theodore Ts'o's avatar Theodore Ts'o

ext4: if zeroout fails fall back to splitting the extent node

If the underlying storage device is using thin-provisioning, it's
possible for a zeroout operation to return ENOSPC.

Commit df22291f ("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: default avataryangerkun <yangerkun@huawei.com>
Signed-off-by: default avatarTheodore Ts'o <tytso@mit.edu>
parent facec450
...@@ -3569,7 +3569,7 @@ static int ext4_ext_convert_to_initialized(handle_t *handle, ...@@ -3569,7 +3569,7 @@ static int ext4_ext_convert_to_initialized(handle_t *handle,
split_map.m_len - ee_block); split_map.m_len - ee_block);
err = ext4_ext_zeroout(inode, &zero_ex1); err = ext4_ext_zeroout(inode, &zero_ex1);
if (err) if (err)
goto out; goto fallback;
split_map.m_len = allocated; split_map.m_len = allocated;
} }
if (split_map.m_lblk - ee_block + split_map.m_len < if (split_map.m_lblk - ee_block + split_map.m_len <
...@@ -3583,7 +3583,7 @@ static int ext4_ext_convert_to_initialized(handle_t *handle, ...@@ -3583,7 +3583,7 @@ static int ext4_ext_convert_to_initialized(handle_t *handle,
ext4_ext_pblock(ex)); ext4_ext_pblock(ex));
err = ext4_ext_zeroout(inode, &zero_ex2); err = ext4_ext_zeroout(inode, &zero_ex2);
if (err) if (err)
goto out; goto fallback;
} }
split_map.m_len += split_map.m_lblk - ee_block; split_map.m_len += split_map.m_lblk - ee_block;
...@@ -3592,6 +3592,7 @@ static int ext4_ext_convert_to_initialized(handle_t *handle, ...@@ -3592,6 +3592,7 @@ static int ext4_ext_convert_to_initialized(handle_t *handle,
} }
} }
fallback:
err = ext4_split_extent(handle, inode, ppath, &split_map, split_flag, err = ext4_split_extent(handle, inode, ppath, &split_map, split_flag,
flags); flags);
if (err > 0) if (err > 0)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment