* Copyright 2022, Raghav Sharma, raghavself28@gmail.com
* Distributed under the terms of the MIT License.
*/
#ifndef LEAF_ATTRIBUTE_H
#define LEAF_ATTRIBUTE_H
#include "Attribute.h"
#include "Inode.h"
#define XFS_ATTR_LEAF_MAPSIZE 3
#define XFS_ATTR_LEAF_MAGIC 0xfbee
#define XFS_ATTR3_LEAF_MAGIC 0x3bee
#define XFS_ATTR_LOCAL_BIT 0
#define XFS_ATTR_LOCAL (1 << XFS_ATTR_LOCAL_BIT)
#define XFS_ATTR3_RMT_MAGIC 0x5841524d
enum AttrType {
ATTR_LEAF,
ATTR_NODE,
ATTR_BTREE,
};
struct AttrLeafMap {
uint16 base;
uint16 size;
};
class AttrLeafHeader {
public:
virtual ~AttrLeafHeader() = 0;
virtual uint16 Magic() = 0;
virtual uint64 Blockno() = 0;
virtual uint64 Owner() = 0;
virtual const uuid_t& Uuid() = 0;
virtual uint16 Count() = 0;
static uint32 ExpectedMagic(int8 WhichDirectory,
Inode* inode);
static uint32 CRCOffset();
static AttrLeafHeader* Create(Inode* inode, const char* buffer);
static uint32 Size(Inode* inode);
};
class AttrLeafHeaderV4 : public AttrLeafHeader {
public:
struct OnDiskData {
public:
uint16 count;
uint16 usedbytes;
uint16 firstused;
uint8 holes;
uint8 pad1;
AttrLeafMap freemap[3];
BlockInfo info;
};
AttrLeafHeaderV4(const char* buffer);
~AttrLeafHeaderV4();
void SwapEndian();
uint16 Magic();
uint64 Blockno();
uint64 Owner();
const uuid_t& Uuid();
uint16 Count();
private:
OnDiskData fData;
};
class AttrLeafHeaderV5 : public AttrLeafHeader {
public:
struct OnDiskData {
public:
uint16 count;
uint16 usedbytes;
uint16 firstused;
uint8 holes;
uint8 pad1;
AttrLeafMap freemap[3];
uint32 pad2;
BlockInfoV5 info;
};
AttrLeafHeaderV5(const char* buffer);
~AttrLeafHeaderV5();
void SwapEndian();
uint16 Magic();
uint64 Blockno();
uint64 Owner();
const uuid_t& Uuid();
uint16 Count();
private:
OnDiskData fData;
};
struct AttrLeafEntry {
uint32 hashval;
uint16 nameidx;
uint8 flags;
uint8 pad2;
};
struct AttrLeafNameLocal {
uint16 valuelen;
uint8 namelen;
uint8 nameval[];
};
struct AttrLeafNameRemote {
uint32 valueblk;
uint32 valuelen;
uint8 namelen;
uint8 name[];
};
struct AttrRemoteHeader {
uint32 rm_magic;
uint32 rm_offset;
uint32 rm_bytes;
uint32 rm_crc;
uuid_t rm_uuid;
uint64 rm_blkno;
uint64 rm_lsn;
};
#define XFS_ATTR3_RMT_CRC_OFF offsetof(struct AttrRemoteHeader, rm_crc)
class LeafAttribute : public Attribute {
public:
LeafAttribute(Inode* inode);
~LeafAttribute();
status_t Init();
status_t Stat(attr_cookie* cookie, struct stat& stat);
status_t Read(attr_cookie* cookie, off_t pos,
uint8* buffer, size_t* length);
status_t Open(const char* name, int openMode, attr_cookie** _cookie);
status_t GetNext(char* name, size_t* nameLength);
status_t Lookup(const char* name, size_t* nameLength);
private:
status_t _FillMapEntry();
status_t _FillLeafBuffer();
Inode* fInode;
const char* fName;
ExtentMapEntry* fMap;
char* fLeafBuffer;
uint16 fLastEntryOffset;
AttrLeafNameLocal* fLocalEntry;
AttrLeafNameRemote* fRemoteEntry;
};
#endif