Just like leaf corruption without using transaction, this patch will corrupt node, doing much more damage to the filesystem, for later leaf/node repair patches.
Signed-off-by: Qu Wenruo <quwen...@cn.fujitsu.com> --- btrfs-corrupt-block.c | 45 ++++++++++++++++++++++++++++++++++++--------- 1 file changed, 36 insertions(+), 9 deletions(-) diff --git a/btrfs-corrupt-block.c b/btrfs-corrupt-block.c index 80eec5b..94c3f12 100644 --- a/btrfs-corrupt-block.c +++ b/btrfs-corrupt-block.c @@ -112,7 +112,8 @@ static void print_usage(void) "to corrupt and a root+key for the item)\n"); fprintf(stderr, "\t-D Corrupt a dir item, must specify key and field\n"); fprintf(stderr, "\t-g <tree_num> Randomly corrupt a leaf in the given tree without changing the csum\n"); - fprintf(stderr, "\t\t can combine with -l to corrupt a given leaf\n"); + fprintf(stderr, "\t-G <tree_num> Randomly corrupt a node in the given tree without changing the csum\n"); + fprintf(stderr, "\t\t '-g/G'can combine with -l to corrupt a given leaf/node\n"); exit(1); } @@ -977,7 +978,8 @@ out: } -struct extent_buffer *find_random_leaf(struct btrfs_root *root, u64 tree_num) +struct extent_buffer *find_random_eb(struct btrfs_root *root, u64 tree_num, + int leaf) { struct btrfs_fs_info *fs_info = root->fs_info; struct btrfs_root *tree_root = fs_info->tree_root; @@ -985,6 +987,7 @@ struct extent_buffer *find_random_leaf(struct btrfs_root *root, u64 tree_num) struct btrfs_key key; struct btrfs_key found_key; struct btrfs_path *path = NULL; + int target_level = -1; int ret = 0; path = btrfs_alloc_path(); @@ -1026,10 +1029,22 @@ struct extent_buffer *find_random_leaf(struct btrfs_root *root, u64 tree_num) goto out; } } + if (!leaf) { + if (btrfs_header_level(eb) == 0) { + fprintf(stderr, "There is no node for the tree %llu\n", + tree_num); + ret = -ENOENT; + goto out; + } + target_level = 1 + rand() % btrfs_header_level(eb); + } while (btrfs_header_level(eb) > 0) { struct extent_buffer *next; int slot = rand() % btrfs_header_nritems(eb); + if (!leaf && btrfs_header_level(eb) == target_level) + goto found; + next = read_tree_block(tree_root, btrfs_node_blockptr(eb, slot), tree_root->nodesize, 0); @@ -1040,6 +1055,7 @@ struct extent_buffer *find_random_leaf(struct btrfs_root *root, u64 tree_num) free_extent_buffer(eb); eb = next; } +found: btrfs_free_path(path); return eb; out: @@ -1087,6 +1103,7 @@ int main(int ac, char **av) int chunk_tree = 0; int corrupt_item = 0; int corrupt_di = 0; + int corrupt_leaf_notrans = 1; u64 metadata_block = 0; u64 inode = 0; u64 file_extent = (u64)-1; @@ -1099,7 +1116,7 @@ int main(int ac, char **av) while(1) { int c; - c = getopt_long(ac, av, "l:c:b:eEkuUi:f:x:m:K:IDg:", long_options, + c = getopt_long(ac, av, "l:c:b:eEkuUi:f:x:m:K:IDg:G:", long_options, &option_index); if (c < 0) break; @@ -1157,6 +1174,11 @@ int main(int ac, char **av) corrupt_item = 1; break; case 'g': + corrupt_leaf_notrans = 1; + tree_num = arg_strtou64(optarg); + break; + case 'G': + corrupt_leaf_notrans = 0; tree_num = arg_strtou64(optarg); break; default: @@ -1179,13 +1201,15 @@ int main(int ac, char **av) } if (tree_num) { if (logical == (u64)-1) { - eb = find_random_leaf(root, tree_num); + eb = find_random_eb(root, tree_num, + corrupt_leaf_notrans); if (IS_ERR(eb) || eb == NULL) { if (eb == NULL) ret = -ENOENT; else ret = PTR_ERR(eb); - fprintf(stderr, "Fail to find a leaf of given tree\n"); + fprintf(stderr, "Fail to find a %s of given tree\n", + corrupt_leaf_notrans ? "leaf" : "node"); goto out_close; } } else { @@ -1195,18 +1219,21 @@ int main(int ac, char **av) ret = -ENOENT; else ret = PTR_ERR(eb); - fprintf(stderr, "Fail to read the given leaf at bytenr: %llu\n", + fprintf(stderr, "Fail to read the given %s at bytenr: %llu\n", + corrupt_leaf_notrans ? "leaf" : "node", logical); goto out_close; } } ret = corrupt_eb_notrans(root, eb, bytes); if (ret < 0) - fprintf(stderr, "fail to corrupt leaf at %llu: %s\n", + fprintf(stderr, "fail to corrupt %s at %llu: %s\n", + corrupt_leaf_notrans ? "leaf" : "node", eb->start, strerror(-ret)); else - printf("Corrupted %llu bytes of the leaf at logical: %llu\n", - bytes, eb->start); + printf("Corrupted %llu bytes of the %s at logical: %llu\n", + bytes, corrupt_leaf_notrans ? "leaf" : "node", + eb->start); free_extent_buffer(eb); goto out_close; } -- 2.1.2 -- To unsubscribe from this list: send the line "unsubscribe linux-btrfs" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html