From 689f8e90609c81c95f1050aa98d1990c57bf86f5 Mon Sep 17 00:00:00 2001 From: Mashijams Date: Sat, 3 Sep 2022 13:46:43 +0530 Subject: [PATCH] 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 Reviewed-by: Adrien Destugues --- .../kernel/file_systems/xfs/LeafAttribute.cpp | 7 +- .../kernel/file_systems/xfs/NodeAttribute.cpp | 89 +++++++++++-------- .../kernel/file_systems/xfs/NodeAttribute.h | 2 + 3 files changed, 58 insertions(+), 40 deletions(-) diff --git a/src/add-ons/kernel/file_systems/xfs/LeafAttribute.cpp b/src/add-ons/kernel/file_systems/xfs/LeafAttribute.cpp index fad73c415b..be4a26127a 100644 --- a/src/add-ons/kernel/file_systems/xfs/LeafAttribute.cpp +++ b/src/add-ons/kernel/file_systems/xfs/LeafAttribute.cpp @@ -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); diff --git a/src/add-ons/kernel/file_systems/xfs/NodeAttribute.cpp b/src/add-ons/kernel/file_systems/xfs/NodeAttribute.cpp index 207a8aed6f..67da48f19e 100644 --- a/src/add-ons/kernel/file_systems/xfs/NodeAttribute.cpp +++ b/src/add-ons/kernel/file_systems/xfs/NodeAttribute.cpp @@ -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; diff --git a/src/add-ons/kernel/file_systems/xfs/NodeAttribute.h b/src/add-ons/kernel/file_systems/xfs/NodeAttribute.h index 983175c388..cd600a7fd5 100644 --- a/src/add-ons/kernel/file_systems/xfs/NodeAttribute.h +++ b/src/add-ons/kernel/file_systems/xfs/NodeAttribute.h @@ -40,6 +40,8 @@ private: char* fLeafBuffer; char* fNodeBuffer; uint16 fLastEntryOffset; + uint16 fLastNodeOffset; + uint8 fNodeFlag; AttrLeafNameLocal* fLocalEntry; AttrLeafNameRemote* fRemoteEntry; };