Currently inside the main loop of cow_file_range(), we do the following
sequence:
- Reserve an extent
- Lock the IO tree range
- Create an IO extent map
- Create an ordered extent
Every step will need extra steps to do cleanup in the following order:
- Drop the newly created extent map
- Unlock extent range and cleanup the involved folios
- Free the reserved extent
However currently the error handling is done inconsistently:
- Extent map drop is handled in a dedicated tag
Out of the main loop, make it much harder to track.
- The extent unlock and folios cleanup is done separately
The extent is unlocked through btrfs_unlock_extent(), then
extent_clear_unlock_delalloc() again in a dedicated tag.
Meanwhile all other callsites (compression/encoded/nocow) all just
call extent_clear_unlock_delalloc() to handle unlock and folio clean
up in one go.
- Reserved extent freeing is handled in a dedicated tag
Out of the main loop, make it much harder to track.
- Error handling of btrfs_reloc_clone_csums() is relying out-of-loop
tags
This is due to the special requirement to finish ordered extents to
handle the metadata reserved space.
Enhance the error handling and align the behavior by:
- Introduce a dedicated cow_one_range() helper
Which do the reserve/lock/allocation in the helper.
And also handle the errors inside the helper.
No more dedicated tags out of the main loop.
- Use a single extent_clear_unlock_delalloc() to unlock and cleanup
folios
- Move the btrfs_reloc_clone_csums() error handling into the new helper
Thankfully it's not that complex compared to other cases.
And since we're here, also reduce the width of the following local
variables to u32:
- cur_alloc_size
- min_alloc_size
Each allocation won't go beyond 128M, thus u32 is more than enough.
- blocksize
The maximum is 64K, no need for u64.
Reviewed-by: Johannes Thumshirn <johannes.thumshirn@wdc.com> Signed-off-by: Qu Wenruo <wqu@suse.com> Reviewed-by: David Sterba <dsterba@suse.com> Signed-off-by: David Sterba <dsterba@suse.com>