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:
@@ -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;
|
||||||
};
|
};
|
||||||
|
|||||||
Reference in New Issue
Block a user