* 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:
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user