xfs: make Directory Iterator class an abstract class
Directory Iterator class represents one instance which could be Short, Extent, Leaf, Node or B+Tree, a good case for making it an abstract class Change-Id: I925255caf4c4f8bc01a975740ef2ebf0bb2e1b49 Reviewed-on: https://review.haiku-os.org/c/haiku/+/5764 Tested-by: Commit checker robot <no-reply+buildbot@haiku-os.org> Reviewed-by: Adrien Destugues <pulkomandy@pulkomandy.tk>
This commit is contained in:
parent
6610656e8f
commit
62a64d0a43
@ -6,6 +6,7 @@
|
||||
#define _BPLUS_TREE_H_
|
||||
|
||||
|
||||
#include "Directory.h"
|
||||
#include "Extent.h"
|
||||
#include "Inode.h"
|
||||
#include "LeafDirectory.h"
|
||||
@ -102,7 +103,7 @@ struct PathNode {
|
||||
/*
|
||||
* This class should handle B+Tree based directories
|
||||
*/
|
||||
class TreeDirectory {
|
||||
class TreeDirectory : public DirectoryIterator {
|
||||
public:
|
||||
TreeDirectory(Inode* inode);
|
||||
~TreeDirectory();
|
||||
|
@ -4,147 +4,84 @@
|
||||
*/
|
||||
|
||||
|
||||
#include "BPlusTree.h"
|
||||
#include "Directory.h"
|
||||
|
||||
|
||||
DirectoryIterator::DirectoryIterator(Inode* inode)
|
||||
:
|
||||
fInode(inode),
|
||||
fShortDir(NULL),
|
||||
fExtentDir(NULL),
|
||||
fLeafDir(NULL),
|
||||
fNodeDir(NULL),
|
||||
fTreeDir(NULL)
|
||||
{
|
||||
}
|
||||
#include "Extent.h"
|
||||
#include "LeafDirectory.h"
|
||||
#include "Node.h"
|
||||
#include "ShortDirectory.h"
|
||||
|
||||
|
||||
DirectoryIterator::~DirectoryIterator()
|
||||
{
|
||||
delete fShortDir;
|
||||
delete fLeafDir;
|
||||
delete fExtentDir;
|
||||
delete fNodeDir;
|
||||
delete fTreeDir;
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
DirectoryIterator::Init()
|
||||
DirectoryIterator*
|
||||
DirectoryIterator::Init(Inode* inode)
|
||||
{
|
||||
if (fInode->Format() == XFS_DINODE_FMT_LOCAL)
|
||||
{
|
||||
if (inode->Format() == XFS_DINODE_FMT_LOCAL) {
|
||||
TRACE("Iterator:Init: LOCAL");
|
||||
fShortDir = new(std::nothrow) ShortDirectory(fInode);
|
||||
if (fShortDir == NULL)
|
||||
return B_NO_MEMORY;
|
||||
return B_OK;
|
||||
ShortDirectory* shortDir = new(std::nothrow) ShortDirectory(inode);
|
||||
return shortDir;
|
||||
}
|
||||
if (fInode->Format() == XFS_DINODE_FMT_EXTENTS) {
|
||||
|
||||
if (inode->Format() == XFS_DINODE_FMT_EXTENTS) {
|
||||
TRACE("Iterator:Init: EXTENTS");
|
||||
fExtentDir = new(std::nothrow) Extent(fInode);
|
||||
if (fExtentDir == NULL)
|
||||
return B_NO_MEMORY;
|
||||
if (fExtentDir->IsBlockType())
|
||||
return fExtentDir->Init();
|
||||
status_t status;
|
||||
|
||||
delete fExtentDir;
|
||||
fExtentDir = NULL;
|
||||
// Check if it is extent based directory
|
||||
Extent* extentDir = new(std::nothrow) Extent(inode);
|
||||
if (extentDir == NULL)
|
||||
return NULL;
|
||||
|
||||
fLeafDir = new(std::nothrow) LeafDirectory(fInode);
|
||||
if (fLeafDir == NULL)
|
||||
return B_NO_MEMORY;
|
||||
if (fLeafDir->IsLeafType())
|
||||
return fLeafDir->Init();
|
||||
delete fLeafDir;
|
||||
fLeafDir = NULL;
|
||||
if (extentDir->IsBlockType()) {
|
||||
status = extentDir->Init();
|
||||
if (status == B_OK)
|
||||
return extentDir;
|
||||
}
|
||||
|
||||
fNodeDir = new(std::nothrow) NodeDirectory(fInode);
|
||||
if (fNodeDir == NULL)
|
||||
return B_NO_MEMORY;
|
||||
if (fNodeDir->IsNodeType())
|
||||
return fNodeDir->Init();
|
||||
delete fNodeDir;
|
||||
fNodeDir = NULL;
|
||||
delete extentDir;
|
||||
|
||||
// Check if it is leaf based directory
|
||||
LeafDirectory* leafDir = new(std::nothrow) LeafDirectory(inode);
|
||||
if (leafDir == NULL)
|
||||
return NULL;
|
||||
|
||||
if (leafDir->IsLeafType()) {
|
||||
status = leafDir->Init();
|
||||
if (status == B_OK)
|
||||
return leafDir;
|
||||
}
|
||||
|
||||
delete leafDir;
|
||||
|
||||
// Check if it is node based directory
|
||||
NodeDirectory* nodeDir = new(std::nothrow) NodeDirectory(inode);
|
||||
if (nodeDir == NULL)
|
||||
return NULL;
|
||||
|
||||
if (nodeDir->IsNodeType()) {
|
||||
status = nodeDir->Init();
|
||||
if (status == B_OK)
|
||||
return nodeDir;
|
||||
}
|
||||
|
||||
delete nodeDir;
|
||||
}
|
||||
|
||||
/* Return B_OK so even if the shortform directory has an extent directory
|
||||
* we can atleast still list the shortform directory
|
||||
*/
|
||||
if (fInode->Format() == XFS_DINODE_FMT_BTREE) {
|
||||
if (inode->Format() == XFS_DINODE_FMT_BTREE) {
|
||||
TRACE("Iterator:Init(): B+TREE");
|
||||
fTreeDir = new(std::nothrow) TreeDirectory(fInode);
|
||||
if (fTreeDir == NULL)
|
||||
return B_NO_MEMORY;
|
||||
return fTreeDir->InitCheck();
|
||||
TreeDirectory* treeDir = new(std::nothrow) TreeDirectory(inode);
|
||||
if (treeDir == NULL)
|
||||
return NULL;
|
||||
|
||||
status_t status = treeDir->InitCheck();
|
||||
|
||||
if (status == B_OK)
|
||||
return treeDir;
|
||||
}
|
||||
|
||||
return B_BAD_VALUE;
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
DirectoryIterator::GetNext(char* name, size_t* length, xfs_ino_t* ino)
|
||||
{
|
||||
status_t status;
|
||||
if (fInode->Format() == XFS_DINODE_FMT_LOCAL) {
|
||||
TRACE("Iterator:GetNext: LOCAL");
|
||||
status = fShortDir->GetNext(name, length, ino);
|
||||
return status;
|
||||
}
|
||||
|
||||
if (fInode->Format() == XFS_DINODE_FMT_EXTENTS) {
|
||||
TRACE("Iterator:GetNext: EXTENTS");
|
||||
if (fExtentDir != NULL)
|
||||
status = fExtentDir->GetNext(name, length, ino);
|
||||
else if (fLeafDir != NULL)
|
||||
status = fLeafDir->GetNext(name, length, ino);
|
||||
else
|
||||
status = fNodeDir->GetNext(name, length, ino);
|
||||
return status;
|
||||
}
|
||||
|
||||
if (fInode->Format() == XFS_DINODE_FMT_BTREE) {
|
||||
TRACE("Iterator:GetNext: B+TREE");
|
||||
if (fTreeDir != NULL)
|
||||
return status = fTreeDir->GetNext(name, length, ino);
|
||||
return B_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
// Only reaches here if Inode is a device or is corrupt.
|
||||
return B_BAD_VALUE;
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
DirectoryIterator::Lookup(const char* name, size_t length, xfs_ino_t* ino)
|
||||
{
|
||||
status_t status;
|
||||
if (fInode->Format() == XFS_DINODE_FMT_LOCAL) {
|
||||
TRACE("Iterator:Lookup: LOCAL\n");
|
||||
status = fShortDir->Lookup(name, length, ino);
|
||||
return status;
|
||||
}
|
||||
|
||||
//TODO: Reading from extent based dirs
|
||||
if (fInode->Format() == XFS_DINODE_FMT_EXTENTS) {
|
||||
TRACE("Iterator:Lookup: EXTENTS\n");
|
||||
if (fExtentDir != NULL)
|
||||
status = fExtentDir->Lookup(name, length, ino);
|
||||
else if (fLeafDir != NULL)
|
||||
status = fLeafDir->Lookup(name, length, ino);
|
||||
else
|
||||
status = fNodeDir->Lookup(name, length, ino);
|
||||
return status;
|
||||
}
|
||||
|
||||
//TODO: Reading from B+Tree based dirs
|
||||
if (fInode->Format() == XFS_DINODE_FMT_BTREE) {
|
||||
TRACE("Iterator:Lookup: B+TREE\n");
|
||||
if (fTreeDir != NULL)
|
||||
return fTreeDir->Lookup(name, length, ino);
|
||||
return B_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
return B_BAD_VALUE;
|
||||
}
|
||||
// Invalid format return NULL
|
||||
return NULL;
|
||||
}
|
@ -6,12 +6,7 @@
|
||||
#define _DIRECTORY_H_
|
||||
|
||||
|
||||
#include "BPlusTree.h"
|
||||
#include "Extent.h"
|
||||
#include "Inode.h"
|
||||
#include "LeafDirectory.h"
|
||||
#include "Node.h"
|
||||
#include "ShortDirectory.h"
|
||||
|
||||
|
||||
/*
|
||||
@ -20,26 +15,15 @@
|
||||
*/
|
||||
class DirectoryIterator {
|
||||
public:
|
||||
DirectoryIterator(Inode* inode);
|
||||
~DirectoryIterator();
|
||||
status_t Init();
|
||||
bool IsLocalDir() { return fInode->IsLocal(); }
|
||||
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);
|
||||
virtual ~DirectoryIterator() = 0;
|
||||
|
||||
private:
|
||||
Inode* fInode;
|
||||
ShortDirectory* fShortDir;
|
||||
// Short form Directory type
|
||||
Extent* fExtentDir;
|
||||
// Extent form Directory type
|
||||
// TODO: Rename all to block type
|
||||
LeafDirectory* fLeafDir;
|
||||
// Extent based leaf directory
|
||||
NodeDirectory* fNodeDir;
|
||||
TreeDirectory* fTreeDir;
|
||||
virtual status_t GetNext(char* name, size_t* length,
|
||||
xfs_ino_t* ino) = 0;
|
||||
|
||||
virtual status_t Lookup(const char* name, size_t length,
|
||||
xfs_ino_t* id) = 0;
|
||||
|
||||
static DirectoryIterator* Init(Inode* inode);
|
||||
};
|
||||
|
||||
|
||||
|
@ -7,6 +7,7 @@
|
||||
#define _EXTENT_H_
|
||||
|
||||
|
||||
#include "Directory.h"
|
||||
#include "Inode.h"
|
||||
#include "system_dependencies.h"
|
||||
|
||||
@ -152,8 +153,7 @@ struct ExtentBlockTail {
|
||||
};
|
||||
|
||||
|
||||
class Extent
|
||||
{
|
||||
class Extent : public DirectoryIterator {
|
||||
public:
|
||||
Extent(Inode* inode);
|
||||
~Extent();
|
||||
|
@ -7,6 +7,7 @@
|
||||
#define _LEAFDIRECTORY_H_
|
||||
|
||||
|
||||
#include "Directory.h"
|
||||
#include "Extent.h"
|
||||
#include "Inode.h"
|
||||
#include "system_dependencies.h"
|
||||
@ -99,7 +100,7 @@ struct ExtentLeafTail {
|
||||
};
|
||||
|
||||
|
||||
class LeafDirectory {
|
||||
class LeafDirectory : public DirectoryIterator {
|
||||
public:
|
||||
LeafDirectory(Inode* inode);
|
||||
~LeafDirectory();
|
||||
|
@ -6,6 +6,7 @@
|
||||
#define _NODE_H_
|
||||
|
||||
|
||||
#include "Directory.h"
|
||||
#include "Extent.h"
|
||||
#include "LeafDirectory.h"
|
||||
|
||||
@ -87,7 +88,7 @@ struct NodeEntry {
|
||||
};
|
||||
|
||||
|
||||
class NodeDirectory {
|
||||
class NodeDirectory : public DirectoryIterator {
|
||||
public:
|
||||
NodeDirectory(Inode* inode);
|
||||
~NodeDirectory();
|
||||
|
@ -6,6 +6,7 @@
|
||||
#define __SHORT_DIR_H__
|
||||
|
||||
|
||||
#include "Directory.h"
|
||||
#include "Inode.h"
|
||||
|
||||
|
||||
@ -50,8 +51,7 @@ struct ShortFormEntry {
|
||||
} __attribute__((packed));
|
||||
|
||||
|
||||
class ShortDirectory
|
||||
{
|
||||
class ShortDirectory : public DirectoryIterator {
|
||||
public:
|
||||
ShortDirectory(Inode* inode);
|
||||
~ShortDirectory();
|
||||
|
@ -205,16 +205,9 @@ xfs_lookup(fs_volume *_volume, fs_vnode *_directory, const char *name,
|
||||
if (status < B_OK)
|
||||
return status;
|
||||
|
||||
DirectoryIterator* iterator =
|
||||
new(std::nothrow) DirectoryIterator(directory);
|
||||
DirectoryIterator* iterator = DirectoryIterator::Init(directory);
|
||||
if (iterator == NULL)
|
||||
return B_NO_MEMORY;
|
||||
|
||||
status = iterator->Init();
|
||||
if (status != B_OK) {
|
||||
delete iterator;
|
||||
return status;
|
||||
}
|
||||
return B_BAD_VALUE;
|
||||
|
||||
status = iterator->Lookup(name, strlen(name), (xfs_ino_t*)_vnodeID);
|
||||
if (status != B_OK) {
|
||||
@ -407,12 +400,10 @@ xfs_open_dir(fs_volume * /*_volume*/, fs_vnode *_node, void **_cookie)
|
||||
if (!inode->IsDirectory())
|
||||
return B_NOT_A_DIRECTORY;
|
||||
|
||||
DirectoryIterator* iterator = new(std::nothrow) DirectoryIterator(inode);
|
||||
if (iterator == NULL) {
|
||||
delete iterator;
|
||||
return B_NO_MEMORY;
|
||||
}
|
||||
status = iterator->Init();
|
||||
DirectoryIterator* iterator = DirectoryIterator::Init(inode);
|
||||
if (iterator == NULL)
|
||||
return B_BAD_VALUE;
|
||||
|
||||
*_cookie = iterator;
|
||||
return status;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user