xref: /haiku/src/add-ons/kernel/file_systems/xfs/Inode.h (revision 410ed2fbba58819ac21e27d3676739728416761d)
1 /*
2  * Copyright 2020, Shubham Bhagat, shubhambhagat111@yahoo.com
3  * All rights reserved. Distributed under the terms of the MIT License.
4  */
5 #ifndef _INODE_H_
6 #define _INODE_H_
7 
8 #include "system_dependencies.h"
9 #include "Volume.h"
10 #include "xfs_types.h"
11 
12 
13 #define INODE_MAGIC 0x494e
14 #define INODE_MINSIZE_LOG 8
15 #define INODE_MAXSIZE_LOG 11
16 #define INODE_CORE_SIZE 96
17 #define INODE_CORE_UNLINKED_SIZE 100
18 	// Inode core but with unlinked pointer
19 #define DATA_FORK_OFFSET 0x64
20 	// For v4 FS
21 #define INO_MASK(x)		((1ULL << (x)) - 1)
22 	// Gets 2^x - 1
23 #define INO_TO_AGNO(id, volume)	(xfs_agnumber_t)id >> (volume->AgInodeBits())
24 	// Gets AG number from inode number
25 #define INO_TO_AGINO(id, bits)	(uint32) id & INO_MASK(bits);
26 	// Gets the AG relative inode number
27 #define INO_TO_AGBLOCK(id, volume) \
28 		(id >> (volume->InodesPerBlkLog())) \
29 		& (INO_MASK(volume->AgBlocksLog()))
30 	// Gets the AG relative block number that contains inode
31 #define INO_TO_BLOCKOFFSET(id, volume) (id & INO_MASK(volume->InodesPerBlkLog()))
32 	// Gets the offset into the block from the inode number
33 #define DIR_DFORK_PTR(dir_ino_ptr) (void*) \
34 		((char*) dir_ino_ptr + DATA_FORK_OFFSET)
35 #define DIR_AFORK_PTR(dir_ino_ptr, forkoff) \
36 					(void*)((char*)DIR_DFORK_PTR(dir_ino_ptr) + \
37 					(((uint32)forkoff)<<3))
38 #define DIR_AFORK_EXIST(dir_ino_ptr) dir_ino_ptr->di_forkoff!=0
39 #define MASK(n) ((1UL << n) - 1)
40 #define FSBLOCKS_TO_AGNO(n, volume) ((n) >> volume->AgBlocksLog())
41 #define FSBLOCKS_TO_AGBLOCKNO(n, volume) ((n) & MASK(volume->AgBlocksLog()))
42 
43 
44 // xfs_da_blkinfo_t
45 struct BlockInfo {
46 			uint32				forw;
47 			uint32				back;
48 			uint16				magic;
49 			uint16				pad;
50 };
51 
52 
53 uint32
54 hashfunction(const char* name, int length);
55 
56 
57 struct xfs_timestamp_t {
58 		int32				t_sec;
59 		int32				t_nsec;
60 };
61 
62 
63 enum xfs_dinode_fmt_t {
64 		XFS_DINODE_FMT_DEV,
65 			// For devices
66 		XFS_DINODE_FMT_LOCAL,
67 			// For Directories and links
68 		XFS_DINODE_FMT_EXTENTS,
69 			// For large number of extents
70 		XFS_DINODE_FMT_BTREE,
71 			// Extents and Directories
72 		XFS_DINODE_FMT_UUID,
73 			// Not used
74 };
75 
76 /*
77  * The xfs_ino_t is the same for all types of inodes, the data and attribute
78  * fork might be different and that is to be handled accordingly.
79  */
80 struct xfs_inode_t {
81 			void				SwapEndian();
82 			int8				Version() const;
83 				//TODO: Check
84 			mode_t				Mode() const;
85 			void				GetModificationTime(struct timespec&
86 									timestamp);
87 			void				GetChangeTime(struct timespec& timestamp);
88 			void				GetAccessTime(struct timespec& timestamp);
89 			int8				Format() const;
90 				// The format of the inode
91 			xfs_fsize_t			Size() const;
92 			xfs_rfsblock_t		BlockCount() const;
93 			uint32				NLink() const;
94 			uint16				Flags() const;
95 			uint32				UserId() const;
96 			uint32				GroupId() const;
97 			xfs_extnum_t		DataExtentsCount() const;
98 			uint8				ForkOffset() const;
99 			uint16				di_magic;
100 			uint16				di_mode;
101 				// uses standard S_Ixxx
102 			int8				di_version;
103 				//This either would be 1 or 2
104 			int8				di_format;
105 			uint16				di_onlink;
106 			uint32				di_uid;
107 			uint32				di_gid;
108 			uint32				di_nlink;
109 			uint16				di_projid;
110 			uint8				di_pad[8];
111 			uint16				di_flushiter;
112 			xfs_timestamp_t		di_atime;
113 			xfs_timestamp_t		di_mtime;
114 			xfs_timestamp_t		di_ctime;
115 			xfs_fsize_t			di_size;
116 				// size in bytes or length if link
117 			xfs_rfsblock_t		di_nblocks;
118 				// blocks used including metadata
119 				// extended attributes not included
120 			xfs_extlen_t		di_extsize;
121 				// extent size
122 			xfs_extnum_t		di_nextents;
123 				// number of data extents
124 			xfs_aextnum_t		di_anextents;
125 				// number of EA extents
126 			uint8				di_forkoff;
127 				// decides where di_a starts
128 			int8				di_aformat;
129 				// similar to di_format
130 			uint32				di_dmevmask;
131 			uint16				di_dmstate;
132 			uint16				di_flags;
133 			uint32				di_gen;
134 
135 			uint32				di_next_unlinked;
136 };
137 
138 
139 class Inode {
140 public:
141 								Inode(Volume* volume, xfs_ino_t id);
142 								~Inode();
143 			status_t			Init();
144 
145 			xfs_ino_t			ID() const { return fId; }
146 
147 			bool				IsDirectory() const
148 									{ return S_ISDIR(Mode()); }
149 
150 			bool				IsFile() const
151 									{ return S_ISREG(Mode()); }
152 
153 			bool				IsSymLink() const
154 									{ return S_ISLNK(Mode()); }
155 
156 			mode_t				Mode() const { return fNode->Mode(); }
157 
158 			Volume*				GetVolume() { return fVolume;}
159 
160 			int8				Format() const { return fNode->Format(); }
161 
162 			bool				IsLocal() const
163 									{ return
164 										Format() == XFS_DINODE_FMT_LOCAL; }
165 
166 			uint32				NLink() const { return fNode->NLink(); }
167 
168 			int8				Version() const { return fNode->Version(); }
169 
170 			xfs_rfsblock_t		BlockCount() const
171 									{ return fNode->BlockCount(); }
172 
173 			char*				Buffer() { return fBuffer; }
174 
175 			int16				Flags() const { return fNode->Flags(); }
176 
177 			xfs_fsize_t			Size() const { return fNode->Size(); }
178 
179 			uint32				DirBlockSize() const
180 									{ return fVolume->DirBlockSize(); }
181 
182 			void				GetChangeTime(struct timespec& timestamp) const
183 								{ fNode->GetChangeTime(timestamp); }
184 
185 			void				GetModificationTime(struct timespec& timestamp)
186 									const
187 								{ fNode->GetModificationTime(timestamp); }
188 
189 			void				GetAccessTime(struct timespec& timestamp) const
190 								{ fNode->GetAccessTime(timestamp); }
191 
192 			status_t			CheckPermissions(int accessMode) const;
193 			uint32				UserId() const { return fNode->UserId(); }
194 			uint32				GroupId() const { return fNode->GroupId(); }
195 			bool				HasFileTypeField() const;
196 			xfs_extnum_t		DataExtentsCount() const
197 									{ return fNode->DataExtentsCount(); }
198 			uint64				FileSystemBlockToAddr(uint64 block);
199 			uint8				ForkOffset() const
200 									{ return fNode->ForkOffset(); }
201 
202 private:
203 			status_t			GetFromDisk();
204 			xfs_inode_t*		fNode;
205 			xfs_ino_t			fId;
206 			Volume*				fVolume;
207 			char*				fBuffer;
208 				// Contains the disk inode in BE format
209 };
210 
211 #endif
212