On Fri, Jul 05, 2019 at 11:09:50AM +0100, [email protected] wrote:
> From: Filipe Manana <[email protected]>
> 
> When cloning extents (or deduplicating) we create a transaction with a
> space reservation that considers we will drop or update a single file
> extent item of the destination inode (that we modify a single leaf). That
> is fine for the vast majority of scenarios, however it might happen that
> we need to drop many file extent items, and adjust at most two file extent
> items, in the destination root, which can span multiple leafs. This will
> lead to either the call to btrfs_drop_extents() to fail with ENOSPC or
> the subsequent calls to btrfs_insert_empty_item() or btrfs_update_inode()
> (called through clone_finish_inode_update()) to fail with ENOSPC. Such
> failure results in a transaction abort, leaving the filesystem in a
> read-only mode.
> 
> In order to fix this we need to follow the same approach as the hole
> punching code, where we create a local reservation with 1 unit and keep
> ending and starting transactions, after balancing the btree inode,
> when __btrfs_drop_extents() returns ENOSPC. So fix this by making the
> extent cloning call calls the recently added btrfs_punch_hole_range()
> helper, which is what does the mentioned work for hole punching, and
> make sure whenever we drop extent items in a transaction, we also add a
> replacing file extent item, to avoid corruption (a hole) if after ending
> a transaction and before starting a new one, the old transaction gets
> committed and a power failure happens before we finish cloning.
> 
> A test case for fstests follows soon.
> 
> Reported-by: David Goodwin <[email protected]>
> Link: 
> https://lore.kernel.org/linux-btrfs/[email protected]/
> Reported-by: Sam Tygier <[email protected]>
> Link: 
> https://lore.kernel.org/linux-btrfs/[email protected]/
> Fixes: b6f3409b2197e8f ("Btrfs: reserve sufficient space for ioctl clone")
> Signed-off-by: Filipe Manana <[email protected]>

Added to misc-next (some time ago), thanks.

Reply via email to