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 const 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 struct OnDiskData { 58 public: 59 uint16 count; 60 uint16 usedbytes; 61 uint16 firstused; 62 uint8 holes; 63 uint8 pad1; 64 AttrLeafMap freemap[3]; 65 BlockInfo info; 66 }; 67 68 AttrLeafHeaderV4(const char* buffer); 69 ~AttrLeafHeaderV4(); 70 void SwapEndian(); 71 uint16 Magic(); 72 uint64 Blockno(); 73 uint64 Owner(); 74 const uuid_t& Uuid(); 75 uint16 Count(); 76 77 private: 78 OnDiskData fData; 79 }; 80 81 82 //xfs_attr3_leaf_hdr 83 class AttrLeafHeaderV5 : public AttrLeafHeader { 84 public: 85 struct OnDiskData { 86 public: 87 uint16 count; 88 uint16 usedbytes; 89 uint16 firstused; 90 uint8 holes; 91 uint8 pad1; 92 AttrLeafMap freemap[3]; 93 uint32 pad2; 94 BlockInfoV5 info; 95 }; 96 97 AttrLeafHeaderV5(const char* buffer); 98 ~AttrLeafHeaderV5(); 99 void SwapEndian(); 100 uint16 Magic(); 101 uint64 Blockno(); 102 uint64 Owner(); 103 const uuid_t& Uuid(); 104 uint16 Count(); 105 106 private: 107 OnDiskData fData; 108 }; 109 110 111 // xfs_attr_leaf_entry 112 struct AttrLeafEntry { 113 uint32 hashval; 114 uint16 nameidx; 115 uint8 flags; 116 uint8 pad2; 117 }; 118 119 120 // xfs_attr_leaf_name_local 121 struct AttrLeafNameLocal { 122 uint16 valuelen; 123 uint8 namelen; 124 uint8 nameval[]; 125 }; 126 127 128 // xfs_attr_leaf_name_remote 129 struct AttrLeafNameRemote { 130 uint32 valueblk; 131 uint32 valuelen; 132 uint8 namelen; 133 uint8 name[]; 134 }; 135 136 137 struct AttrRemoteHeader { 138 uint32 rm_magic; 139 uint32 rm_offset; 140 uint32 rm_bytes; 141 uint32 rm_crc; 142 uuid_t rm_uuid; 143 uint64 rm_blkno; 144 uint64 rm_lsn; 145 }; 146 147 #define XFS_ATTR3_RMT_CRC_OFF offsetof(struct AttrRemoteHeader, rm_crc) 148 149 150 class LeafAttribute : public Attribute { 151 public: 152 LeafAttribute(Inode* inode); 153 ~LeafAttribute(); 154 155 status_t Init(); 156 157 status_t Stat(attr_cookie* cookie, struct stat& stat); 158 159 status_t Read(attr_cookie* cookie, off_t pos, 160 uint8* buffer, size_t* length); 161 162 status_t Open(const char* name, int openMode, attr_cookie** _cookie); 163 164 status_t GetNext(char* name, size_t* nameLength); 165 166 status_t Lookup(const char* name, size_t* nameLength); 167 private: 168 status_t _FillMapEntry(); 169 170 status_t _FillLeafBuffer(); 171 172 Inode* fInode; 173 const char* fName; 174 ExtentMapEntry* fMap; 175 char* fLeafBuffer; 176 uint16 fLastEntryOffset; 177 AttrLeafNameLocal* fLocalEntry; 178 AttrLeafNameRemote* fRemoteEntry; 179 }; 180 181 #endif 182