* 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


git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@39234 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Jérôme Duval
2010-10-31 17:16:02 +00:00
parent ca093f29a9
commit 583f39e94d
18 changed files with 140 additions and 81 deletions
@@ -463,6 +463,7 @@ BitmapBlock::FindNextUnmarked(uint32& pos)
"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 @@ BitmapBlock::FindNextUnmarked(uint32& pos)
} 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;
@@ -131,7 +131,7 @@ AllocationBlockGroup::Initialize(Volume* volume, uint32 blockGroup,
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()));
@@ -502,7 +502,7 @@ DirectoryIterator::_SplitIndexedBlock(Transaction& transaction,
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);
@@ -66,7 +66,7 @@ protected:
uint32 fNumBlocks;
uint32 fLogicalBlock;
uint32 fPhysicalBlock;
off_t fPhysicalBlock;
uint32 fDisplacement;
uint32 fPreviousDisplacement;
@@ -84,7 +84,7 @@ HTree::~HTree()
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 @@ HTree::Lookup(const char* name, DirectoryIterator** iterator)
return _FallbackToLinearIteration(iterator);
}
uint32 blockNum;
off_t blockNum;
status_t status = fDirectory->FindBlock(0, blockNum);
if (status != B_OK)
return _FallbackToLinearIteration(iterator);
@@ -41,7 +41,7 @@ HTreeEntryIterator::HTreeEntryIterator(off_t offset, Inode* directory)
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 @@ HTreeEntryIterator::Init()
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 @@ HTreeEntryIterator::Lookup(uint32 hash, int indirections,
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 @@ HTreeEntryIterator::InsertEntry(Transaction& transaction, uint32 hash,
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;
@@ -53,7 +53,7 @@ private:
uint16 fCurrentEntry;
uint32 fBlockSize;
uint32 fBlockNum;
off_t fBlockNum;
HTreeEntryIterator* fParent;
HTreeEntryIterator* fChild;
+46 -10
View File
@@ -217,7 +217,7 @@ Inode::CheckPermissions(int accessMode) const
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 @@ Inode::FindBlock(off_t offset, uint32& block)
// 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 @@ Inode::FindBlock(off_t offset, uint32& block)
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 @@ Inode::FindBlock(off_t offset, uint32& block)
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 @@ Inode::FindBlock(off_t offset, uint32& block)
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 @@ Inode::FindBlock(off_t offset, uint32& block)
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 @@ Inode::WriteAt(Transaction& transaction, off_t pos, const uint8* buffer,
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 @@ Inode::FillGapWithZeros(off_t start, off_t end)
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 @@ Inode::InitDirectory(Transaction& transaction, Inode* parent)
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 @@ Inode::Create(Transaction& transaction, Inode* parent, const char* name,
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 @@ Inode::Create(Transaction& transaction, Inode* parent, const char* name,
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 @@ Inode::EnableFileCache()
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;
}
+2 -1
View File
@@ -79,7 +79,8 @@ public:
//::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);
@@ -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 @@ InodeAllocator::_Allocate(Transaction& transaction, uint32 preferredBlockGroup,
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 @@ InodeAllocator::_Allocate(Transaction& transaction, uint32 preferredBlockGroup,
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 @@ InodeAllocator::_Allocate(Transaction& transaction, uint32 preferredBlockGroup,
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 @@ InodeAllocator::_MarkInBitmap(Transaction& transaction, uint32 bitmapBlock,
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 @@ InodeAllocator::_MarkInBitmap(Transaction& transaction, uint32 bitmapBlock,
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;
}
@@ -32,10 +32,10 @@ private:
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;
@@ -84,7 +84,7 @@ InodeJournal::InitCheck()
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);
@@ -20,7 +20,7 @@ public:
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;
@@ -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 @@ Journal::Unlock(Transaction* owner, bool success)
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 @@ Journal::_WritePartialTransactionToLog(JournalHeader* descriptorBlock,
logBlock = _WrapAroundLog(logBlock + 1);
uint32 physicalBlock;
off_t physicalBlock;
status = MapBlock(logBlock, physicalBlock);
if (status != B_OK)
return status;
@@ -402,7 +403,7 @@ Journal::_WritePartialTransactionToLog(JournalHeader* descriptorBlock,
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 @@ Journal::_WritePartialTransactionToLog(JournalHeader* descriptorBlock,
--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 @@ Journal::_WriteTransactionToLog()
// 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 @@ Journal::_WriteTransactionToLog()
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 @@ Journal::_WriteTransactionToLog()
}
// 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 @@ Journal::_WriteTransactionToLog()
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 @@ status_t
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 @@ Journal::_SaveSuperBlock()
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 @@ status_t
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 @@ Journal::_LoadSuperBlock()
* 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 @@ Journal::_LoadSuperBlock()
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 @@ Journal::_LoadSuperBlock()
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 @@ Journal::_RecoverPassScan(uint32& lastCommitID)
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 @@ Journal::_RecoverPassRevoke(uint32 lastCommitID)
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 @@ Journal::_RecoverPassReplay(uint32 lastCommitID)
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 @@ Journal::_RecoverPassReplay(uint32 lastCommitID)
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;
}
@@ -173,7 +173,7 @@ public:
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();
@@ -400,8 +400,12 @@ Volume::Mount(const char* deviceName, uint32 flags)
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
@@ -547,6 +547,7 @@ struct ext2_inode {
#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
@@ -186,8 +186,8 @@ ext2_get_vnode(fs_volume* _volume, ino_t id, fs_vnode* _node, int* _type,
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 @@ ext2_get_file_map(fs_volume* _volume, fs_vnode* _node, off_t offset,
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 @@ ext2_get_file_map(fs_volume* _volume, fs_vnode* _node, off_t offset,
}
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 @@ ext2_create_symlink(fs_volume* _volume, fs_vnode* _directory, const char* name,
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 @@ ext2_rename(fs_volume* _volume, fs_vnode* _oldDir, const char* oldName,
if (status != B_OK)
return B_IO_ERROR;
uint32 blockNum;
off_t blockNum;
status = parent->FindBlock(0, blockNum);
if (status != B_OK)
return status;