btrfs-progs: dump-tree: let --tree understand name of the tree
authorDavid Sterba <dsterba@suse.com>
Thu, 10 Mar 2016 14:57:46 +0000 (15:57 +0100)
committerDavid Sterba <dsterba@suse.com>
Mon, 14 Mar 2016 12:42:47 +0000 (13:42 +0100)
For practical purposes teach -t about the human readable names of the
trees in addition to the numerical id. The name syntax is flexible.

Signed-off-by: David Sterba <dsterba@suse.com>
Documentation/btrfs-inspect-internal.asciidoc
cmds-inspect-dump-tree.c

index f19522f..d71b10a 100644 (file)
@@ -46,7 +46,16 @@ print only the uuid tree information, empty output if the tree does not exist
 -b <block_num>::::
 print info of the specified block only
 -t <tree_id>::::
-print only the tree with the specified numerical ID
+print only the tree with the specified ID, where the ID can be numerical or
+common name in a flexible human readable form
++
+The tree id name recognition rules:
+[options="compact"]
+* case does not matter
+* the C source definition, eg. BTRFS_ROOT_TREE_OBJECTID
+* short forms without BTRFS_ prefix, without _TREE and _OBJECTID suffix, eg. ROOT_TREE, ROOT
+* convenience aliases, eg. DEVICE for the DEV tree, CHECKSUM for CSUM
+* unrecognized ID is an error
 
 *inode-resolve* [-v] <ino> <path>::
 (needs root privileges)
index f548efa..43c8b67 100644 (file)
@@ -106,6 +106,72 @@ static void print_old_roots(struct btrfs_super_block *super)
        }
 }
 
+/*
+ * Convert a tree name from various forms to the numerical id if possible
+ * Accepted forms:
+ * - case does not matter
+ * - same as the key name, BTRFS_ROOT_TREE_OBJECTID
+ * - dtto shortened, BTRFS_ROOT_TREE
+ * - dtto without prefix, ROOT_TREE
+ * - common name, ROOT, CHUNK, EXTENT, ...
+ * - dtto alias, DEVICE for DEV, CHECKSUM for CSUM
+ *
+ * Returns 0 if the tree id was not recognized.
+ */
+static u64 treeid_from_string(const char *str, const char **end)
+{
+       int match = 0;
+       int i;
+       u64 id;
+       static struct treename {
+               const char *name;
+               u64 id;
+       } tn[] = {
+               { "ROOT", BTRFS_ROOT_TREE_OBJECTID },
+               { "EXTENT", BTRFS_EXTENT_TREE_OBJECTID },
+               { "CHUNK", BTRFS_CHUNK_TREE_OBJECTID },
+               { "DEVICE", BTRFS_DEV_TREE_OBJECTID },
+               { "DEV", BTRFS_DEV_TREE_OBJECTID },
+               { "FS_TREE", BTRFS_FS_TREE_OBJECTID },
+               { "CSUM", BTRFS_CSUM_TREE_OBJECTID },
+               { "CHECKSUM", BTRFS_CSUM_TREE_OBJECTID },
+               { "QUOTA", BTRFS_QUOTA_TREE_OBJECTID },
+               { "UUID", BTRFS_UUID_TREE_OBJECTID },
+               { "FREE_SPACE", BTRFS_FREE_SPACE_TREE_OBJECTID },
+               { "TREE_LOG_FIXUP", BTRFS_TREE_LOG_FIXUP_OBJECTID },
+               { "TREE_LOG", BTRFS_TREE_LOG_OBJECTID },
+               { "TREE_RELOC", BTRFS_TREE_RELOC_OBJECTID },
+               { "DATA_RELOC", BTRFS_DATA_RELOC_TREE_OBJECTID }
+       };
+
+       if (strncasecmp("BTRFS_", str, strlen("BTRFS_")) == 0)
+               str += strlen("BTRFS_");
+
+       for (i = 0; i < ARRAY_SIZE(tn); i++) {
+               int len = strlen(tn[i].name);
+
+               if (strncasecmp(tn[i].name, str, len) == 0) {
+                       id = tn[i].id;
+                       match = 1;
+                       str += len;
+                       break;
+               }
+       }
+
+       if (!match)
+               return 0;
+
+       if (strncasecmp("_TREE", str, strlen("_TREE")) == 0)
+               str += strlen("_TREE");
+
+       if (strncasecmp("_OBJECTID", str, strlen("_OBJECTID")) == 0)
+               str += strlen("_OBJECTID");
+
+       *end = str;
+
+       return id;
+}
+
 const char * const cmd_inspect_dump_tree_usage[] = {
        "btrfs inspect-internal dump-tree [options] device",
        "Dump tree structures from a given device",
@@ -120,7 +186,7 @@ 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",
-       "-t|--tree <tree_id>    print only the tree with the given tree_id",
+       "-t|--tree <tree_id>    print only tree with the given id (string or number)",
        NULL
 };
 
@@ -183,7 +249,24 @@ int cmd_inspect_dump_tree(int argc, char **argv)
                        block_only = arg_strtou64(optarg);
                        break;
                case 't':
-                       tree_id = arg_strtou64(optarg);
+                       if (string_is_numerical(optarg)) {
+                               tree_id = arg_strtou64(optarg);
+                       } else {
+                               const char *end = NULL;
+
+                               tree_id = treeid_from_string(optarg, &end);
+
+                               if (*end) {
+                                       error("unexpected tree id suffix of '%s': %s\n",
+                                                       optarg, end);
+                                       exit(1);
+                               }
+                       }
+                       if (!tree_id) {
+                               error("unrecognized tree id: %s\n",
+                                               optarg);
+                               exit(1);
+                       }
                        break;
                default:
                        usage(cmd_inspect_dump_tree_usage);