xref: /haiku/src/add-ons/kernel/file_systems/xfs/Directory.cpp (revision 410ed2fbba58819ac21e27d3676739728416761d)
1 /*
2  * Copyright 2020, Shubham Bhagat, shubhambhagat111@yahoo.com
3  * All rights reserved. Distributed under the terms of the MIT License.
4  */
5 
6 
7 #include "Directory.h"
8 
9 
10 DirectoryIterator::DirectoryIterator(Inode* inode)
11 	:
12 	fInode(inode),
13 	fShortDir(NULL),
14 	fExtentDir(NULL),
15 	fLeafDir(NULL),
16 	fNodeDir(NULL)
17 {
18 }
19 
20 
21 DirectoryIterator::~DirectoryIterator()
22 {
23 	delete fShortDir;
24 	delete fLeafDir;
25 	delete fExtentDir;
26 	delete fNodeDir;
27 }
28 
29 
30 status_t
31 DirectoryIterator::Init()
32 {
33 	if (fInode->Format() == XFS_DINODE_FMT_LOCAL)
34 	{
35 		fShortDir = new(std::nothrow) ShortDirectory(fInode);
36 		if (fShortDir == NULL)
37 			return B_NO_MEMORY;
38 		return B_OK;
39 	}
40 	if (fInode->Format() == XFS_DINODE_FMT_EXTENTS) {
41 		// TODO: Only working with Block directories, not leaf.
42 		fExtentDir = new(std::nothrow) Extent(fInode);
43 		if (fExtentDir == NULL)
44 			return B_NO_MEMORY;
45 		if (fExtentDir->IsBlockType())
46 			return fExtentDir->Init();
47 
48 		delete fExtentDir;
49 		fExtentDir = NULL;
50 
51 		fLeafDir = new(std::nothrow) LeafDirectory(fInode);
52 		if (fLeafDir == NULL)
53 			return B_NO_MEMORY;
54 		status_t status = fLeafDir->Init();
55 		if (status != B_OK)
56 			return status;
57 		if (fLeafDir->IsLeafType())
58 			return B_OK;
59 		delete fLeafDir;
60 		fLeafDir = NULL;
61 
62 		fNodeDir = new(std::nothrow) NodeDirectory(fInode);
63 		if (fNodeDir == NULL)
64 			return B_NO_MEMORY;
65 		status = fNodeDir->Init();
66 		if (status != B_OK)
67 			return status;
68 		if (fNodeDir->IsNodeType())
69 			return B_OK;
70 		delete fNodeDir;
71 		fNodeDir = NULL;
72 	}
73 
74 	/* Return B_OK so even if the shortform directory has an extent directory
75 	 * we can atleast still list the shortform directory
76 	 */
77 
78 	//TODO: Reading from extent based directories
79 	if (fInode->Format() == XFS_DINODE_FMT_EXTENTS) {
80 		TRACE("Iterator:GetNext: EXTENTS");
81 		return B_OK;
82 	}
83 
84 	//TODO: Reading from B+Trees based directories
85 	if (fInode->Format() == XFS_DINODE_FMT_BTREE) {
86 		TRACE("Iterator:GetNext: B+TREE");
87 		return B_OK;
88 	}
89 
90 	return B_BAD_VALUE;
91 }
92 
93 
94 status_t
95 DirectoryIterator::GetNext(char* name, size_t* length, xfs_ino_t* ino)
96 {
97 	status_t status;
98 	if (fInode->Format() == XFS_DINODE_FMT_LOCAL) {
99 		status = fShortDir->GetNext(name, length, ino);
100 		return status;
101 	}
102 
103 	//TODO: Reading from extent based directories
104 	if (fInode->Format() == XFS_DINODE_FMT_EXTENTS) {
105 		TRACE("Iterator:GetNext: EXTENTS");
106 		if (fExtentDir != NULL)
107 			status = fExtentDir->GetNext(name, length, ino);
108 		else if (fLeafDir != NULL)
109 			status = fLeafDir->GetNext(name, length, ino);
110 		else
111 			status = fNodeDir->GetNext(name, length, ino);
112 		return status;
113 	}
114 
115 	//TODO: Reading from B+Trees based directories
116 	if (fInode->Format() == XFS_DINODE_FMT_BTREE) {
117 		TRACE("Iterator:GetNext: B+TREE");
118 		return B_NOT_SUPPORTED;
119 	}
120 
121 	// Only reaches here if Inode is a device or is corrupt.
122 	return B_BAD_VALUE;
123 }
124 
125 
126 status_t
127 DirectoryIterator::Lookup(const char* name, size_t length, xfs_ino_t* ino)
128 {
129 	status_t status;
130 	if (fInode->Format() == XFS_DINODE_FMT_LOCAL) {
131 		status = fShortDir->Lookup(name, length, ino);
132 		return status;
133 	}
134 
135 	//TODO: Reading from extent based dirs
136 	if (fInode->Format() == XFS_DINODE_FMT_EXTENTS) {
137 		TRACE("Iterator:Lookup: EXTENTS");
138 		if (fExtentDir != NULL)
139 			status = fExtentDir->Lookup(name, length, ino);
140 		else if (fLeafDir != NULL)
141 			status = fLeafDir->Lookup(name, length, ino);
142 		else
143 			status = fNodeDir->Lookup(name, length, ino);
144 		return status;
145 	}
146 
147 	//TODO: Reading from B+Tree based dirs
148 	if (fInode->Format() == XFS_DINODE_FMT_BTREE) {
149 		TRACE("Iterator:Lookup: B+TREE");
150 		return B_NOT_SUPPORTED;
151 	}
152 
153 	return B_BAD_VALUE;
154 }
155