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, forkoff) \ 36 (void*)((char*)DIR_DFORK_PTR(dir_ino_ptr) + \ 37 (((uint32)forkoff)<<3)) 38 #define DIR_AFORK_EXIST(dir_ino_ptr) dir_ino_ptr->di_forkoff!=0 39 #define MASK(n) ((1UL << n) - 1) 40 #define FSBLOCKS_TO_AGNO(n, volume) ((n) >> volume->AgBlocksLog()) 41 #define FSBLOCKS_TO_AGBLOCKNO(n, volume) ((n) & MASK(volume->AgBlocksLog())) 42 43 44 // xfs_da_blkinfo_t 45 struct BlockInfo { 46 uint32 forw; 47 uint32 back; 48 uint16 magic; 49 uint16 pad; 50 }; 51 52 53 uint32 54 hashfunction(const char* name, int length); 55 56 57 struct xfs_timestamp_t { 58 int32 t_sec; 59 int32 t_nsec; 60 }; 61 62 63 enum xfs_dinode_fmt_t { 64 XFS_DINODE_FMT_DEV, 65 // For devices 66 XFS_DINODE_FMT_LOCAL, 67 // For Directories and links 68 XFS_DINODE_FMT_EXTENTS, 69 // For large number of extents 70 XFS_DINODE_FMT_BTREE, 71 // Extents and Directories 72 XFS_DINODE_FMT_UUID, 73 // Not used 74 }; 75 76 /* 77 * The xfs_ino_t is the same for all types of inodes, the data and attribute 78 * fork might be different and that is to be handled accordingly. 79 */ 80 struct xfs_inode_t { 81 void SwapEndian(); 82 int8 Version() const; 83 //TODO: Check 84 mode_t Mode() const; 85 void GetModificationTime(struct timespec& 86 timestamp); 87 void GetChangeTime(struct timespec& timestamp); 88 void GetAccessTime(struct timespec& timestamp); 89 int8 Format() const; 90 // The format of the inode 91 xfs_fsize_t Size() const; 92 xfs_rfsblock_t BlockCount() const; 93 uint32 NLink() const; 94 uint16 Flags() const; 95 uint32 UserId() const; 96 uint32 GroupId() const; 97 xfs_extnum_t DataExtentsCount() const; 98 uint8 ForkOffset() const; 99 uint16 di_magic; 100 uint16 di_mode; 101 // uses standard S_Ixxx 102 int8 di_version; 103 //This either would be 1 or 2 104 int8 di_format; 105 uint16 di_onlink; 106 uint32 di_uid; 107 uint32 di_gid; 108 uint32 di_nlink; 109 uint16 di_projid; 110 uint8 di_pad[8]; 111 uint16 di_flushiter; 112 xfs_timestamp_t di_atime; 113 xfs_timestamp_t di_mtime; 114 xfs_timestamp_t di_ctime; 115 xfs_fsize_t di_size; 116 // size in bytes or length if link 117 xfs_rfsblock_t di_nblocks; 118 // blocks used including metadata 119 // extended attributes not included 120 xfs_extlen_t di_extsize; 121 // extent size 122 xfs_extnum_t di_nextents; 123 // number of data extents 124 xfs_aextnum_t di_anextents; 125 // number of EA extents 126 uint8 di_forkoff; 127 // decides where di_a starts 128 int8 di_aformat; 129 // similar to di_format 130 uint32 di_dmevmask; 131 uint16 di_dmstate; 132 uint16 di_flags; 133 uint32 di_gen; 134 135 uint32 di_next_unlinked; 136 }; 137 138 139 class Inode { 140 public: 141 Inode(Volume* volume, xfs_ino_t id); 142 ~Inode(); 143 status_t Init(); 144 145 xfs_ino_t ID() const { return fId; } 146 147 bool IsDirectory() const 148 { return S_ISDIR(Mode()); } 149 150 bool IsFile() const 151 { return S_ISREG(Mode()); } 152 153 bool IsSymLink() const 154 { return S_ISLNK(Mode()); } 155 156 mode_t Mode() const { return fNode->Mode(); } 157 158 Volume* GetVolume() { return fVolume;} 159 160 int8 Format() const { return fNode->Format(); } 161 162 bool IsLocal() const 163 { return 164 Format() == XFS_DINODE_FMT_LOCAL; } 165 166 uint32 NLink() const { return fNode->NLink(); } 167 168 int8 Version() const { return fNode->Version(); } 169 170 xfs_rfsblock_t BlockCount() const 171 { return fNode->BlockCount(); } 172 173 char* Buffer() { return fBuffer; } 174 175 int16 Flags() const { return fNode->Flags(); } 176 177 xfs_fsize_t Size() const { return fNode->Size(); } 178 179 uint32 DirBlockSize() const 180 { return fVolume->DirBlockSize(); } 181 182 void GetChangeTime(struct timespec& timestamp) const 183 { fNode->GetChangeTime(timestamp); } 184 185 void GetModificationTime(struct timespec& timestamp) 186 const 187 { fNode->GetModificationTime(timestamp); } 188 189 void GetAccessTime(struct timespec& timestamp) const 190 { fNode->GetAccessTime(timestamp); } 191 192 status_t CheckPermissions(int accessMode) const; 193 uint32 UserId() const { return fNode->UserId(); } 194 uint32 GroupId() const { return fNode->GroupId(); } 195 bool HasFileTypeField() const; 196 xfs_extnum_t DataExtentsCount() const 197 { return fNode->DataExtentsCount(); } 198 uint64 FileSystemBlockToAddr(uint64 block); 199 uint8 ForkOffset() const 200 { return fNode->ForkOffset(); } 201 202 private: 203 status_t GetFromDisk(); 204 xfs_inode_t* fNode; 205 xfs_ino_t fId; 206 Volume* fVolume; 207 char* fBuffer; 208 // Contains the disk inode in BE format 209 }; 210 211 #endif 212