@@ -308,6 +308,7 @@ enum btrfs_inode_field {
enum btrfs_file_extent_field {
BTRFS_FILE_EXTENT_DISK_BYTENR,
+ BTRFS_FILE_EXTENT_TYPE,
BTRFS_FILE_EXTENT_BAD,
};
@@ -380,6 +381,8 @@ static enum btrfs_file_extent_field convert_file_extent_field(char *field)
{
if (!strncmp(field, "disk_bytenr", FIELD_BUF_LEN))
return BTRFS_FILE_EXTENT_DISK_BYTENR;
+ if (!strncmp(field, "type", FIELD_BUF_LEN))
+ return BTRFS_FILE_EXTENT_TYPE;
return BTRFS_FILE_EXTENT_BAD;
}
@@ -753,13 +756,12 @@ out:
static int corrupt_file_extent(struct btrfs_trans_handle *trans,
struct btrfs_root *root, u64 inode, u64 extent,
- char *field)
+ char *field, u64 bogus)
{
struct btrfs_file_extent_item *fi;
struct btrfs_path *path;
struct btrfs_key key;
enum btrfs_file_extent_field corrupt_field;
- u64 bogus;
u64 orig;
int ret = 0;
@@ -792,9 +794,17 @@ static int corrupt_file_extent(struct btrfs_trans_handle *trans,
switch (corrupt_field) {
case BTRFS_FILE_EXTENT_DISK_BYTENR:
orig = btrfs_file_extent_disk_bytenr(path->nodes[0], fi);
- bogus = generate_u64(orig);
+ bogus = (bogus == UNSET_U64) ? generate_u64(orig) : bogus;
btrfs_set_file_extent_disk_bytenr(path->nodes[0], fi, bogus);
break;
+ case BTRFS_FILE_EXTENT_TYPE:
+ if (bogus == UNSET_U64) {
+ fprintf(stderr, "Specify a new extent type value (-v)\n");
+ ret = -EINVAL;
+ goto out;
+ }
+ btrfs_set_file_extent_type(path->nodes[0], fi, (u8)bogus);
+ break;
default:
ret = -EINVAL;
break;
@@ -1487,9 +1497,9 @@ int main(int argc, char **argv)
printf("corrupting inode\n");
ret = corrupt_inode(trans, root, inode, field);
} else {
- printf("corrupting file extent\n");
ret = corrupt_file_extent(trans, root, inode,
- file_extent, field);
+ file_extent, field,
+ bogus_value);
}
btrfs_commit_transaction(trans, root);
goto out_close;