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:
@@ -4,6 +4,7 @@
|
|||||||
*
|
*
|
||||||
* Authors:
|
* Authors:
|
||||||
* Janito V. Ferreira Filho
|
* Janito V. Ferreira Filho
|
||||||
|
* Jérôme Duval
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
@@ -16,6 +17,7 @@
|
|||||||
#else
|
#else
|
||||||
# define TRACE(x...) ;
|
# define TRACE(x...) ;
|
||||||
#endif
|
#endif
|
||||||
|
#define ERROR(x...) dprintf("\33[34mext2:\33[0m " x)
|
||||||
|
|
||||||
|
|
||||||
BitmapBlock::BitmapBlock(Volume* volume, uint32 numBits)
|
BitmapBlock::BitmapBlock(Volume* volume, uint32 numBits)
|
||||||
@@ -35,7 +37,7 @@ BitmapBlock::~BitmapBlock()
|
|||||||
|
|
||||||
|
|
||||||
/*virtual*/ bool
|
/*virtual*/ bool
|
||||||
BitmapBlock::SetTo(uint32 block)
|
BitmapBlock::SetTo(off_t block)
|
||||||
{
|
{
|
||||||
fData = NULL;
|
fData = NULL;
|
||||||
fReadOnlyData = (uint32*)CachedBlock::SetTo(block);
|
fReadOnlyData = (uint32*)CachedBlock::SetTo(block);
|
||||||
@@ -45,7 +47,7 @@ BitmapBlock::SetTo(uint32 block)
|
|||||||
|
|
||||||
|
|
||||||
/*virtual*/ bool
|
/*virtual*/ bool
|
||||||
BitmapBlock::SetToWritable(Transaction& transaction, uint32 block, bool empty)
|
BitmapBlock::SetToWritable(Transaction& transaction, off_t block, bool empty)
|
||||||
{
|
{
|
||||||
fReadOnlyData = NULL;
|
fReadOnlyData = NULL;
|
||||||
fData = (uint32*)CachedBlock::SetToWritable(transaction, block, empty);
|
fData = (uint32*)CachedBlock::SetToWritable(transaction, block, empty);
|
||||||
@@ -74,7 +76,7 @@ BitmapBlock::CheckUnmarked(uint32 start, uint32 length)
|
|||||||
|
|
||||||
if (length < 32) {
|
if (length < 32) {
|
||||||
if (startBit + 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;
|
uint32 mask = (1 << (startBit + length)) - 1;
|
||||||
mask &= ~((1 << startBit) - 1);
|
mask &= ~((1 << startBit) - 1);
|
||||||
@@ -147,7 +149,7 @@ BitmapBlock::CheckMarked(uint32 start, uint32 length)
|
|||||||
|
|
||||||
if (length < 32) {
|
if (length < 32) {
|
||||||
if (startBit + 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;
|
uint32 mask = (1 << (startBit + length)) - 1;
|
||||||
mask &= ~((1 << startBit) - 1);
|
mask &= ~((1 << startBit) - 1);
|
||||||
@@ -165,8 +167,10 @@ BitmapBlock::CheckMarked(uint32 start, uint32 length)
|
|||||||
mask = ~((1 << startBit) - 1);
|
mask = ~((1 << startBit) - 1);
|
||||||
uint32 bits = B_LENDIAN_TO_HOST_INT32(data[index]);
|
uint32 bits = B_LENDIAN_TO_HOST_INT32(data[index]);
|
||||||
|
|
||||||
if ((bits & mask) != mask)
|
if ((bits & mask) != mask) {
|
||||||
|
TRACE("BitmapBlock::CheckMarked(): failed\n");
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
index += 1;
|
index += 1;
|
||||||
} else
|
} else
|
||||||
@@ -174,16 +178,20 @@ BitmapBlock::CheckMarked(uint32 start, uint32 length)
|
|||||||
|
|
||||||
mask = 0xFFFFFFFF;
|
mask = 0xFFFFFFFF;
|
||||||
for (; iterations > 0; --iterations) {
|
for (; iterations > 0; --iterations) {
|
||||||
if (data[index++] != mask)
|
if (data[index++] != mask) {
|
||||||
|
TRACE("BitmapBlock::CheckMarked(): failed at index %ld\n", index);
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (remainingBits != 0) {
|
if (remainingBits != 0) {
|
||||||
mask = (1 << remainingBits) - 1;
|
mask = (1 << remainingBits) - 1;
|
||||||
uint32 bits = B_HOST_TO_LENDIAN_INT32(data[index]);
|
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 false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
@@ -210,7 +218,7 @@ BitmapBlock::Mark(uint32 start, uint32 length, bool force)
|
|||||||
mask &= ~((1 << startBit) - 1);
|
mask &= ~((1 << startBit) - 1);
|
||||||
|
|
||||||
if ((bits & mask) != 0) {
|
if ((bits & mask) != 0) {
|
||||||
TRACE("BitmapBlock::Mark() Marking failed bits %lx "
|
ERROR("BitmapBlock::Mark() Marking failed bits %lx "
|
||||||
"startBit %ld\n", bits, startBit);
|
"startBit %ld\n", bits, startBit);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -240,7 +248,7 @@ BitmapBlock::Mark(uint32 start, uint32 length, bool force)
|
|||||||
mask, bits);
|
mask, bits);
|
||||||
|
|
||||||
if (!force && (bits & mask) != 0) {
|
if (!force && (bits & mask) != 0) {
|
||||||
TRACE("BitmapBlock::Mark() Marking failed bits %lx "
|
ERROR("BitmapBlock::Mark() Marking failed bits %lx "
|
||||||
"startBit %ld\n", bits, startBit);
|
"startBit %ld\n", bits, startBit);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -255,7 +263,7 @@ BitmapBlock::Mark(uint32 start, uint32 length, bool force)
|
|||||||
mask = 0xFFFFFFFF;
|
mask = 0xFFFFFFFF;
|
||||||
for (; iterations > 0; --iterations) {
|
for (; iterations > 0; --iterations) {
|
||||||
if (!force && fData[index] != 0) {
|
if (!force && fData[index] != 0) {
|
||||||
TRACE("BitmapBlock::Mark() Marking failed "
|
ERROR("BitmapBlock::Mark() Marking failed "
|
||||||
"index %ld, iterations %ld\n", index, iterations);
|
"index %ld, iterations %ld\n", index, iterations);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -269,7 +277,7 @@ BitmapBlock::Mark(uint32 start, uint32 length, bool force)
|
|||||||
" mask: %lX\n", index, remainingBits, bits, mask);
|
" mask: %lX\n", index, remainingBits, bits, mask);
|
||||||
|
|
||||||
if (!force && (bits & mask) != 0) {
|
if (!force && (bits & mask) != 0) {
|
||||||
TRACE("BitmapBlock::Mark() Marking failed remaining\n");
|
ERROR("BitmapBlock::Mark() Marking failed remaining\n");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -309,7 +317,7 @@ BitmapBlock::Unmark(uint32 start, uint32 length, bool force)
|
|||||||
TRACE("BitmapBlock::Unmark(): mask: %lx\n", mask);
|
TRACE("BitmapBlock::Unmark(): mask: %lx\n", mask);
|
||||||
|
|
||||||
if ((bits & mask) != mask) {
|
if ((bits & mask) != mask) {
|
||||||
TRACE("BitmapBlock::Unmark() Marking failed bits %lx "
|
ERROR("BitmapBlock::Unmark() Marking failed bits %lx "
|
||||||
"startBit %ld\n", bits, startBit);
|
"startBit %ld\n", bits, startBit);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -349,7 +357,7 @@ BitmapBlock::Unmark(uint32 start, uint32 length, bool force)
|
|||||||
mask = 0xFFFFFFFF;
|
mask = 0xFFFFFFFF;
|
||||||
for (; iterations > 0; --iterations) {
|
for (; iterations > 0; --iterations) {
|
||||||
if (!force && fData[index] != mask) {
|
if (!force && fData[index] != mask) {
|
||||||
TRACE("BitmapBlock::Unmark() Marking failed "
|
ERROR("BitmapBlock::Unmark() Marking failed "
|
||||||
"index %ld, iterations %ld\n", index, iterations);
|
"index %ld, iterations %ld\n", index, iterations);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -365,7 +373,7 @@ BitmapBlock::Unmark(uint32 start, uint32 length, bool force)
|
|||||||
TRACE("BitmapBlock::Unmark(): mask: %lx, bits: %lx\n", mask, bits);
|
TRACE("BitmapBlock::Unmark(): mask: %lx, bits: %lx\n", mask, bits);
|
||||||
|
|
||||||
if (!force && (bits & mask) != mask) {
|
if (!force && (bits & mask) != mask) {
|
||||||
TRACE("BitmapBlock::Unmark() Marking failed remaining\n");
|
ERROR("BitmapBlock::Unmark() Marking failed remaining\n");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -16,9 +16,9 @@ public:
|
|||||||
BitmapBlock(Volume* volume, uint32 numBits);
|
BitmapBlock(Volume* volume, uint32 numBits);
|
||||||
~BitmapBlock();
|
~BitmapBlock();
|
||||||
|
|
||||||
bool SetTo(uint32 block);
|
bool SetTo(off_t block);
|
||||||
bool SetToWritable(Transaction& transaction,
|
bool SetToWritable(Transaction& transaction,
|
||||||
uint32 block, bool empty = false);
|
off_t block, bool empty = false);
|
||||||
|
|
||||||
bool CheckMarked(uint32 start, uint32 length);
|
bool CheckMarked(uint32 start, uint32 length);
|
||||||
bool CheckUnmarked(uint32 start, uint32 length);
|
bool CheckUnmarked(uint32 start, uint32 length);
|
||||||
|
|||||||
@@ -4,6 +4,7 @@
|
|||||||
*
|
*
|
||||||
* Authors:
|
* Authors:
|
||||||
* Janito V. Ferreira Filho
|
* Janito V. Ferreira Filho
|
||||||
|
* Jérôme Duval
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
@@ -130,11 +131,13 @@ AllocationBlockGroup::Initialize(Volume* volume, uint32 blockGroup,
|
|||||||
|
|
||||||
status = ScanFreeRanges();
|
status = ScanFreeRanges();
|
||||||
|
|
||||||
if (fGroupDescriptor->FreeBlocks(fVolume->Has64bitFeature()) != fFreeBits) {
|
if (fGroupDescriptor->FreeBlocks(fVolume->Has64bitFeature())
|
||||||
ERROR("AllocationBlockGroup::Initialize(): Mismatch between counted "
|
!= fFreeBits) {
|
||||||
"free blocks (%lu) and what is set on the group descriptor "
|
ERROR("AllocationBlockGroup(%lu,%lld)::Initialize(): Mismatch between "
|
||||||
"(%lu)\n", fFreeBits,
|
"counted free blocks (%lu/%lu) and what is set on the group "
|
||||||
fGroupDescriptor->FreeBlocks(fVolume->Has64bitFeature()));
|
"descriptor (%lu)\n", fBlockGroup, fBitmapBlock, fFreeBits,
|
||||||
|
fNumBits, fGroupDescriptor->FreeBlocks(
|
||||||
|
fVolume->Has64bitFeature()));
|
||||||
return B_BAD_DATA;
|
return B_BAD_DATA;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -161,6 +164,7 @@ AllocationBlockGroup::ScanFreeRanges()
|
|||||||
|
|
||||||
while (end < fNumBits) {
|
while (end < fNumBits) {
|
||||||
block.FindNextUnmarked(start);
|
block.FindNextUnmarked(start);
|
||||||
|
ASSERT(block.CheckMarked(end, start - end));
|
||||||
end = start;
|
end = start;
|
||||||
|
|
||||||
if (start != block.NumBits()) {
|
if (start != block.NumBits()) {
|
||||||
|
|||||||
@@ -214,7 +214,7 @@ ext2_super_block::IsValid()
|
|||||||
Volume::Volume(fs_volume* volume)
|
Volume::Volume(fs_volume* volume)
|
||||||
:
|
:
|
||||||
fFSVolume(volume),
|
fFSVolume(volume),
|
||||||
fBlockAllocator(this),
|
fBlockAllocator(NULL),
|
||||||
fInodeAllocator(this),
|
fInodeAllocator(this),
|
||||||
fJournalInode(NULL),
|
fJournalInode(NULL),
|
||||||
fFlags(0),
|
fFlags(0),
|
||||||
@@ -228,6 +228,7 @@ Volume::Volume(fs_volume* volume)
|
|||||||
Volume::~Volume()
|
Volume::~Volume()
|
||||||
{
|
{
|
||||||
TRACE("Volume destructor.\n");
|
TRACE("Volume destructor.\n");
|
||||||
|
delete fBlockAllocator;
|
||||||
if (fGroupBlocks != NULL) {
|
if (fGroupBlocks != NULL) {
|
||||||
uint32 blockCount = (fNumGroups + fGroupsPerBlock - 1)
|
uint32 blockCount = (fNumGroups + fGroupsPerBlock - 1)
|
||||||
/ fGroupsPerBlock;
|
/ fGroupsPerBlock;
|
||||||
@@ -396,16 +397,24 @@ Volume::Mount(const char* deviceName, uint32 flags)
|
|||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Initialize allocators
|
if (!IsReadOnly()) {
|
||||||
TRACE("Volume::Mount(): Initialize block allocator\n");
|
// Initialize allocators
|
||||||
status = fBlockAllocator.Initialize();
|
fBlockAllocator = new(std::nothrow) BlockAllocator(this);
|
||||||
if (status != B_OK) {
|
if (fBlockAllocator != NULL) {
|
||||||
FATAL("could not initialize block allocator, going read-only!\n");
|
TRACE("Volume::Mount(): Initialize block allocator\n");
|
||||||
fFlags |= VOLUME_READ_ONLY;
|
status = fBlockAllocator->Initialize();
|
||||||
fJournal->Uninit();
|
}
|
||||||
delete fJournal;
|
if (fBlockAllocator == NULL || status != B_OK) {
|
||||||
delete fJournalInode;
|
delete fBlockAllocator;
|
||||||
fJournal = new(std::nothrow) NoJournal(this);
|
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
|
// ready
|
||||||
@@ -562,12 +571,14 @@ Volume::GetBlockGroup(int32 index, ext2_block_group** _group)
|
|||||||
return B_NO_MEMORY;
|
return B_NO_MEMORY;
|
||||||
|
|
||||||
memcpy(fGroupBlocks[blockIndex], block, fBlockSize);
|
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]
|
*_group = (ext2_block_group*)(fGroupBlocks[blockIndex]
|
||||||
+ (index % fGroupsPerBlock) * fGroupDescriptorSize);
|
+ (index % fGroupsPerBlock) * fGroupDescriptorSize);
|
||||||
TRACE("group [%ld]: inode table %lld\n", index,
|
|
||||||
(*_group)->InodeTable(Has64bitFeature()));
|
|
||||||
return B_OK;
|
return B_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -739,7 +750,7 @@ Volume::AllocateBlocks(Transaction& transaction, uint32 minimum, uint32 maximum,
|
|||||||
|
|
||||||
TRACE("Volume::AllocateBlocks(): Calling the block allocator\n");
|
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);
|
maximum, blockGroup, start, length);
|
||||||
if (status != B_OK)
|
if (status != B_OK)
|
||||||
return status;
|
return status;
|
||||||
@@ -759,7 +770,7 @@ Volume::FreeBlocks(Transaction& transaction, off_t start, uint32 length)
|
|||||||
if (IsReadOnly())
|
if (IsReadOnly())
|
||||||
return B_READ_ONLY_DEVICE;
|
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)
|
if (status != B_OK)
|
||||||
return status;
|
return status;
|
||||||
|
|
||||||
|
|||||||
@@ -136,7 +136,7 @@ private:
|
|||||||
ext2_super_block fSuperBlock;
|
ext2_super_block fSuperBlock;
|
||||||
char fName[32];
|
char fName[32];
|
||||||
|
|
||||||
BlockAllocator fBlockAllocator;
|
BlockAllocator* fBlockAllocator;
|
||||||
InodeAllocator fInodeAllocator;
|
InodeAllocator fInodeAllocator;
|
||||||
Journal* fJournal;
|
Journal* fJournal;
|
||||||
Inode* fJournalInode;
|
Inode* fJournalInode;
|
||||||
|
|||||||
Reference in New Issue
Block a user