Volume: don't use a block allocator when mounting readonly.

BitmapBlock: also use file system blocks, current type is off_t. Also added more trace.
BlockAllocator: added an assert and more trace


git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@39302 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Jérôme Duval 2010-11-04 18:25:58 +00:00
parent 6fa1b3a596
commit eb7aa0dafb
5 changed files with 60 additions and 37 deletions

View File

@ -4,6 +4,7 @@
*
* Authors:
* Janito V. Ferreira Filho
* Jérôme Duval
*/
@ -16,6 +17,7 @@
#else
# define TRACE(x...) ;
#endif
#define ERROR(x...) dprintf("\33[34mext2:\33[0m " x)
BitmapBlock::BitmapBlock(Volume* volume, uint32 numBits)
@ -35,7 +37,7 @@ BitmapBlock::~BitmapBlock()
/*virtual*/ bool
BitmapBlock::SetTo(uint32 block)
BitmapBlock::SetTo(off_t block)
{
fData = NULL;
fReadOnlyData = (uint32*)CachedBlock::SetTo(block);
@ -45,7 +47,7 @@ BitmapBlock::SetTo(uint32 block)
/*virtual*/ bool
BitmapBlock::SetToWritable(Transaction& transaction, uint32 block, bool empty)
BitmapBlock::SetToWritable(Transaction& transaction, off_t block, bool empty)
{
fReadOnlyData = NULL;
fData = (uint32*)CachedBlock::SetToWritable(transaction, block, empty);
@ -74,7 +76,7 @@ BitmapBlock::CheckUnmarked(uint32 start, uint32 length)
if (length < 32) {
if (startBit + length < 32) {
uint32 bits = B_LENDIAN_TO_HOST_INT32(fData[startIndex]);
uint32 bits = B_LENDIAN_TO_HOST_INT32(data[startIndex]);
uint32 mask = (1 << (startBit + length)) - 1;
mask &= ~((1 << startBit) - 1);
@ -147,7 +149,7 @@ BitmapBlock::CheckMarked(uint32 start, uint32 length)
if (length < 32) {
if (startBit + length < 32) {
uint32 bits = B_LENDIAN_TO_HOST_INT32(fData[startIndex]);
uint32 bits = B_LENDIAN_TO_HOST_INT32(data[startIndex]);
uint32 mask = (1 << (startBit + length)) - 1;
mask &= ~((1 << startBit) - 1);
@ -165,8 +167,10 @@ BitmapBlock::CheckMarked(uint32 start, uint32 length)
mask = ~((1 << startBit) - 1);
uint32 bits = B_LENDIAN_TO_HOST_INT32(data[index]);
if ((bits & mask) != mask)
if ((bits & mask) != mask) {
TRACE("BitmapBlock::CheckMarked(): failed\n");
return false;
}
index += 1;
} else
@ -174,17 +178,21 @@ BitmapBlock::CheckMarked(uint32 start, uint32 length)
mask = 0xFFFFFFFF;
for (; iterations > 0; --iterations) {
if (data[index++] != mask)
if (data[index++] != mask) {
TRACE("BitmapBlock::CheckMarked(): failed at index %ld\n", index);
return false;
}
}
if (remainingBits != 0) {
mask = (1 << remainingBits) - 1;
uint32 bits = B_HOST_TO_LENDIAN_INT32(data[index]);
if ((bits & mask) != mask)
if ((bits & mask) != mask) {
TRACE("BitmapBlock::CheckMarked(): failed remaining\n");
return false;
}
}
return true;
}
@ -210,7 +218,7 @@ BitmapBlock::Mark(uint32 start, uint32 length, bool force)
mask &= ~((1 << startBit) - 1);
if ((bits & mask) != 0) {
TRACE("BitmapBlock::Mark() Marking failed bits %lx "
ERROR("BitmapBlock::Mark() Marking failed bits %lx "
"startBit %ld\n", bits, startBit);
return false;
}
@ -240,7 +248,7 @@ BitmapBlock::Mark(uint32 start, uint32 length, bool force)
mask, bits);
if (!force && (bits & mask) != 0) {
TRACE("BitmapBlock::Mark() Marking failed bits %lx "
ERROR("BitmapBlock::Mark() Marking failed bits %lx "
"startBit %ld\n", bits, startBit);
return false;
}
@ -255,7 +263,7 @@ BitmapBlock::Mark(uint32 start, uint32 length, bool force)
mask = 0xFFFFFFFF;
for (; iterations > 0; --iterations) {
if (!force && fData[index] != 0) {
TRACE("BitmapBlock::Mark() Marking failed "
ERROR("BitmapBlock::Mark() Marking failed "
"index %ld, iterations %ld\n", index, iterations);
return false;
}
@ -269,7 +277,7 @@ BitmapBlock::Mark(uint32 start, uint32 length, bool force)
" mask: %lX\n", index, remainingBits, bits, mask);
if (!force && (bits & mask) != 0) {
TRACE("BitmapBlock::Mark() Marking failed remaining\n");
ERROR("BitmapBlock::Mark() Marking failed remaining\n");
return false;
}
@ -309,7 +317,7 @@ BitmapBlock::Unmark(uint32 start, uint32 length, bool force)
TRACE("BitmapBlock::Unmark(): mask: %lx\n", mask);
if ((bits & mask) != mask) {
TRACE("BitmapBlock::Unmark() Marking failed bits %lx "
ERROR("BitmapBlock::Unmark() Marking failed bits %lx "
"startBit %ld\n", bits, startBit);
return false;
}
@ -349,7 +357,7 @@ BitmapBlock::Unmark(uint32 start, uint32 length, bool force)
mask = 0xFFFFFFFF;
for (; iterations > 0; --iterations) {
if (!force && fData[index] != mask) {
TRACE("BitmapBlock::Unmark() Marking failed "
ERROR("BitmapBlock::Unmark() Marking failed "
"index %ld, iterations %ld\n", index, iterations);
return false;
}
@ -365,7 +373,7 @@ BitmapBlock::Unmark(uint32 start, uint32 length, bool force)
TRACE("BitmapBlock::Unmark(): mask: %lx, bits: %lx\n", mask, bits);
if (!force && (bits & mask) != mask) {
TRACE("BitmapBlock::Unmark() Marking failed remaining\n");
ERROR("BitmapBlock::Unmark() Marking failed remaining\n");
return false;
}

View File

@ -16,9 +16,9 @@ public:
BitmapBlock(Volume* volume, uint32 numBits);
~BitmapBlock();
bool SetTo(uint32 block);
bool SetTo(off_t block);
bool SetToWritable(Transaction& transaction,
uint32 block, bool empty = false);
off_t block, bool empty = false);
bool CheckMarked(uint32 start, uint32 length);
bool CheckUnmarked(uint32 start, uint32 length);

View File

@ -4,6 +4,7 @@
*
* Authors:
* Janito V. Ferreira Filho
* Jérôme Duval
*/
@ -130,11 +131,13 @@ AllocationBlockGroup::Initialize(Volume* volume, uint32 blockGroup,
status = ScanFreeRanges();
if (fGroupDescriptor->FreeBlocks(fVolume->Has64bitFeature()) != fFreeBits) {
ERROR("AllocationBlockGroup::Initialize(): Mismatch between counted "
"free blocks (%lu) and what is set on the group descriptor "
"(%lu)\n", fFreeBits,
fGroupDescriptor->FreeBlocks(fVolume->Has64bitFeature()));
if (fGroupDescriptor->FreeBlocks(fVolume->Has64bitFeature())
!= fFreeBits) {
ERROR("AllocationBlockGroup(%lu,%lld)::Initialize(): Mismatch between "
"counted free blocks (%lu/%lu) and what is set on the group "
"descriptor (%lu)\n", fBlockGroup, fBitmapBlock, fFreeBits,
fNumBits, fGroupDescriptor->FreeBlocks(
fVolume->Has64bitFeature()));
return B_BAD_DATA;
}
@ -161,6 +164,7 @@ AllocationBlockGroup::ScanFreeRanges()
while (end < fNumBits) {
block.FindNextUnmarked(start);
ASSERT(block.CheckMarked(end, start - end));
end = start;
if (start != block.NumBits()) {

View File

@ -214,7 +214,7 @@ ext2_super_block::IsValid()
Volume::Volume(fs_volume* volume)
:
fFSVolume(volume),
fBlockAllocator(this),
fBlockAllocator(NULL),
fInodeAllocator(this),
fJournalInode(NULL),
fFlags(0),
@ -228,6 +228,7 @@ Volume::Volume(fs_volume* volume)
Volume::~Volume()
{
TRACE("Volume destructor.\n");
delete fBlockAllocator;
if (fGroupBlocks != NULL) {
uint32 blockCount = (fNumGroups + fGroupsPerBlock - 1)
/ fGroupsPerBlock;
@ -396,17 +397,25 @@ Volume::Mount(const char* deviceName, uint32 flags)
return status;
}
if (!IsReadOnly()) {
// Initialize allocators
fBlockAllocator = new(std::nothrow) BlockAllocator(this);
if (fBlockAllocator != NULL) {
TRACE("Volume::Mount(): Initialize block allocator\n");
status = fBlockAllocator.Initialize();
if (status != B_OK) {
status = fBlockAllocator->Initialize();
}
if (fBlockAllocator == NULL || status != B_OK) {
delete fBlockAllocator;
fBlockAllocator = NULL;
FATAL("could not initialize block allocator, going read-only!\n");
fFlags |= VOLUME_READ_ONLY;
fJournal->Uninit();
delete fJournal;
delete fJournalInode;
fJournalInode = NULL;
fJournal = new(std::nothrow) NoJournal(this);
}
}
// ready
status = get_vnode(fFSVolume, EXT2_ROOT_NODE, (void**)&fRootNode);
@ -562,12 +571,14 @@ Volume::GetBlockGroup(int32 index, ext2_block_group** _group)
return B_NO_MEMORY;
memcpy(fGroupBlocks[blockIndex], block, fBlockSize);
TRACE("group [%ld]: inode table %lld\n", index, ((ext2_block_group*)
(fGroupBlocks[blockIndex] + (index % fGroupsPerBlock)
* fGroupDescriptorSize))->InodeTable(Has64bitFeature()));
}
*_group = (ext2_block_group*)(fGroupBlocks[blockIndex]
+ (index % fGroupsPerBlock) * fGroupDescriptorSize);
TRACE("group [%ld]: inode table %lld\n", index,
(*_group)->InodeTable(Has64bitFeature()));
return B_OK;
}
@ -739,7 +750,7 @@ Volume::AllocateBlocks(Transaction& transaction, uint32 minimum, uint32 maximum,
TRACE("Volume::AllocateBlocks(): Calling the block allocator\n");
status_t status = fBlockAllocator.AllocateBlocks(transaction, minimum,
status_t status = fBlockAllocator->AllocateBlocks(transaction, minimum,
maximum, blockGroup, start, length);
if (status != B_OK)
return status;
@ -759,7 +770,7 @@ Volume::FreeBlocks(Transaction& transaction, off_t start, uint32 length)
if (IsReadOnly())
return B_READ_ONLY_DEVICE;
status_t status = fBlockAllocator.Free(transaction, start, length);
status_t status = fBlockAllocator->Free(transaction, start, length);
if (status != B_OK)
return status;

View File

@ -136,7 +136,7 @@ private:
ext2_super_block fSuperBlock;
char fName[32];
BlockAllocator fBlockAllocator;
BlockAllocator* fBlockAllocator;
InodeAllocator fInodeAllocator;
Journal* fJournal;
Inode* fJournalInode;