xfs: Read Leaf Directories

We can read leaf directories now.

Change-Id: I4276c264f9e72013fa99c898a8332cb363e9ab3e
Reviewed-on: https://review.haiku-os.org/c/haiku/+/3035
Reviewed-by: Adrien Destugues <pulkomandy@gmail.com>
This commit is contained in:
CruxBox 2020-07-15 14:16:40 +05:30 committed by Adrien Destugues
parent bd0708fd41
commit 0dc6805e00
2 changed files with 55 additions and 17 deletions

View File

@ -93,7 +93,7 @@ LeafDirectory::FillMapEntry(int num, ExtentMapEntry* fMap)
status_t
LeafDirectory::FillBuffer(int type, char* blockBuffer)
LeafDirectory::FillBuffer(int type, char* blockBuffer, int howManyBlocksFurthur)
{
TRACE("FILLBUFFER\n");
ExtentMapEntry* map;
@ -116,8 +116,11 @@ LeafDirectory::FillBuffer(int type, char* blockBuffer)
Volume* volume = fInode->GetVolume();
xfs_agblock_t numberOfBlocksInAg = volume->AgBlocks();
uint64 agNo = FSBLOCKS_TO_AGNO(map->br_startblock, volume);
uint64 agBlockNo = FSBLOCKS_TO_AGBLOCKNO(map->br_startblock, volume);
uint64 agNo =
FSBLOCKS_TO_AGNO(map->br_startblock + howManyBlocksFurthur, volume);
uint64 agBlockNo =
FSBLOCKS_TO_AGBLOCKNO(map->br_startblock + howManyBlocksFurthur, volume);
xfs_fsblock_t blockToRead = FSBLOCKS_TO_BASICBLOCKS(volume->BlockLog(),
(agNo * numberOfBlocksInAg + agBlockNo));
@ -168,7 +171,7 @@ LeafDirectory::FirstLeaf()
TRACE("LeafDirectory: FirstLeaf\n");
if (fLeafBuffer == NULL) {
ASSERT(fLeafMap != NULL);
status_t status = FillBuffer(LEAF, fLeafBuffer);
status_t status = FillBuffer(LEAF, fLeafBuffer, 0);
if (status != B_OK)
return NULL;
}
@ -189,6 +192,21 @@ LeafDirectory::EntrySize(int len) const
}
void
LeafDirectory::SearchAndFillDataMap(int blockNo)
{
int len = fInode->DataExtentsCount();
for(int i = 0; i < len - 1; i++) {
FillMapEntry(i, fDataMap);
if (fDataMap->br_startoff <= blockNo
&& (blockNo <= fDataMap->br_startoff + fDataMap->br_blockcount - 1))
// Map found
return;
}
}
status_t
LeafDirectory::GetNext(char* name, size_t* length, xfs_ino_t* ino)
{
@ -196,7 +214,7 @@ LeafDirectory::GetNext(char* name, size_t* length, xfs_ino_t* ino)
status_t status;
if (fDataBuffer == NULL) {
status = FillBuffer(DATA, fDataBuffer);
status = FillBuffer(DATA, fDataBuffer, 0);
if (status != B_OK)
return status;
}
@ -205,25 +223,42 @@ LeafDirectory::GetNext(char* name, size_t* length, xfs_ino_t* ino)
void* entry = (void*)((ExtentDataHeader*)fDataBuffer + 1);
// This could be an unused entry so we should check
if (BLOCKNO_FROM_ADDRESS(fOffset, volume) == fCurBlockNumber
&& fOffset != 0)
uint32 blockNoFromAddress = BLOCKNO_FROM_ADDRESS(fOffset, volume);
if (fOffset != 0 && blockNoFromAddress == fCurBlockNumber)
entry = (void*)(fDataBuffer
+ BLOCKOFFSET_FROM_ADDRESS(fOffset, fInode));
// This gets us a little faster to the next entry
ExtentLeafHeader* leafHeader = (ExtentLeafHeader*)(void*)fLeafBuffer;
uint32 curDirectorySize = fInode->Size();
while (fOffset != curDirectorySize) {
TRACE("fOffset:(%d)\n", fOffset);
if (fCurBlockNumber != BLOCKNO_FROM_ADDRESS(fOffset, volume)) {
fCurBlockNumber = BLOCKNO_FROM_ADDRESS(fOffset, volume);
FillMapEntry(fCurBlockNumber, fDataMap);
status = FillBuffer(DATA, fDataBuffer);
blockNoFromAddress = BLOCKNO_FROM_ADDRESS(fOffset, volume);
TRACE("fOffset:(%d), blockNoFromAddress:(%d)\n",
fOffset, blockNoFromAddress);
if (fCurBlockNumber != blockNoFromAddress
&& blockNoFromAddress > fDataMap->br_startoff
&& blockNoFromAddress
<= fDataMap->br_startoff + fDataMap->br_blockcount - 1) {
// When the block is mapped in the same data
// map entry but is not the first block
status = FillBuffer(DATA, fDataBuffer,
blockNoFromAddress - fDataMap->br_startoff);
if (status != B_OK)
return status;
entry = (void*)((ExtentDataHeader*)fDataBuffer + 1);
fOffset = fOffset + sizeof(ExtentDataHeader);
fCurBlockNumber = blockNoFromAddress;
} else if (fCurBlockNumber != blockNoFromAddress) {
// When the block isn't mapped in the current data map entry
SearchAndFillDataMap(blockNoFromAddress);
status = FillBuffer(DATA, fDataBuffer,
blockNoFromAddress - fDataMap->br_startoff);
if (status != B_OK)
return status;
entry = (void*)((ExtentDataHeader*)fDataBuffer + 1);
fOffset = fOffset + sizeof(ExtentDataHeader);
fCurBlockNumber = blockNoFromAddress;
}
ExtentUnusedEntry* unusedEntry = (ExtentUnusedEntry*)entry;
@ -274,7 +309,7 @@ LeafDirectory::Lookup(const char* name, size_t length, xfs_ino_t* ino)
status_t status;
if (fLeafBuffer == NULL)
status = FillBuffer(LEAF, fLeafBuffer);
status = FillBuffer(LEAF, fLeafBuffer, 0);
if (status != B_OK)
return status;
@ -323,8 +358,9 @@ LeafDirectory::Lookup(const char* name, size_t length, xfs_ino_t* ino)
TRACE("DataBlockNumber:(%d), offset:(%d)\n", dataBlockNumber, offset);
if (dataBlockNumber != fCurBlockNumber) {
fCurBlockNumber = dataBlockNumber;
FillMapEntry(dataBlockNumber, fDataMap);
status = FillBuffer(DATA, fDataBuffer);
SearchAndFillDataMap(dataBlockNumber);
status = FillBuffer(DATA, fDataBuffer,
dataBlockNumber - fDataMap->br_startoff);
if (status != B_OK)
return B_OK;
}

View File

@ -52,7 +52,9 @@ public:
status_t Init();
bool IsLeafType();
void FillMapEntry(int num, ExtentMapEntry* map);
status_t FillBuffer(int type, char* buffer);
status_t FillBuffer(int type, char* buffer,
int howManyBlocksFurthur);
void SearchAndFillDataMap(int blockNo);
ExtentLeafEntry* FirstLeaf();
xfs_ino_t GetIno();
uint32 GetOffsetFromAddress(uint32 address);