From 01f868b5a99b412212ede924a81aa15e6d408381 Mon Sep 17 00:00:00 2001 From: Josef Bacik Date: Fri, 3 Oct 2014 10:54:26 -0400 Subject: [PATCH] btrfs-progs: make fsck deal with bogus items We can deal with corrupt items by deleting them in a few cases. Fsck can easily recover from a missing extent item or a dir index item. So if we notice a item is completely bogus and it is of a key that we know we can repair then just delete it and carry on. Thanks, Signed-off-by: Josef Bacik Signed-off-by: David Sterba --- cmds-check.c | 45 +++++++++++++++++++++++ tests/fsck-tests/005-bad-item-offset.img | Bin 0 -> 398336 bytes 2 files changed, 45 insertions(+) create mode 100644 tests/fsck-tests/005-bad-item-offset.img diff --git a/cmds-check.c b/cmds-check.c index db7f7452..acdf312f 100644 --- a/cmds-check.c +++ b/cmds-check.c @@ -2834,6 +2834,42 @@ static int fix_key_order(struct btrfs_trans_handle *trans, return ret; } +static int delete_bogus_item(struct btrfs_trans_handle *trans, + struct btrfs_root *root, + struct btrfs_path *path, + struct extent_buffer *buf, int slot) +{ + struct btrfs_key key; + int nritems = btrfs_header_nritems(buf); + + btrfs_item_key_to_cpu(buf, &key, slot); + + /* These are all the keys we can deal with missing. */ + if (key.type != BTRFS_DIR_INDEX_KEY && + key.type != BTRFS_EXTENT_ITEM_KEY && + key.type != BTRFS_METADATA_ITEM_KEY && + key.type != BTRFS_TREE_BLOCK_REF_KEY && + key.type != BTRFS_EXTENT_DATA_REF_KEY) + return -1; + + printf("Deleting bogus item [%llu,%u,%llu] at slot %d on block %llu\n", + (unsigned long long)key.objectid, key.type, + (unsigned long long)key.offset, slot, buf->start); + memmove_extent_buffer(buf, btrfs_item_nr_offset(slot), + btrfs_item_nr_offset(slot + 1), + sizeof(struct btrfs_item) * + (nritems - slot - 1)); + btrfs_set_header_nritems(buf, nritems - 1); + if (slot == 0) { + struct btrfs_disk_key disk_key; + + btrfs_item_key(buf, &disk_key, 0); + btrfs_fixup_low_keys(root, path, &disk_key, 1); + } + btrfs_mark_buffer_dirty(buf); + return 0; +} + static int fix_item_offset(struct btrfs_trans_handle *trans, struct btrfs_root *root, struct extent_buffer *buf) @@ -2873,6 +2909,7 @@ static int fix_item_offset(struct btrfs_trans_handle *trans, } buf = path->nodes[level]; +again: for (i = 0; i < btrfs_header_nritems(buf); i++) { unsigned int shift = 0, offset; @@ -2880,6 +2917,10 @@ static int fix_item_offset(struct btrfs_trans_handle *trans, BTRFS_LEAF_DATA_SIZE(root)) { if (btrfs_item_end_nr(buf, i) > BTRFS_LEAF_DATA_SIZE(root)) { + ret = delete_bogus_item(trans, root, path, + buf, i); + if (!ret) + goto again; fprintf(stderr, "item is off the end of the " "leaf, can't fix\n"); ret = -EIO; @@ -2891,6 +2932,10 @@ static int fix_item_offset(struct btrfs_trans_handle *trans, btrfs_item_offset_nr(buf, i - 1)) { if (btrfs_item_end_nr(buf, i) > btrfs_item_offset_nr(buf, i - 1)) { + ret = delete_bogus_item(trans, root, path, + buf, i); + if (!ret) + goto again; fprintf(stderr, "items overlap, can't fix\n"); ret = -EIO; break; diff --git a/tests/fsck-tests/005-bad-item-offset.img b/tests/fsck-tests/005-bad-item-offset.img new file mode 100644 index 0000000000000000000000000000000000000000..e11e1e32686112f12418ca8dbba6e03c2517f598 GIT binary patch literal 398336 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 z0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZ zfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&U zAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C7 z2oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N z0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+ z009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBly zK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF z5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk w1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBly@X`|aKM|?Lv;Y7A literal 0 HcmV?d00001