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