btrfs-progs: alias btrfs device delete to btrfs device remove
[platform/upstream/btrfs-progs.git] / btrfs-debug-tree.c
index 4a9d89d..7d8e876 100644 (file)
 #include <stdlib.h>
 #include <unistd.h>
 #include <uuid/uuid.h>
+#include <getopt.h>
+
 #include "kerncompat.h"
 #include "radix-tree.h"
 #include "ctree.h"
 #include "disk-io.h"
 #include "print-tree.h"
 #include "transaction.h"
-#include "version.h"
+#include "utils.h"
 
-static int print_usage(void)
+static int print_usage(int ret)
 {
        fprintf(stderr, "usage: btrfs-debug-tree [-e] [-d] [-r] [-R] [-u]\n");
        fprintf(stderr, "                        [-b block_num ] device\n");
@@ -40,8 +42,10 @@ static int print_usage(void)
        fprintf(stderr, "\t-u : print info of uuid tree only\n");
        fprintf(stderr, "\t-b block_num : print info of the specified block"
                     " only\n");
-       fprintf(stderr, "%s\n", BTRFS_BUILD_VERSION);
-       exit(1);
+       fprintf(stderr,
+               "\t-t tree_id : print only the tree with the given id\n");
+       fprintf(stderr, "%s\n", PACKAGE_STRING);
+       exit(ret);
 }
 
 static void print_extents(struct btrfs_root *root, struct extent_buffer *eb)
@@ -65,6 +69,8 @@ static void print_extents(struct btrfs_root *root, struct extent_buffer *eb)
                                             btrfs_node_blockptr(eb, i),
                                             size,
                                             btrfs_node_ptr_generation(eb, i));
+               if (!extent_buffer_uptodate(next))
+                       continue;
                if (btrfs_is_leaf(next) &&
                    btrfs_header_level(eb) != 1)
                        BUG();
@@ -125,7 +131,7 @@ int main(int ac, char **av)
        struct extent_buffer *leaf;
        struct btrfs_disk_key disk_key;
        struct btrfs_key found_key;
-       char uuidbuf[37];
+       char uuidbuf[BTRFS_UUID_UNPARSED_SIZE];
        int ret;
        int slot;
        int extent_only = 0;
@@ -135,12 +141,18 @@ int main(int ac, char **av)
        int root_backups = 0;
        u64 block_only = 0;
        struct btrfs_root *tree_root_scan;
+       u64 tree_id = 0;
 
        radix_tree_init();
 
        while(1) {
                int c;
-               c = getopt(ac, av, "deb:rRu");
+               static const struct option long_options[] = {
+                       { "help", no_argument, NULL, GETOPT_VAL_HELP},
+                       { NULL, 0, NULL, 0 }
+               };
+
+               c = getopt_long(ac, av, "deb:rRut:", long_options, NULL);
                if (c < 0)
                        break;
                switch(c) {
@@ -161,33 +173,47 @@ int main(int ac, char **av)
                                root_backups = 1;
                                break;
                        case 'b':
-                               block_only = atoll(optarg);
+                               block_only = arg_strtou64(optarg);
                                break;
+                       case 't':
+                               tree_id = arg_strtou64(optarg);
+                               break;
+                       case GETOPT_VAL_HELP:
                        default:
-                               print_usage();
+                               print_usage(c != GETOPT_VAL_HELP);
                }
        }
+       set_argv0(av);
        ac = ac - optind;
-       if (ac != 1)
-               print_usage();
+       if (check_argc_exact(ac, 1))
+               print_usage(1);
 
-       info = open_ctree_fs_info(av[optind], 0, 0, 0, 1, 0);
+       ret = check_arg_type(av[optind]);
+       if (ret != BTRFS_ARG_BLKDEV && ret != BTRFS_ARG_REG) {
+               fprintf(stderr, "'%s' is not a block device or regular file\n",
+                       av[optind]);
+               exit(1);
+       }
+
+       info = open_ctree_fs_info(av[optind], 0, 0, OPEN_CTREE_PARTIAL);
        if (!info) {
                fprintf(stderr, "unable to open %s\n", av[optind]);
                exit(1);
        }
+
        root = info->fs_root;
+       if (!root) {
+               fprintf(stderr, "unable to open %s\n", av[optind]);
+               exit(1);
+       }
 
        if (block_only) {
-               if (!root) {
-                       fprintf(stderr, "unable to open %s\n", av[optind]);
-                       exit(1);
-               }
                leaf = read_tree_block(root,
                                      block_only,
                                      root->leafsize, 0);
 
-               if (leaf && btrfs_header_level(leaf) != 0) {
+               if (extent_buffer_uptodate(leaf) &&
+                   btrfs_header_level(leaf) != 0) {
                        free_extent_buffer(leaf);
                        leaf = NULL;
                }
@@ -197,16 +223,17 @@ int main(int ac, char **av)
                                              block_only,
                                              root->nodesize, 0);
                }
-               if (!leaf) {
+               if (!extent_buffer_uptodate(leaf)) {
                        fprintf(stderr, "failed to read %llu\n",
                                (unsigned long long)block_only);
                        goto close_root;
                }
                btrfs_print_tree(root, leaf, 0);
+               free_extent_buffer(leaf);
                goto close_root;
        }
 
-       if (!(extent_only || uuid_tree_only)) {
+       if (!(extent_only || uuid_tree_only || tree_id)) {
                if (roots_only) {
                        printf("root tree: %llu level %d\n",
                             (unsigned long long)info->tree_root->node->start,
@@ -266,6 +293,10 @@ again:
                                              0);
                        if (!extent_buffer_uptodate(buf))
                                goto next;
+                       if (tree_id && found_key.objectid != tree_id) {
+                               free_extent_buffer(buf);
+                               goto next;
+                       }
 
                        switch(found_key.objectid) {
                        case BTRFS_ROOT_TREE_OBJECTID:
@@ -392,10 +423,10 @@ no_node:
               (unsigned long long)btrfs_super_total_bytes(info->super_copy));
        printf("bytes used %llu\n",
               (unsigned long long)btrfs_super_bytes_used(info->super_copy));
-       uuidbuf[36] = '\0';
+       uuidbuf[BTRFS_UUID_UNPARSED_SIZE - 1] = '\0';
        uuid_unparse(info->super_copy->fsid, uuidbuf);
        printf("uuid %s\n", uuidbuf);
-       printf("%s\n", BTRFS_BUILD_VERSION);
+       printf("%s\n", PACKAGE_STRING);
 close_root:
        return close_ctree(root);
 }