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 <[email protected]>
This commit is contained in:
committed by
Adrien Destugues
parent
bd0708fd41
commit
0dc6805e00
@@ -93,7 +93,7 @@ LeafDirectory::FillMapEntry(int num, ExtentMapEntry* fMap)
|
|||||||
|
|
||||||
|
|
||||||
status_t
|
status_t
|
||||||
LeafDirectory::FillBuffer(int type, char* blockBuffer)
|
LeafDirectory::FillBuffer(int type, char* blockBuffer, int howManyBlocksFurthur)
|
||||||
{
|
{
|
||||||
TRACE("FILLBUFFER\n");
|
TRACE("FILLBUFFER\n");
|
||||||
ExtentMapEntry* map;
|
ExtentMapEntry* map;
|
||||||
@@ -116,8 +116,11 @@ LeafDirectory::FillBuffer(int type, char* blockBuffer)
|
|||||||
Volume* volume = fInode->GetVolume();
|
Volume* volume = fInode->GetVolume();
|
||||||
xfs_agblock_t numberOfBlocksInAg = volume->AgBlocks();
|
xfs_agblock_t numberOfBlocksInAg = volume->AgBlocks();
|
||||||
|
|
||||||
uint64 agNo = FSBLOCKS_TO_AGNO(map->br_startblock, volume);
|
uint64 agNo =
|
||||||
uint64 agBlockNo = FSBLOCKS_TO_AGBLOCKNO(map->br_startblock, volume);
|
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(),
|
xfs_fsblock_t blockToRead = FSBLOCKS_TO_BASICBLOCKS(volume->BlockLog(),
|
||||||
(agNo * numberOfBlocksInAg + agBlockNo));
|
(agNo * numberOfBlocksInAg + agBlockNo));
|
||||||
|
|
||||||
@@ -168,7 +171,7 @@ LeafDirectory::FirstLeaf()
|
|||||||
TRACE("LeafDirectory: FirstLeaf\n");
|
TRACE("LeafDirectory: FirstLeaf\n");
|
||||||
if (fLeafBuffer == NULL) {
|
if (fLeafBuffer == NULL) {
|
||||||
ASSERT(fLeafMap != NULL);
|
ASSERT(fLeafMap != NULL);
|
||||||
status_t status = FillBuffer(LEAF, fLeafBuffer);
|
status_t status = FillBuffer(LEAF, fLeafBuffer, 0);
|
||||||
if (status != B_OK)
|
if (status != B_OK)
|
||||||
return NULL;
|
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
|
status_t
|
||||||
LeafDirectory::GetNext(char* name, size_t* length, xfs_ino_t* ino)
|
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;
|
status_t status;
|
||||||
|
|
||||||
if (fDataBuffer == NULL) {
|
if (fDataBuffer == NULL) {
|
||||||
status = FillBuffer(DATA, fDataBuffer);
|
status = FillBuffer(DATA, fDataBuffer, 0);
|
||||||
if (status != B_OK)
|
if (status != B_OK)
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
@@ -205,25 +223,42 @@ LeafDirectory::GetNext(char* name, size_t* length, xfs_ino_t* ino)
|
|||||||
void* entry = (void*)((ExtentDataHeader*)fDataBuffer + 1);
|
void* entry = (void*)((ExtentDataHeader*)fDataBuffer + 1);
|
||||||
// This could be an unused entry so we should check
|
// This could be an unused entry so we should check
|
||||||
|
|
||||||
if (BLOCKNO_FROM_ADDRESS(fOffset, volume) == fCurBlockNumber
|
uint32 blockNoFromAddress = BLOCKNO_FROM_ADDRESS(fOffset, volume);
|
||||||
&& fOffset != 0)
|
if (fOffset != 0 && blockNoFromAddress == fCurBlockNumber)
|
||||||
entry = (void*)(fDataBuffer
|
entry = (void*)(fDataBuffer
|
||||||
+ BLOCKOFFSET_FROM_ADDRESS(fOffset, fInode));
|
+ BLOCKOFFSET_FROM_ADDRESS(fOffset, fInode));
|
||||||
// This gets us a little faster to the next entry
|
// This gets us a little faster to the next entry
|
||||||
|
|
||||||
ExtentLeafHeader* leafHeader = (ExtentLeafHeader*)(void*)fLeafBuffer;
|
|
||||||
uint32 curDirectorySize = fInode->Size();
|
uint32 curDirectorySize = fInode->Size();
|
||||||
|
|
||||||
while (fOffset != curDirectorySize) {
|
while (fOffset != curDirectorySize) {
|
||||||
TRACE("fOffset:(%d)\n", fOffset);
|
blockNoFromAddress = BLOCKNO_FROM_ADDRESS(fOffset, volume);
|
||||||
if (fCurBlockNumber != BLOCKNO_FROM_ADDRESS(fOffset, volume)) {
|
|
||||||
fCurBlockNumber = BLOCKNO_FROM_ADDRESS(fOffset, volume);
|
TRACE("fOffset:(%d), blockNoFromAddress:(%d)\n",
|
||||||
FillMapEntry(fCurBlockNumber, fDataMap);
|
fOffset, blockNoFromAddress);
|
||||||
status = FillBuffer(DATA, fDataBuffer);
|
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)
|
if (status != B_OK)
|
||||||
return status;
|
return status;
|
||||||
entry = (void*)((ExtentDataHeader*)fDataBuffer + 1);
|
entry = (void*)((ExtentDataHeader*)fDataBuffer + 1);
|
||||||
fOffset = fOffset + sizeof(ExtentDataHeader);
|
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;
|
ExtentUnusedEntry* unusedEntry = (ExtentUnusedEntry*)entry;
|
||||||
@@ -274,7 +309,7 @@ LeafDirectory::Lookup(const char* name, size_t length, xfs_ino_t* ino)
|
|||||||
|
|
||||||
status_t status;
|
status_t status;
|
||||||
if (fLeafBuffer == NULL)
|
if (fLeafBuffer == NULL)
|
||||||
status = FillBuffer(LEAF, fLeafBuffer);
|
status = FillBuffer(LEAF, fLeafBuffer, 0);
|
||||||
if (status != B_OK)
|
if (status != B_OK)
|
||||||
return status;
|
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);
|
TRACE("DataBlockNumber:(%d), offset:(%d)\n", dataBlockNumber, offset);
|
||||||
if (dataBlockNumber != fCurBlockNumber) {
|
if (dataBlockNumber != fCurBlockNumber) {
|
||||||
fCurBlockNumber = dataBlockNumber;
|
fCurBlockNumber = dataBlockNumber;
|
||||||
FillMapEntry(dataBlockNumber, fDataMap);
|
SearchAndFillDataMap(dataBlockNumber);
|
||||||
status = FillBuffer(DATA, fDataBuffer);
|
status = FillBuffer(DATA, fDataBuffer,
|
||||||
|
dataBlockNumber - fDataMap->br_startoff);
|
||||||
if (status != B_OK)
|
if (status != B_OK)
|
||||||
return B_OK;
|
return B_OK;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -52,7 +52,9 @@ public:
|
|||||||
status_t Init();
|
status_t Init();
|
||||||
bool IsLeafType();
|
bool IsLeafType();
|
||||||
void FillMapEntry(int num, ExtentMapEntry* map);
|
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();
|
ExtentLeafEntry* FirstLeaf();
|
||||||
xfs_ino_t GetIno();
|
xfs_ino_t GetIno();
|
||||||
uint32 GetOffsetFromAddress(uint32 address);
|
uint32 GetOffsetFromAddress(uint32 address);
|
||||||
|
|||||||
Reference in New Issue
Block a user