summaryrefslogtreecommitdiff
path: root/btrfs-corrupt-block.c
diff options
context:
space:
mode:
Diffstat (limited to 'btrfs-corrupt-block.c')
-rw-r--r--btrfs-corrupt-block.c64
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",