* Let checkfs collect stats of how the data streams are used.

* Would be nice to only show this when an extra argument had been passed to
  checkfs, but I'm afraid the API is somewhat limited, not to say pretty much
  unusable for the task.


git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@42125 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Axel Dörfler 2011-06-12 15:24:54 +00:00
parent b23ab34f66
commit 21d6b8e2c7
4 changed files with 72 additions and 11 deletions

View File

@ -20,6 +20,7 @@
#include <MutablePartition.h>
#include <AutoDeleter.h>
#include <StringForSize.h>
#ifdef ASSERT
# undef ASSERT
@ -54,6 +55,18 @@ static const uint32 kDiskSystemFlags =
;
static BString
size_string(double size)
{
BString string;
char* buffer = string.LockBuffer(256);
string_for_size(size, buffer, 256);
string.UnlockBuffer();
return string;
}
// #pragma mark - BFSAddOn
@ -231,9 +244,9 @@ BFSPartitionHandle::Repair(bool checkOnly)
if (ioctl(fd, BFS_IOCTL_START_CHECKING, &result, sizeof(result)) < 0)
return errno;
off_t attributeDirectories = 0, attributes = 0;
off_t files = 0, directories = 0, indices = 0;
off_t counter = 0;
uint64 attributeDirectories = 0, attributes = 0;
uint64 files = 0, directories = 0, indices = 0;
uint64 counter = 0;
// check all files and report errors
while (ioctl(fd, BFS_IOCTL_CHECK_NEXT_NODE, &result,
@ -277,14 +290,33 @@ BFSPartitionHandle::Repair(bool checkOnly)
close(fd);
printf("\t%lld nodes checked,\n\t%lld blocks not allocated,"
"\n\t%lld blocks already set,\n\t%lld blocks could be freed\n\n",
counter, result.stats.missing, result.stats.already_set,
result.stats.freed);
printf("\tfiles\t\t%lld\n\tdirectories\t%lld\n\tattributes\t%lld\n\tattr. "
"dirs\t%lld\n\tindices\t\t%lld\n", files, directories, attributes,
printf("\t%" B_PRIu64 " nodes checked,\n\t%" B_PRIu64 " blocks not "
"allocated,\n\t%" B_PRIu64 " blocks already set,\n\t%" B_PRIu64
" blocks could be freed\n\n", counter, result.stats.missing,
result.stats.already_set, result.stats.freed);
printf("\tfiles\t\t%" B_PRIu64 "\n\tdirectories\t%" B_PRIu64 "\n"
"\tattributes\t%" B_PRIu64 "\n\tattr. dirs\t%" B_PRIu64 "\n"
"\tindices\t\t%" B_PRIu64 "\n", files, directories, attributes,
attributeDirectories, indices);
printf("\n\tdirect block runs\t\t%" B_PRIu64 " (%s)\n",
result.stats.direct_block_runs, size_string(1.0
* result.stats.blocks_in_direct
* result.stats.block_size).String());
printf("\tindirect block runs\t\t%" B_PRIu64 " (in %" B_PRIu64
" array blocks, %s)\n", result.stats.indirect_block_runs,
result.stats.indirect_array_blocks,
size_string(1.0 * result.stats.blocks_in_indirect
* result.stats.block_size).String());
printf("\tdouble indirect block runs\t%" B_PRIu64 " (in %" B_PRIu64
" array blocks, %s)\n", result.stats.double_indirect_block_runs,
result.stats.double_indirect_array_blocks,
size_string(1.0 * result.stats.blocks_in_double_indirect
* result.stats.block_size).String());
// TODO: this is currently not maintained correctly
//printf("\tpartial block runs\t%" B_PRIu64 "\n",
// result.stats.partial_block_runs);
if (result.status == B_ENTRY_NOT_FOUND)
result.status = B_OK;

View File

@ -13,11 +13,11 @@ Addon <disk_system>bfs :
bfs_disk_system.cpp
: be $(HAIKU_LOCALE_LIBS) $(TARGET_LIBSUPC++)
: be $(HAIKU_LOCALE_LIBS) $(TARGET_LIBSUPC++) libshared.a
;
DoCatalogs <disk_system>bfs :
x-vnd.Haiku-BFSAddOn
:
InitializeParameterEditor.cpp
InitializeParameterEditor.cpp
;

View File

@ -1226,6 +1226,7 @@ BlockAllocator::StartChecking(const check_control* control)
}
memcpy(&fCheckCookie->control, control, sizeof(check_control));
memset(&fCheckCookie->control.stats, 0, sizeof(control->stats));
// initialize bitmap
memset(fCheckBitmap, 0, size);
@ -1237,6 +1238,7 @@ BlockAllocator::StartChecking(const check_control* control)
fCheckCookie->stack.Push(fVolume->Root());
fCheckCookie->stack.Push(fVolume->Indices());
fCheckCookie->iterator = NULL;
fCheckCookie->control.stats.block_size = fVolume->BlockSize();
// Put removed vnodes to the stack -- they are not reachable by traversing
// the file system anymore.
@ -1812,6 +1814,10 @@ BlockAllocator::CheckInode(Inode* inode)
status = CheckBlockRun(data->direct[i], "direct");
if (status < B_OK)
return status;
fCheckCookie->control.stats.direct_block_runs++;
fCheckCookie->control.stats.blocks_in_direct
+= data->direct[i].Length();
}
}
@ -1840,7 +1846,13 @@ BlockAllocator::CheckInode(Inode* inode)
status = CheckBlockRun(runs[index], "indirect->run");
if (status < B_OK)
return status;
fCheckCookie->control.stats.indirect_block_runs++;
fCheckCookie->control.stats.blocks_in_indirect
+= runs[index].Length();
}
fCheckCookie->control.stats.indirect_array_blocks++;
if (index < runsPerBlock)
break;
}
@ -1894,8 +1906,14 @@ BlockAllocator::CheckInode(Inode* inode)
"double indirect->runs->run");
if (status != B_OK)
return status;
fCheckCookie->control.stats.double_indirect_block_runs++;
fCheckCookie->control.stats.blocks_in_double_indirect
+= runs[index % runsPerBlock].Length();
} while ((++index % runsPerArray) != 0);
}
fCheckCookie->control.stats.double_indirect_array_blocks++;
}
}

View File

@ -50,6 +50,17 @@ struct check_control {
uint64 missing;
uint64 already_set;
uint64 freed;
uint64 direct_block_runs;
uint64 indirect_block_runs;
uint64 indirect_array_blocks;
uint64 double_indirect_block_runs;
uint64 double_indirect_array_blocks;
uint64 blocks_in_direct;
uint64 blocks_in_indirect;
uint64 blocks_in_double_indirect;
uint64 partial_block_runs;
uint32 block_size;
} stats;
status_t status;
};