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:
parent
6fa1b3a596
commit
eb7aa0dafb
|
@ -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,16 +178,20 @@ 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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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()) {
|
||||
|
|
|
@ -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,16 +397,24 @@ Volume::Mount(const char* deviceName, uint32 flags)
|
|||
return status;
|
||||
}
|
||||
|
||||
// Initialize allocators
|
||||
TRACE("Volume::Mount(): Initialize block allocator\n");
|
||||
status = fBlockAllocator.Initialize();
|
||||
if (status != B_OK) {
|
||||
FATAL("could not initialize block allocator, going read-only!\n");
|
||||
fFlags |= VOLUME_READ_ONLY;
|
||||
fJournal->Uninit();
|
||||
delete fJournal;
|
||||
delete fJournalInode;
|
||||
fJournal = new(std::nothrow) NoJournal(this);
|
||||
if (!IsReadOnly()) {
|
||||
// Initialize allocators
|
||||
fBlockAllocator = new(std::nothrow) BlockAllocator(this);
|
||||
if (fBlockAllocator != NULL) {
|
||||
TRACE("Volume::Mount(): Initialize block allocator\n");
|
||||
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
|
||||
|
@ -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;
|
||||
|
||||
|
|
|
@ -136,7 +136,7 @@ private:
|
|||
ext2_super_block fSuperBlock;
|
||||
char fName[32];
|
||||
|
||||
BlockAllocator fBlockAllocator;
|
||||
BlockAllocator* fBlockAllocator;
|
||||
InodeAllocator fInodeAllocator;
|
||||
Journal* fJournal;
|
||||
Inode* fJournalInode;
|
||||
|
|
Loading…
Reference in New Issue