feat: add getBlockForRead to sfs
This commit is contained in:
1 parent
8f2ecdb2d4
commit
1203e0880e
1 file changed
+161
@@ -307,3 +307,164 @@ static bool getOrAllocBlockForWrite(SfsInode* inode, uint32 logicalIndex, uint32
|
||||
if (!loadOrAllocPointerBlock(inode, &inode->doubleIndirect, outerBuf))
|
||||
return false;
|
||||
|
||||
uint32* outerPtrs = (uint32*)outerBuf;
|
||||
uint8 innerBuf[sfsBlockSize];
|
||||
bool outerNeedsFlush = false;
|
||||
if (outerPtrs[outerIndex] == 0) {
|
||||
int32 nb = allocDataBlockAbs();
|
||||
if (nb < 0)
|
||||
return false;
|
||||
outerPtrs[outerIndex] = (uint32)nb;
|
||||
inode->blockCount++;
|
||||
outerNeedsFlush = true;
|
||||
memset(innerBuf, 0, sizeof(innerBuf));
|
||||
if (!blockWrite(outerPtrs[outerIndex], innerBuf))
|
||||
return false;
|
||||
} else if (!blockRead(outerPtrs[outerIndex], innerBuf)) {
|
||||
return false;
|
||||
}
|
||||
if (outerNeedsFlush && !blockWrite(inode->doubleIndirect, outerBuf))
|
||||
return false;
|
||||
|
||||
uint32* innerPtrs = (uint32*)innerBuf;
|
||||
if (innerPtrs[innerIndex] == 0) {
|
||||
int32 nb = allocDataBlockAbs();
|
||||
if (nb < 0)
|
||||
return false;
|
||||
innerPtrs[innerIndex] = (uint32)nb;
|
||||
inode->blockCount++;
|
||||
if (!blockWrite(outerPtrs[outerIndex], innerBuf))
|
||||
return false;
|
||||
}
|
||||
*outAbs = innerPtrs[innerIndex];
|
||||
return true;
|
||||
}
|
||||
|
||||
/* Same three-level shape as the double-indirect block above, one level
|
||||
deeper: tripleIndirect -> top (128 mid-block pointers) -> mid (128
|
||||
leaf-block pointers) -> leaf (128 data-block pointers) -> data. */
|
||||
uint32 tripleIndex = doubleIndex - sfsPtrsPerBlock * sfsPtrsPerBlock;
|
||||
uint32 topIndex = tripleIndex / (sfsPtrsPerBlock * sfsPtrsPerBlock);
|
||||
uint32 midIndex = (tripleIndex / sfsPtrsPerBlock) % sfsPtrsPerBlock;
|
||||
uint32 leafIndex = tripleIndex % sfsPtrsPerBlock;
|
||||
if (topIndex >= sfsPtrsPerBlock)
|
||||
return false; /* past the addressing limit (~1 GiB) */
|
||||
|
||||
uint8 topBuf[sfsBlockSize];
|
||||
if (!loadOrAllocPointerBlock(inode, &inode->tripleIndirect, topBuf))
|
||||
return false;
|
||||
|
||||
uint32* topPtrs = (uint32*)topBuf;
|
||||
uint8 midBuf[sfsBlockSize];
|
||||
bool topNeedsFlush = false;
|
||||
if (topPtrs[topIndex] == 0) {
|
||||
int32 nb = allocDataBlockAbs();
|
||||
if (nb < 0)
|
||||
return false;
|
||||
topPtrs[topIndex] = (uint32)nb;
|
||||
inode->blockCount++;
|
||||
topNeedsFlush = true;
|
||||
memset(midBuf, 0, sizeof(midBuf));
|
||||
if (!blockWrite(topPtrs[topIndex], midBuf))
|
||||
return false;
|
||||
} else if (!blockRead(topPtrs[topIndex], midBuf)) {
|
||||
return false;
|
||||
}
|
||||
if (topNeedsFlush && !blockWrite(inode->tripleIndirect, topBuf))
|
||||
return false;
|
||||
|
||||
uint32* midPtrs = (uint32*)midBuf;
|
||||
uint8 leafBuf[sfsBlockSize];
|
||||
bool midNeedsFlush = false;
|
||||
if (midPtrs[midIndex] == 0) {
|
||||
int32 nb = allocDataBlockAbs();
|
||||
if (nb < 0)
|
||||
return false;
|
||||
midPtrs[midIndex] = (uint32)nb;
|
||||
inode->blockCount++;
|
||||
midNeedsFlush = true;
|
||||
memset(leafBuf, 0, sizeof(leafBuf));
|
||||
if (!blockWrite(midPtrs[midIndex], leafBuf))
|
||||
return false;
|
||||
} else if (!blockRead(midPtrs[midIndex], leafBuf)) {
|
||||
return false;
|
||||
}
|
||||
if (midNeedsFlush && !blockWrite(topPtrs[topIndex], midBuf))
|
||||
return false;
|
||||
|
||||
uint32* leafPtrs = (uint32*)leafBuf;
|
||||
if (leafPtrs[leafIndex] == 0) {
|
||||
int32 nb = allocDataBlockAbs();
|
||||
if (nb < 0)
|
||||
return false;
|
||||
leafPtrs[leafIndex] = (uint32)nb;
|
||||
inode->blockCount++;
|
||||
if (!blockWrite(midPtrs[midIndex], leafBuf))
|
||||
return false;
|
||||
}
|
||||
*outAbs = leafPtrs[leafIndex];
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool getBlockForRead(const SfsInode* inode, uint32 logicalIndex, uint32* outAbs)
|
||||
{
|
||||
if (logicalIndex < sfsDirectBlocks) {
|
||||
*outAbs = inode->direct[logicalIndex];
|
||||
return *outAbs != 0;
|
||||
}
|
||||
|
||||
uint32 indIndex = logicalIndex - sfsDirectBlocks;
|
||||
if (indIndex < sfsPtrsPerBlock) {
|
||||
if (inode->indirect == 0)
|
||||
return false;
|
||||
uint8 indBuf[sfsBlockSize];
|
||||
if (!blockRead(inode->indirect, indBuf))
|
||||
return false;
|
||||
uint32* ptrs = (uint32*)indBuf;
|
||||
*outAbs = ptrs[indIndex];
|
||||
return *outAbs != 0;
|
||||
}
|
||||
|
||||
uint32 doubleIndex = indIndex - sfsPtrsPerBlock;
|
||||
if (doubleIndex < sfsPtrsPerBlock * sfsPtrsPerBlock) {
|
||||
uint32 outerIndex = doubleIndex / sfsPtrsPerBlock;
|
||||
uint32 innerIndex = doubleIndex % sfsPtrsPerBlock;
|
||||
if (inode->doubleIndirect == 0)
|
||||
return false;
|
||||
|
||||
uint8 outerBuf[sfsBlockSize];
|
||||
if (!blockRead(inode->doubleIndirect, outerBuf))
|
||||
return false;
|
||||
uint32* outerPtrs = (uint32*)outerBuf;
|
||||
if (outerPtrs[outerIndex] == 0)
|
||||
return false;
|
||||
|
||||
uint8 innerBuf[sfsBlockSize];
|
||||
if (!blockRead(outerPtrs[outerIndex], innerBuf))
|
||||
return false;
|
||||
uint32* innerPtrs = (uint32*)innerBuf;
|
||||
*outAbs = innerPtrs[innerIndex];
|
||||
return *outAbs != 0;
|
||||
}
|
||||
|
||||
uint32 tripleIndex = doubleIndex - sfsPtrsPerBlock * sfsPtrsPerBlock;
|
||||
uint32 topIndex = tripleIndex / (sfsPtrsPerBlock * sfsPtrsPerBlock);
|
||||
uint32 midIndex = (tripleIndex / sfsPtrsPerBlock) % sfsPtrsPerBlock;
|
||||
uint32 leafIndex = tripleIndex % sfsPtrsPerBlock;
|
||||
if (topIndex >= sfsPtrsPerBlock || inode->tripleIndirect == 0)
|
||||
return false;
|
||||
|
||||
uint8 topBuf[sfsBlockSize];
|
||||
if (!blockRead(inode->tripleIndirect, topBuf))
|
||||
return false;
|
||||
uint32* topPtrs = (uint32*)topBuf;
|
||||
if (topPtrs[topIndex] == 0)
|
||||
return false;
|
||||
|
||||
uint8 midBuf[sfsBlockSize];
|
||||
if (!blockRead(topPtrs[topIndex], midBuf))
|
||||
return false;
|
||||
uint32* midPtrs = (uint32*)midBuf;
|
||||
if (midPtrs[midIndex] == 0)
|
||||
return false;
|
||||
|
||||
Reference in new issue
Block a user