Author: korli Date: 2010-10-31 18:16:02 +0100 (Sun, 31 Oct 2010) New Revision: 39234 Changeset: http://dev.haiku-os.org/changeset/39234 Modified: haiku/trunk/src/add-ons/kernel/file_systems/ext2/BitmapBlock.cpp haiku/trunk/src/add-ons/kernel/file_systems/ext2/BlockAllocator.cpp haiku/trunk/src/add-ons/kernel/file_systems/ext2/DirectoryIterator.cpp haiku/trunk/src/add-ons/kernel/file_systems/ext2/DirectoryIterator.h haiku/trunk/src/add-ons/kernel/file_systems/ext2/HTree.cpp haiku/trunk/src/add-ons/kernel/file_systems/ext2/HTreeEntryIterator.cpp haiku/trunk/src/add-ons/kernel/file_systems/ext2/HTreeEntryIterator.h haiku/trunk/src/add-ons/kernel/file_systems/ext2/Inode.cpp haiku/trunk/src/add-ons/kernel/file_systems/ext2/Inode.h haiku/trunk/src/add-ons/kernel/file_systems/ext2/InodeAllocator.cpp haiku/trunk/src/add-ons/kernel/file_systems/ext2/InodeAllocator.h haiku/trunk/src/add-ons/kernel/file_systems/ext2/InodeJournal.cpp haiku/trunk/src/add-ons/kernel/file_systems/ext2/InodeJournal.h haiku/trunk/src/add-ons/kernel/file_systems/ext2/Journal.cpp haiku/trunk/src/add-ons/kernel/file_systems/ext2/Journal.h haiku/trunk/src/add-ons/kernel/file_systems/ext2/Volume.cpp haiku/trunk/src/add-ons/kernel/file_systems/ext2/ext2.h haiku/trunk/src/add-ons/kernel/file_systems/ext2/kernel_interface.cpp Log: * switched more uint32 to off_t for 64bit support * added error messages in InodeAllocator, Inode * if BlockAllocator can't initialize, don't fail completely but switch to readonly * fixed a bug in FindNextMarked() for bitmaps with a length non multiple of 32 * Inode::FindBlock() now returns an optional block_run length, useful for get_file_map() * added flag for Inode for extents Modified: haiku/trunk/src/add-ons/kernel/file_systems/ext2/BitmapBlock.cpp =================================================================== --- haiku/trunk/src/add-ons/kernel/file_systems/ext2/BitmapBlock.cpp 2010-10-31 15:42:21 UTC (rev 39233) +++ haiku/trunk/src/add-ons/kernel/file_systems/ext2/BitmapBlock.cpp 2010-10-31 17:16:02 UTC (rev 39234) @@ -463,6 +463,7 @@ "bits: %lX\n", index, bit, mask, bits); bits &= ~mask; + uint32 maxBit = 32; if (bits == ~mask) { // Find an block of 32 bits that has a unmarked bit @@ -474,18 +475,22 @@ } while (index < maxIndex && data[index] == 0xFFFFFFFF); if (index >= maxIndex) { - // Not found - TRACE("BitmapBlock::FindNextUnmarked(): reached end of block, num " - "bits: %lu\n", fNumBits); - pos = fNumBits; - return; + maxBit = fNumBits & 0x1F; + + if (maxBit == 0) { + // Not found + TRACE("BitmapBlock::FindNextUnmarked(): reached end of block, " + "num bits: %lu\n", fNumBits); + pos = fNumBits; + return; + } + maxBit++; } - bits = B_LENDIAN_TO_HOST_INT32(data[index]); bit = 0; } - for (; bit < 32; ++bit) { + for (; bit < maxBit; ++bit) { // Find the unmarked bit if ((bits >> bit & 1) == 0) { pos = index << 5 | bit; Modified: haiku/trunk/src/add-ons/kernel/file_systems/ext2/BlockAllocator.cpp =================================================================== --- haiku/trunk/src/add-ons/kernel/file_systems/ext2/BlockAllocator.cpp 2010-10-31 15:42:21 UTC (rev 39233) +++ haiku/trunk/src/add-ons/kernel/file_systems/ext2/BlockAllocator.cpp 2010-10-31 17:16:02 UTC (rev 39234) @@ -131,7 +131,7 @@ status = ScanFreeRanges(); if (fGroupDescriptor->FreeBlocks(fVolume->Has64bitFeature()) != fFreeBits) { - TRACE("AllocationBlockGroup::Initialize(): Mismatch between counted " + ERROR("AllocationBlockGroup::Initialize(): Mismatch between counted " "free blocks (%lu) and what is set on the group descriptor " "(%lu)\n", fFreeBits, fGroupDescriptor->FreeBlocks(fVolume->Has64bitFeature())); Modified: haiku/trunk/src/add-ons/kernel/file_systems/ext2/DirectoryIterator.cpp =================================================================== --- haiku/trunk/src/add-ons/kernel/file_systems/ext2/DirectoryIterator.cpp 2010-10-31 15:42:21 UTC (rev 39233) +++ haiku/trunk/src/add-ons/kernel/file_systems/ext2/DirectoryIterator.cpp 2010-10-31 17:16:02 UTC (rev 39234) @@ -502,7 +502,7 @@ return B_NO_MEMORY; ArrayDeleter<uint8> bufferDeleter(buffer); - uint32 firstPhysicalBlock = 0; + off_t firstPhysicalBlock = 0; // Prepare block to hold the first half of the entries and fill the buffer CachedBlock cachedFirst(fVolume); Modified: haiku/trunk/src/add-ons/kernel/file_systems/ext2/DirectoryIterator.h =================================================================== --- haiku/trunk/src/add-ons/kernel/file_systems/ext2/DirectoryIterator.h 2010-10-31 15:42:21 UTC (rev 39233) +++ haiku/trunk/src/add-ons/kernel/file_systems/ext2/DirectoryIterator.h 2010-10-31 17:16:02 UTC (rev 39234) @@ -66,7 +66,7 @@ uint32 fNumBlocks; uint32 fLogicalBlock; - uint32 fPhysicalBlock; + off_t fPhysicalBlock; uint32 fDisplacement; uint32 fPreviousDisplacement; Modified: haiku/trunk/src/add-ons/kernel/file_systems/ext2/HTree.cpp =================================================================== --- haiku/trunk/src/add-ons/kernel/file_systems/ext2/HTree.cpp 2010-10-31 15:42:21 UTC (rev 39233) +++ haiku/trunk/src/add-ons/kernel/file_systems/ext2/HTree.cpp 2010-10-31 17:16:02 UTC (rev 39234) @@ -84,7 +84,7 @@ status_t HTree::PrepareForHash() { - uint32 blockNum; + off_t blockNum; status_t status = fDirectory->FindBlock(0, blockNum); if (status != B_OK) return status; @@ -115,7 +115,7 @@ return _FallbackToLinearIteration(iterator); } - uint32 blockNum; + off_t blockNum; status_t status = fDirectory->FindBlock(0, blockNum); if (status != B_OK) return _FallbackToLinearIteration(iterator); Modified: haiku/trunk/src/add-ons/kernel/file_systems/ext2/HTreeEntryIterator.cpp =================================================================== --- haiku/trunk/src/add-ons/kernel/file_systems/ext2/HTreeEntryIterator.cpp 2010-10-31 15:42:21 UTC (rev 39233) +++ haiku/trunk/src/add-ons/kernel/file_systems/ext2/HTreeEntryIterator.cpp 2010-10-31 17:16:02 UTC (rev 39234) @@ -41,7 +41,7 @@ fCurrentEntry = fFirstEntry; } - TRACE("HTreeEntryIterator::HTreeEntryIterator(): created %p, block %lu, " + TRACE("HTreeEntryIterator::HTreeEntryIterator(): created %p, block %llu, " "entry no. %lu, parent: %p\n", this, fBlockNum, (uint32)fCurrentEntry, fParent); } @@ -100,7 +100,7 @@ if (fLimit != fBlockSize / sizeof(HTreeEntry) - fFirstEntry) { ERROR("HTreeEntryIterator::Init() bad fLimit %lu should be %lu " - "at block %lu\n", (uint32)fLimit, fBlockSize / sizeof(HTreeEntry) + "at block %llu\n", (uint32)fLimit, fBlockSize / sizeof(HTreeEntry) - fFirstEntry, fBlockNum); fCount = fLimit = 0; return B_ERROR; @@ -189,7 +189,7 @@ TRACE("HTreeEntryIterator::Lookup(): Creating a HTree entry iterator " "starting at block: %lu, hash: 0x%lX\n", start->Block(), start->Hash()); - uint32 blockNum; + off_t blockNum; status_t status = fDirectory->FindBlock(start->Block() * fBlockSize, blockNum); if (status != B_OK) @@ -322,7 +322,7 @@ panic("Splitting a HTree node required, but isn't yet fully " "supported\n"); - uint32 physicalBlock; + off_t physicalBlock; status_t status = fDirectory->FindBlock(newBlocksPos, physicalBlock); if (status != B_OK) return status; Modified: haiku/trunk/src/add-ons/kernel/file_systems/ext2/HTreeEntryIterator.h =================================================================== --- haiku/trunk/src/add-ons/kernel/file_systems/ext2/HTreeEntryIterator.h 2010-10-31 15:42:21 UTC (rev 39233) +++ haiku/trunk/src/add-ons/kernel/file_systems/ext2/HTreeEntryIterator.h 2010-10-31 17:16:02 UTC (rev 39234) @@ -53,7 +53,7 @@ uint16 fCurrentEntry; uint32 fBlockSize; - uint32 fBlockNum; + off_t fBlockNum; HTreeEntryIterator* fParent; HTreeEntryIterator* fChild; Modified: haiku/trunk/src/add-ons/kernel/file_systems/ext2/Inode.cpp =================================================================== --- haiku/trunk/src/add-ons/kernel/file_systems/ext2/Inode.cpp 2010-10-31 15:42:21 UTC (rev 39233) +++ haiku/trunk/src/add-ons/kernel/file_systems/ext2/Inode.cpp 2010-10-31 17:16:02 UTC (rev 39234) @@ -217,7 +217,7 @@ status_t -Inode::FindBlock(off_t offset, uint32& block) +Inode::FindBlock(off_t offset, off_t& block, uint32 *_count) { uint32 perBlock = fVolume->BlockSize() / 4; uint32 perIndirectBlock = perBlock * perBlock; @@ -235,6 +235,13 @@ // direct blocks block = B_LENDIAN_TO_HOST_INT32(Node().stream.direct[index]); ASSERT(block != 0); + if (_count) { + *_count = 1; + uint32 nextBlock = block; + while (++index < EXT2_DIRECT_BLOCKS + && Node().stream.direct[index] == ++nextBlock) + (*_count)++; + } } else if ((index -= EXT2_DIRECT_BLOCKS) < perBlock) { // indirect blocks CachedBlock cached(fVolume); @@ -245,6 +252,13 @@ block = B_LENDIAN_TO_HOST_INT32(indirectBlocks[index]); ASSERT(block != 0); + if (_count) { + *_count = 1; + uint32 nextBlock = block; + while (++index < perBlock + && indirectBlocks[index] == ++nextBlock) + (*_count)++; + } } else if ((index -= perBlock) < perIndirectBlock) { // double indirect blocks CachedBlock cached(fVolume); @@ -265,6 +279,13 @@ block = B_LENDIAN_TO_HOST_INT32( indirectBlocks[index & (perBlock - 1)]); + if (_count) { + *_count = 1; + uint32 nextBlock = block; + while (((++index & (perBlock - 1)) != 0) + && indirectBlocks[index & (perBlock - 1)] == ++nextBlock) + (*_count)++; + } } ASSERT(block != 0); } else if ((index -= perIndirectBlock) / perBlock < perIndirectBlock) { @@ -297,6 +318,14 @@ block = B_LENDIAN_TO_HOST_INT32( indirectBlocks[index & (perBlock - 1)]); + if (_count) { + *_count = 1; + uint32 nextBlock = block; + while (((++index & (perBlock - 1)) != 0) + && indirectBlocks[index & (perBlock - 1)] + == ++nextBlock) + (*_count)++; + } } } ASSERT(block != 0); @@ -306,7 +335,8 @@ return B_ERROR; } - TRACE("inode %Ld: FindBlock(offset %lld): %lu\n", ID(), offset, block); + TRACE("inode %Ld: FindBlock(offset %lld): %lld %ld\n", ID(), offset, block, + _count != NULL ? *_count : 1); return B_OK; } @@ -398,7 +428,7 @@ return B_OK; } - TRACE("Inode::WriteAt(): Performing write: %p, %ld, %p, %ld\n", + TRACE("Inode::WriteAt(): Performing write: %p, %lld, %p, %ld\n", FileCache(), pos, buffer, *_length); status_t status = file_cache_write(FileCache(), NULL, pos, buffer, _length); @@ -424,7 +454,7 @@ size = end - start; TRACE("Inode::FillGapWithZeros(): Calling file_cache_write(%p, NULL, " - "%lld, NULL, &(%lld) = %p)\n", fCache, start, size, &size); + "%lld, NULL, &(%ld) = %p)\n", fCache, start, size, &size); status_t status = file_cache_write(fCache, NULL, start, NULL, &size); if (status != B_OK) @@ -485,7 +515,7 @@ if (status != B_OK) return status; - uint32 blockNum; + off_t blockNum; status = FindBlock(0, blockNum); if (status != B_OK) return status; @@ -657,14 +687,18 @@ TRACE("Inode::Create(): Allocating inode\n"); ino_t id; status = volume->AllocateInode(transaction, parent, mode, id); - if (status != B_OK) + if (status != B_OK) { + ERROR("Inode::Create(): AllocateInode() failed\n"); return status; + } if (entries != NULL) { size_t nameLength = strlen(name); status = entries->AddEntry(transaction, name, nameLength, id, type); - if (status != B_OK) + if (status != B_OK) { + ERROR("Inode::Create(): AddEntry() failed\n"); return status; + } } TRACE("Inode::Create(): Creating inode\n"); @@ -696,8 +730,10 @@ if (inode->IsDirectory()) { TRACE("Inode::Create(): Initializing directory\n"); status = inode->InitDirectory(transaction, parent); - if (status != B_OK) + if (status != B_OK) { + ERROR("Inode::Create(): InitDirectory() failed\n"); return status; + } } // TODO: Maybe it can be better @@ -776,13 +812,13 @@ return B_OK; } - TRACE("Inode::EnableFileCache(): Creating file cache: %ld, %ld, %lld\n", + TRACE("Inode::EnableFileCache(): Creating file cache: %ld, %lld, %lld\n", fVolume->ID(), ID(), Size()); fCache = file_cache_create(fVolume->ID(), ID(), Size()); fMap = file_map_create(fVolume->ID(), ID(), Size()); if (fCache == NULL) { - TRACE("Inode::EnableFileCache(): Failed to create file cache\n"); + ERROR("Inode::EnableFileCache(): Failed to create file cache\n"); fCached = false; return B_ERROR; } Modified: haiku/trunk/src/add-ons/kernel/file_systems/ext2/Inode.h =================================================================== --- haiku/trunk/src/add-ons/kernel/file_systems/ext2/Inode.h 2010-10-31 15:42:21 UTC (rev 39233) +++ haiku/trunk/src/add-ons/kernel/file_systems/ext2/Inode.h 2010-10-31 17:16:02 UTC (rev 39234) @@ -79,7 +79,8 @@ //::Volume* _Volume() const { return fVolume; } Volume* GetVolume() const { return fVolume; } - status_t FindBlock(off_t offset, uint32& block); + status_t FindBlock(off_t offset, off_t& block, + uint32 *_count = NULL); status_t ReadAt(off_t pos, uint8 *buffer, size_t *length); status_t WriteAt(Transaction& transaction, off_t pos, const uint8* buffer, size_t* length); Modified: haiku/trunk/src/add-ons/kernel/file_systems/ext2/InodeAllocator.cpp =================================================================== --- haiku/trunk/src/add-ons/kernel/file_systems/ext2/InodeAllocator.cpp 2010-10-31 15:42:21 UTC (rev 39233) +++ haiku/trunk/src/add-ons/kernel/file_systems/ext2/InodeAllocator.cpp 2010-10-31 17:16:02 UTC (rev 39234) @@ -22,6 +22,7 @@ #else # define TRACE(x...) ; #endif +#define ERROR(x...) dprintf("\33[34mext2:\33[0m " x) InodeAllocator::InodeAllocator(Volume* volume) @@ -98,11 +99,15 @@ ext2_block_group* group; status_t status = fVolume->GetBlockGroup(blockGroup, &group); - if (status != B_OK) + if (status != B_OK) { + ERROR("InodeAllocator::_Allocate() GetBlockGroup() failed\n"); return status; + } uint32 freeInodes = group->FreeInodes(fVolume->Has64bitFeature()); if (freeInodes != 0) { + TRACE("InodeAllocator::_Allocate() freeInodes %ld bitmap %lld\n", + freeInodes, group->InodeBitmap(fVolume->Has64bitFeature())); group->SetFreeInodes(freeInodes - 1, fVolume->Has64bitFeature()); if (isDirectory) group->SetUsedDirectories(group->UsedDirectories( @@ -123,11 +128,14 @@ ext2_block_group* group; status_t status = fVolume->GetBlockGroup(blockGroup, &group); - if (status != B_OK) + if (status != B_OK) { + ERROR("InodeAllocator::_Allocate() GetBlockGroup() failed\n"); return status; + } uint32 freeInodes = group->FreeInodes(fVolume->Has64bitFeature()); if (freeInodes != 0) { + TRACE("InodeAllocator::_Allocate() freeInodes %ld\n", freeInodes); group->SetFreeInodes(freeInodes - 1, fVolume->Has64bitFeature()); @@ -142,18 +150,19 @@ lastBlockGroup = preferredBlockGroup; } + ERROR("InodeAllocator::_Allocate() device is full\n"); return B_DEVICE_FULL; } status_t -InodeAllocator::_MarkInBitmap(Transaction& transaction, uint32 bitmapBlock, +InodeAllocator::_MarkInBitmap(Transaction& transaction, off_t bitmapBlock, uint32 blockGroup, uint32 numInodes, ino_t& id) { BitmapBlock inodeBitmap(fVolume, numInodes); if (!inodeBitmap.SetToWritable(transaction, bitmapBlock)) { - TRACE("Unable to open inode bitmap (block number: %lu) for block group " + ERROR("Unable to open inode bitmap (block number: %llu) for block group " "%lu\n", bitmapBlock, blockGroup); return B_IO_ERROR; } @@ -162,14 +171,14 @@ inodeBitmap.FindNextUnmarked(pos); if (pos == inodeBitmap.NumBits()) { - TRACE("Even though the block group %lu indicates there are free " + ERROR("Even though the block group %lu indicates there are free " "inodes, no unmarked bit was found in the inode bitmap at block " - "%lu.", blockGroup, bitmapBlock); + "%llu (numInodes %lu).\n", blockGroup, bitmapBlock, numInodes); return B_ERROR; } if (!inodeBitmap.Mark(pos, 1)) { - TRACE("Failed to mark bit %lu at bitmap block %lu\n", pos, + ERROR("Failed to mark bit %lu at bitmap block %llu\n", pos, bitmapBlock); return B_BAD_DATA; } @@ -181,19 +190,19 @@ status_t -InodeAllocator::_UnmarkInBitmap(Transaction& transaction, uint32 bitmapBlock, +InodeAllocator::_UnmarkInBitmap(Transaction& transaction, off_t bitmapBlock, uint32 numInodes, ino_t id) { BitmapBlock inodeBitmap(fVolume, numInodes); if (!inodeBitmap.SetToWritable(transaction, bitmapBlock)) { - TRACE("Unable to open inode bitmap at block %lu\n", bitmapBlock); + TRACE("Unable to open inode bitmap at block %llu\n", bitmapBlock); return B_IO_ERROR; } uint32 pos = (id - 1) % fVolume->InodesPerGroup(); if (!inodeBitmap.Unmark(pos, 1)) { - TRACE("Unable to unmark bit %lu in inode bitmap block %lu\n", pos, + TRACE("Unable to unmark bit %lu in inode bitmap block %llu\n", pos, bitmapBlock); return B_BAD_DATA; } Modified: haiku/trunk/src/add-ons/kernel/file_systems/ext2/InodeAllocator.h =================================================================== --- haiku/trunk/src/add-ons/kernel/file_systems/ext2/InodeAllocator.h 2010-10-31 15:42:21 UTC (rev 39233) +++ haiku/trunk/src/add-ons/kernel/file_systems/ext2/InodeAllocator.h 2010-10-31 17:16:02 UTC (rev 39234) @@ -32,10 +32,10 @@ uint32 prefferedBlockGroup, bool isDirectory, ino_t& id); status_t _MarkInBitmap(Transaction& transaction, - uint32 bitmapBlock, uint32 blockGroup, + off_t bitmapBlock, uint32 blockGroup, uint32 numInodes, ino_t& id); status_t _UnmarkInBitmap(Transaction& transaction, - uint32 bitmapBlock, uint32 numInodes, ino_t id); + off_t bitmapBlock, uint32 numInodes, ino_t id); Volume* fVolume; Modified: haiku/trunk/src/add-ons/kernel/file_systems/ext2/InodeJournal.cpp =================================================================== --- haiku/trunk/src/add-ons/kernel/file_systems/ext2/InodeJournal.cpp 2010-10-31 15:42:21 UTC (rev 39233) +++ haiku/trunk/src/add-ons/kernel/file_systems/ext2/InodeJournal.cpp 2010-10-31 17:16:02 UTC (rev 39234) @@ -84,7 +84,7 @@ status_t -InodeJournal::MapBlock(uint32 logical, uint32& physical) +InodeJournal::MapBlock(off_t logical, off_t& physical) { TRACE("InodeJournal::MapBlock()\n"); return fInode->FindBlock(logical * fBlockSize, physical); Modified: haiku/trunk/src/add-ons/kernel/file_systems/ext2/InodeJournal.h =================================================================== --- haiku/trunk/src/add-ons/kernel/file_systems/ext2/InodeJournal.h 2010-10-31 15:42:21 UTC (rev 39233) +++ haiku/trunk/src/add-ons/kernel/file_systems/ext2/InodeJournal.h 2010-10-31 17:16:02 UTC (rev 39234) @@ -20,7 +20,7 @@ status_t InitCheck(); - status_t MapBlock(uint32 logical, uint32& physical); + status_t MapBlock(off_t logical, off_t& physical); private: Inode* fInode; status_t fInitStatus; Modified: haiku/trunk/src/add-ons/kernel/file_systems/ext2/Journal.cpp =================================================================== --- haiku/trunk/src/add-ons/kernel/file_systems/ext2/Journal.cpp 2010-10-31 15:42:21 UTC (rev 39233) +++ haiku/trunk/src/add-ons/kernel/file_systems/ext2/Journal.cpp 2010-10-31 17:16:02 UTC (rev 39234) @@ -26,6 +26,7 @@ #else # define TRACE(x...) ; #endif +#define ERROR(x...) dprintf("\33[34mext2:\33[0m " x) class LogEntry : public DoublyLinkedListLinkImpl<LogEntry> { @@ -296,7 +297,7 @@ status_t -Journal::MapBlock(uint32 logical, uint32& physical) +Journal::MapBlock(off_t logical, off_t& physical) { TRACE("Journal::MapBlock()\n"); physical = logical; @@ -394,7 +395,7 @@ logBlock = _WrapAroundLog(logBlock + 1); - uint32 physicalBlock; + off_t physicalBlock; status = MapBlock(logBlock, physicalBlock); if (status != B_OK) return status; @@ -402,7 +403,7 @@ off_t logOffset = physicalBlock * fBlockSize; TRACE("Journal::_WritePartialTransactionToLog(): Writing from memory: " - "%p, to disk: %ld\n", finalData, (long)logOffset); + "%p, to disk: %llu\n", finalData, logOffset); size_t written = write_pos(fJournalVolume->Device(), logOffset, finalData, fBlockSize); if (written != fBlockSize) { @@ -426,15 +427,15 @@ --tag; tag->SetLastTagFlag(); - uint32 physicalBlock; + off_t physicalBlock; status = MapBlock(descriptorBlockPos, physicalBlock); if (status != B_OK) return status; off_t descriptorBlockOffset = physicalBlock * fBlockSize; - TRACE("Journal::_WritePartialTransactionToLog(): Writing to: %ld\n", - (long)descriptorBlockOffset); + TRACE("Journal::_WritePartialTransactionToLog(): Writing to: %lld\n", + descriptorBlockOffset); size_t written = write_pos(fJournalVolume->Device(), descriptorBlockOffset, descriptorBlock, fBlockSize); if (written != fBlockSize) { @@ -569,7 +570,7 @@ // written. When it recovery reaches where the first commit should be // and doesn't find it, it considers it found the end of the log. - uint32 physicalBlock; + off_t physicalBlock; status = MapBlock(logBlock, physicalBlock); if (status != B_OK) return status; @@ -577,7 +578,7 @@ off_t logOffset = physicalBlock * fBlockSize; TRACE("Journal::_WriteTransactionToLog(): Writting commit block to " - "%ld\n", (long)logOffset); + "%lld\n", logOffset); off_t written = write_pos(fJournalVolume->Device(), logOffset, commitBlock, fBlockSize); if (written != fBlockSize) { @@ -592,15 +593,14 @@ } // Transaction will enter the Commit state - uint32 physicalBlock; + off_t physicalBlock; status = MapBlock(commitBlockPos, physicalBlock); if (status != B_OK) return status; off_t logOffset = physicalBlock * fBlockSize; - TRACE("Journal::_WriteTansactionToLog(): Writing to: %ld\n", - (long)logOffset); + TRACE("Journal::_WriteTransactionToLog(): Writing to: %lld\n", logOffset); off_t written = write_pos(fJournalVolume->Device(), logOffset, commitBlock, fBlockSize); if (written != fBlockSize) { @@ -634,8 +634,8 @@ if (status == B_OK && _FullTransactionSize() > fLogSize) { // If the transaction is too large after writing, there is no way to // recover, so let this transaction fail. - dprintf("transaction too large (%d blocks, log size %d)!\n", - (int)_FullTransactionSize(), (int)fLogSize); + ERROR("transaction too large (%ld blocks, log size %ld)!\n", + _FullTransactionSize(), fLogSize); return B_BUFFER_OVERFLOW; } } else { @@ -652,7 +652,7 @@ Journal::_SaveSuperBlock() { TRACE("Journal::_SaveSuperBlock()\n"); - uint32 physicalBlock; + off_t physicalBlock; status_t status = MapBlock(0, physicalBlock); if (status != B_OK) return status; @@ -669,7 +669,7 @@ superblock.SetFirstCommitID(fFirstCommitID); superblock.SetLogStart(fLogStart); - TRACE("Journal::SaveSuperBlock(): Write to %ld\n", (long)superblockPos); + TRACE("Journal::SaveSuperBlock(): Write to %lld\n", superblockPos); size_t bytesWritten = write_pos(fJournalVolume->Device(), superblockPos, &superblock, sizeof(superblock)); @@ -686,13 +686,13 @@ Journal::_LoadSuperBlock() { TRACE("Journal::_LoadSuperBlock()\n"); - uint32 superblockPos; + off_t superblockPos; status_t status = MapBlock(0, superblockPos); if (status != B_OK) return status; - TRACE("Journal::_LoadSuperBlock(): super block physical block: %lu\n", + TRACE("Journal::_LoadSuperBlock(): super block physical block: %llu\n", superblockPos); JournalSuperBlock superblock; @@ -700,12 +700,12 @@ * fJournalVolume->BlockSize(), &superblock, sizeof(superblock)); if (bytesRead != sizeof(superblock)) { - TRACE("Journal::_LoadSuperBlock(): failed to read superblock\n"); + ERROR("Journal::_LoadSuperBlock(): failed to read superblock\n"); return B_IO_ERROR; } if (!superblock.header.CheckMagic()) { - TRACE("Journal::_LoadSuperBlock(): Invalid superblock magic %lX\n", + ERROR("Journal::_LoadSuperBlock(): Invalid superblock magic %lX\n", superblock.header.Magic()); return B_BAD_VALUE; } @@ -717,7 +717,7 @@ TRACE("Journal::_LoadSuperBlock(): Journal superblock version 2\n"); fVersion = 2; } else { - TRACE("Journal::_LoadSuperBlock(): Invalid superblock version\n"); + ERROR("Journal::_LoadSuperBlock(): Invalid superblock version\n"); return B_BAD_VALUE; } @@ -725,7 +725,7 @@ status = _CheckFeatures(&superblock); if (status != B_OK) { - TRACE("Journal::_LoadSuperBlock(): Unsupported features\n"); + ERROR("Journal::_LoadSuperBlock(): Unsupported features\n"); return status; } } @@ -833,7 +833,7 @@ JournalHeader* header; uint32 nextCommitID = fFirstCommitID; uint32 nextBlock = fLogStart; - uint32 nextBlockPos; + off_t nextBlockPos; status_t status = MapBlock(nextBlock, nextBlockPos); if (status != B_OK) @@ -889,7 +889,7 @@ JournalHeader* header; uint32 nextCommitID = fFirstCommitID; uint32 nextBlock = fLogStart; - uint32 nextBlockPos; + off_t nextBlockPos; status_t status = MapBlock(nextBlock, nextBlockPos); if (status != B_OK) @@ -951,7 +951,7 @@ uint32 nextCommitID = fFirstCommitID; uint32 nextBlock = fLogStart; - uint32 nextBlockPos; + off_t nextBlockPos; status_t status = MapBlock(nextBlock, nextBlockPos); if (status != B_OK) @@ -973,8 +973,8 @@ while (nextCommitID < lastCommitID) { if (!header->CheckMagic() || header->Sequence() != nextCommitID) { - // Somehow the log is different than the expexted - TRACE("Journal::_RecoverPassReplay(): Wierd problem with block\n"); + // Somehow the log is different than the expected + ERROR("Journal::_RecoverPassReplay(): Weird problem with block\n"); return B_ERROR; } Modified: haiku/trunk/src/add-ons/kernel/file_systems/ext2/Journal.h =================================================================== --- haiku/trunk/src/add-ons/kernel/file_systems/ext2/Journal.h 2010-10-31 15:42:21 UTC (rev 39233) +++ haiku/trunk/src/add-ons/kernel/file_systems/ext2/Journal.h 2010-10-31 17:16:02 UTC (rev 39234) @@ -173,7 +173,7 @@ bool separateSubTransactions); virtual status_t Unlock(Transaction* owner, bool success); - virtual status_t MapBlock(uint32 logical, uint32& physical); + virtual status_t MapBlock(off_t logical, off_t& physical); inline uint32 FreeLogBlocks() const; status_t FlushLogAndBlocks(); Modified: haiku/trunk/src/add-ons/kernel/file_systems/ext2/Volume.cpp =================================================================== --- haiku/trunk/src/add-ons/kernel/file_systems/ext2/Volume.cpp 2010-10-31 15:42:21 UTC (rev 39233) +++ haiku/trunk/src/add-ons/kernel/file_systems/ext2/Volume.cpp 2010-10-31 17:16:02 UTC (rev 39234) @@ -400,8 +400,12 @@ TRACE("Volume::Mount(): Initialize block allocator\n"); status = fBlockAllocator.Initialize(); if (status != B_OK) { - FATAL("could not initialize block allocator!\n"); - return status; + 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); } // ready Modified: haiku/trunk/src/add-ons/kernel/file_systems/ext2/ext2.h =================================================================== --- haiku/trunk/src/add-ons/kernel/file_systems/ext2/ext2.h 2010-10-31 15:42:21 UTC (rev 39233) +++ haiku/trunk/src/add-ons/kernel/file_systems/ext2/ext2.h 2010-10-31 17:16:02 UTC (rev 39234) @@ -547,6 +547,7 @@ #define EXT2_INODE_BTREE 0x00001000 #define EXT2_INODE_INDEXED 0x00001000 #define EXT2_INODE_HUGE_FILE 0x00040000 +#define EXT2_INODE_EXTENTS 0x00080000 #define EXT2_NAME_LENGTH 255 Modified: haiku/trunk/src/add-ons/kernel/file_systems/ext2/kernel_interface.cpp =================================================================== --- haiku/trunk/src/add-ons/kernel/file_systems/ext2/kernel_interface.cpp 2010-10-31 15:42:21 UTC (rev 39233) +++ haiku/trunk/src/add-ons/kernel/file_systems/ext2/kernel_interface.cpp 2010-10-31 17:16:02 UTC (rev 39234) @@ -186,8 +186,8 @@ Volume* volume = (Volume*)_volume->private_volume; if (id < 2 || id > volume->NumInodes()) { - dprintf("ext2: inode at %Ld requested!\n", id); - return B_ERROR; + dprintf("ext2: invalid inode id %lld requested!\n", id); + return B_BAD_VALUE; } Inode* inode = new Inode(volume, id); @@ -397,15 +397,17 @@ size_t index = 0, max = *_count; while (true) { - uint32 block; - status_t status = inode->FindBlock(offset, block); + off_t block; + uint32 count = 1; + status_t status = inode->FindBlock(offset, block, &count); if (status != B_OK) return status; - off_t blockOffset = (off_t)block << volume->BlockShift(); - uint32 blockLength = volume->BlockSize(); + off_t blockOffset = block << volume->BlockShift(); + uint32 blockLength = volume->BlockSize() * count; - if (index > 0 && (vecs[index - 1].offset == blockOffset - blockLength + if (index > 0 && (vecs[index - 1].offset + == blockOffset - vecs[index - 1].length || (vecs[index - 1].offset == -1 && block == 0))) { vecs[index - 1].length += blockLength; } else { @@ -426,11 +428,12 @@ } offset += blockLength; + size -= blockLength; if (size <= vecs[index - 1].length || offset >= inode->Size()) { // We're done! *_count = index; - TRACE("ext2_get_file_map for inode %ld\n", (long)inode->ID()); + TRACE("ext2_get_file_map for inode %lld\n", inode->ID()); return B_OK; } } @@ -750,7 +753,7 @@ ino_t id; status = Inode::Create(transaction, directory, name, S_SYMLINK | 0777, 0, (uint8)EXT2_TYPE_SYMLINK, NULL, &id, &link); - if (status < B_OK) + if (status != B_OK) return status; // TODO: We have to prepare the link before publishing? @@ -925,7 +928,7 @@ if (status != B_OK) return B_IO_ERROR; - uint32 blockNum; + off_t blockNum; status = parent->FindBlock(0, blockNum); if (status != B_OK) return status;