From 90f195890fc38d6c86659b3e59233b53fc580d87 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Axel=20D=C3=B6rfler?= Date: Tue, 14 May 2013 22:47:48 +0200 Subject: [PATCH] bfsinfo: Added double indirect block output. --- src/bin/bfs_tools/bfsinfo.cpp | 76 ++++++++++++++++++++++++++++++++--- 1 file changed, 70 insertions(+), 6 deletions(-) diff --git a/src/bin/bfs_tools/bfsinfo.cpp b/src/bin/bfs_tools/bfsinfo.cpp index 4c9a565daf..306b709eac 100644 --- a/src/bin/bfs_tools/bfsinfo.cpp +++ b/src/bin/bfs_tools/bfsinfo.cpp @@ -79,7 +79,7 @@ dump_indirect_stream(Disk &disk, bfs_inode *node, bool showOffsets) if (runs[i].IsZero()) return; - printf(" indirect[%02" B_PRId32 "] = ", i); + printf(" indirect[%04" B_PRId32 "] = ", i); char buffer[256]; if (showOffsets) @@ -94,6 +94,68 @@ dump_indirect_stream(Disk &disk, bfs_inode *node, bool showOffsets) } +void +dump_double_indirect_stream(Disk& disk, bfs_inode* node, bool showOffsets) +{ + if (node->data.max_double_indirect_range == 0) + return; + + int32 bytes = node->data.double_indirect.length * disk.BlockSize(); + int32 count = bytes / sizeof(block_run); + block_run runs[count]; + + off_t offset = node->data.max_indirect_range; + + ssize_t bytesRead = disk.ReadAt(disk.ToOffset(node->data.double_indirect), + (uint8*)runs, bytes); + if (bytesRead < bytes) { + fprintf(stderr, "couldn't read double indirect runs: %s\n", + strerror(bytesRead)); + return; + } + + puts("double indirect stream:"); + + for (int32 i = 0; i < count; i++) { + if (runs[i].IsZero()) + return; + + printf(" double_indirect[%02" B_PRId32 "] = ", i); + + dump_block_run("", runs[i], ""); + + int32 indirectBytes = runs[i].length * disk.BlockSize(); + int32 indirectCount = indirectBytes / sizeof(block_run); + block_run indirectRuns[indirectCount]; + + bytesRead = disk.ReadAt(disk.ToOffset(runs[i]), (uint8*)indirectRuns, + indirectBytes); + if (bytesRead < indirectBytes) { + fprintf(stderr, "couldn't read double indirect runs: %s\n", + strerror(bytesRead)); + continue; + } + + for (int32 j = 0; j < indirectCount; j++) { + if (indirectRuns[j].IsZero()) + break; + + printf(" [%04" B_PRId32 "] = ", j); + + char buffer[256]; + if (showOffsets) + snprintf(buffer, sizeof(buffer), " %16" B_PRIdOFF, offset); + else + buffer[0] = '\0'; + + dump_block_run("", indirectRuns[j], buffer); + + offset += indirectRuns[j].length * disk.BlockSize(); + } + } +} + + block_run parseBlockRun(Disk &disk, char *first, char *last) { @@ -235,6 +297,7 @@ main(int argc, char **argv) } char buffer[disk.BlockSize()]; + bfs_inode* bfsInode = (bfs_inode*)buffer; block_run run; Inode *inode = NULL; @@ -253,7 +316,7 @@ main(int argc, char **argv) return -1; } - inode = Inode::Factory(&disk, (bfs_inode *)buffer, false); + inode = Inode::Factory(&disk, bfsInode, false); if (inode == NULL || inode->InitCheck() < B_OK) { fprintf(stderr,"Not a valid inode!\n"); delete inode; @@ -264,13 +327,14 @@ main(int argc, char **argv) if (dumpInode) { printf("Inode at block %" B_PRIdOFF ":\n------------------------------" "-----------\n", disk.ToBlock(run)); - dump_inode(inode, (bfs_inode *)buffer, showOffsets); - dump_indirect_stream(disk, (bfs_inode *)buffer, showOffsets); + dump_inode(inode, bfsInode, showOffsets); + dump_indirect_stream(disk, bfsInode, showOffsets); + dump_double_indirect_stream(disk, bfsInode, showOffsets); dump_small_data(inode); putchar('\n'); } - if (dumpBTree && inode) { + if (dumpBTree && inode != NULL) { printf("B+Tree at block %" B_PRIdOFF ":\n-----------------------------" "------------\n", disk.ToBlock(run)); if (inode->IsDirectory() || inode->IsAttributeDirectory()) { @@ -280,7 +344,7 @@ main(int argc, char **argv) fprintf(stderr, "Inode is not a directory!\n"); } - if (validateBTree && inode) { + if (validateBTree && inode != NULL) { printf("Validating B+Tree at block %" B_PRIdOFF ":\n------------------" "-----------------------\n", disk.ToBlock(run)); if (inode->IsDirectory() || inode->IsAttributeDirectory()) {