Implemented initalizing the bitmap of a fresh volume in the new call

BlockAllocator::InitializeAndClearBitmap().
Added BlockAllocator::BitmapSize() which returns the size of the block
bitmap in bytes - used it where appropriate.


git-svn-id: file:///srv/svn/repos/haiku/trunk/current@6311 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Axel Dörfler
2004-01-26 02:06:47 +00:00
parent daf0126bb2
commit 81566b9389
2 changed files with 68 additions and 8 deletions
@@ -328,7 +328,7 @@ BlockAllocator::~BlockAllocator()
status_t status_t
BlockAllocator::Initialize() BlockAllocator::Initialize(bool full)
{ {
if (fLock.InitCheck() < B_OK) if (fLock.InitCheck() < B_OK)
return B_ERROR; return B_ERROR;
@@ -339,8 +339,11 @@ BlockAllocator::Initialize()
if (fGroups == NULL) if (fGroups == NULL)
return B_NO_MEMORY; return B_NO_MEMORY;
if (!full)
return B_OK;
thread_id id = spawn_kernel_thread((thread_func)BlockAllocator::initialize, thread_id id = spawn_kernel_thread((thread_func)BlockAllocator::initialize,
"bfs block allocator", B_LOW_PRIORITY, (void *)this); "bfs block allocator", B_LOW_PRIORITY, (void *)this);
if (id < B_OK) if (id < B_OK)
return initialize(this); return initialize(this);
@@ -348,6 +351,52 @@ BlockAllocator::Initialize()
} }
status_t
BlockAllocator::InitializeAndClearBitmap(Transaction &transaction)
{
status_t status = Initialize(false);
if (status < B_OK)
return status;
uint32 blocks = fBlocksPerGroup;
uint32 numBits = 8 * blocks * fVolume->BlockSize();
uint32 *buffer = (uint32 *)malloc(numBits >> 3);
if (buffer == NULL)
RETURN_ERROR(B_NO_MEMORY);
memset(buffer, 0, numBits >> 3);
off_t offset = 1;
// initialize the AllocationGroup objects and clear the on-disk bitmap
for (int32 i = 0; i < fNumGroups; i++) {
if (cached_write(fVolume->Device(), offset, buffer, blocks, fVolume->BlockSize()) < B_OK)
return B_ERROR;
// the last allocation group may contain less blocks than the others
fGroups[i].fNumBits = i == fNumGroups - 1 ? fVolume->NumBlocks() - i * numBits : numBits;
fGroups[i].fStart = offset;
fGroups[i].fFirstFree = fGroups[i].fLargestFirst = 0;
fGroups[i].fFreeBits = fGroups[i].fLargest = fGroups[i].fNumBits;
offset += blocks;
}
free(buffer);
// reserve the boot block, the log area, and the block bitmap itself
uint32 reservedBlocks = fVolume->Log().Start() + fVolume->Log().Length();
if (fGroups[0].Allocate(&transaction, 0, reservedBlocks) < B_OK) {
FATAL(("could not allocate reserved space for block bitmap/log!\n"));
return B_ERROR;
}
return B_OK;
}
status_t status_t
BlockAllocator::initialize(BlockAllocator *allocator) BlockAllocator::initialize(BlockAllocator *allocator)
{ {
@@ -371,7 +420,7 @@ BlockAllocator::initialize(BlockAllocator *allocator)
break; break;
// the last allocation group may contain less blocks than the others // the last allocation group may contain less blocks than the others
groups[i].fNumBits = i == num - 1 ? allocator->fVolume->NumBlocks() - i * numBits : numBits; groups[i].fNumBits = i == num - 1 ? volume->NumBlocks() - i * numBits : numBits;
groups[i].fStart = offset; groups[i].fStart = offset;
// finds all free ranges in this allocation group // finds all free ranges in this allocation group
@@ -641,6 +690,13 @@ BlockAllocator::Free(Transaction *transaction, block_run run)
} }
size_t
BlockAllocator::BitmapSize() const
{
return fVolume->BlockSize() * fNumGroups * fBlocksPerGroup;
}
// #pragma mark - // #pragma mark -
// Functions to check the validity of the bitmap - they are used from // Functions to check the validity of the bitmap - they are used from
// the "chkbfs" command // the "chkbfs" command
@@ -669,7 +725,7 @@ BlockAllocator::StartChecking(check_control *control)
if (status < B_OK) if (status < B_OK)
return status; return status;
size_t size = fVolume->BlockSize() * fNumGroups * fBlocksPerGroup; size_t size = BitmapSize();
fCheckBitmap = (uint32 *)malloc(size); fCheckBitmap = (uint32 *)malloc(size);
if (fCheckBitmap == NULL) { if (fCheckBitmap == NULL) {
fLock.Unlock(); fLock.Unlock();
@@ -942,7 +998,7 @@ BlockAllocator::CheckNextNode(check_control *control)
bool bool
BlockAllocator::CheckBitmapIsUsedAt(off_t block) const BlockAllocator::CheckBitmapIsUsedAt(off_t block) const
{ {
size_t size = fVolume->BlockSize() * fNumGroups * fBlocksPerGroup; size_t size = BitmapSize();
uint32 index = block / 32; // 32bit resolution uint32 index = block / 32; // 32bit resolution
if (index > size / 4) if (index > size / 4)
return false; return false;
@@ -954,7 +1010,7 @@ BlockAllocator::CheckBitmapIsUsedAt(off_t block) const
void void
BlockAllocator::SetCheckBitmapAt(off_t block) BlockAllocator::SetCheckBitmapAt(off_t block)
{ {
size_t size = fVolume->BlockSize() * fNumGroups * fBlocksPerGroup; size_t size = BitmapSize();
uint32 index = block / 32; // 32bit resolution uint32 index = block / 32; // 32bit resolution
if (index > size / 4) if (index > size / 4)
return; return;
@@ -25,7 +25,8 @@ class BlockAllocator {
BlockAllocator(Volume *volume); BlockAllocator(Volume *volume);
~BlockAllocator(); ~BlockAllocator();
status_t Initialize(); status_t Initialize(bool full = true);
status_t InitializeAndClearBitmap(Transaction &transaction);
status_t AllocateForInode(Transaction *transaction, const block_run *parent, status_t AllocateForInode(Transaction *transaction, const block_run *parent,
mode_t type, block_run &run); mode_t type, block_run &run);
@@ -43,6 +44,8 @@ class BlockAllocator {
status_t CheckBlockRun(block_run run, const char *type = NULL, check_control *control = NULL); status_t CheckBlockRun(block_run run, const char *type = NULL, check_control *control = NULL);
status_t CheckInode(Inode *inode, check_control *control = NULL); status_t CheckInode(Inode *inode, check_control *control = NULL);
size_t BitmapSize() const;
private: private:
bool IsValidCheckControl(check_control *control); bool IsValidCheckControl(check_control *control);
bool CheckBitmapIsUsedAt(off_t block) const; bool CheckBitmapIsUsedAt(off_t block) const;
@@ -55,6 +58,7 @@ class BlockAllocator {
AllocationGroup *fGroups; AllocationGroup *fGroups;
int32 fNumGroups; int32 fNumGroups;
uint32 fBlocksPerGroup; uint32 fBlocksPerGroup;
uint32 *fCheckBitmap; uint32 *fCheckBitmap;
check_cookie *fCheckCookie; check_cookie *fCheckCookie;
}; };