/* * Copyright 2022, Raghav Sharma, raghavself28@gmail.com * Copyright 2020, Shubham Bhagat, shubhambhagat111@yahoo.com * All rights reserved. Distributed under the terms of the MIT License. */ #ifndef _LEAFDIRECTORY_H_ #define _LEAFDIRECTORY_H_ #include "Directory.h" #include "Extent.h" #include "Inode.h" #include "system_dependencies.h" #define V4_DATA_HEADER_MAGIC 0x58443244 #define V5_DATA_HEADER_MAGIC 0x58444433 #define V4_LEAF_HEADER_MAGIC 0xd2f1 #define V5_LEAF_HEADER_MAGIC 0x3df1 enum ContentType { DATA, LEAF }; // This class will act as interface for V4 and V5 leaf header class ExtentLeafHeader { public: virtual ~ExtentLeafHeader() = 0; virtual uint16 Magic() = 0; virtual uint64 Blockno() = 0; virtual uint64 Lsn() = 0; virtual uint64 Owner() = 0; virtual const uuid_t& Uuid() = 0; virtual uint16 Count() = 0; virtual uint32 Forw() = 0; static uint32 ExpectedMagic(int8 WhichDirectory, Inode* inode); static uint32 CRCOffset(); static ExtentLeafHeader* Create(Inode* inode, const char* buffer); static uint32 Size(Inode* inode); }; //xfs_dir_leaf_hdr_t class ExtentLeafHeaderV4 : public ExtentLeafHeader { public: struct OnDiskData { public: BlockInfo info; uint16 count; uint16 stale; }; ExtentLeafHeaderV4(const char* buffer); ~ExtentLeafHeaderV4(); void SwapEndian(); uint16 Magic(); uint64 Blockno(); uint64 Lsn(); uint64 Owner(); const uuid_t& Uuid(); uint16 Count(); uint32 Forw(); private: OnDiskData fData; }; // xfs_dir3_leaf_hdr_t class ExtentLeafHeaderV5 : public ExtentLeafHeader { public: struct OnDiskData { BlockInfoV5 info; uint16 count; uint16 stale; uint32 pad; }; ExtentLeafHeaderV5(const char* buffer); ~ExtentLeafHeaderV5(); void SwapEndian(); uint16 Magic(); uint64 Blockno(); uint64 Lsn(); uint64 Owner(); const uuid_t& Uuid(); uint16 Count(); uint32 Forw(); private: OnDiskData fData; }; // xfs_dir2_leaf_tail_t struct ExtentLeafTail { uint32 bestcount; // # of best free entries }; class LeafDirectory : public DirectoryIterator { public: LeafDirectory(Inode* inode); ~LeafDirectory(); status_t Init(); bool IsLeafType(); void FillMapEntry(int num, ExtentMapEntry* map); status_t FillBuffer(int type, char* buffer, int howManyBlocksFurthur); void SearchAndFillDataMap(uint64 blockNo); ExtentLeafEntry* FirstLeaf(); xfs_ino_t GetIno(); uint32 GetOffsetFromAddress(uint32 address); int EntrySize(int len) const; status_t GetNext(char* name, size_t* length, xfs_ino_t* ino); status_t Lookup(const char* name, size_t length, xfs_ino_t* id); private: Inode* fInode; ExtentMapEntry* fDataMap; ExtentMapEntry* fLeafMap; uint32 fOffset; char* fDataBuffer; // This isn't inode data. It holds the directory block. char* fLeafBuffer; uint32 fCurBlockNumber; }; #endif