bfsinfo: Added option to list/count B+tree entries.
* -l now lists the contents of string B+trees. * -c now counts the keys in a B+tree. * Use BPLUSTREE_MAX_KEY_LENGTH to determine the maximum allowed key length (was hardcoded to 255 before).
This commit is contained in:
@@ -156,6 +156,40 @@ dump_double_indirect_stream(Disk& disk, bfs_inode* node, bool showOffsets)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
list_bplustree(Disk& disk, Directory* directory, off_t size)
|
||||||
|
{
|
||||||
|
directory->Rewind();
|
||||||
|
|
||||||
|
char name[B_FILE_NAME_LENGTH];
|
||||||
|
char buffer[512];
|
||||||
|
uint64 count = 0;
|
||||||
|
block_run run;
|
||||||
|
while (directory->GetNextEntry(name, &run) == B_OK) {
|
||||||
|
snprintf(buffer, sizeof(buffer), " %s", name);
|
||||||
|
dump_block_run("", run, buffer);
|
||||||
|
count++;
|
||||||
|
}
|
||||||
|
|
||||||
|
printf("--\n%lld items.\n", count);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
count_bplustree(Disk& disk, Directory* directory, off_t size)
|
||||||
|
{
|
||||||
|
directory->Rewind();
|
||||||
|
|
||||||
|
char name[B_FILE_NAME_LENGTH];
|
||||||
|
uint64 count = 0;
|
||||||
|
block_run run;
|
||||||
|
while (directory->GetNextEntry(name, &run) == B_OK)
|
||||||
|
count++;
|
||||||
|
|
||||||
|
printf("%lld items.\n", count);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
block_run
|
block_run
|
||||||
parseBlockRun(Disk &disk, char *first, char *last)
|
parseBlockRun(Disk &disk, char *first, char *last)
|
||||||
{
|
{
|
||||||
@@ -186,6 +220,8 @@ main(int argc, char **argv)
|
|||||||
"parameters:\n"
|
"parameters:\n"
|
||||||
"\t-i\tdump inode\n"
|
"\t-i\tdump inode\n"
|
||||||
"\t-b\tdump b+tree\n"
|
"\t-b\tdump b+tree\n"
|
||||||
|
"\t-c\tlist b+tree leaves\n"
|
||||||
|
"\t-c\tcount b+tree leaves\n"
|
||||||
"\t-v\tvalidate b+tree\n"
|
"\t-v\tvalidate b+tree\n"
|
||||||
"\t-h\thexdump\n"
|
"\t-h\thexdump\n"
|
||||||
"\t-o\tshow disk offsets\n",
|
"\t-o\tshow disk offsets\n",
|
||||||
@@ -197,6 +233,8 @@ main(int argc, char **argv)
|
|||||||
bool dumpInode = false;
|
bool dumpInode = false;
|
||||||
bool dumpSuperBlock = false;
|
bool dumpSuperBlock = false;
|
||||||
bool dumpBTree = false;
|
bool dumpBTree = false;
|
||||||
|
bool listBTree = false;
|
||||||
|
bool countBTree = false;
|
||||||
bool validateBTree = false;
|
bool validateBTree = false;
|
||||||
bool dumpHex = false;
|
bool dumpHex = false;
|
||||||
bool showOffsets = false;
|
bool showOffsets = false;
|
||||||
@@ -218,6 +256,12 @@ main(int argc, char **argv)
|
|||||||
case 'b':
|
case 'b':
|
||||||
dumpBTree = true;
|
dumpBTree = true;
|
||||||
break;
|
break;
|
||||||
|
case 'l':
|
||||||
|
listBTree = true;
|
||||||
|
break;
|
||||||
|
case 'c':
|
||||||
|
countBTree = true;
|
||||||
|
break;
|
||||||
case 'v':
|
case 'v':
|
||||||
validateBTree = true;
|
validateBTree = true;
|
||||||
break;
|
break;
|
||||||
@@ -242,7 +286,7 @@ main(int argc, char **argv)
|
|||||||
putchar('\n');
|
putchar('\n');
|
||||||
|
|
||||||
if (!dumpSuperBlock && !dumpRootNode && !dumpInode && !dumpBTree
|
if (!dumpSuperBlock && !dumpRootNode && !dumpInode && !dumpBTree
|
||||||
&& !dumpHex) {
|
&& !dumpHex && !listBTree && !countBTree) {
|
||||||
printf(" Name:\t\t\t\"%s\"\n", disk.SuperBlock()->name);
|
printf(" Name:\t\t\t\"%s\"\n", disk.SuperBlock()->name);
|
||||||
printf(" (disk is %s)\n\n",
|
printf(" (disk is %s)\n\n",
|
||||||
disk.ValidateSuperBlock() == B_OK ? "valid" : "invalid!!");
|
disk.ValidateSuperBlock() == B_OK ? "valid" : "invalid!!");
|
||||||
@@ -301,7 +345,8 @@ main(int argc, char **argv)
|
|||||||
block_run run;
|
block_run run;
|
||||||
Inode *inode = NULL;
|
Inode *inode = NULL;
|
||||||
|
|
||||||
if (dumpInode || dumpBTree || dumpHex || validateBTree) {
|
if (dumpInode || dumpBTree || dumpHex || validateBTree || listBTree
|
||||||
|
|| countBTree) {
|
||||||
// Set the block_run to the right value (as specified on the command
|
// Set the block_run to the right value (as specified on the command
|
||||||
// line)
|
// line)
|
||||||
if (!argv[1]) {
|
if (!argv[1]) {
|
||||||
@@ -338,7 +383,25 @@ main(int argc, char **argv)
|
|||||||
printf("B+Tree at block %" B_PRIdOFF ":\n-----------------------------"
|
printf("B+Tree at block %" B_PRIdOFF ":\n-----------------------------"
|
||||||
"------------\n", disk.ToBlock(run));
|
"------------\n", disk.ToBlock(run));
|
||||||
if (inode->IsDirectory() || inode->IsAttributeDirectory()) {
|
if (inode->IsDirectory() || inode->IsAttributeDirectory()) {
|
||||||
dump_bplustree(disk, (Directory *)inode, inode->Size(), dumpHex);
|
dump_bplustree(disk, (Directory*)inode, inode->Size(), dumpHex);
|
||||||
|
putchar('\n');
|
||||||
|
} else
|
||||||
|
fprintf(stderr, "Inode is not a directory!\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (listBTree && inode != NULL) {
|
||||||
|
printf("Directory contents: ------------------------------------------\n");
|
||||||
|
if (inode->IsDirectory() || inode->IsAttributeDirectory()) {
|
||||||
|
list_bplustree(disk, (Directory*)inode, inode->Size());
|
||||||
|
putchar('\n');
|
||||||
|
} else
|
||||||
|
fprintf(stderr, "Inode is not a directory!\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (countBTree && inode != NULL) {
|
||||||
|
printf("Count contents: ------------------------------------------\n");
|
||||||
|
if (inode->IsDirectory() || inode->IsAttributeDirectory()) {
|
||||||
|
count_bplustree(disk, (Directory*)inode, inode->Size());
|
||||||
putchar('\n');
|
putchar('\n');
|
||||||
} else
|
} else
|
||||||
fprintf(stderr, "Inode is not a directory!\n");
|
fprintf(stderr, "Inode is not a directory!\n");
|
||||||
|
|||||||
@@ -233,7 +233,7 @@ dump_bplustree_node(const bplustree_node* node, const bplustree_header* header,
|
|||||||
for (int32 i = 0;i < node->all_key_count;i++) {
|
for (int32 i = 0;i < node->all_key_count;i++) {
|
||||||
uint16 length;
|
uint16 length;
|
||||||
char* key = (char *)node->KeyAt(i, &length);
|
char* key = (char *)node->KeyAt(i, &length);
|
||||||
if (length > 255) {
|
if (length > BPLUSTREE_MAX_KEY_LENGTH) {
|
||||||
Print(" %2" B_PRId32 ". Invalid length (%u)!!\n", i, length);
|
Print(" %2" B_PRId32 ". Invalid length (%u)!!\n", i, length);
|
||||||
dump_block((char *)node, header->node_size, sizeof(off_t));
|
dump_block((char *)node, header->node_size, sizeof(off_t));
|
||||||
break;
|
break;
|
||||||
|
|||||||
Reference in New Issue
Block a user