1/*
2 * Copyright 2020, Shubham Bhagat, shubhambhagat111@yahoo.com
3 * All rights reserved. Distributed under the terms of the MIT License.
4 */
5#ifndef _NODE_H_
6#define _NODE_H_
7
8
9#include "Directory.h"
10#include "Extent.h"
11#include "LeafDirectory.h"
12
13
14#define XFS_DIR2_LEAFN_MAGIC (0xd2ff)
15#define XFS_DIR3_LEAFN_MAGIC (0x3dff)
16#define XFS_DA_NODE_MAGIC (0xfebe)
17#define XFS_DA3_NODE_MAGIC (0x3ebe)
18
19
20class NodeHeader
21{
22public:
23			virtual						~NodeHeader()			=	0;
24			virtual	uint16				Magic()					=	0;
25			virtual	uint64				Blockno()				=	0;
26			virtual	uint64				Lsn()					=	0;
27			virtual	uint64				Owner()					=	0;
28			virtual	const uuid_t&		Uuid()					=	0;
29			virtual	uint16				Count()					=	0;
30
31			static	uint32				ExpectedMagic(int8 WhichDirectory,
32										Inode* inode);
33			static	uint32				CRCOffset();
34			static	NodeHeader*			Create(Inode* inode, const char* buffer);
35			static	uint32				Size(Inode* inode);
36};
37
38
39//xfs_da_node_hdr
40class NodeHeaderV4 : public NodeHeader
41{
42public:
43			struct OnDiskData {
44			public:
45				BlockInfo			info;
46				uint16				count;
47				uint16				level;
48			};
49
50								NodeHeaderV4(const char* buffer);
51								~NodeHeaderV4();
52			void				SwapEndian();
53			uint16				Magic();
54			uint64				Blockno();
55			uint64				Lsn();
56			uint64				Owner();
57			const uuid_t&		Uuid();
58			uint16				Count();
59
60private:
61			OnDiskData 			fData;
62};
63
64
65class NodeHeaderV5 : public NodeHeader {
66public:
67			struct OnDiskData {
68			public:
69				BlockInfoV5			info;
70				uint16				count;
71				uint16				level;
72				uint32				pad32;
73			};
74
75								NodeHeaderV5(const char* buffer);
76								~NodeHeaderV5();
77			void				SwapEndian();
78			uint16				Magic();
79			uint64				Blockno();
80			uint64				Lsn();
81			uint64				Owner();
82			const uuid_t&		Uuid();
83			uint16				Count();
84
85private:
86			OnDiskData 			fData;
87};
88
89
90//xfs_da_node_entry
91struct NodeEntry {
92			uint32				hashval;
93			uint32				before;
94};
95
96
97class NodeDirectory : public DirectoryIterator {
98public:
99								NodeDirectory(Inode* inode);
100								~NodeDirectory();
101			status_t			Init();
102			bool				IsNodeType();
103			void				FillMapEntry(int num, ExtentMapEntry* map);
104			status_t			FillBuffer(int type, char* buffer,
105									int howManyBlocksFurther);
106			void				SearchAndFillDataMap(uint64 blockNo);
107			status_t			FindHashInNode(uint32 hashVal, uint32* rightMapOffset);
108			uint32				GetOffsetFromAddress(uint32 address);
109			xfs_extnum_t		FirstLeafMapIndex();
110			int					EntrySize(int len) const;
111			status_t			GetNext(char* name, size_t* length,
112									xfs_ino_t* ino);
113			status_t			Lookup(const char* name, size_t length,
114									xfs_ino_t* id);
115private:
116			Inode*				fInode;
117			ExtentMapEntry*		fDataMap;
118			ExtentMapEntry*		fLeafMap;
119			uint32				fOffset;
120			char*				fDataBuffer;
121				// This isn't inode data. It holds the directory block.
122			char*				fLeafBuffer;
123			uint32				fCurBlockNumber;
124			uint8				fCurLeafMapNumber;
125			uint8				fCurLeafBufferNumber;
126			xfs_extnum_t		fFirstLeafMapIndex;
127};
128
129#endif
130