Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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 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>

+3 -2
+3 -2
fs/ext4/extents.c
··· 3569 3569 split_map.m_len - ee_block); 3570 3570 err = ext4_ext_zeroout(inode, &zero_ex1); 3571 3571 if (err) 3572 - goto out; 3572 + goto fallback; 3573 3573 split_map.m_len = allocated; 3574 3574 } 3575 3575 if (split_map.m_lblk - ee_block + split_map.m_len < ··· 3583 3583 ext4_ext_pblock(ex)); 3584 3584 err = ext4_ext_zeroout(inode, &zero_ex2); 3585 3585 if (err) 3586 - goto out; 3586 + goto fallback; 3587 3587 } 3588 3588 3589 3589 split_map.m_len += split_map.m_lblk - ee_block; ··· 3592 3592 } 3593 3593 } 3594 3594 3595 + fallback: 3595 3596 err = ext4_split_extent(handle, inode, ppath, &split_map, split_flag, 3596 3597 flags); 3597 3598 if (err > 0)