* [PATCH REBASED 0/1] btrfs-progs: dump-tree: allow -b multiple times @ 2018-06-01 5:15 Qu Wenruo 2018-06-01 5:15 ` [PATCH REBASED 1/1] btrfs-progs: inspect-dump-tree: Allow '-b|--block' to be specified " Qu Wenruo 0 siblings, 1 reply; 5+ messages in thread From: Qu Wenruo @ 2018-06-01 5:15 UTC (permalink / raw) To: linux-btrfs Although just one patch, it needs the extent buffer cleanup code as basis, so please fetch it from my github repo: https://github.com/adam900710/btrfs-progs/tree/dump_tree_multi_blocks It's based on David's devel branch, with HEAD as: commit ffc7e4f730bd5ec49ba14ae3a13576311d57d4a6 (david/devel) Author: Axel Burri <axel@tty0.ch> Date: Tue May 15 17:22:14 2018 +0200 btrfs-progs: fix regression preventing send -p with subvolumes mounted on "/" This patch allow -b to be specified multiple times, and add extra basic check for them. For later enhancement (Issue: #113) it needs extra work to handle special roots. Qu Wenruo (1): btrfs-progs: inspect-dump-tree: Allow '-b|--block' to be specified multiple times Documentation/btrfs-inspect-internal.asciidoc | 2 +- cmds-inspect-dump-tree.c | 109 +++++++++++++++--- 2 files changed, 91 insertions(+), 20 deletions(-) -- 2.17.1 ^ permalink raw reply [flat|nested] 5+ messages in thread
* [PATCH REBASED 1/1] btrfs-progs: inspect-dump-tree: Allow '-b|--block' to be specified multiple times 2018-06-01 5:15 [PATCH REBASED 0/1] btrfs-progs: dump-tree: allow -b multiple times Qu Wenruo @ 2018-06-01 5:15 ` Qu Wenruo 2018-06-01 6:54 ` Nikolay Borisov 2018-06-01 8:27 ` [PATCH v1.1] " Qu Wenruo 0 siblings, 2 replies; 5+ messages in thread From: Qu Wenruo @ 2018-06-01 5:15 UTC (permalink / raw) To: linux-btrfs Reuse extent-cache facility to record multiple bytenr so '-b|--block' can be specified multiple times. Despite that, add a sector size alignment check before we try to print a tree block. (Please note that, nodesize alignment check is not suitable here as meta chunk start bytenr could be unaligned to nodesize) Signed-off-by: Qu Wenruo <wqu@suse.com> --- Documentation/btrfs-inspect-internal.asciidoc | 2 +- cmds-inspect-dump-tree.c | 109 +++++++++++++++--- 2 files changed, 91 insertions(+), 20 deletions(-) diff --git a/Documentation/btrfs-inspect-internal.asciidoc b/Documentation/btrfs-inspect-internal.asciidoc index e2db64660b9a..ba8529f57660 100644 --- a/Documentation/btrfs-inspect-internal.asciidoc +++ b/Documentation/btrfs-inspect-internal.asciidoc @@ -86,7 +86,7 @@ the respective tree root block offset -u|--uuid:::: print only the uuid tree information, empty output if the tree does not exist -b <block_num>:::: -print info of the specified block only +print info of the specified block only, can be specified multiple times. --follow:::: use with '-b', print all children tree blocks of '<block_num>' -t <tree_id>:::: diff --git a/cmds-inspect-dump-tree.c b/cmds-inspect-dump-tree.c index 92a2a45b267e..abb9a2bcc7cb 100644 --- a/cmds-inspect-dump-tree.c +++ b/cmds-inspect-dump-tree.c @@ -198,11 +198,92 @@ const char * const cmd_inspect_dump_tree_usage[] = { "-R|--backups same as --roots plus print backup root info", "-u|--uuid print only the uuid tree", "-b|--block <block_num> print info from the specified block only", + " can be specified multile times", "-t|--tree <tree_id> print only tree with the given id (string or number)", "--follow use with -b, to show all children tree blocks of <block_num>", NULL }; +/* + * Helper function to record all tree block bytenr so we don't need to put + * all code into deep indent. + * + * Return >0 if we hit a duplicated bytenr (already recorded) + * Return 0 if nothing went wrong + * Return <0 if error happens (ENOMEM) + * + * For != 0 return value, all warning/error will be outputted by this function. + */ +static int dump_add_tree_block(struct cache_tree *tree, u64 bytenr) +{ + int ret; + + /* + * We don't really care about the size and we don't have + * nodesize before we open the fs, so just use 1 as size here. + */ + ret = add_cache_extent(tree, bytenr, 1); + if (ret == -EEXIST) { + warning("tree block bytenr %llu is duplicated", bytenr); + return 1; + } + if (ret < 0) { + error("failed to record tree block bytenr %llu: %d(%s)", + bytenr, ret, strerror(-ret)); + return ret; + } + return ret; +} + +/* + * Print all tree blocks recorded. + * All tree block bytenr record will also be freed in this function. + * + * Return 0 if nothing wrong happened for *each* tree blocks + * Return <0 if anything wrong happened, and return value will be the last + * error. + */ +static int dump_print_tree_blocks(struct btrfs_fs_info *fs_info, + struct cache_tree *tree, bool follow) +{ + struct cache_extent *ce; + struct extent_buffer *eb; + u64 bytenr; + int ret = 0; + + ce = first_cache_extent(tree); + while (ce) { + bytenr = ce->start; + + /* + * Please note that here we can't check it against nodesize, + * as it's possible a chunk is just aligned to sectorsize but + * not aligned to nodesize. + */ + if (!IS_ALIGNED(bytenr, fs_info->sectorsize)) { + error( + "tree block bytenr %llu is not aligned to sectorsize %u", + bytenr, fs_info->sectorsize); + ret = -EINVAL; + goto next; + } + + eb = read_tree_block(fs_info, bytenr, 0); + if (!extent_buffer_uptodate(eb)) { + error("failed to read tree block %llu", bytenr); + ret = -EIO; + goto next; + } + btrfs_print_tree(eb, follow); + free_extent_buffer(eb); +next: + remove_cache_extent(tree, ce); + free(ce); + ce = first_cache_extent(tree); + } + return ret; +} + int cmd_inspect_dump_tree(int argc, char **argv) { struct btrfs_root *root; @@ -213,6 +294,7 @@ int cmd_inspect_dump_tree(int argc, char **argv) struct extent_buffer *leaf; struct btrfs_disk_key disk_key; struct btrfs_key found_key; + struct cache_tree block_root; /* for multiple --block parameters */ char uuidbuf[BTRFS_UUID_UNPARSED_SIZE]; int ret; int slot; @@ -222,7 +304,7 @@ int cmd_inspect_dump_tree(int argc, char **argv) int roots_only = 0; int root_backups = 0; unsigned open_ctree_flags; - u64 block_only = 0; + u64 block_bytenr; struct btrfs_root *tree_root_scan; u64 tree_id = 0; bool follow = false; @@ -235,6 +317,7 @@ int cmd_inspect_dump_tree(int argc, char **argv) * tree blocks as possible. */ open_ctree_flags = OPEN_CTREE_PARTIAL | OPEN_CTREE_NO_BLOCK_GROUPS; + cache_tree_init(&block_root); while (1) { int c; enum { GETOPT_VAL_FOLLOW = 256 }; @@ -276,7 +359,10 @@ int cmd_inspect_dump_tree(int argc, char **argv) * other than chunk root */ open_ctree_flags |= __OPEN_CTREE_RETURN_CHUNK_ROOT; - block_only = arg_strtou64(optarg); + block_bytenr = arg_strtou64(optarg); + ret = dump_add_tree_block(&block_root, block_bytenr); + if (ret < 0) + goto out; break; case 't': { const char *end = NULL; @@ -324,24 +410,9 @@ int cmd_inspect_dump_tree(int argc, char **argv) goto out; } - if (block_only) { + if (!cache_tree_empty(&block_root)) { root = info->chunk_root; - leaf = read_tree_block(info, block_only, 0); - if (extent_buffer_uptodate(leaf) && - btrfs_header_level(leaf) != 0) { - free_extent_buffer(leaf); - leaf = NULL; - } - - if (!leaf) - leaf = read_tree_block(info, block_only, 0); - if (!extent_buffer_uptodate(leaf)) { - error("failed to read %llu", - (unsigned long long)block_only); - goto close_root; - } - btrfs_print_tree(leaf, follow); - free_extent_buffer(leaf); + ret = dump_print_tree_blocks(info, &block_root, follow); goto close_root; } -- 2.17.1 ^ permalink raw reply related [flat|nested] 5+ messages in thread
* Re: [PATCH REBASED 1/1] btrfs-progs: inspect-dump-tree: Allow '-b|--block' to be specified multiple times 2018-06-01 5:15 ` [PATCH REBASED 1/1] btrfs-progs: inspect-dump-tree: Allow '-b|--block' to be specified " Qu Wenruo @ 2018-06-01 6:54 ` Nikolay Borisov 2018-06-01 8:27 ` [PATCH v1.1] " Qu Wenruo 1 sibling, 0 replies; 5+ messages in thread From: Nikolay Borisov @ 2018-06-01 6:54 UTC (permalink / raw) To: Qu Wenruo, linux-btrfs On 1.06.2018 08:15, Qu Wenruo wrote: > Reuse extent-cache facility to record multiple bytenr so '-b|--block' > can be specified multiple times. > > Despite that, add a sector size alignment check before we try to print a > tree block. > (Please note that, nodesize alignment check is not suitable here as meta > chunk start bytenr could be unaligned to nodesize) > > Signed-off-by: Qu Wenruo <wqu@suse.com> Just one minor misspell but otherwise LGTM: Reviewed-by: Nikolay Borisov <nborisov@suse.com> > --- > Documentation/btrfs-inspect-internal.asciidoc | 2 +- > cmds-inspect-dump-tree.c | 109 +++++++++++++++--- > 2 files changed, 91 insertions(+), 20 deletions(-) > > diff --git a/Documentation/btrfs-inspect-internal.asciidoc b/Documentation/btrfs-inspect-internal.asciidoc > index e2db64660b9a..ba8529f57660 100644 > --- a/Documentation/btrfs-inspect-internal.asciidoc > +++ b/Documentation/btrfs-inspect-internal.asciidoc > @@ -86,7 +86,7 @@ the respective tree root block offset > -u|--uuid:::: > print only the uuid tree information, empty output if the tree does not exist > -b <block_num>:::: > -print info of the specified block only > +print info of the specified block only, can be specified multiple times. > --follow:::: > use with '-b', print all children tree blocks of '<block_num>' > -t <tree_id>:::: > diff --git a/cmds-inspect-dump-tree.c b/cmds-inspect-dump-tree.c > index 92a2a45b267e..abb9a2bcc7cb 100644 > --- a/cmds-inspect-dump-tree.c > +++ b/cmds-inspect-dump-tree.c > @@ -198,11 +198,92 @@ const char * const cmd_inspect_dump_tree_usage[] = { > "-R|--backups same as --roots plus print backup root info", > "-u|--uuid print only the uuid tree", > "-b|--block <block_num> print info from the specified block only", > + " can be specified multile times", nit: s/multile/multiple ^ permalink raw reply [flat|nested] 5+ messages in thread
* [PATCH v1.1] btrfs-progs: inspect-dump-tree: Allow '-b|--block' to be specified multiple times 2018-06-01 5:15 ` [PATCH REBASED 1/1] btrfs-progs: inspect-dump-tree: Allow '-b|--block' to be specified " Qu Wenruo 2018-06-01 6:54 ` Nikolay Borisov @ 2018-06-01 8:27 ` Qu Wenruo 2019-03-05 14:57 ` David Sterba 1 sibling, 1 reply; 5+ messages in thread From: Qu Wenruo @ 2018-06-01 8:27 UTC (permalink / raw) To: linux-btrfs Reuse extent-cache facility to record multiple bytenr so '-b|--block' can be specified multiple times. Despite that, add a sector size alignment check before we try to print a tree block. (Please note that, nodesize alignment check is not suitable here as meta chunk start bytenr could be unaligned to nodesize) Signed-off-by: Qu Wenruo <wqu@suse.com> --- Documentation/btrfs-inspect-internal.asciidoc | 2 +- cmds-inspect-dump-tree.c | 109 +++++++++++++++--- 2 files changed, 91 insertions(+), 20 deletions(-) diff --git a/Documentation/btrfs-inspect-internal.asciidoc b/Documentation/btrfs-inspect-internal.asciidoc index e2db64660b9a..ba8529f57660 100644 --- a/Documentation/btrfs-inspect-internal.asciidoc +++ b/Documentation/btrfs-inspect-internal.asciidoc @@ -86,7 +86,7 @@ the respective tree root block offset -u|--uuid:::: print only the uuid tree information, empty output if the tree does not exist -b <block_num>:::: -print info of the specified block only +print info of the specified block only, can be specified multiple times. --follow:::: use with '-b', print all children tree blocks of '<block_num>' -t <tree_id>:::: diff --git a/cmds-inspect-dump-tree.c b/cmds-inspect-dump-tree.c index 92a2a45b267e..d67406141394 100644 --- a/cmds-inspect-dump-tree.c +++ b/cmds-inspect-dump-tree.c @@ -198,11 +198,92 @@ const char * const cmd_inspect_dump_tree_usage[] = { "-R|--backups same as --roots plus print backup root info", "-u|--uuid print only the uuid tree", "-b|--block <block_num> print info from the specified block only", + " can be specified multiple times", "-t|--tree <tree_id> print only tree with the given id (string or number)", "--follow use with -b, to show all children tree blocks of <block_num>", NULL }; +/* + * Helper function to record all tree block bytenr so we don't need to put + * all code into deep indent. + * + * Return >0 if we hit a duplicated bytenr (already recorded) + * Return 0 if nothing went wrong + * Return <0 if error happens (ENOMEM) + * + * For != 0 return value, all warning/error will be outputted by this function. + */ +static int dump_add_tree_block(struct cache_tree *tree, u64 bytenr) +{ + int ret; + + /* + * We don't really care about the size and we don't have + * nodesize before we open the fs, so just use 1 as size here. + */ + ret = add_cache_extent(tree, bytenr, 1); + if (ret == -EEXIST) { + warning("tree block bytenr %llu is duplicated", bytenr); + return 1; + } + if (ret < 0) { + error("failed to record tree block bytenr %llu: %d(%s)", + bytenr, ret, strerror(-ret)); + return ret; + } + return ret; +} + +/* + * Print all tree blocks recorded. + * All tree block bytenr record will also be freed in this function. + * + * Return 0 if nothing wrong happened for *each* tree blocks + * Return <0 if anything wrong happened, and return value will be the last + * error. + */ +static int dump_print_tree_blocks(struct btrfs_fs_info *fs_info, + struct cache_tree *tree, bool follow) +{ + struct cache_extent *ce; + struct extent_buffer *eb; + u64 bytenr; + int ret = 0; + + ce = first_cache_extent(tree); + while (ce) { + bytenr = ce->start; + + /* + * Please note that here we can't check it against nodesize, + * as it's possible a chunk is just aligned to sectorsize but + * not aligned to nodesize. + */ + if (!IS_ALIGNED(bytenr, fs_info->sectorsize)) { + error( + "tree block bytenr %llu is not aligned to sectorsize %u", + bytenr, fs_info->sectorsize); + ret = -EINVAL; + goto next; + } + + eb = read_tree_block(fs_info, bytenr, 0); + if (!extent_buffer_uptodate(eb)) { + error("failed to read tree block %llu", bytenr); + ret = -EIO; + goto next; + } + btrfs_print_tree(eb, follow); + free_extent_buffer(eb); +next: + remove_cache_extent(tree, ce); + free(ce); + ce = first_cache_extent(tree); + } + return ret; +} + int cmd_inspect_dump_tree(int argc, char **argv) { struct btrfs_root *root; @@ -213,6 +294,7 @@ int cmd_inspect_dump_tree(int argc, char **argv) struct extent_buffer *leaf; struct btrfs_disk_key disk_key; struct btrfs_key found_key; + struct cache_tree block_root; /* for multiple --block parameters */ char uuidbuf[BTRFS_UUID_UNPARSED_SIZE]; int ret; int slot; @@ -222,7 +304,7 @@ int cmd_inspect_dump_tree(int argc, char **argv) int roots_only = 0; int root_backups = 0; unsigned open_ctree_flags; - u64 block_only = 0; + u64 block_bytenr; struct btrfs_root *tree_root_scan; u64 tree_id = 0; bool follow = false; @@ -235,6 +317,7 @@ int cmd_inspect_dump_tree(int argc, char **argv) * tree blocks as possible. */ open_ctree_flags = OPEN_CTREE_PARTIAL | OPEN_CTREE_NO_BLOCK_GROUPS; + cache_tree_init(&block_root); while (1) { int c; enum { GETOPT_VAL_FOLLOW = 256 }; @@ -276,7 +359,10 @@ int cmd_inspect_dump_tree(int argc, char **argv) * other than chunk root */ open_ctree_flags |= __OPEN_CTREE_RETURN_CHUNK_ROOT; - block_only = arg_strtou64(optarg); + block_bytenr = arg_strtou64(optarg); + ret = dump_add_tree_block(&block_root, block_bytenr); + if (ret < 0) + goto out; break; case 't': { const char *end = NULL; @@ -324,24 +410,9 @@ int cmd_inspect_dump_tree(int argc, char **argv) goto out; } - if (block_only) { + if (!cache_tree_empty(&block_root)) { root = info->chunk_root; - leaf = read_tree_block(info, block_only, 0); - if (extent_buffer_uptodate(leaf) && - btrfs_header_level(leaf) != 0) { - free_extent_buffer(leaf); - leaf = NULL; - } - - if (!leaf) - leaf = read_tree_block(info, block_only, 0); - if (!extent_buffer_uptodate(leaf)) { - error("failed to read %llu", - (unsigned long long)block_only); - goto close_root; - } - btrfs_print_tree(leaf, follow); - free_extent_buffer(leaf); + ret = dump_print_tree_blocks(info, &block_root, follow); goto close_root; } -- 2.17.1 ^ permalink raw reply related [flat|nested] 5+ messages in thread
* Re: [PATCH v1.1] btrfs-progs: inspect-dump-tree: Allow '-b|--block' to be specified multiple times 2018-06-01 8:27 ` [PATCH v1.1] " Qu Wenruo @ 2019-03-05 14:57 ` David Sterba 0 siblings, 0 replies; 5+ messages in thread From: David Sterba @ 2019-03-05 14:57 UTC (permalink / raw) To: Qu Wenruo; +Cc: linux-btrfs On Fri, Jun 01, 2018 at 04:27:46PM +0800, Qu Wenruo wrote: > Reuse extent-cache facility to record multiple bytenr so '-b|--block' > can be specified multiple times. > > Despite that, add a sector size alignment check before we try to print a > tree block. > (Please note that, nodesize alignment check is not suitable here as meta > chunk start bytenr could be unaligned to nodesize) > > Signed-off-by: Qu Wenruo <wqu@suse.com> I'm going to add this patch to devel, but there's a crash when there's not valid block on the offset, eg. 'btrfs inspect dump-tree -b 8192 /dev/' $ ./btrfs inspect dump-tree -b 1024 -b 2048 -b 4096 -b 8192 zimg btrfs-progs v4.20.2 ERROR: tree block bytenr 1024 is not aligned to sectorsize 4096 ERROR: tree block bytenr 2048 is not aligned to sectorsize 4096 Couldn't map the block 4096 Invalid mapping for 4096-20480, got 13631488-22020096 Couldn't map the block 4096 bad tree block 4096, bytenr mismatch, want=4096, have=0 ERROR: failed to read tree block 4096 extent_io.c:665: free_extent_buffer_internal: BUG_ON `eb->refs < 0` triggered, value 1 ./btrfs[0x426e57] ./btrfs(free_extent_buffer+0xe)[0x427701] ./btrfs(alloc_extent_buffer+0x3f)[0x427872] ./btrfs(btrfs_find_create_tree_block+0xf)[0x415b3c] ./btrfs(read_tree_block+0x5c)[0x4171b5] ./btrfs(cmd_inspect_dump_tree+0x587)[0x46fb75] ./btrfs(handle_command_group+0x44)[0x40df89] ./btrfs(cmd_inspect+0x15)[0x44b569] ./btrfs(main+0x8b)[0x40e032] /lib64/libc.so.6(__libc_start_main+0xeb)[0x7f2001a54b7b] ./btrfs(_start+0x2a)[0x40dd1a] Aborted (core dumped) I think the fix will be simple so I'll fold it in, otherwise the multiple block offsets work and using the cache is ok. ^ permalink raw reply [flat|nested] 5+ messages in thread
end of thread, other threads:[~2019-03-05 14:56 UTC | newest] Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed) -- links below jump to the message on this page -- 2018-06-01 5:15 [PATCH REBASED 0/1] btrfs-progs: dump-tree: allow -b multiple times Qu Wenruo 2018-06-01 5:15 ` [PATCH REBASED 1/1] btrfs-progs: inspect-dump-tree: Allow '-b|--block' to be specified " Qu Wenruo 2018-06-01 6:54 ` Nikolay Borisov 2018-06-01 8:27 ` [PATCH v1.1] " Qu Wenruo 2019-03-05 14:57 ` David Sterba
This is an external index of several public inboxes, see mirroring instructions on how to clone and mirror all data and code used by this external index.