mirror of
https://github.com/torvalds/linux.git
synced 2026-06-02 03:24:19 +02:00
btrfs: update stripe extents for existing logical addresses
Update a stripe extent in case of an already existing logical address, but with different physical addresses and/or device id instead of bailing out with EEXIST. This can happen i.e. in case of a device replace operation, where data extents get rewritten to a new disk. Reviewed-by: Qu Wenruo <wqu@suse.com> Signed-off-by: Johannes Thumshirn <johannes.thumshirn@wdc.com> Signed-off-by: David Sterba <dsterba@suse.com>
This commit is contained in:
parent
da3ea35007
commit
8c4cba2adb
|
|
@ -73,6 +73,36 @@ int btrfs_delete_raid_extent(struct btrfs_trans_handle *trans, u64 start, u64 le
|
|||
return ret;
|
||||
}
|
||||
|
||||
static int update_raid_extent_item(struct btrfs_trans_handle *trans,
|
||||
struct btrfs_key *key,
|
||||
struct btrfs_stripe_extent *stripe_extent,
|
||||
const size_t item_size)
|
||||
{
|
||||
struct btrfs_path *path;
|
||||
struct extent_buffer *leaf;
|
||||
int ret;
|
||||
int slot;
|
||||
|
||||
path = btrfs_alloc_path();
|
||||
if (!path)
|
||||
return -ENOMEM;
|
||||
|
||||
ret = btrfs_search_slot(trans, trans->fs_info->stripe_root, key, path,
|
||||
0, 1);
|
||||
if (ret)
|
||||
return (ret == 1 ? ret : -EINVAL);
|
||||
|
||||
leaf = path->nodes[0];
|
||||
slot = path->slots[0];
|
||||
|
||||
write_extent_buffer(leaf, stripe_extent, btrfs_item_ptr_offset(leaf, slot),
|
||||
item_size);
|
||||
btrfs_mark_buffer_dirty(trans, leaf);
|
||||
btrfs_free_path(path);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int btrfs_insert_one_raid_extent(struct btrfs_trans_handle *trans,
|
||||
struct btrfs_io_context *bioc)
|
||||
{
|
||||
|
|
@ -112,6 +142,9 @@ static int btrfs_insert_one_raid_extent(struct btrfs_trans_handle *trans,
|
|||
|
||||
ret = btrfs_insert_item(trans, stripe_root, &stripe_key, stripe_extent,
|
||||
item_size);
|
||||
if (ret == -EEXIST)
|
||||
ret = update_raid_extent_item(trans, &stripe_key, stripe_extent,
|
||||
item_size);
|
||||
if (ret)
|
||||
btrfs_abort_transaction(trans, ret);
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user