From eb7aa0dafb0bba235428b5360e8e83a4f1203f4b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=B4me=20Duval?= Date: Thu, 4 Nov 2010 18:25:58 +0000 Subject: [PATCH] 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 --- .../kernel/file_systems/ext2/BitmapBlock.cpp | 36 +++++++++------- .../kernel/file_systems/ext2/BitmapBlock.h | 4 +- .../file_systems/ext2/BlockAllocator.cpp | 14 ++++--- .../kernel/file_systems/ext2/Volume.cpp | 41 ++++++++++++------- src/add-ons/kernel/file_systems/ext2/Volume.h | 2 +- 5 files changed, 60 insertions(+), 37 deletions(-) diff --git a/src/add-ons/kernel/file_systems/ext2/BitmapBlock.cpp b/src/add-ons/kernel/file_systems/ext2/BitmapBlock.cpp index 8f9bb570f6..1db1251cde 100644 --- a/src/add-ons/kernel/file_systems/ext2/BitmapBlock.cpp +++ b/src/add-ons/kernel/file_systems/ext2/BitmapBlock.cpp @@ -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; } diff --git a/src/add-ons/kernel/file_systems/ext2/BitmapBlock.h b/src/add-ons/kernel/file_systems/ext2/BitmapBlock.h index 996d563d41..3086244eed 100644 --- a/src/add-ons/kernel/file_systems/ext2/BitmapBlock.h +++ b/src/add-ons/kernel/file_systems/ext2/BitmapBlock.h @@ -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); diff --git a/src/add-ons/kernel/file_systems/ext2/BlockAllocator.cpp b/src/add-ons/kernel/file_systems/ext2/BlockAllocator.cpp index d00840fa89..4b98471d9f 100644 --- a/src/add-ons/kernel/file_systems/ext2/BlockAllocator.cpp +++ b/src/add-ons/kernel/file_systems/ext2/BlockAllocator.cpp @@ -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()) { diff --git a/src/add-ons/kernel/file_systems/ext2/Volume.cpp b/src/add-ons/kernel/file_systems/ext2/Volume.cpp index b86b708e53..8a2dffb305 100644 --- a/src/add-ons/kernel/file_systems/ext2/Volume.cpp +++ b/src/add-ons/kernel/file_systems/ext2/Volume.cpp @@ -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; diff --git a/src/add-ons/kernel/file_systems/ext2/Volume.h b/src/add-ons/kernel/file_systems/ext2/Volume.h index b9b62b13a4..eb28f31fb1 100644 --- a/src/add-ons/kernel/file_systems/ext2/Volume.h +++ b/src/add-ons/kernel/file_systems/ext2/Volume.h @@ -136,7 +136,7 @@ private: ext2_super_block fSuperBlock; char fName[32]; - BlockAllocator fBlockAllocator; + BlockAllocator* fBlockAllocator; InodeAllocator fInodeAllocator; Journal* fJournal; Inode* fJournalInode;