1 /* 2 * Copyright 2022, Raghav Sharma, raghavself28@gmail.com 3 * Distributed under the terms of the MIT License. 4 */ 5 #ifndef LEAF_ATTRIBUTE_H 6 #define LEAF_ATTRIBUTE_H 7 8 9 #include "Attribute.h" 10 #include "Inode.h" 11 12 13 #define XFS_ATTR_LEAF_MAPSIZE 3 14 #define XFS_ATTR_LEAF_MAGIC 0xfbee 15 #define XFS_ATTR3_LEAF_MAGIC 0x3bee 16 #define XFS_ATTR_LOCAL_BIT 0 17 #define XFS_ATTR_LOCAL (1 << XFS_ATTR_LOCAL_BIT) 18 #define XFS_ATTR3_RMT_MAGIC 0x5841524d 19 20 21 // Enum values to check which directory we are reading 22 enum AttrType { 23 ATTR_LEAF, 24 ATTR_NODE, 25 ATTR_BTREE, 26 }; 27 28 29 // xfs_attr_leaf_map 30 struct AttrLeafMap { 31 uint16 base; 32 uint16 size; 33 }; 34 35 36 // This class will act as interface for V4 and V5 Attr leaf header 37 class AttrLeafHeader { 38 public: 39 40 virtual ~AttrLeafHeader() = 0; 41 virtual uint16 Magic() = 0; 42 virtual uint64 Blockno() = 0; 43 virtual uint64 Owner() = 0; 44 virtual uuid_t* Uuid() = 0; 45 virtual uint16 Count() = 0; 46 static uint32 ExpectedMagic(int8 WhichDirectory, 47 Inode* inode); 48 static uint32 CRCOffset(); 49 static AttrLeafHeader* Create(Inode* inode, const char* buffer); 50 static uint32 Size(Inode* inode); 51 }; 52 53 54 //xfs_attr_leaf_hdr 55 class AttrLeafHeaderV4 : public AttrLeafHeader { 56 public: 57 58 AttrLeafHeaderV4(const char* buffer); 59 ~AttrLeafHeaderV4(); 60 void SwapEndian(); 61 uint16 Magic(); 62 uint64 Blockno(); 63 uint64 Owner(); 64 uuid_t* Uuid(); 65 uint16 Count(); 66 67 BlockInfo info; 68 private: 69 uint16 count; 70 uint16 usedbytes; 71 uint16 firstused; 72 uint8 holes; 73 uint8 pad1; 74 AttrLeafMap freemap[3]; 75 }; 76 77 78 //xfs_attr3_leaf_hdr 79 class AttrLeafHeaderV5 : public AttrLeafHeader { 80 public: 81 82 AttrLeafHeaderV5(const char* buffer); 83 ~AttrLeafHeaderV5(); 84 void SwapEndian(); 85 uint16 Magic(); 86 uint64 Blockno(); 87 uint64 Owner(); 88 uuid_t* Uuid(); 89 uint16 Count(); 90 91 BlockInfoV5 info; 92 private: 93 uint16 count; 94 uint16 usedbytes; 95 uint16 firstused; 96 uint8 holes; 97 uint8 pad1; 98 AttrLeafMap freemap[3]; 99 uint32 pad2; 100 }; 101 102 #define ATTR_LEAF_CRC_OFF offsetof(ExtentLeafHeaderV5, info.crc) 103 #define ATTR_LEAF_V5_VPTR_OFF offsetof(ExtentLeafHeaderV5, info.forw) 104 #define ATTR_LEAF_V4_VPTR_OFF offsetof(ExtentLeafHeaderV4, info.forw) 105 106 107 // xfs_attr_leaf_entry 108 struct AttrLeafEntry { 109 uint32 hashval; 110 uint16 nameidx; 111 uint8 flags; 112 uint8 pad2; 113 }; 114 115 116 // xfs_attr_leaf_name_local 117 struct AttrLeafNameLocal { 118 uint16 valuelen; 119 uint8 namelen; 120 uint8 nameval[]; 121 }; 122 123 124 // xfs_attr_leaf_name_remote 125 struct AttrLeafNameRemote { 126 uint32 valueblk; 127 uint32 valuelen; 128 uint8 namelen; 129 uint8 name[]; 130 }; 131 132 133 struct AttrRemoteHeader { 134 uint32 rm_magic; 135 uint32 rm_offset; 136 uint32 rm_bytes; 137 uint32 rm_crc; 138 uuid_t rm_uuid; 139 uint64 rm_blkno; 140 uint64 rm_lsn; 141 }; 142 143 #define XFS_ATTR3_RMT_CRC_OFF offsetof(struct AttrRemoteHeader, rm_crc) 144 145 146 class LeafAttribute : public Attribute { 147 public: 148 LeafAttribute(Inode* inode); 149 ~LeafAttribute(); 150 151 status_t Init(); 152 153 status_t Stat(attr_cookie* cookie, struct stat& stat); 154 155 status_t Read(attr_cookie* cookie, off_t pos, 156 uint8* buffer, size_t* length); 157 158 status_t Open(const char* name, int openMode, attr_cookie** _cookie); 159 160 status_t GetNext(char* name, size_t* nameLength); 161 162 status_t Lookup(const char* name, size_t* nameLength); 163 private: 164 status_t _FillMapEntry(); 165 166 status_t _FillLeafBuffer(); 167 168 Inode* fInode; 169 const char* fName; 170 ExtentMapEntry* fMap; 171 char* fLeafBuffer; 172 uint16 fLastEntryOffset; 173 AttrLeafNameLocal* fLocalEntry; 174 AttrLeafNameRemote* fRemoteEntry; 175 }; 176 177 #endif