diff options
Diffstat (limited to 'btrfs-corrupt-block.c')
-rw-r--r-- | btrfs-corrupt-block.c | 64 |
1 files changed, 62 insertions, 2 deletions
diff --git a/btrfs-corrupt-block.c b/btrfs-corrupt-block.c index 789cbc70..0e1eb524 100644 --- a/btrfs-corrupt-block.c +++ b/btrfs-corrupt-block.c @@ -65,7 +65,7 @@ static int debug_corrupt_block(struct extent_buffer *eb, "mirror %d logical %llu physical %llu device %s\n", mirror_num, (unsigned long long)bytenr, (unsigned long long)eb->dev_bytenr, device->name); - kfree(multi); + free(multi); if (!copy || mirror_num == copy) { ret = read_extent_from_disk(eb, 0, eb->len); @@ -308,6 +308,13 @@ static void btrfs_corrupt_extent_tree(struct btrfs_trans_handle *trans, enum btrfs_inode_field { BTRFS_INODE_FIELD_ISIZE, BTRFS_INODE_FIELD_NBYTES, + BTRFS_INODE_FIELD_NLINK, + BTRFS_INODE_FIELD_GENERATION, + BTRFS_INODE_FIELD_TRANSID, + BTRFS_INODE_FIELD_BLOCK_GROUP, + BTRFS_INODE_FIELD_MODE, + BTRFS_INODE_FIELD_UID, + BTRFS_INODE_FIELD_GID, BTRFS_INODE_FIELD_BAD, }; @@ -346,6 +353,20 @@ static enum btrfs_inode_field convert_inode_field(char *field) return BTRFS_INODE_FIELD_ISIZE; if (!strncmp(field, "nbytes", FIELD_BUF_LEN)) return BTRFS_INODE_FIELD_NBYTES; + if (!strncmp(field, "nlink", FIELD_BUF_LEN)) + return BTRFS_INODE_FIELD_NLINK; + if (!strncmp(field, "generation", FIELD_BUF_LEN)) + return BTRFS_INODE_FIELD_GENERATION; + if (!strncmp(field, "transid", FIELD_BUF_LEN)) + return BTRFS_INODE_FIELD_TRANSID; + if (!strncmp(field, "block_group", FIELD_BUF_LEN)) + return BTRFS_INODE_FIELD_BLOCK_GROUP; + if (!strncmp(field, "mode", FIELD_BUF_LEN)) + return BTRFS_INODE_FIELD_MODE; + if (!strncmp(field, "uid", FIELD_BUF_LEN)) + return BTRFS_INODE_FIELD_UID; + if (!strncmp(field, "gid", FIELD_BUF_LEN)) + return BTRFS_INODE_FIELD_GID; return BTRFS_INODE_FIELD_BAD; } @@ -603,6 +624,41 @@ static int corrupt_inode(struct btrfs_trans_handle *trans, bogus = generate_u64(orig); btrfs_set_inode_nbytes(path->nodes[0], ei, bogus); break; + case BTRFS_INODE_FIELD_NLINK: + orig = btrfs_inode_nlink(path->nodes[0], ei); + bogus = generate_u32(orig); + btrfs_set_inode_nlink(path->nodes[0], ei, bogus); + break; + case BTRFS_INODE_FIELD_GENERATION: + orig = btrfs_inode_generation(path->nodes[0], ei); + bogus = generate_u64(orig); + btrfs_set_inode_generation(path->nodes[0], ei, bogus); + break; + case BTRFS_INODE_FIELD_TRANSID: + orig = btrfs_inode_transid(path->nodes[0], ei); + bogus = generate_u64(orig); + btrfs_set_inode_transid(path->nodes[0], ei, bogus); + break; + case BTRFS_INODE_FIELD_BLOCK_GROUP: + orig = btrfs_inode_block_group(path->nodes[0], ei); + bogus = generate_u64(orig); + btrfs_set_inode_block_group(path->nodes[0], ei, bogus); + break; + case BTRFS_INODE_FIELD_MODE: + orig = btrfs_inode_mode(path->nodes[0], ei); + bogus = generate_u32(orig); + btrfs_set_inode_mode(path->nodes[0], ei, bogus); + break; + case BTRFS_INODE_FIELD_UID: + orig = btrfs_inode_uid(path->nodes[0], ei); + bogus = generate_u32(orig); + btrfs_set_inode_uid(path->nodes[0], ei, bogus); + break; + case BTRFS_INODE_FIELD_GID: + orig = btrfs_inode_gid(path->nodes[0], ei); + bogus = generate_u32(orig); + btrfs_set_inode_gid(path->nodes[0], ei, bogus); + break; default: ret = -EINVAL; break; @@ -899,7 +955,11 @@ static int corrupt_item_nocow(struct btrfs_trans_handle *trans, if (slot == 0) del = 0; /* Only accept valid eb */ - BUG_ON(!leaf->data || slot >= btrfs_header_nritems(leaf)); + if (slot >= btrfs_header_nritems(leaf)) { + error("invalid eb: no data or slot out of range: %d >= %d", + slot, btrfs_header_nritems(leaf)); + return -EINVAL; + } btrfs_item_key_to_cpu(leaf, &key, slot); if (del) { fprintf(stdout, "Deleting key and data [%llu, %u, %llu].\n", |