On Fri, Jul 05, 2019 at 11:09:50AM +0100, fdmanana@xxxxxxxxxx wrote: > From: Filipe Manana <fdmanana@xxxxxxxx> > > 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 <david@xxxxxxxxxxxxxxx> > Link: https://lore.kernel.org/linux-btrfs/a4a4cf31-9cf4-e52c-1f86-c62d336c9cd1@xxxxxxxxxxxxxxx/ > Reported-by: Sam Tygier <sam@xxxxxxxxxxxx> > Link: https://lore.kernel.org/linux-btrfs/82aace9f-a1e3-1f0b-055f-3ea75f7a41a0@xxxxxxxxxxxx/ > Fixes: b6f3409b2197e8f ("Btrfs: reserve sufficient space for ioctl clone") > Signed-off-by: Filipe Manana <fdmanana@xxxxxxxx> Added to misc-next (some time ago), thanks.
