1 /* 2 * Copyright 2022, Raghav Sharma, raghavself28@gmail.com 3 * Copyright 2020, Shubham Bhagat, shubhambhagat111@yahoo.com 4 * All rights reserved. Distributed under the terms of the MIT License. 5 */ 6 #ifndef _EXTENT_H_ 7 #define _EXTENT_H_ 8 9 10 #include "Inode.h" 11 #include "system_dependencies.h" 12 13 14 #define DIR2_BLOCK_HEADER_MAGIC 0x58443242 15 // for v4 system 16 #define DIR3_BLOCK_HEADER_MAGIC 0x58444233 17 // for v5 system 18 #define DIR2_FREE_TAG 0xffff 19 #define XFS_DIR2_DATA_FD_COUNT 3 20 #define EXTENT_REC_SIZE 128 21 #define EXTENT_SIZE 16 22 #define BLOCKNO_FROM_ADDRESS(n, volume) \ 23 ((n) >> (volume->BlockLog() + volume->DirBlockLog())) 24 #define BLOCKOFFSET_FROM_ADDRESS(n, inode) ((n) & (inode->DirBlockSize() - 1)) 25 #define LEAF_STARTOFFSET(n) 1UL << (35 - (n)) 26 27 28 // xfs_exntst_t 29 enum ExtentState { 30 XFS_EXT_NORM, 31 XFS_EXT_UNWRITTEN, 32 XFS_EXT_INVALID 33 }; 34 35 36 // Enum values to check which directory we are reading 37 enum DirectoryType { 38 XFS_BLOCK, 39 XFS_LEAF, 40 XFS_NODE, 41 XFS_BTREE, 42 }; 43 44 45 // xfs_dir2_data_free_t 46 struct FreeRegion { 47 uint16 offset; 48 uint16 length; 49 }; 50 51 52 // This class will act as interface for V4 and V5 data header 53 class ExtentDataHeader { 54 public: 55 56 virtual ~ExtentDataHeader() = 0; 57 virtual uint32 Magic() = 0; 58 virtual uint64 Blockno() = 0; 59 virtual uint64 Lsn() = 0; 60 virtual uint64 Owner() = 0; 61 virtual uuid_t* Uuid() = 0; 62 static uint32 ExpectedMagic(int8 WhichDirectory, 63 Inode* inode); 64 static uint32 CRCOffset(); 65 static ExtentDataHeader* Create(Inode* inode, const char* buffer); 66 static uint32 Size(Inode* inode); 67 }; 68 69 70 //xfs_dir_data_hdr_t 71 class ExtentDataHeaderV4 : public ExtentDataHeader { 72 public : 73 74 ExtentDataHeaderV4(const char* buffer); 75 ~ExtentDataHeaderV4(); 76 void SwapEndian(); 77 uint32 Magic(); 78 uint64 Blockno(); 79 uint64 Lsn(); 80 uint64 Owner(); 81 uuid_t* Uuid(); 82 83 uint32 magic; 84 private: 85 FreeRegion bestfree[XFS_DIR2_DATA_FD_COUNT]; 86 }; 87 88 89 // xfs_dir3_data_hdr_t 90 class ExtentDataHeaderV5 : public ExtentDataHeader { 91 public: 92 ExtentDataHeaderV5(const char* buffer); 93 ~ExtentDataHeaderV5(); 94 void SwapEndian(); 95 uint32 Magic(); 96 uint64 Blockno(); 97 uint64 Lsn(); 98 uint64 Owner(); 99 uuid_t* Uuid(); 100 public: 101 uint32 magic; 102 uint32 crc; 103 private: 104 uint64 blkno; 105 uint64 lsn; 106 uuid_t uuid; 107 uint64 owner; 108 FreeRegion bestfree[XFS_DIR2_DATA_FD_COUNT]; 109 uint32 pad; 110 }; 111 112 #define XFS_EXTENT_CRC_OFF offsetof(ExtentDataHeaderV5, crc) 113 #define XFS_EXTENT_V5_VPTR_OFF offsetof(ExtentDataHeaderV5, magic) 114 #define XFS_EXTENT_V4_VPTR_OFF offsetof(ExtentDataHeaderV4, magic) 115 116 117 // xfs_dir2_data_entry_t 118 struct ExtentDataEntry { 119 xfs_ino_t inumber; 120 uint8 namelen; 121 uint8 name[]; 122 123 // Followed by a file type (8bit) if applicable and a 16bit tag 124 // tag is the offset from start of the block 125 }; 126 127 128 // xfs_dir2_data_unused_t 129 struct ExtentUnusedEntry { 130 uint16 freetag; 131 // takes the value 0xffff 132 uint16 length; 133 // freetag+length overrides the inumber of an entry 134 uint16 tag; 135 }; 136 137 138 // xfs_dir2_leaf_entry_t 139 struct ExtentLeafEntry { 140 uint32 hashval; 141 uint32 address; 142 // offset into block after >> 3 143 }; 144 145 146 // xfs_dir2_block_tail_t 147 struct ExtentBlockTail { 148 uint32 count; 149 // # of entries in leaf 150 uint32 stale; 151 // # of free leaf entries 152 }; 153 154 155 class Extent 156 { 157 public: 158 Extent(Inode* inode); 159 ~Extent(); 160 status_t Init(); 161 bool IsBlockType(); 162 void FillMapEntry(void* pointerToMap); 163 status_t FillBlockBuffer(); 164 ExtentBlockTail* BlockTail(); 165 ExtentLeafEntry* BlockFirstLeaf(ExtentBlockTail* tail); 166 xfs_ino_t GetIno(); 167 uint32 GetOffsetFromAddress(uint32 address); 168 int EntrySize(int len) const; 169 status_t GetNext(char* name, size_t* length, 170 xfs_ino_t* ino); 171 status_t Lookup(const char* name, size_t length, 172 xfs_ino_t* id); 173 private: 174 Inode* fInode; 175 ExtentMapEntry* fMap; 176 uint32 fOffset; 177 char* fBlockBuffer; 178 // This isn't inode data. It holds the directory block. 179 }; 180 181 #endif 182