xfs: minimised disk seeks for node xattrs

- Made GetNext() function in Node Attributes efficient by reducing disk seeks to number of Node entries

Change-Id: I4e2bf8fb1898676c30eca2c6d6f39dc1999ae2f8
Reviewed-on: https://review.haiku-os.org/c/haiku/+/5612
Tested-by: Commit checker robot <no-reply+buildbot@haiku-os.org>
Reviewed-by: Adrien Destugues <pulkomandy@pulkomandy.tk>
This commit is contained in:
Mashijams 2022-09-03 13:46:43 +05:30 committed by Adrien Destugues
parent 082d1bcdcf
commit 689f8e9060
3 changed files with 58 additions and 40 deletions

View File

@ -23,7 +23,7 @@ LeafAttribute::LeafAttribute(Inode* inode)
LeafAttribute::~LeafAttribute()
{
delete fMap;
delete fLeafBuffer;
delete[] fLeafBuffer;
}
@ -237,7 +237,7 @@ LeafAttribute::GetNext(char* name, size_t* nameLength)
TRACE("LeafAttribute::GetNext\n");
AttrLeafHeader* header = AttrLeafHeader::Create(fInode,fLeafBuffer);
AttrLeafEntry* entry = (AttrLeafEntry*)(fLeafBuffer + AttrLeafHeader::Size(fInode));
AttrLeafEntry* firstEntry = (AttrLeafEntry*)(fLeafBuffer + AttrLeafHeader::Size(fInode));
int totalEntries = header->Count();
@ -245,7 +245,8 @@ LeafAttribute::GetNext(char* name, size_t* nameLength)
for (int i = fLastEntryOffset; i < totalEntries; i++) {
entry = (AttrLeafEntry*)((char*)entry + i * sizeof(AttrLeafEntry));
AttrLeafEntry* entry =
(AttrLeafEntry*)((char*)firstEntry + i * sizeof(AttrLeafEntry));
uint32 offset = B_BENDIAN_TO_HOST_INT16(entry->nameidx);
TRACE("offset:(%" B_PRIu16 ")\n", offset);

View File

@ -12,9 +12,13 @@
NodeAttribute::NodeAttribute(Inode* inode)
:
fInode(inode),
fName(NULL)
fName(NULL),
fLeafBuffer(NULL),
fNodeBuffer(NULL)
{
fLastEntryOffset = 0;
fLastEntryOffset = 0;
fLastNodeOffset = 0;
fNodeFlag = 0;
}
@ -258,55 +262,66 @@ NodeAttribute::GetNext(char* name, size_t* nameLength)
TRACE("NodeAttribute::GetNext\n");
NodeHeader* node = NodeHeader::Create(fInode, fNodeBuffer);
NodeEntry* nodeEntry = (NodeEntry*)(fNodeBuffer + NodeHeader::Size(fInode));
NodeEntry* firstNodeEntry = (NodeEntry*)(fNodeBuffer + NodeHeader::Size(fInode));
int TotalNodeEntries = node->Count();
int totalNodeEntries = node->Count();
delete node;
uint16 curOffset = 1;
for (int i = fLastNodeOffset; i < totalNodeEntries; i++) {
for (int i = 0; i < TotalNodeEntries; i++) {
// First see the leaf block from NodeEntry and logical block offset
uint32 logicalBlock = B_BENDIAN_TO_HOST_INT32(nodeEntry->before);
// Now calculate File system Block of This logical block
xfs_fsblock_t block = _LogicalToFileSystemBlock(logicalBlock);
_FillBuffer(fLeafBuffer, block);
NodeEntry* nodeEntry = (NodeEntry*)((char*)firstNodeEntry + i * sizeof(NodeEntry));
fLastNodeOffset = i;
AttrLeafHeader* header = AttrLeafHeader::Create(fInode,fLeafBuffer);
AttrLeafEntry* entry = (AttrLeafEntry*)(fLeafBuffer + AttrLeafHeader::Size(fInode));
// if we are at next node entry fill up leaf buffer
if (fNodeFlag == 0) {
// First see the leaf block from NodeEntry and logical block offset
uint32 logicalBlock = B_BENDIAN_TO_HOST_INT32(nodeEntry->before);
TRACE("Logical block : %d", logicalBlock);
// Now calculate File system Block of This logical block
xfs_fsblock_t block = _LogicalToFileSystemBlock(logicalBlock);
_FillBuffer(fLeafBuffer, block);
fNodeFlag = 1;
fLastEntryOffset = 0;
}
AttrLeafHeader* header = AttrLeafHeader::Create(fInode, fLeafBuffer);
AttrLeafEntry* firstLeafEntry =
(AttrLeafEntry*)(fLeafBuffer + AttrLeafHeader::Size(fInode));
int totalEntries = header->Count();
delete header;
for (int j = 0; j < totalEntries; j++) {
if (curOffset > fLastEntryOffset) {
uint32 offset = B_BENDIAN_TO_HOST_INT16(entry->nameidx);
TRACE("offset:(%" B_PRIu16 ")\n", offset);
fLastEntryOffset = curOffset;
for (int j = fLastEntryOffset; j < totalEntries; j++) {
// First check if its local or remote value
if (entry->flags & XFS_ATTR_LOCAL) {
AttrLeafNameLocal* local = (AttrLeafNameLocal*)(fLeafBuffer + offset);
memcpy(name, local->nameval, local->namelen);
name[local->namelen] = '\0';
*nameLength = local->namelen + 1;
TRACE("Entry found name : %s, namelength : %ld", name, *nameLength);
return B_OK;
} else {
AttrLeafNameRemote* remote = (AttrLeafNameRemote*)(fLeafBuffer + offset);
memcpy(name, remote->name, remote->namelen);
name[remote->namelen] = '\0';
*nameLength = remote->namelen + 1;
TRACE("Entry found name : %s, namelength : %ld", name, *nameLength);
return B_OK;
}
AttrLeafEntry* entry = (AttrLeafEntry*)(
(char*)firstLeafEntry + j * sizeof(AttrLeafEntry));
uint32 offset = B_BENDIAN_TO_HOST_INT16(entry->nameidx);
TRACE("offset:(%" B_PRIu16 ")\n", offset);
fLastEntryOffset = j + 1;
// First check if its local or remote value
if (entry->flags & XFS_ATTR_LOCAL) {
AttrLeafNameLocal* local = (AttrLeafNameLocal*)(fLeafBuffer + offset);
memcpy(name, local->nameval, local->namelen);
name[local->namelen] = '\0';
*nameLength = local->namelen + 1;
TRACE("Entry found name : %s, namelength : %ld", name, *nameLength);
return B_OK;
} else {
AttrLeafNameRemote* remote = (AttrLeafNameRemote*)(fLeafBuffer + offset);
memcpy(name, remote->name, remote->namelen);
name[remote->namelen] = '\0';
*nameLength = remote->namelen + 1;
TRACE("Entry found name : %s, namelength : %ld", name, *nameLength);
return B_OK;
}
curOffset++;
entry = (AttrLeafEntry*)((char*)entry + sizeof(AttrLeafEntry));
}
nodeEntry = (NodeEntry*)((char*)nodeEntry + sizeof(NodeEntry));
// we are now at next nodeEntry initialize it as 0
fNodeFlag = 0;
}
return B_ENTRY_NOT_FOUND;

View File

@ -40,6 +40,8 @@ private:
char* fLeafBuffer;
char* fNodeBuffer;
uint16 fLastEntryOffset;
uint16 fLastNodeOffset;
uint8 fNodeFlag;
AttrLeafNameLocal* fLocalEntry;
AttrLeafNameRemote* fRemoteEntry;
};