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 BlockCount() const; 81 uint32 NLink() const; 82 uint16 Flags() const; 83 uint32 UserId() const; 84 uint32 GroupId() const; 85 xfs_extnum_t DataExtentsCount() const; 86 87 uint16 di_magic; 88 uint16 di_mode; 89 // uses standard S_Ixxx 90 int8 di_version; 91 //This either would be 1 or 2 92 int8 di_format; 93 uint16 di_onlink; 94 uint32 di_uid; 95 uint32 di_gid; 96 uint32 di_nlink; 97 uint16 di_projid; 98 uint8 di_pad[8]; 99 uint16 di_flushiter; 100 xfs_timestamp_t di_atime; 101 xfs_timestamp_t di_mtime; 102 xfs_timestamp_t di_ctime; 103 xfs_fsize_t di_size; 104 // size in bytes or length if link 105 xfs_rfsblock_t di_nblocks; 106 // blocks used including metadata 107 // extended attributes not included 108 xfs_extlen_t di_extsize; 109 // extent size 110 xfs_extnum_t di_nextents; 111 // number of data extents 112 xfs_aextnum_t di_anextents; 113 // number of EA extents 114 uint8 di_forkoff; 115 // decides where di_a starts 116 int8 di_aformat; 117 // similar to di_format 118 uint32 di_dmevmask; 119 uint16 di_dmstate; 120 uint16 di_flags; 121 uint32 di_gen; 122 123 uint32 di_next_unlinked; 124 }; 125 126 127 class Inode { 128 public: 129 Inode(Volume* volume, xfs_ino_t id); 130 ~Inode(); 131 status_t Init(); 132 133 xfs_ino_t ID() const { return fId; } 134 135 bool IsDirectory() const 136 { return S_ISDIR(Mode()); } 137 138 bool IsFile() const 139 { return S_ISREG(Mode()); } 140 141 bool IsSymLink() const 142 { return S_ISLNK(Mode()); } 143 144 mode_t Mode() const { return fNode->Mode(); } 145 146 Volume* GetVolume() { return fVolume;} 147 148 int8 Format() const { return fNode->Format(); } 149 150 bool IsLocal() const 151 { return 152 Format() == XFS_DINODE_FMT_LOCAL; } 153 154 uint32 NLink() const { return fNode->NLink(); } 155 156 int8 Version() const { return fNode->Version(); } 157 158 xfs_rfsblock_t BlockCount() const 159 { return fNode->BlockCount(); } 160 161 char* Buffer() { return fBuffer; } 162 163 int16 Flags() const { return fNode->Flags(); } 164 165 xfs_fsize_t Size() const { return fNode->Size(); } 166 167 uint32 DirBlockSize() const 168 { return fVolume->DirBlockSize(); } 169 170 void GetChangeTime(struct timespec& timestamp) const 171 { fNode->GetChangeTime(timestamp); } 172 173 void GetModificationTime(struct timespec& timestamp) 174 const 175 { fNode->GetModificationTime(timestamp); } 176 177 void GetAccessTime(struct timespec& timestamp) const 178 { fNode->GetAccessTime(timestamp); } 179 180 uint32 UserId() const { return fNode->UserId(); } 181 uint32 GroupId() const { return fNode->GroupId(); } 182 bool HasFileTypeField() const; 183 xfs_extnum_t DataExtentsCount() const 184 { return fNode->DataExtentsCount(); } 185 186 private: 187 status_t GetFromDisk(); 188 xfs_inode_t* fNode; 189 xfs_ino_t fId; 190 Volume* fVolume; 191 char* fBuffer; 192 // Contains the disk inode in BE format 193 }; 194 195 #endif 196