mirror of
https://github.com/kdave/btrfs-progs
synced 2025-02-12 15:47:03 +00:00
btrfs-progs: dump-tree: add options to dump checksums
Add new options to dumps checksums in node headers and in the checksum items: $ btrfs inspect dump-tree --csum-headers image root tree leaf 471515136 items 19 free space 12186 generation 15 owner ROOT_TREE leaf 471515136 flags 0x1(WRITTEN) backref revision 1 csum 0x756b2d54 fs uuid df0348df-5773-47dd-81e9-a18221461239 For nodes/leaves it's appended on the 2nd line of the header. Checksum items are stored in leaves as EXTENT_CSUM key type, with offset value as the logical offset starting. As the array would be hard to parse or match, each offset value is printed with the checksum. For crc32c it's 4 values on a line, for xxhash it's 2 and for the long 256bit checksums it's one checksum per line. $ btrfs inspect dump-tree --csum-items image leaf 5423104 items 1 free space 30 generation 6 owner CSUM_TREE leaf 5423104 flags 0x1(WRITTEN) backref revision 1 fs uuid bd7c981e-16ff-4081-a734-3ef5d50cafc1 chunk uuid 13f4c76c-7845-4984-88ed-f01b52e05cf8 item 0 key (EXTENT_CSUM EXTENT_CSUM 22020096) itemoff 55 itemsize 16228 range start 22020096 end 38637568 length 16617472 [22020096] 0x8941f998 [22024192] 0x8941f998 [22028288] 0x8941f998 [22032384] 0x8941f998 [22036480] 0x8941f998 [22040576] 0x8941f998 [22044672] 0x8941f998 [22048768] 0x8941f998 ... $ btrfs inspect dump-tree --csum-items image leaf 5718016 items 1 free space 7746 generation 6 owner CSUM_TREE leaf 5718016 flags 0x1(WRITTEN) backref revision 1 fs uuid f453a5b4-8b4a-4fbf-90a2-2925e4fe2335 chunk uuid eb1da63b-248b-44c2-82da-71b2564bf50e item 0 key (EXTENT_CSUM EXTENT_CSUM 52387840) itemoff 7771 itemsize 8512 range start 52387840 end 53477376 length 1089536 [52387840] 0x686ede9288c391e7e05026e56f2f91bfd879987a040ea98445dabc76f55b8e5f [52391936] 0x686ede9288c391e7e05026e56f2f91bfd879987a040ea98445dabc76f55b8e5f ... The options are not on by default, the header checksum is not important for the structures. Data checksums can be quite big so that would make the dump long and without any actual data to match against. Signed-off-by: David Sterba <dsterba@suse.com>
This commit is contained in:
parent
72d710637c
commit
9f6c055e38
@ -114,6 +114,10 @@ This is:
|
||||
+
|
||||
NOTE: lengths are not hidden because they can be calculated from the item size anyway.
|
||||
+
|
||||
--csum-headers::::
|
||||
print b-tree node checksums stored in headers (metadata)
|
||||
--csum-items::::
|
||||
print checksums stored in checksum items (data)
|
||||
--noscan::::
|
||||
do not automatically scan the system for other devices from the same
|
||||
filesystem, only use the devices provided as the arguments
|
||||
|
@ -46,7 +46,7 @@ static void print_extents(struct extent_buffer *eb)
|
||||
return;
|
||||
|
||||
if (btrfs_is_leaf(eb)) {
|
||||
btrfs_print_leaf(eb);
|
||||
btrfs_print_leaf(eb, BTRFS_PRINT_TREE_DEFAULT);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -207,6 +207,8 @@ static const char * const cmd_inspect_dump_tree_usage[] = {
|
||||
"--bfs breadth-first traversal of the trees, print nodes, then leaves (default)",
|
||||
"--dfs depth-first traversal of the trees",
|
||||
"--hide-names hide filenames/subvolume/xattrs and other name references",
|
||||
"--csum-headers print node checksums stored in headers (metadata)",
|
||||
"--csum-items print checksums stored in checksum items (data)",
|
||||
NULL
|
||||
};
|
||||
|
||||
@ -318,6 +320,8 @@ static int cmd_inspect_dump_tree(const struct cmd_struct *cmd,
|
||||
struct btrfs_root *tree_root_scan;
|
||||
u64 tree_id = 0;
|
||||
unsigned int follow = 0;
|
||||
unsigned int csum_mode = 0;
|
||||
unsigned int print_mode;
|
||||
|
||||
/*
|
||||
* For debug-tree, we care nothing about extent tree (it's just backref
|
||||
@ -332,7 +336,9 @@ static int cmd_inspect_dump_tree(const struct cmd_struct *cmd,
|
||||
while (1) {
|
||||
int c;
|
||||
enum { GETOPT_VAL_FOLLOW = 256, GETOPT_VAL_DFS, GETOPT_VAL_BFS,
|
||||
GETOPT_VAL_NOSCAN, GETOPT_VAL_HIDE_NAMES };
|
||||
GETOPT_VAL_NOSCAN, GETOPT_VAL_HIDE_NAMES,
|
||||
GETOPT_VAL_CSUM_HEADERS, GETOPT_VAL_CSUM_ITEMS,
|
||||
};
|
||||
static const struct option long_options[] = {
|
||||
{ "extents", no_argument, NULL, 'e'},
|
||||
{ "device", no_argument, NULL, 'd'},
|
||||
@ -346,6 +352,8 @@ static int cmd_inspect_dump_tree(const struct cmd_struct *cmd,
|
||||
{ "dfs", no_argument, NULL, GETOPT_VAL_DFS },
|
||||
{ "noscan", no_argument, NULL, GETOPT_VAL_NOSCAN },
|
||||
{ "hide-names", no_argument, NULL, GETOPT_VAL_HIDE_NAMES },
|
||||
{ "csum-headers", no_argument, NULL, GETOPT_VAL_CSUM_HEADERS },
|
||||
{ "csum-items", no_argument, NULL, GETOPT_VAL_CSUM_ITEMS },
|
||||
{ NULL, 0, NULL, 0 }
|
||||
};
|
||||
|
||||
@ -416,6 +424,12 @@ static int cmd_inspect_dump_tree(const struct cmd_struct *cmd,
|
||||
case GETOPT_VAL_HIDE_NAMES:
|
||||
open_ctree_flags |= OPEN_CTREE_HIDE_NAMES;
|
||||
break;
|
||||
case GETOPT_VAL_CSUM_HEADERS:
|
||||
csum_mode |= BTRFS_PRINT_TREE_CSUM_HEADERS;
|
||||
break;
|
||||
case GETOPT_VAL_CSUM_ITEMS:
|
||||
csum_mode |= BTRFS_PRINT_TREE_CSUM_ITEMS;
|
||||
break;
|
||||
default:
|
||||
usage_unknown_option(cmd, argv);
|
||||
}
|
||||
@ -468,9 +482,11 @@ static int cmd_inspect_dump_tree(const struct cmd_struct *cmd,
|
||||
goto out;
|
||||
}
|
||||
|
||||
print_mode = follow | traverse | csum_mode;
|
||||
|
||||
if (!cache_tree_empty(&block_root)) {
|
||||
root = info->chunk_root;
|
||||
ret = dump_print_tree_blocks(info, &block_root, follow | traverse);
|
||||
ret = dump_print_tree_blocks(info, &block_root, print_mode);
|
||||
goto close_root;
|
||||
}
|
||||
|
||||
@ -497,19 +513,19 @@ static int cmd_inspect_dump_tree(const struct cmd_struct *cmd,
|
||||
if (info->tree_root->node) {
|
||||
printf("root tree\n");
|
||||
btrfs_print_tree(info->tree_root->node,
|
||||
BTRFS_PRINT_TREE_FOLLOW | traverse);
|
||||
BTRFS_PRINT_TREE_FOLLOW | print_mode);
|
||||
}
|
||||
|
||||
if (info->chunk_root->node) {
|
||||
printf("chunk tree\n");
|
||||
btrfs_print_tree(info->chunk_root->node,
|
||||
BTRFS_PRINT_TREE_FOLLOW | traverse);
|
||||
BTRFS_PRINT_TREE_FOLLOW | print_mode);
|
||||
}
|
||||
|
||||
if (info->log_root_tree) {
|
||||
printf("log root tree\n");
|
||||
btrfs_print_tree(info->log_root_tree->node,
|
||||
BTRFS_PRINT_TREE_FOLLOW | traverse);
|
||||
BTRFS_PRINT_TREE_FOLLOW | print_mode);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -530,7 +546,7 @@ again:
|
||||
}
|
||||
printf("root tree\n");
|
||||
btrfs_print_tree(info->tree_root->node,
|
||||
BTRFS_PRINT_TREE_FOLLOW | traverse);
|
||||
BTRFS_PRINT_TREE_FOLLOW | print_mode);
|
||||
goto close_root;
|
||||
}
|
||||
|
||||
@ -541,7 +557,7 @@ again:
|
||||
}
|
||||
printf("chunk tree\n");
|
||||
btrfs_print_tree(info->chunk_root->node,
|
||||
BTRFS_PRINT_TREE_FOLLOW | traverse);
|
||||
BTRFS_PRINT_TREE_FOLLOW | print_mode);
|
||||
goto close_root;
|
||||
}
|
||||
|
||||
@ -552,7 +568,7 @@ again:
|
||||
}
|
||||
printf("log root tree\n");
|
||||
btrfs_print_tree(info->log_root_tree->node,
|
||||
BTRFS_PRINT_TREE_FOLLOW | traverse);
|
||||
BTRFS_PRINT_TREE_FOLLOW | print_mode);
|
||||
goto close_root;
|
||||
}
|
||||
|
||||
@ -699,7 +715,7 @@ again:
|
||||
} else {
|
||||
printf(" \n");
|
||||
btrfs_print_tree(buf,
|
||||
BTRFS_PRINT_TREE_FOLLOW | traverse);
|
||||
BTRFS_PRINT_TREE_FOLLOW | print_mode);
|
||||
}
|
||||
}
|
||||
free_extent_buffer(buf);
|
||||
|
@ -2545,7 +2545,7 @@ split:
|
||||
|
||||
ret = 0;
|
||||
if (btrfs_leaf_free_space(leaf) < 0) {
|
||||
btrfs_print_leaf(leaf);
|
||||
btrfs_print_leaf(leaf, BTRFS_PRINT_TREE_DEFAULT);
|
||||
BUG();
|
||||
}
|
||||
kfree(buf);
|
||||
@ -2641,7 +2641,7 @@ int btrfs_truncate_item(struct btrfs_root *root, struct btrfs_path *path,
|
||||
|
||||
ret = 0;
|
||||
if (btrfs_leaf_free_space(leaf) < 0) {
|
||||
btrfs_print_leaf(leaf);
|
||||
btrfs_print_leaf(leaf, BTRFS_PRINT_TREE_DEFAULT);
|
||||
BUG();
|
||||
}
|
||||
return ret;
|
||||
@ -2666,7 +2666,7 @@ int btrfs_extend_item(struct btrfs_root *root, struct btrfs_path *path,
|
||||
data_end = leaf_data_end(root->fs_info, leaf);
|
||||
|
||||
if (btrfs_leaf_free_space(leaf) < data_size) {
|
||||
btrfs_print_leaf(leaf);
|
||||
btrfs_print_leaf(leaf, BTRFS_PRINT_TREE_DEFAULT);
|
||||
BUG();
|
||||
}
|
||||
slot = path->slots[0];
|
||||
@ -2674,7 +2674,7 @@ int btrfs_extend_item(struct btrfs_root *root, struct btrfs_path *path,
|
||||
|
||||
BUG_ON(slot < 0);
|
||||
if (slot >= nritems) {
|
||||
btrfs_print_leaf(leaf);
|
||||
btrfs_print_leaf(leaf, BTRFS_PRINT_TREE_DEFAULT);
|
||||
printk("slot %d too large, nritems %u\n", slot, nritems);
|
||||
BUG_ON(1);
|
||||
}
|
||||
@ -2703,7 +2703,7 @@ int btrfs_extend_item(struct btrfs_root *root, struct btrfs_path *path,
|
||||
|
||||
ret = 0;
|
||||
if (btrfs_leaf_free_space(leaf) < 0) {
|
||||
btrfs_print_leaf(leaf);
|
||||
btrfs_print_leaf(leaf, BTRFS_PRINT_TREE_DEFAULT);
|
||||
BUG();
|
||||
}
|
||||
return ret;
|
||||
@ -2752,7 +2752,7 @@ int btrfs_insert_empty_items(struct btrfs_trans_handle *trans,
|
||||
data_end = leaf_data_end(root->fs_info, leaf);
|
||||
|
||||
if (btrfs_leaf_free_space(leaf) < total_size) {
|
||||
btrfs_print_leaf(leaf);
|
||||
btrfs_print_leaf(leaf, BTRFS_PRINT_TREE_DEFAULT);
|
||||
printk("not enough freespace need %u have %d\n",
|
||||
total_size, btrfs_leaf_free_space(leaf));
|
||||
BUG();
|
||||
@ -2765,7 +2765,7 @@ int btrfs_insert_empty_items(struct btrfs_trans_handle *trans,
|
||||
unsigned int old_data = btrfs_item_end_nr(leaf, slot);
|
||||
|
||||
if (old_data < data_end) {
|
||||
btrfs_print_leaf(leaf);
|
||||
btrfs_print_leaf(leaf, BTRFS_PRINT_TREE_DEFAULT);
|
||||
printk("slot %d old_data %u data_end %u\n",
|
||||
slot, old_data, data_end);
|
||||
BUG_ON(1);
|
||||
@ -2813,7 +2813,7 @@ int btrfs_insert_empty_items(struct btrfs_trans_handle *trans,
|
||||
}
|
||||
|
||||
if (btrfs_leaf_free_space(leaf) < 0) {
|
||||
btrfs_print_leaf(leaf);
|
||||
btrfs_print_leaf(leaf, BTRFS_PRINT_TREE_DEFAULT);
|
||||
BUG();
|
||||
}
|
||||
|
||||
|
@ -934,7 +934,7 @@ again:
|
||||
printf("Size is %u, needs to be %u, slot %d\n",
|
||||
(unsigned)item_size,
|
||||
(unsigned)sizeof(*ei), path->slots[0]);
|
||||
btrfs_print_leaf(leaf);
|
||||
btrfs_print_leaf(leaf, BTRFS_PRINT_TREE_DEFAULT);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
@ -1420,7 +1420,7 @@ again:
|
||||
}
|
||||
|
||||
if (ret != 0) {
|
||||
btrfs_print_leaf(path->nodes[0]);
|
||||
btrfs_print_leaf(path->nodes[0], BTRFS_PRINT_TREE_DEFAULT);
|
||||
printk("failed to find block number %Lu\n",
|
||||
(unsigned long long)bytenr);
|
||||
BUG();
|
||||
@ -2014,7 +2014,7 @@ static int __free_extent(struct btrfs_trans_handle *trans,
|
||||
printk(KERN_ERR "umm, got %d back from search"
|
||||
", was looking for %llu\n", ret,
|
||||
(unsigned long long)bytenr);
|
||||
btrfs_print_leaf(path->nodes[0]);
|
||||
btrfs_print_leaf(path->nodes[0], BTRFS_PRINT_TREE_DEFAULT);
|
||||
}
|
||||
BUG_ON(ret);
|
||||
extent_slot = path->slots[0];
|
||||
@ -2028,7 +2028,7 @@ static int __free_extent(struct btrfs_trans_handle *trans,
|
||||
(unsigned long long)owner_objectid,
|
||||
(unsigned long long)owner_offset);
|
||||
printf("path->slots[0]: %d path->nodes[0]:\n", path->slots[0]);
|
||||
btrfs_print_leaf(path->nodes[0]);
|
||||
btrfs_print_leaf(path->nodes[0], BTRFS_PRINT_TREE_DEFAULT);
|
||||
ret = -EIO;
|
||||
goto fail;
|
||||
}
|
||||
|
@ -1161,23 +1161,58 @@ static void print_temporary_item(struct extent_buffer *eb, void *ptr,
|
||||
}
|
||||
|
||||
static void print_extent_csum(struct extent_buffer *eb,
|
||||
struct btrfs_fs_info *fs_info, u32 item_size, u64 start)
|
||||
int item_size, u64 offset, void *ptr, bool print_csum_items)
|
||||
{
|
||||
struct btrfs_fs_info *fs_info = eb->fs_info;
|
||||
u32 size;
|
||||
int csum_size;
|
||||
|
||||
/*
|
||||
* If we don't have fs_info, only output its start position as we
|
||||
* don't have sectorsize for the calculation
|
||||
*/
|
||||
if (!fs_info) {
|
||||
printf("\t\trange start %llu\n", (unsigned long long)start);
|
||||
printf("\t\trange start %llu\n", (unsigned long long)offset);
|
||||
return;
|
||||
}
|
||||
size = (item_size / btrfs_super_csum_size(fs_info->super_copy)) *
|
||||
fs_info->sectorsize;
|
||||
csum_size = btrfs_super_csum_size(fs_info->super_copy);
|
||||
size = (item_size / csum_size) * fs_info->sectorsize;
|
||||
printf("\t\trange start %llu end %llu length %u\n",
|
||||
(unsigned long long)start,
|
||||
(unsigned long long)start + size, size);
|
||||
(unsigned long long)offset,
|
||||
(unsigned long long)offset + size, size);
|
||||
|
||||
|
||||
/*
|
||||
* Fill one long line, which is 1 item of sha256/blake2,
|
||||
* 2x xxhash, 4x crc32c with format:
|
||||
* [offset] 0xCHECKSUM [offset] 0xCHECKSUM
|
||||
*/
|
||||
if (print_csum_items) {
|
||||
const int one_line = max(1, BTRFS_CSUM_SIZE / csum_size / 2);
|
||||
int curline;
|
||||
const u8 *csum = (const u8 *)(eb->data + (unsigned long)ptr);
|
||||
|
||||
curline = one_line;
|
||||
while (size > 0) {
|
||||
int i;
|
||||
|
||||
if (curline == one_line) {
|
||||
printf("\t\t");
|
||||
} else if (curline == 0) {
|
||||
curline = one_line;
|
||||
printf("\n\t\t");
|
||||
} else {
|
||||
putchar(' ');
|
||||
}
|
||||
printf("[%llu] 0x", offset);
|
||||
for (i = 0; i < csum_size; i++)
|
||||
printf("%02x", *csum++);
|
||||
offset += fs_info->sectorsize;
|
||||
size -= fs_info->sectorsize;
|
||||
curline--;
|
||||
}
|
||||
putchar('\n');
|
||||
}
|
||||
}
|
||||
|
||||
/* Caller must ensure sizeof(*ret) >= 14 "WRITTEN|RELOC" */
|
||||
@ -1196,12 +1231,16 @@ static void header_flags_to_str(u64 flags, char *ret)
|
||||
}
|
||||
}
|
||||
|
||||
static void print_header_info(struct extent_buffer *eb)
|
||||
static void print_header_info(struct extent_buffer *eb, unsigned int mode)
|
||||
{
|
||||
struct btrfs_fs_info *fs_info = eb->fs_info;
|
||||
char flags_str[128];
|
||||
u64 flags;
|
||||
u32 nr;
|
||||
u8 backref_rev;
|
||||
char csum_str[2 * BTRFS_CSUM_SIZE + strlen(" csum 0x") + 1];
|
||||
int i;
|
||||
int csum_size;
|
||||
|
||||
flags = btrfs_header_flags(eb) & ~BTRFS_BACKREF_REV_MASK;
|
||||
backref_rev = btrfs_header_flags(eb) >> BTRFS_BACKREF_REV_SHIFT;
|
||||
@ -1222,23 +1261,40 @@ static void print_header_info(struct extent_buffer *eb)
|
||||
(unsigned long long)btrfs_header_generation(eb));
|
||||
print_objectid(stdout, btrfs_header_owner(eb), 0);
|
||||
printf("\n");
|
||||
printf("%s %llu flags 0x%llx(%s) backref revision %d\n",
|
||||
if (fs_info && (mode & BTRFS_PRINT_TREE_CSUM_HEADERS)) {
|
||||
char *tmp = csum_str;
|
||||
u8 *csum = (u8 *)(eb->data + offsetof(struct btrfs_header, csum));
|
||||
|
||||
csum_size = btrfs_super_csum_size(fs_info->super_copy);
|
||||
strcpy(csum_str, " csum 0x");
|
||||
tmp = csum_str + strlen(csum_str);
|
||||
for (i = 0; i < csum_size; i++) {
|
||||
sprintf(tmp, "%02x", csum[i]);
|
||||
tmp++;
|
||||
tmp++;
|
||||
}
|
||||
} else {
|
||||
/* We don't have fs_info, can't print the csum */
|
||||
csum_str[0] = 0;
|
||||
}
|
||||
printf("%s %llu flags 0x%llx(%s) backref revision %d%s\n",
|
||||
btrfs_header_level(eb) ? "node" : "leaf",
|
||||
btrfs_header_bytenr(eb), flags, flags_str, backref_rev);
|
||||
btrfs_header_bytenr(eb), flags, flags_str, backref_rev,
|
||||
csum_str);
|
||||
print_uuids(eb);
|
||||
fflush(stdout);
|
||||
}
|
||||
|
||||
void btrfs_print_leaf(struct extent_buffer *eb)
|
||||
void btrfs_print_leaf(struct extent_buffer *eb, unsigned int mode)
|
||||
{
|
||||
struct btrfs_fs_info *fs_info = eb->fs_info;
|
||||
struct btrfs_item *item;
|
||||
struct btrfs_disk_key disk_key;
|
||||
u32 leaf_data_size = __BTRFS_LEAF_DATA_SIZE(eb->len);
|
||||
u32 i;
|
||||
u32 nr;
|
||||
const bool print_csum_items = (mode & BTRFS_PRINT_TREE_CSUM_ITEMS);
|
||||
|
||||
print_header_info(eb);
|
||||
print_header_info(eb, mode);
|
||||
nr = btrfs_header_nritems(eb);
|
||||
for (i = 0; i < nr; i++) {
|
||||
u32 item_size;
|
||||
@ -1344,8 +1400,7 @@ void btrfs_print_leaf(struct extent_buffer *eb)
|
||||
printf("\t\tcsum item\n");
|
||||
break;
|
||||
case BTRFS_EXTENT_CSUM_KEY:
|
||||
print_extent_csum(eb, fs_info, item_size,
|
||||
offset);
|
||||
print_extent_csum(eb, item_size, offset, ptr, print_csum_items);
|
||||
break;
|
||||
case BTRFS_EXTENT_DATA_KEY:
|
||||
print_file_extent_item(eb, item, i, ptr);
|
||||
@ -1436,7 +1491,7 @@ out:
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void bfs_print_children(struct extent_buffer *root_eb)
|
||||
static void bfs_print_children(struct extent_buffer *root_eb, unsigned int mode)
|
||||
{
|
||||
struct btrfs_fs_info *fs_info = root_eb->fs_info;
|
||||
struct btrfs_path path;
|
||||
@ -1447,6 +1502,10 @@ static void bfs_print_children(struct extent_buffer *root_eb)
|
||||
if (root_level < 1)
|
||||
return;
|
||||
|
||||
mode &= ~(BTRFS_PRINT_TREE_FOLLOW);
|
||||
mode |= BTRFS_PRINT_TREE_BFS;
|
||||
mode &= ~(BTRFS_PRINT_TREE_DFS);
|
||||
|
||||
btrfs_init_path(&path);
|
||||
/* For path */
|
||||
extent_buffer_get(root_eb);
|
||||
@ -1462,7 +1521,7 @@ static void bfs_print_children(struct extent_buffer *root_eb)
|
||||
|
||||
/* Print all sibling tree blocks */
|
||||
while (1) {
|
||||
btrfs_print_tree(path.nodes[cur_level], BTRFS_PRINT_TREE_BFS);
|
||||
btrfs_print_tree(path.nodes[cur_level], mode);
|
||||
ret = btrfs_next_sibling_tree_block(fs_info, &path);
|
||||
if (ret < 0)
|
||||
goto out;
|
||||
@ -1477,7 +1536,7 @@ out:
|
||||
return;
|
||||
}
|
||||
|
||||
static void dfs_print_children(struct extent_buffer *root_eb)
|
||||
static void dfs_print_children(struct extent_buffer *root_eb, unsigned int mode)
|
||||
{
|
||||
struct btrfs_fs_info *fs_info = root_eb->fs_info;
|
||||
struct extent_buffer *next;
|
||||
@ -1485,6 +1544,10 @@ static void dfs_print_children(struct extent_buffer *root_eb)
|
||||
int root_eb_level = btrfs_header_level(root_eb);
|
||||
int i;
|
||||
|
||||
mode |= BTRFS_PRINT_TREE_FOLLOW;
|
||||
mode |= BTRFS_PRINT_TREE_DFS;
|
||||
mode &= ~(BTRFS_PRINT_TREE_BFS);
|
||||
|
||||
for (i = 0; i < nr; i++) {
|
||||
next = read_tree_block(fs_info, btrfs_node_blockptr(root_eb, i),
|
||||
btrfs_node_ptr_generation(root_eb, i));
|
||||
@ -1503,7 +1566,7 @@ static void dfs_print_children(struct extent_buffer *root_eb)
|
||||
free_extent_buffer(next);
|
||||
continue;
|
||||
}
|
||||
btrfs_print_tree(next, BTRFS_PRINT_TREE_FOLLOW | BTRFS_PRINT_TREE_DFS);
|
||||
btrfs_print_tree(next, mode);
|
||||
free_extent_buffer(next);
|
||||
}
|
||||
}
|
||||
@ -1535,7 +1598,7 @@ void btrfs_print_tree(struct extent_buffer *eb, unsigned int mode)
|
||||
|
||||
nr = btrfs_header_nritems(eb);
|
||||
if (btrfs_is_leaf(eb)) {
|
||||
btrfs_print_leaf(eb);
|
||||
btrfs_print_leaf(eb, mode);
|
||||
return;
|
||||
}
|
||||
/* We are crossing eb boundary, this node must be corrupted */
|
||||
@ -1543,7 +1606,7 @@ void btrfs_print_tree(struct extent_buffer *eb, unsigned int mode)
|
||||
warning(
|
||||
"node nr_items corrupted, has %u limit %u, continue anyway",
|
||||
nr, BTRFS_NODEPTRS_PER_EXTENT_BUFFER(eb));
|
||||
print_header_info(eb);
|
||||
print_header_info(eb, mode);
|
||||
ptr_num = BTRFS_NODEPTRS_PER_EXTENT_BUFFER(eb);
|
||||
for (i = 0; i < nr && i < ptr_num; i++) {
|
||||
u64 blocknr = btrfs_node_blockptr(eb, i);
|
||||
@ -1563,10 +1626,13 @@ void btrfs_print_tree(struct extent_buffer *eb, unsigned int mode)
|
||||
if (follow && !fs_info)
|
||||
return;
|
||||
|
||||
if (traverse == BTRFS_PRINT_TREE_DFS)
|
||||
dfs_print_children(eb);
|
||||
else
|
||||
bfs_print_children(eb);
|
||||
/* Keep non-traversal modes */
|
||||
mode &= ~(BTRFS_PRINT_TREE_DFS | BTRFS_PRINT_TREE_BFS);
|
||||
if (traverse == BTRFS_PRINT_TREE_DFS) {
|
||||
dfs_print_children(eb, mode);
|
||||
} else {
|
||||
bfs_print_children(eb, mode);
|
||||
}
|
||||
}
|
||||
|
||||
static bool is_valid_csum_type(u16 csum_type)
|
||||
|
@ -19,8 +19,6 @@
|
||||
#ifndef __PRINT_TREE_H__
|
||||
#define __PRINT_TREE_H__
|
||||
|
||||
void btrfs_print_leaf(struct extent_buffer *l);
|
||||
|
||||
enum {
|
||||
/* Depth-first search, nodes and leaves can be interleaved */
|
||||
BTRFS_PRINT_TREE_DFS = (1 << 0),
|
||||
@ -28,10 +26,15 @@ enum {
|
||||
BTRFS_PRINT_TREE_BFS = (1 << 1),
|
||||
/* Follow to child nodes */
|
||||
BTRFS_PRINT_TREE_FOLLOW = (1 << 2),
|
||||
/* Print checksum of node/leaf */
|
||||
BTRFS_PRINT_TREE_CSUM_HEADERS = (1 << 3),
|
||||
/* Print checksums in checksum items */
|
||||
BTRFS_PRINT_TREE_CSUM_ITEMS = (1 << 4),
|
||||
BTRFS_PRINT_TREE_DEFAULT = BTRFS_PRINT_TREE_BFS,
|
||||
};
|
||||
|
||||
void btrfs_print_tree(struct extent_buffer *eb, unsigned int mode);
|
||||
void btrfs_print_leaf(struct extent_buffer *eb, unsigned int mode);
|
||||
|
||||
void btrfs_print_key(struct btrfs_disk_key *disk_key);
|
||||
void print_chunk_item(struct extent_buffer *eb, struct btrfs_chunk *chunk);
|
||||
|
Loading…
Reference in New Issue
Block a user