xref: /haiku/src/add-ons/kernel/file_systems/xfs/Extent.h (revision 388d91a7b829b91b95abd2505437d431c468ce7d)
1 /*
2  * Copyright 2022, Raghav Sharma, raghavself28@gmail.com
3  * Copyright 2020, Shubham Bhagat, shubhambhagat111@yahoo.com
4  * All rights reserved. Distributed under the terms of the MIT License.
5  */
6 #ifndef _EXTENT_H_
7 #define _EXTENT_H_
8 
9 
10 #include "Inode.h"
11 #include "system_dependencies.h"
12 
13 
14 #define DIR2_BLOCK_HEADER_MAGIC 0x58443242
15 	// for v4 system
16 #define DIR3_BLOCK_HEADER_MAGIC 0x58444233
17 	// for v5 system
18 #define DIR2_FREE_TAG 0xffff
19 #define XFS_DIR2_DATA_FD_COUNT 3
20 #define EXTENT_REC_SIZE		128
21 #define EXTENT_SIZE 16
22 #define BLOCKNO_FROM_ADDRESS(n, volume) \
23 	((n) >> (volume->BlockLog() + volume->DirBlockLog()))
24 #define BLOCKOFFSET_FROM_ADDRESS(n, inode) ((n) & (inode->DirBlockSize() - 1))
25 #define LEAF_STARTOFFSET(n) 1UL << (35 - (n))
26 
27 
28 // xfs_exntst_t
29 enum ExtentState {
30 	XFS_EXT_NORM,
31 	XFS_EXT_UNWRITTEN,
32 	XFS_EXT_INVALID
33 };
34 
35 
36 // Enum values to check which directory we are reading
37 enum DirectoryType {
38 	XFS_BLOCK,
39 	XFS_LEAF,
40 	XFS_NODE,
41 	XFS_BTREE,
42 };
43 
44 
45 // xfs_dir2_data_free_t
46 struct FreeRegion {
47 			uint16				offset;
48 			uint16				length;
49 };
50 
51 
52 // This class will act as interface for V4 and V5 data header
53 class ExtentDataHeader {
54 public:
55 
56 			virtual						~ExtentDataHeader()			=	0;
57 			virtual uint32				Magic()						=	0;
58 			virtual uint64				Blockno()					=	0;
59 			virtual uint64				Lsn()						=	0;
60 			virtual uint64				Owner()						=	0;
61 			virtual uuid_t*				Uuid()						=	0;
62 			static	uint32				ExpectedMagic(int8 WhichDirectory,
63 										Inode* inode);
64 			static	uint32				CRCOffset();
65 };
66 
67 
68 //xfs_dir_data_hdr_t
69 class ExtentDataHeaderV4 : public ExtentDataHeader {
70 public :
71 
72 								ExtentDataHeaderV4(const char* buffer);
73 								~ExtentDataHeaderV4();
74 			void				SwapEndian();
75 			uint32				Magic();
76 			uint64				Blockno();
77 			uint64				Lsn();
78 			uint64				Owner();
79 			uuid_t*				Uuid();
80 
81 			uint32				magic;
82 private:
83 			FreeRegion			bestfree[XFS_DIR2_DATA_FD_COUNT];
84 };
85 
86 
87 // xfs_dir3_data_hdr_t
88 class ExtentDataHeaderV5 : public ExtentDataHeader {
89 public:
90 								ExtentDataHeaderV5(const char* buffer);
91 								~ExtentDataHeaderV5();
92 			void				SwapEndian();
93 			uint32				Magic();
94 			uint64				Blockno();
95 			uint64				Lsn();
96 			uint64				Owner();
97 			uuid_t*				Uuid();
98 public:
99 			uint32				magic;
100 			uint32				crc;
101 private:
102 			uint64				blkno;
103 			uint64				lsn;
104 			uuid_t				uuid;
105 			uint64				owner;
106 			FreeRegion			bestfree[XFS_DIR2_DATA_FD_COUNT];
107 			uint32				pad;
108 };
109 
110 #define XFS_EXTENT_CRC_OFF  offsetof(ExtentDataHeaderV5, crc)
111 #define XFS_EXTENT_V5_VPTR_OFF offsetof(ExtentDataHeaderV5, magic)
112 #define XFS_EXTENT_V4_VPTR_OFF offsetof(ExtentDataHeaderV4, magic)
113 
114 
115 // xfs_dir2_data_entry_t
116 struct ExtentDataEntry {
117 			xfs_ino_t			inumber;
118 			uint8				namelen;
119 			uint8				name[];
120 
121 // Followed by a file type (8bit) if applicable and a 16bit tag
122 // tag is the offset from start of the block
123 };
124 
125 
126 // xfs_dir2_data_unused_t
127 struct ExtentUnusedEntry {
128 			uint16				freetag;
129 				// takes the value 0xffff
130 			uint16				length;
131 				// freetag+length overrides the inumber of an entry
132 			uint16				tag;
133 };
134 
135 
136 // xfs_dir2_leaf_entry_t
137 struct ExtentLeafEntry {
138 			uint32				hashval;
139 			uint32				address;
140 				// offset into block after >> 3
141 };
142 
143 
144 // xfs_dir2_block_tail_t
145 struct ExtentBlockTail {
146 			uint32				count;
147 				// # of entries in leaf
148 			uint32				stale;
149 				// # of free leaf entries
150 };
151 
152 
153 class Extent
154 {
155 public:
156 								Extent(Inode* inode);
157 								~Extent();
158 			status_t			Init();
159 			bool				IsBlockType();
160 			void				FillMapEntry(void* pointerToMap);
161 			status_t			FillBlockBuffer();
162 			ExtentBlockTail*	BlockTail();
163 			ExtentLeafEntry*	BlockFirstLeaf(ExtentBlockTail* tail);
164 			xfs_ino_t			GetIno();
165 			uint32				GetOffsetFromAddress(uint32 address);
166 			int					EntrySize(int len) const;
167 			status_t			GetNext(char* name, size_t* length,
168 									xfs_ino_t* ino);
169 			status_t			Lookup(const char* name, size_t length,
170 									xfs_ino_t* id);
171 private:
172 			Inode*				fInode;
173 			ExtentMapEntry*		fMap;
174 			uint32				fOffset;
175 			char*				fBlockBuffer;
176 				// This isn't inode data. It holds the directory block.
177 };
178 
179 
180 ExtentDataHeader*
181 CreateDataHeader(Inode* inode, const char* buffer);
182 
183 
184 uint32
185 SizeOfDataHeader(Inode* inode);
186 
187 #endif
188