1 /* 2 * Copyright 2020, Shubham Bhagat, shubhambhagat111@yahoo.com 3 * All rights reserved. Distributed under the terms of the MIT License. 4 */ 5 #ifndef _EXTENT_H_ 6 #define _EXTENT_H_ 7 8 9 #include "Inode.h" 10 #include "system_dependencies.h" 11 12 13 #define DIR2_BLOCK_HEADER_MAGIC 0x58443242 14 // for v4 system 15 #define DIR2_FREE_TAG 0xffff 16 #define XFS_DIR2_DATA_FD_COUNT 3 17 #define EXTENT_REC_SIZE 128 18 #define EXTENT_SIZE 16 19 #define BLOCKNO_FROM_ADDRESS(n, volume) \ 20 ((n) >> (volume->BlockLog() + volume->DirBlockLog())) 21 #define BLOCKOFFSET_FROM_ADDRESS(n, inode) ((n) & (inode->DirBlockSize() - 1)) 22 #define LEAF_STARTOFFSET(n) 1UL << (35 - (n)) 23 24 25 // xfs_exntst_t 26 enum ExtentState { 27 XFS_EXT_NORM, 28 XFS_EXT_UNWRITTEN, 29 XFS_EXT_INVALID 30 }; 31 32 33 // xfs_dir2_data_free_t 34 struct FreeRegion { 35 uint16 offset; 36 uint16 length; 37 }; 38 39 40 // xfs_dir2_data_hdr_t 41 struct ExtentDataHeader { 42 uint32 magic; 43 FreeRegion bestfree[XFS_DIR2_DATA_FD_COUNT]; 44 }; 45 46 47 // xfs_dir2_data_entry_t 48 struct ExtentDataEntry { 49 xfs_ino_t inumber; 50 uint8 namelen; 51 uint8 name[]; 52 53 // Followed by a file type (8bit) if applicable and a 16bit tag 54 // tag is the offset from start of the block 55 }; 56 57 58 // xfs_dir2_data_unused_t 59 struct ExtentUnusedEntry { 60 uint16 freetag; 61 // takes the value 0xffff 62 uint16 length; 63 // freetag+length overrides the inumber of an entry 64 uint16 tag; 65 }; 66 67 68 // xfs_dir2_leaf_entry_t 69 struct ExtentLeafEntry { 70 uint32 hashval; 71 uint32 address; 72 // offset into block after >> 3 73 }; 74 75 76 // xfs_dir2_block_tail_t 77 struct ExtentBlockTail { 78 uint32 count; 79 // # of entries in leaf 80 uint32 stale; 81 // # of free leaf entries 82 }; 83 84 85 struct ExtentMapEntry { 86 xfs_fileoff_t br_startoff; 87 // logical file block offset 88 xfs_fsblock_t br_startblock; 89 // absolute block number 90 xfs_filblks_t br_blockcount; 91 // # of blocks 92 uint8 br_state; 93 // state of the extent 94 }; 95 96 97 class Extent 98 { 99 public: 100 Extent(Inode* inode); 101 ~Extent(); 102 status_t Init(); 103 bool IsBlockType(); 104 void FillMapEntry(void* pointerToMap); 105 status_t FillBlockBuffer(); 106 ExtentBlockTail* BlockTail(); 107 ExtentLeafEntry* BlockFirstLeaf(ExtentBlockTail* tail); 108 xfs_ino_t GetIno(); 109 uint32 GetOffsetFromAddress(uint32 address); 110 int EntrySize(int len) const; 111 status_t GetNext(char* name, size_t* length, 112 xfs_ino_t* ino); 113 status_t Lookup(const char* name, size_t length, 114 xfs_ino_t* id); 115 private: 116 Inode* fInode; 117 ExtentMapEntry* fMap; 118 uint32 fOffset; 119 char* fBlockBuffer; 120 // This isn't inode data. It holds the directory block. 121 }; 122 123 124 #endif 125