summaryrefslogtreecommitdiffstats
path: root/fs/btrfs/relocation.c
diff options
context:
space:
mode:
authorNikolay Borisov <nborisov@suse.com>2018-06-26 09:57:36 -0400
committerDavid Sterba <dsterba@suse.com>2018-08-06 07:12:41 -0400
commitba3c2b196bf59ba8574808fe6f8fd88d0fed7510 (patch)
treeab2b0b500783df91dbf434d18617882830b23120 /fs/btrfs/relocation.c
parenta79865c680d81220a1355cd13098e75227dc2994 (diff)
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>
Diffstat (limited to 'fs/btrfs/relocation.c')
-rw-r--r--fs/btrfs/relocation.c27
1 files changed, 24 insertions, 3 deletions
diff --git a/fs/btrfs/relocation.c b/fs/btrfs/relocation.c
index 6dfa92e5ceed..eaf59c742dc8 100644
--- a/fs/btrfs/relocation.c
+++ b/fs/btrfs/relocation.c
@@ -598,6 +598,11 @@ int find_inline_backref(struct extent_buffer *leaf, int slot,
598 btrfs_item_key_to_cpu(leaf, &key, slot); 598 btrfs_item_key_to_cpu(leaf, &key, slot);
599 599
600 item_size = btrfs_item_size_nr(leaf, slot); 600 item_size = btrfs_item_size_nr(leaf, slot);
601 if (item_size < sizeof(*ei)) {
602 btrfs_print_v0_err(leaf->fs_info);
603 btrfs_handle_fs_error(leaf->fs_info, -EINVAL, NULL);
604 return 1;
605 }
601 ei = btrfs_item_ptr(leaf, slot, struct btrfs_extent_item); 606 ei = btrfs_item_ptr(leaf, slot, struct btrfs_extent_item);
602 WARN_ON(!(btrfs_extent_flags(leaf, ei) & 607 WARN_ON(!(btrfs_extent_flags(leaf, ei) &
603 BTRFS_EXTENT_FLAG_TREE_BLOCK)); 608 BTRFS_EXTENT_FLAG_TREE_BLOCK));
@@ -782,7 +787,6 @@ again:
782 goto next; 787 goto next;
783 } 788 }
784 789
785 ASSERT(key.type != BTRFS_EXTENT_REF_V0_KEY);
786 if (key.type == BTRFS_SHARED_BLOCK_REF_KEY) { 790 if (key.type == BTRFS_SHARED_BLOCK_REF_KEY) {
787 if (key.objectid == key.offset) { 791 if (key.objectid == key.offset) {
788 /* 792 /*
@@ -826,6 +830,12 @@ again:
826 edge->node[UPPER] = upper; 830 edge->node[UPPER] = upper;
827 831
828 goto next; 832 goto next;
833 } else if (key.type == BTRFS_EXTENT_REF_V0_KEY) {
834 err = -EINVAL;
835 btrfs_print_v0_err(rc->extent_root->fs_info);
836 btrfs_handle_fs_error(rc->extent_root->fs_info, err,
837 NULL);
838 goto out;
829 } else if (key.type != BTRFS_TREE_BLOCK_REF_KEY) { 839 } else if (key.type != BTRFS_TREE_BLOCK_REF_KEY) {
830 goto next; 840 goto next;
831 } 841 }
@@ -3315,6 +3325,10 @@ static int add_tree_block(struct reloc_control *rc,
3315 level = (int)extent_key->offset; 3325 level = (int)extent_key->offset;
3316 } 3326 }
3317 generation = btrfs_extent_generation(eb, ei); 3327 generation = btrfs_extent_generation(eb, ei);
3328 } else if (item_size == sizeof(struct btrfs_extent_item_v0)) {
3329 btrfs_print_v0_err(eb->fs_info);
3330 btrfs_handle_fs_error(eb->fs_info, -EINVAL, NULL);
3331 return -EINVAL;
3318 } else { 3332 } else {
3319 BUG(); 3333 BUG();
3320 } 3334 }
@@ -3720,7 +3734,6 @@ int add_data_references(struct reloc_control *rc,
3720 if (key.objectid != extent_key->objectid) 3734 if (key.objectid != extent_key->objectid)
3721 break; 3735 break;
3722 3736
3723 BUG_ON(key.type == BTRFS_EXTENT_REF_V0_KEY);
3724 if (key.type == BTRFS_SHARED_DATA_REF_KEY) { 3737 if (key.type == BTRFS_SHARED_DATA_REF_KEY) {
3725 ret = __add_tree_block(rc, key.offset, blocksize, 3738 ret = __add_tree_block(rc, key.offset, blocksize,
3726 blocks); 3739 blocks);
@@ -3729,6 +3742,10 @@ int add_data_references(struct reloc_control *rc,
3729 struct btrfs_extent_data_ref); 3742 struct btrfs_extent_data_ref);
3730 ret = find_data_references(rc, extent_key, 3743 ret = find_data_references(rc, extent_key,
3731 eb, dref, blocks); 3744 eb, dref, blocks);
3745 } else if (key.type == BTRFS_EXTENT_REF_V0_KEY) {
3746 btrfs_print_v0_err(eb->fs_info);
3747 btrfs_handle_fs_error(eb->fs_info, -EINVAL, NULL);
3748 ret = -EINVAL;
3732 } else { 3749 } else {
3733 ret = 0; 3750 ret = 0;
3734 } 3751 }
@@ -3967,7 +3984,11 @@ restart:
3967 flags = btrfs_extent_flags(path->nodes[0], ei); 3984 flags = btrfs_extent_flags(path->nodes[0], ei);
3968 ret = check_extent_flags(flags); 3985 ret = check_extent_flags(flags);
3969 BUG_ON(ret); 3986 BUG_ON(ret);
3970 3987 } else if (item_size == sizeof(struct btrfs_extent_item_v0)) {
3988 err = -EINVAL;
3989 btrfs_print_v0_err(trans->fs_info);
3990 btrfs_abort_transaction(trans, err);
3991 break;
3971 } else { 3992 } else {
3972 BUG(); 3993 BUG();
3973 } 3994 }