btrfs: Add graceful handling of V0 extents
Following the removal of the v0 handling code let's be courteous and print an error message when such extents are handled. In the cases where we have a transaction just abort it, otherwise just call btrfs_handle_fs_error. Both cases result in the FS being re-mounted RO. In case the error handling would be too intrusive, leave the BUG_ON in place, like extent_data_ref_count, other proper handling would catch that earlier. Signed-off-by: Nikolay Borisov <nborisov@suse.com> Reviewed-by: David Sterba <dsterba@suse.com> Signed-off-by: David Sterba <dsterba@suse.com>
This commit is contained in:

committed by
David Sterba

parent
a79865c680
commit
ba3c2b196b
@@ -867,8 +867,16 @@ search_again:
|
||||
num_refs = btrfs_extent_refs(leaf, ei);
|
||||
extent_flags = btrfs_extent_flags(leaf, ei);
|
||||
} else {
|
||||
BUG();
|
||||
ret = -EINVAL;
|
||||
btrfs_print_v0_err(fs_info);
|
||||
if (trans)
|
||||
btrfs_abort_transaction(trans, ret);
|
||||
else
|
||||
btrfs_handle_fs_error(fs_info, ret, NULL);
|
||||
|
||||
goto out_free;
|
||||
}
|
||||
|
||||
BUG_ON(num_refs == 0);
|
||||
} else {
|
||||
num_refs = 0;
|
||||
@@ -1296,6 +1304,10 @@ static noinline int remove_extent_data_ref(struct btrfs_trans_handle *trans,
|
||||
ref2 = btrfs_item_ptr(leaf, path->slots[0],
|
||||
struct btrfs_shared_data_ref);
|
||||
num_refs = btrfs_shared_data_ref_count(leaf, ref2);
|
||||
} else if (key.type == BTRFS_EXTENT_REF_V0_KEY) {
|
||||
btrfs_print_v0_err(trans->fs_info);
|
||||
btrfs_abort_transaction(trans, -EINVAL);
|
||||
return -EINVAL;
|
||||
} else {
|
||||
BUG();
|
||||
}
|
||||
@@ -1328,6 +1340,8 @@ static noinline u32 extent_data_ref_count(struct btrfs_path *path,
|
||||
|
||||
leaf = path->nodes[0];
|
||||
btrfs_item_key_to_cpu(leaf, &key, path->slots[0]);
|
||||
|
||||
BUG_ON(key.type == BTRFS_EXTENT_REF_V0_KEY);
|
||||
if (iref) {
|
||||
/*
|
||||
* If type is invalid, we should have bailed out earlier than
|
||||
@@ -1541,7 +1555,12 @@ again:
|
||||
|
||||
leaf = path->nodes[0];
|
||||
item_size = btrfs_item_size_nr(leaf, path->slots[0]);
|
||||
BUG_ON(item_size < sizeof(*ei));
|
||||
if (item_size < sizeof(*ei)) {
|
||||
err = -EINVAL;
|
||||
btrfs_print_v0_err(fs_info);
|
||||
btrfs_abort_transaction(trans, err);
|
||||
goto out;
|
||||
}
|
||||
|
||||
ei = btrfs_item_ptr(leaf, path->slots[0], struct btrfs_extent_item);
|
||||
flags = btrfs_extent_flags(leaf, ei);
|
||||
@@ -2265,7 +2284,14 @@ again:
|
||||
|
||||
leaf = path->nodes[0];
|
||||
item_size = btrfs_item_size_nr(leaf, path->slots[0]);
|
||||
BUG_ON(item_size < sizeof(*ei));
|
||||
|
||||
if (item_size < sizeof(*ei)) {
|
||||
err = -EINVAL;
|
||||
btrfs_print_v0_err(fs_info);
|
||||
btrfs_abort_transaction(trans, err);
|
||||
goto out;
|
||||
}
|
||||
|
||||
ei = btrfs_item_ptr(leaf, path->slots[0], struct btrfs_extent_item);
|
||||
__run_delayed_extent_op(extent_op, leaf, ei);
|
||||
|
||||
@@ -6796,7 +6822,12 @@ static int __btrfs_free_extent(struct btrfs_trans_handle *trans,
|
||||
|
||||
leaf = path->nodes[0];
|
||||
item_size = btrfs_item_size_nr(leaf, extent_slot);
|
||||
BUG_ON(item_size < sizeof(*ei));
|
||||
if (item_size < sizeof(*ei)) {
|
||||
ret = -EINVAL;
|
||||
btrfs_print_v0_err(info);
|
||||
btrfs_abort_transaction(trans, ret);
|
||||
goto out;
|
||||
}
|
||||
ei = btrfs_item_ptr(leaf, extent_slot,
|
||||
struct btrfs_extent_item);
|
||||
if (owner_objectid < BTRFS_FIRST_FREE_OBJECTID &&
|
||||
|
Reference in New Issue
Block a user