1 /* 2 * Copyright 2020, Shubham Bhagat, shubhambhagat111@yahoo.com 3 * All rights reserved. Distributed under the terms of the MIT License. 4 */ 5 #ifndef _INODE_H_ 6 #define _INODE_H_ 7 8 #include "system_dependencies.h" 9 #include "Volume.h" 10 #include "xfs_types.h" 11 12 13 #define INODE_MAGIC 0x494e 14 #define INODE_MINSIZE_LOG 8 15 #define INODE_MAXSIZE_LOG 11 16 #define INODE_CORE_SIZE 96 17 #define INODE_CORE_UNLINKED_SIZE 100 18 // Inode core but with unlinked pointer 19 #define DATA_FORK_OFFSET 0x64 20 // For v4 FS 21 #define INO_MASK(x) ((1ULL << (x)) - 1) 22 // Gets 2^x - 1 23 #define INO_TO_AGNO(id, volume) (xfs_agnumber_t)id >> (volume->AgInodeBits()) 24 // Gets AG number from inode number 25 #define INO_TO_AGINO(id, bits) (uint32) id & INO_MASK(bits); 26 // Gets the AG relative inode number 27 #define INO_TO_AGBLOCK(id, volume) \ 28 (id >> (volume->InodesPerBlkLog())) \ 29 & (INO_MASK(volume->AgBlocksLog())) 30 // Gets the AG relative block number that contains inode 31 #define INO_TO_BLOCKOFFSET(id, volume) (id & INO_MASK(volume->InodesPerBlkLog())) 32 // Gets the offset into the block from the inode number 33 #define DIR_DFORK_PTR(dir_ino_ptr) (void*) \ 34 ((char*) dir_ino_ptr + DATA_FORK_OFFSET) 35 #define DIR_AFORK_PTR(dir_ino_ptr) \ 36 (void*)((char*)XFS_DFORK_PTR + \ 37 ((uint32)dir_ino_ptr->di_forkoff<<3)) 38 #define DIR_AFORK_EXIST(dir_ino_ptr) dir_ino_ptr->di_forkoff!=0 39 40 41 uint32 42 hashfunction(const char* name, int length); 43 44 45 struct xfs_timestamp_t { 46 int32 t_sec; 47 int32 t_nsec; 48 }; 49 50 51 enum xfs_dinode_fmt_t { 52 XFS_DINODE_FMT_DEV, 53 // For devices 54 XFS_DINODE_FMT_LOCAL, 55 // For Directories and links 56 XFS_DINODE_FMT_EXTENTS, 57 // For large number of extents 58 XFS_DINODE_FMT_BTREE, 59 // Extents and Directories 60 XFS_DINODE_FMT_UUID, 61 // Not used 62 }; 63 64 /* 65 * The xfs_ino_t is the same for all types of inodes, the data and attribute 66 * fork might be different and that is to be handled accordingly. 67 */ 68 struct xfs_inode_t { 69 void SwapEndian(); 70 int8 Version() const; 71 //TODO: Check 72 mode_t Mode() const; 73 void GetModificationTime(struct timespec& 74 timestamp); 75 void GetChangeTime(struct timespec& timestamp); 76 void GetAccessTime(struct timespec& timestamp); 77 int8 Format() const; 78 // The format of the inode 79 xfs_fsize_t Size() const; 80 xfs_rfsblock_t NoOfBlocks() const; 81 uint32 NLink() const; 82 uint16 Flags() const; 83 uint32 UserId() const; 84 uint32 GroupId() const; 85 86 uint16 di_magic; 87 uint16 di_mode; 88 // uses standard S_Ixxx 89 int8 di_version; 90 //This either would be 1 or 2 91 int8 di_format; 92 uint16 di_onlink; 93 uint32 di_uid; 94 uint32 di_gid; 95 uint32 di_nlink; 96 uint16 di_projid; 97 uint8 di_pad[8]; 98 uint16 di_flushiter; 99 xfs_timestamp_t di_atime; 100 xfs_timestamp_t di_mtime; 101 xfs_timestamp_t di_ctime; 102 xfs_fsize_t di_size; 103 // size in bytes or length if link 104 xfs_rfsblock_t di_nblocks; 105 // blocks used including metadata 106 // extended attributes not included 107 xfs_extlen_t di_extsize; 108 // extent size 109 xfs_extnum_t di_nextents; 110 // number of data extents 111 xfs_aextnum_t di_anextents; 112 // number of EA extents 113 uint8 di_forkoff; 114 // decides where di_a starts 115 int8 di_aformat; 116 // similar to di_format 117 uint32 di_dmevmask; 118 uint16 di_dmstate; 119 uint16 di_flags; 120 uint32 di_gen; 121 122 uint32 di_next_unlinked; 123 }; 124 125 126 class Inode { 127 public: 128 Inode(Volume* volume, xfs_ino_t id); 129 ~Inode(); 130 status_t Init(); 131 132 xfs_ino_t ID() const { return fId; } 133 134 bool IsDirectory() const 135 { return S_ISDIR(Mode()); } 136 137 bool IsFile() const 138 { return S_ISREG(Mode()); } 139 140 bool IsSymLink() const 141 { return S_ISLNK(Mode()); } 142 143 mode_t Mode() const { return fNode->Mode(); } 144 145 Volume* GetVolume() { return fVolume;} 146 147 int8 Format() const { return fNode->Format(); } 148 149 bool IsLocal() const 150 { return 151 Format() == XFS_DINODE_FMT_LOCAL; } 152 153 uint32 NLink() const { return fNode->NLink(); } 154 155 int8 Version() const { return fNode->Version(); } 156 157 xfs_rfsblock_t NoOfBlocks() const 158 { return fNode->NoOfBlocks(); } 159 160 char* Buffer() { return fBuffer; } 161 162 int16 Flags() const { return fNode->Flags(); } 163 164 xfs_fsize_t Size() const { return fNode->Size(); } 165 166 uint32 DirBlockSize() const 167 { return fVolume->DirBlockSize(); } 168 169 void GetChangeTime(struct timespec& timestamp) const 170 { fNode->GetChangeTime(timestamp); } 171 172 void GetModificationTime(struct timespec& timestamp) 173 const 174 { fNode->GetModificationTime(timestamp); } 175 176 void GetAccessTime(struct timespec& timestamp) const 177 { fNode->GetAccessTime(timestamp); } 178 179 uint32 UserId() const { return fNode->UserId(); } 180 uint32 GroupId() const { return fNode->GroupId(); } 181 182 private: 183 status_t GetFromDisk(); 184 xfs_inode_t* fNode; 185 xfs_ino_t fId; 186 Volume* fVolume; 187 char* fBuffer; 188 // Contains the disk inode in BE format 189 }; 190 191 #endif 192