mirror of
https://github.com/torvalds/linux.git
synced 2026-09-22 04:34:03 +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;
|
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,
|
static int btrfs_insert_one_raid_extent(struct btrfs_trans_handle *trans,
|
||||||
struct btrfs_io_context *bioc)
|
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,
|
ret = btrfs_insert_item(trans, stripe_root, &stripe_key, stripe_extent,
|
||||||
item_size);
|
item_size);
|
||||||
|
if (ret == -EEXIST)
|
||||||
|
ret = update_raid_extent_item(trans, &stripe_key, stripe_extent,
|
||||||
|
item_size);
|
||||||
if (ret)
|
if (ret)
|
||||||
btrfs_abort_transaction(trans, ret);
|
btrfs_abort_transaction(trans, ret);
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user