xfs: B+Tree ExtentMap reading
We can now read all the extent maps from the leaves. This will be needed to implement the GetNext() functionality. Change-Id: Ie10b453c33bec6e6d3109743d695f86a90de45cd Reviewed-on: https://review.haiku-os.org/c/haiku/+/3119 Tested-by: Commit checker robot <[email protected]> Reviewed-by: Adrien Destugues <[email protected]>
This commit is contained in:
committed by
Adrien Destugues
parent
d9b9a94c4f
commit
b4763972bd
@@ -7,122 +7,219 @@
|
|||||||
#include "BPlusTree.h"
|
#include "BPlusTree.h"
|
||||||
|
|
||||||
|
|
||||||
void
|
TreeDirectory::TreeDirectory(Inode* inode)
|
||||||
bplustree_short_block::SwapEndian()
|
:
|
||||||
|
fInode(inode),
|
||||||
|
fInitStatus(B_OK),
|
||||||
|
fRoot(NULL),
|
||||||
|
fExtents(NULL),
|
||||||
|
fSingleDirBlock(NULL),
|
||||||
|
fCountOfFilledExtents(0)
|
||||||
{
|
{
|
||||||
bb_magic = B_BENDIAN_TO_HOST_INT32(bb_magic);
|
fRoot = new(std::nothrow) BlockInDataFork;
|
||||||
bb_level = B_BENDIAN_TO_HOST_INT16(bb_level);
|
if (fRoot == NULL) {
|
||||||
bb_numrecs = B_BENDIAN_TO_HOST_INT16(bb_numrecs);
|
fInitStatus = B_NO_MEMORY;
|
||||||
bb_leftsib = B_BENDIAN_TO_HOST_INT32(bb_leftsib);
|
return;
|
||||||
bb_rightsib = B_BENDIAN_TO_HOST_INT32(bb_rightsib);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void
|
|
||||||
bplustree_long_block::SwapEndian()
|
|
||||||
{
|
|
||||||
bb_magic = B_BENDIAN_TO_HOST_INT32(bb_magic);
|
|
||||||
bb_level = B_BENDIAN_TO_HOST_INT16(bb_level);
|
|
||||||
bb_numrecs = B_BENDIAN_TO_HOST_INT16(bb_numrecs);
|
|
||||||
bb_leftsib = B_BENDIAN_TO_HOST_INT64(bb_leftsib);
|
|
||||||
bb_rightsib = B_BENDIAN_TO_HOST_INT64(bb_rightsib);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void
|
|
||||||
xfs_alloc_rec::SwapEndian()
|
|
||||||
{
|
|
||||||
ar_startblock = B_BENDIAN_TO_HOST_INT32(ar_startblock);
|
|
||||||
ar_blockcount = B_BENDIAN_TO_HOST_INT32(ar_blockcount);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
uint32
|
|
||||||
BPlusTree::BlockSize()
|
|
||||||
{
|
|
||||||
return fVolume.SuperBlock().BlockSize();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
int
|
|
||||||
BPlusTree::RecordSize()
|
|
||||||
{
|
|
||||||
if (fRecType == ALLOC_FLAG)
|
|
||||||
return XFS_ALLOC_REC_SIZE;
|
|
||||||
|
|
||||||
return B_BAD_VALUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
int
|
|
||||||
BPlusTree::MaxRecords(bool leaf)
|
|
||||||
{
|
|
||||||
int blockLen = BlockSize();
|
|
||||||
|
|
||||||
if (fPtrType == SHORT_BLOCK_FLAG)
|
|
||||||
blockLen - XFS_BTREE_SBLOCK_SIZE;
|
|
||||||
|
|
||||||
if (leaf) {
|
|
||||||
if (fRecType == ALLOC_FLAG)
|
|
||||||
return blockLen / sizeof(xfs_alloc_rec_t);
|
|
||||||
} else {
|
|
||||||
if (fKeyType == ALLOC_FLAG) {
|
|
||||||
return blockLen / (sizeof(xfs_alloc_key_t)
|
|
||||||
+ sizeof(xfs_alloc_ptr_t));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return B_BAD_VALUE;
|
fSingleDirBlock = new(std::nothrow) char[fInode->DirBlockSize()];
|
||||||
|
if (fSingleDirBlock == NULL) {
|
||||||
|
fInitStatus = B_NO_MEMORY;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
memcpy((void*)fRoot,
|
||||||
|
DIR_DFORK_PTR(fInode->Buffer()), sizeof(BlockInDataFork));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
TreeDirectory::~TreeDirectory()
|
||||||
|
{
|
||||||
|
delete fRoot;
|
||||||
|
delete[] fExtents;
|
||||||
|
delete fSingleDirBlock;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
status_t
|
||||||
|
TreeDirectory::InitCheck()
|
||||||
|
{
|
||||||
|
return fInitStatus;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int
|
int
|
||||||
BPlusTree::KeyLen()
|
TreeDirectory::BlockLen()
|
||||||
{
|
{
|
||||||
if (fKeyType == ALLOC_FLAG)
|
return XFS_BTREE_LBLOCK_SIZE;
|
||||||
return XFS_ALLOC_REC_SIZE;
|
|
||||||
return B_BAD_VALUE;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int
|
TreeKey
|
||||||
BPlusTree::BlockLen()
|
TreeDirectory::GetKey(int pos)
|
||||||
{
|
{
|
||||||
if (fPtrType == LONG_BLOCK_FLAG)
|
return BlockLen() + (pos - 1) * XFS_KEY_SIZE;
|
||||||
return XFS_BTREE_LBLOCK_SIZE;
|
|
||||||
if (fPtrType == SHORT_BLOCK_FLAG)
|
|
||||||
return XFS_BTREE_SBLOCK_SIZE;
|
|
||||||
return B_BAD_VALUE;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int
|
size_t
|
||||||
BPlusTree::PtrLen()
|
TreeDirectory::KeySize()
|
||||||
{
|
{
|
||||||
if (fPtrType == LONG_BLOCK_FLAG)
|
return XFS_KEY_SIZE;
|
||||||
return sizeof(uint64);
|
}
|
||||||
|
|
||||||
|
|
||||||
|
size_t
|
||||||
|
TreeDirectory::PtrSize()
|
||||||
|
{
|
||||||
|
return XFS_PTR_SIZE;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
TreePointer*
|
||||||
|
TreeDirectory::GetPtr(int pos, LongBlock* curLongBlock)
|
||||||
|
{
|
||||||
|
size_t availableSpace = fInode->GetVolume()->BlockSize() - BlockLen();
|
||||||
|
size_t maxRecords = availableSpace / (KeySize() + PtrSize());
|
||||||
|
size_t offsetIntoNode =
|
||||||
|
BlockLen() + maxRecords * KeySize() + (pos - 1) * PtrSize();
|
||||||
|
return (TreePointer*)((char*)curLongBlock + offsetIntoNode);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
size_t
|
||||||
|
TreeDirectory::MaxRecordsPossible(size_t len)
|
||||||
|
{
|
||||||
|
len -= sizeof(BlockInDataFork);
|
||||||
|
return len / (KeySize() + PtrSize());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
status_t
|
||||||
|
TreeDirectory::GetAllExtents()
|
||||||
|
{
|
||||||
|
xfs_extnum_t noOfExtents = fInode->DataExtentsCount();
|
||||||
|
ExtentMapUnwrap* extentsWrapped
|
||||||
|
= new(std::nothrow) ExtentMapUnwrap[noOfExtents];
|
||||||
|
if (extentsWrapped == NULL)
|
||||||
|
return B_NO_MEMORY;
|
||||||
|
|
||||||
|
Volume* volume = fInode->GetVolume();
|
||||||
|
uint16 levelsInTree = fRoot->Levels();
|
||||||
|
|
||||||
|
size_t lengthOfDataFork;
|
||||||
|
if (fInode->ForkOffset() != 0)
|
||||||
|
lengthOfDataFork = fInode->ForkOffset() << 3;
|
||||||
else
|
else
|
||||||
return sizeof(uint32);
|
lengthOfDataFork = volume->InodeSize() - INODE_CORE_UNLINKED_SIZE;
|
||||||
|
|
||||||
|
TRACE("Length Of Data Fork: (%d)\n", lengthOfDataFork);
|
||||||
|
size_t maxRecords = MaxRecordsPossible(lengthOfDataFork);
|
||||||
|
TRACE("Maxrecords: (%d)\n", maxRecords);
|
||||||
|
TreePointer* ptrToNode = (TreePointer*)
|
||||||
|
((char*)DIR_DFORK_PTR(fInode->Buffer())
|
||||||
|
+ sizeof(BlockInDataFork) + maxRecords*KeySize());
|
||||||
|
|
||||||
|
size_t len = volume->BlockSize();
|
||||||
|
char node[len];
|
||||||
|
// This isn't for a directory block but for one of the tree nodes
|
||||||
|
|
||||||
|
TRACE("levels:(%d)\n", levelsInTree);
|
||||||
|
TRACE("Numrecs:(%d)\n", fRoot->NumRecords());
|
||||||
|
|
||||||
|
// Go down the tree by taking the leftest pointer to go to the first leaf
|
||||||
|
uint64 fileSystemBlockNo = B_BENDIAN_TO_HOST_INT64(*ptrToNode);
|
||||||
|
uint64 readPos = fInode->FileSystemBlockToAddr(fileSystemBlockNo);
|
||||||
|
while (levelsInTree != 1) {
|
||||||
|
fileSystemBlockNo = B_BENDIAN_TO_HOST_INT64(*ptrToNode);
|
||||||
|
// The fs block that contains node at next lower level. Now read.
|
||||||
|
readPos = fInode->FileSystemBlockToAddr(fileSystemBlockNo);
|
||||||
|
if (read_pos(volume->Device(), readPos, node, len) != len) {
|
||||||
|
ERROR("Extent::FillBlockBuffer(): IO Error");
|
||||||
|
|
||||||
|
delete[] extentsWrapped;
|
||||||
|
extentsWrapped = NULL;
|
||||||
|
return B_IO_ERROR;
|
||||||
|
}
|
||||||
|
LongBlock* curLongBlock = (LongBlock*)node;
|
||||||
|
ASSERT(curLongBlock->Magic() == XFS_BMAP_MAGIC);
|
||||||
|
ptrToNode = GetPtr(1, curLongBlock);
|
||||||
|
// Get's the first pointer. This points to next node.
|
||||||
|
levelsInTree--;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Next level wil contain leaf nodes. Now Read Directory Buffer
|
||||||
|
len = fInode->DirBlockSize();
|
||||||
|
if (read_pos(volume->Device(), readPos, fSingleDirBlock, len)
|
||||||
|
!= len) {
|
||||||
|
ERROR("Extent::FillBlockBuffer(): IO Error");
|
||||||
|
|
||||||
|
delete[] extentsWrapped;
|
||||||
|
extentsWrapped = NULL;
|
||||||
|
return B_IO_ERROR;
|
||||||
|
}
|
||||||
|
levelsInTree--;
|
||||||
|
ASSERT(levelsInTree == 0);
|
||||||
|
|
||||||
|
// We should be at the left most leaf node.
|
||||||
|
// This could be a multilevel node type directory
|
||||||
|
while (1) {
|
||||||
|
// Run till you have leaf blocks to checkout
|
||||||
|
char* leafBuffer = fSingleDirBlock;
|
||||||
|
ASSERT(((LongBlock*)leafBuffer)->Magic() == XFS_BMAP_MAGIC);
|
||||||
|
uint32 offset = sizeof(LongBlock);
|
||||||
|
int numRecs = ((LongBlock*)leafBuffer)->NumRecs();
|
||||||
|
|
||||||
|
for (int i = 0; i < numRecs; i++) {
|
||||||
|
extentsWrapped[fCountOfFilledExtents].first =
|
||||||
|
*(uint64*)(leafBuffer + offset);
|
||||||
|
extentsWrapped[fCountOfFilledExtents].second =
|
||||||
|
*(uint64*)(leafBuffer + offset + sizeof(uint64));
|
||||||
|
offset += sizeof(ExtentMapUnwrap);
|
||||||
|
fCountOfFilledExtents++;
|
||||||
|
}
|
||||||
|
|
||||||
|
fileSystemBlockNo = ((LongBlock*)leafBuffer)->Right();
|
||||||
|
TRACE("Next leaf is at: (%d)\n", fileSystemBlockNo);
|
||||||
|
if (fileSystemBlockNo == -1)
|
||||||
|
break;
|
||||||
|
uint64 readPos = fInode->FileSystemBlockToAddr(fileSystemBlockNo);
|
||||||
|
if (read_pos(volume->Device(), readPos, fSingleDirBlock, len)
|
||||||
|
!= len) {
|
||||||
|
ERROR("Extent::FillBlockBuffer(): IO Error");
|
||||||
|
|
||||||
|
delete[] extentsWrapped;
|
||||||
|
extentsWrapped = NULL;
|
||||||
|
return B_IO_ERROR;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
TRACE("Total covered: (%d)\n", fCountOfFilledExtents);
|
||||||
|
|
||||||
|
status_t status = UnWrapExtents(extentsWrapped);
|
||||||
|
|
||||||
|
delete[] extentsWrapped;
|
||||||
|
extentsWrapped = NULL;
|
||||||
|
|
||||||
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int
|
status_t
|
||||||
BPlusTree::RecordOffset(int pos)
|
TreeDirectory::UnWrapExtents(ExtentMapUnwrap* extentsWrapped)
|
||||||
{
|
{
|
||||||
return BlockLen() + (pos - 1) * RecordSize();
|
fExtents = new(std::nothrow) ExtentMapEntry[fCountOfFilledExtents];
|
||||||
}
|
if (fExtents == NULL)
|
||||||
|
return B_NO_MEMORY;
|
||||||
|
uint64 first, second;
|
||||||
int
|
|
||||||
BPlusTree::KeyOffset(int pos)
|
for (int i = 0; i < fCountOfFilledExtents; i++) {
|
||||||
{
|
first = B_BENDIAN_TO_HOST_INT64(extentsWrapped[i].first);
|
||||||
return BlockLen() + (pos - 1) * KeyLen();
|
second = B_BENDIAN_TO_HOST_INT64(extentsWrapped[i].second);
|
||||||
}
|
fExtents[i].br_state = first >> 63;
|
||||||
|
fExtents[i].br_startoff = (first & MASK(63)) >> 9;
|
||||||
|
fExtents[i].br_startblock = ((first & MASK(9)) << 43) | (second >> 21);
|
||||||
int
|
fExtents[i].br_blockcount = second & MASK(21);
|
||||||
BPlusTree::PtrOffset(int pos, int level)
|
}
|
||||||
{
|
|
||||||
return BlockLen() + MaxRecords(level > 0) * KeyLen()
|
return B_OK;
|
||||||
+ (pos - 1) * PtrLen();
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,136 +5,115 @@
|
|||||||
#ifndef _BPLUS_TREE_H_
|
#ifndef _BPLUS_TREE_H_
|
||||||
#define _BPLUS_TREE_H_
|
#define _BPLUS_TREE_H_
|
||||||
|
|
||||||
|
|
||||||
|
#include "Extent.h"
|
||||||
|
#include "Inode.h"
|
||||||
|
#include "LeafDirectory.h"
|
||||||
|
#include "Node.h"
|
||||||
#include "system_dependencies.h"
|
#include "system_dependencies.h"
|
||||||
|
|
||||||
|
|
||||||
/* Allocation B+ Tree Format */
|
|
||||||
#define XFS_ABTB_MAGICNUM 0x41425442
|
|
||||||
// For block offset B+Tree
|
|
||||||
#define XFS_ABTC_MAGICNUM 0x41425443
|
|
||||||
// For block count B+ Tree
|
|
||||||
#define XFS_BTREE_SBLOCK_SIZE 18
|
#define XFS_BTREE_SBLOCK_SIZE 18
|
||||||
// Header for Short Format btree
|
// Header for Short Format btree
|
||||||
#define XFS_BTREE_LBLOCK_SIZE 24
|
#define XFS_BTREE_LBLOCK_SIZE 24
|
||||||
// Header for Long Format btree
|
// Header for Long Format btree
|
||||||
|
#define XFS_KEY_SIZE sizeof(xfs_fileoff_t)
|
||||||
|
#define XFS_PTR_SIZE sizeof(xfs_fsblock_t)
|
||||||
|
#define XFS_BMAP_MAGIC 0x424d4150
|
||||||
|
|
||||||
|
|
||||||
|
typedef xfs_fileoff_t TreeKey;
|
||||||
|
typedef xfs_fsblock_t TreePointer;
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Headers are the "nodes" really and are called "blocks". The records, keys
|
* Headers(here, the LongBlock) are the "nodes" really and are called "blocks".
|
||||||
* and ptrs are calculated using helpers
|
* The records, keys and ptrs are calculated using helpers
|
||||||
*/
|
*/
|
||||||
struct bplustree_short_block {
|
struct LongBlock {
|
||||||
void SwapEndian();
|
|
||||||
|
|
||||||
uint32 Magic()
|
uint32 Magic()
|
||||||
{ return bb_magic; }
|
{ return B_BENDIAN_TO_HOST_INT32(bb_magic); }
|
||||||
|
|
||||||
uint16 Level()
|
uint16 Level()
|
||||||
{ return bb_level; }
|
{ return B_BENDIAN_TO_HOST_INT16(bb_level); }
|
||||||
|
|
||||||
uint16 NumRecs()
|
uint16 NumRecs()
|
||||||
{ return bb_numrecs; }
|
{ return B_BENDIAN_TO_HOST_INT16(bb_numrecs); }
|
||||||
|
|
||||||
xfs_alloc_ptr_t Left()
|
TreePointer Left()
|
||||||
{ return bb_leftsib; }
|
{ return B_BENDIAN_TO_HOST_INT64(bb_leftsib); }
|
||||||
|
|
||||||
xfs_alloc_ptr_t Right()
|
TreePointer Right()
|
||||||
{ return bb_rightsib;}
|
{ return B_BENDIAN_TO_HOST_INT64(bb_rightsib); }
|
||||||
|
|
||||||
uint32 bb_magic;
|
|
||||||
uint16 bb_level;
|
|
||||||
uint16 bb_numrecs;
|
|
||||||
uint32 bb_leftsib;
|
|
||||||
uint32 bb_rightsib;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
struct bplustree_long_block {
|
|
||||||
void SwapEndian();
|
|
||||||
|
|
||||||
uint32 Magic()
|
|
||||||
{ return bb_magic; }
|
|
||||||
|
|
||||||
uint16 Level()
|
|
||||||
{ return bb_level; }
|
|
||||||
|
|
||||||
uint16 NumRecs()
|
|
||||||
{ return bb_numrecs; }
|
|
||||||
|
|
||||||
xfs_alloc_ptr_t Left()
|
|
||||||
{ return bb_leftsib; }
|
|
||||||
|
|
||||||
xfs_alloc_ptr_t Right()
|
|
||||||
{ return bb_rightsib;}
|
|
||||||
|
|
||||||
uint32 bb_magic;
|
uint32 bb_magic;
|
||||||
uint16 bb_level;
|
uint16 bb_level;
|
||||||
uint16 bb_numrecs;
|
uint16 bb_numrecs;
|
||||||
uint64 bb_leftsib;
|
uint64 bb_leftsib;
|
||||||
uint64 bb_rightsib;
|
uint64 bb_rightsib;
|
||||||
}
|
};
|
||||||
|
|
||||||
|
|
||||||
/* Array of these records in the leaf node along with above headers */
|
/* We have an array of extent records in
|
||||||
#define XFS_ALLOC_REC_SIZE 8
|
* the leaf node along with above headers
|
||||||
typedef struct xfs_alloc_rec {
|
* The behaviour is very much like node directories.
|
||||||
void SwapEndian();
|
*/
|
||||||
|
|
||||||
uint32 StartBlock()
|
|
||||||
{ return ar_startblock; }
|
|
||||||
|
|
||||||
uint32 BlockCount()
|
|
||||||
{ return ar_blockcount; }
|
|
||||||
|
|
||||||
uint32 ar_startblock;
|
|
||||||
uint32 ar_blockcount;
|
|
||||||
|
|
||||||
} xfs_alloc_rec_t, xfs_alloc_key_t;
|
|
||||||
|
|
||||||
|
|
||||||
typedef uint32 xfs_alloc_ptr_t;
|
//xfs_bmdr_block
|
||||||
// Node pointers, AG relative block pointer
|
struct BlockInDataFork {
|
||||||
|
uint16 Levels()
|
||||||
#define ALLOC_FLAG 0x1
|
{ return
|
||||||
#define LONG_BLOCK_FLAG 0x1
|
B_BENDIAN_TO_HOST_INT16(bb_level); }
|
||||||
#define SHORT_BLOCK_FLAG 0x2
|
uint16 NumRecords()
|
||||||
|
{ return
|
||||||
union btree_ptr {
|
B_BENDIAN_TO_HOST_INT16(bb_numrecs); }
|
||||||
bplustree_long_block fLongBlock;
|
uint16 bb_level;
|
||||||
bplustree_short_block fShortBlock;
|
uint16 bb_numrecs;
|
||||||
}
|
};
|
||||||
|
|
||||||
|
|
||||||
union btree_key {
|
struct ExtentMapUnwrap {
|
||||||
xfs_alloc_key_t fAlloc;
|
uint64 first;
|
||||||
}
|
uint64 second;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
union btree_rec {
|
/*
|
||||||
xfs_alloc_rec_t fAlloc;
|
* This class should handle B+Tree based directories
|
||||||
}
|
*/
|
||||||
|
class TreeDirectory {
|
||||||
|
|
||||||
class BPlusTree {
|
|
||||||
public:
|
public:
|
||||||
uint32 BlockSize();
|
TreeDirectory(Inode* inode);
|
||||||
int RecordSize();
|
~TreeDirectory();
|
||||||
int MaxRecords(bool leaf);
|
status_t InitCheck();
|
||||||
int KeyLen();
|
status_t GetNext(char* name, size_t* length,
|
||||||
|
xfs_ino_t* ino);
|
||||||
|
status_t Lookup(const char* name, size_t length,
|
||||||
|
xfs_ino_t* id);
|
||||||
|
int EntrySize(int len) const;
|
||||||
int BlockLen();
|
int BlockLen();
|
||||||
int PtrLen();
|
size_t PtrSize();
|
||||||
int RecordOffset(int pos); // get the pos'th record
|
size_t KeySize();
|
||||||
int KeyOffset(int pos); // get the pos'th key
|
TreeKey GetKey(int pos);
|
||||||
int PtrOffset(int pos); // get the pos'th ptr
|
// get the pos'th key
|
||||||
|
TreePointer* GetPtr(int pos, LongBlock* pointer);
|
||||||
|
// get the pos'th pointer
|
||||||
|
status_t GetAllExtents();
|
||||||
|
size_t MaxRecordsPossible(size_t len);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Volume* fVolume;
|
inline status_t UnWrapExtents(ExtentMapUnwrap* extentsWrapped);
|
||||||
xfs_agnumber_t fAgnumber;
|
|
||||||
btree_ptr* fRoot;
|
private:
|
||||||
int fRecType;
|
Inode* fInode;
|
||||||
int fKeyType;
|
status_t fInitStatus;
|
||||||
int fPtrType;
|
BlockInDataFork* fRoot;
|
||||||
}
|
ExtentMapEntry* fExtents;
|
||||||
|
uint32 fCountOfFilledExtents;
|
||||||
|
char* fSingleDirBlock;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -13,7 +13,8 @@ DirectoryIterator::DirectoryIterator(Inode* inode)
|
|||||||
fShortDir(NULL),
|
fShortDir(NULL),
|
||||||
fExtentDir(NULL),
|
fExtentDir(NULL),
|
||||||
fLeafDir(NULL),
|
fLeafDir(NULL),
|
||||||
fNodeDir(NULL)
|
fNodeDir(NULL),
|
||||||
|
fTreeDir(NULL)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -24,6 +25,7 @@ DirectoryIterator::~DirectoryIterator()
|
|||||||
delete fLeafDir;
|
delete fLeafDir;
|
||||||
delete fExtentDir;
|
delete fExtentDir;
|
||||||
delete fNodeDir;
|
delete fNodeDir;
|
||||||
|
delete fTreeDir;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -75,16 +77,13 @@ DirectoryIterator::Init()
|
|||||||
* we can atleast still list the shortform directory
|
* we can atleast still list the shortform directory
|
||||||
*/
|
*/
|
||||||
|
|
||||||
//TODO: Reading from extent based directories
|
|
||||||
if (fInode->Format() == XFS_DINODE_FMT_EXTENTS) {
|
|
||||||
TRACE("Iterator:GetNext: EXTENTS");
|
|
||||||
return B_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
//TODO: Reading from B+Trees based directories
|
//TODO: Reading from B+Trees based directories
|
||||||
if (fInode->Format() == XFS_DINODE_FMT_BTREE) {
|
if (fInode->Format() == XFS_DINODE_FMT_BTREE) {
|
||||||
TRACE("Iterator:GetNext: B+TREE");
|
TRACE("Iterator:GetNext: B+TREE");
|
||||||
return B_OK;
|
fTreeDir = new(std::nothrow) TreeDirectory(fInode);
|
||||||
|
if (fTreeDir == NULL)
|
||||||
|
return B_NO_MEMORY;
|
||||||
|
return fTreeDir->InitCheck();
|
||||||
}
|
}
|
||||||
|
|
||||||
return B_BAD_VALUE;
|
return B_BAD_VALUE;
|
||||||
|
|||||||
@@ -6,6 +6,7 @@
|
|||||||
#define _DIRECTORY_H_
|
#define _DIRECTORY_H_
|
||||||
|
|
||||||
|
|
||||||
|
#include "BPlusTree.h"
|
||||||
#include "Extent.h"
|
#include "Extent.h"
|
||||||
#include "Inode.h"
|
#include "Inode.h"
|
||||||
#include "LeafDirectory.h"
|
#include "LeafDirectory.h"
|
||||||
@@ -38,6 +39,7 @@ private:
|
|||||||
LeafDirectory* fLeafDir;
|
LeafDirectory* fLeafDir;
|
||||||
// Extent based leaf directory
|
// Extent based leaf directory
|
||||||
NodeDirectory* fNodeDir;
|
NodeDirectory* fNodeDir;
|
||||||
|
TreeDirectory* fTreeDir;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -20,6 +20,7 @@ DEFINES += DEBUG_APP="\\\"xfs\\\"" ;
|
|||||||
UseHeaders [ FDirName $(HAIKU_TOP) src libs uuid ] : true ;
|
UseHeaders [ FDirName $(HAIKU_TOP) src libs uuid ] : true ;
|
||||||
|
|
||||||
local xfsSources =
|
local xfsSources =
|
||||||
|
BPlusTree.cpp
|
||||||
DeviceOpener.cpp
|
DeviceOpener.cpp
|
||||||
Directory.cpp
|
Directory.cpp
|
||||||
Extent.cpp
|
Extent.cpp
|
||||||
|
|||||||
@@ -39,6 +39,7 @@ UseHeaders [ FDirName $(HAIKU_TOP) headers private ] : true ;
|
|||||||
UseHeaders [ FDirName $(HAIKU_TOP) src tools fs_shell ] ;
|
UseHeaders [ FDirName $(HAIKU_TOP) src tools fs_shell ] ;
|
||||||
|
|
||||||
local xfsSource =
|
local xfsSource =
|
||||||
|
BPlusTree.cpp
|
||||||
DeviceOpener.cpp
|
DeviceOpener.cpp
|
||||||
Directory.cpp
|
Directory.cpp
|
||||||
Extent.cpp
|
Extent.cpp
|
||||||
|
|||||||
Reference in New Issue
Block a user