btrfs-progs: dump-tree: let --tree understand name of the tree

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>
master
David Sterba 2016-03-10 15:57:46 +01:00
parent 1538bc01ad
commit 69874af7b8
2 changed files with 95 additions and 3 deletions

View 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)

View 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);