xref: /haiku/src/add-ons/kernel/file_systems/xfs/Inode.h (revision 68d37cfb3a755a7270d772b505ee15c8b18aa5e0)
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) \
36 					(void*)((char*)XFS_DFORK_PTR + \
37 					((uint32)dir_ino_ptr->di_forkoff<<3))
38 #define DIR_AFORK_EXIST(dir_ino_ptr) dir_ino_ptr->di_forkoff!=0
39 
40 
41 uint32
42 hashfunction(const char* name, int length);
43 
44 
45 struct xfs_timestamp_t {
46 		int32				t_sec;
47 		int32				t_nsec;
48 };
49 
50 
51 enum xfs_dinode_fmt_t {
52 		XFS_DINODE_FMT_DEV,
53 			// For devices
54 		XFS_DINODE_FMT_LOCAL,
55 			// For Directories and links
56 		XFS_DINODE_FMT_EXTENTS,
57 			// For large number of extents
58 		XFS_DINODE_FMT_BTREE,
59 			// Extents and Directories
60 		XFS_DINODE_FMT_UUID,
61 			// Not used
62 };
63 
64 /*
65  * The xfs_ino_t is the same for all types of inodes, the data and attribute
66  * fork might be different and that is to be handled accordingly.
67  */
68 struct xfs_inode_t {
69 			void				SwapEndian();
70 			int8				Version() const;
71 				//TODO: Check
72 			mode_t				Mode() const;
73 			void				GetModificationTime(struct timespec&
74 									timestamp);
75 			void				GetChangeTime(struct timespec& timestamp);
76 			void				GetAccessTime(struct timespec& timestamp);
77 			int8				Format() const;
78 				// The format of the inode
79 			xfs_fsize_t			Size() const;
80 			xfs_rfsblock_t		BlockCount() const;
81 			uint32				NLink() const;
82 			uint16				Flags() const;
83 			uint32				UserId() const;
84 			uint32				GroupId() const;
85 			xfs_extnum_t		DataExtentsCount() const;
86 
87 			uint16				di_magic;
88 			uint16				di_mode;
89 				// uses standard S_Ixxx
90 			int8				di_version;
91 				//This either would be 1 or 2
92 			int8				di_format;
93 			uint16				di_onlink;
94 			uint32				di_uid;
95 			uint32				di_gid;
96 			uint32				di_nlink;
97 			uint16				di_projid;
98 			uint8				di_pad[8];
99 			uint16				di_flushiter;
100 			xfs_timestamp_t		di_atime;
101 			xfs_timestamp_t		di_mtime;
102 			xfs_timestamp_t		di_ctime;
103 			xfs_fsize_t			di_size;
104 				// size in bytes or length if link
105 			xfs_rfsblock_t		di_nblocks;
106 				// blocks used including metadata
107 				// extended attributes not included
108 			xfs_extlen_t		di_extsize;
109 				// extent size
110 			xfs_extnum_t		di_nextents;
111 				// number of data extents
112 			xfs_aextnum_t		di_anextents;
113 				// number of EA extents
114 			uint8				di_forkoff;
115 				// decides where di_a starts
116 			int8				di_aformat;
117 				// similar to di_format
118 			uint32				di_dmevmask;
119 			uint16				di_dmstate;
120 			uint16				di_flags;
121 			uint32				di_gen;
122 
123 			uint32				di_next_unlinked;
124 };
125 
126 
127 class Inode {
128 public:
129 								Inode(Volume* volume, xfs_ino_t id);
130 								~Inode();
131 			status_t			Init();
132 
133 			xfs_ino_t			ID() const { return fId; }
134 
135 			bool				IsDirectory() const
136 									{ return S_ISDIR(Mode()); }
137 
138 			bool				IsFile() const
139 									{ return S_ISREG(Mode()); }
140 
141 			bool				IsSymLink() const
142 									{ return S_ISLNK(Mode()); }
143 
144 			mode_t				Mode() const { return fNode->Mode(); }
145 
146 			Volume*				GetVolume() { return fVolume;}
147 
148 			int8				Format() const { return fNode->Format(); }
149 
150 			bool				IsLocal() const
151 									{ return
152 										Format() == XFS_DINODE_FMT_LOCAL; }
153 
154 			uint32				NLink() const { return fNode->NLink(); }
155 
156 			int8				Version() const { return fNode->Version(); }
157 
158 			xfs_rfsblock_t		BlockCount() const
159 									{ return fNode->BlockCount(); }
160 
161 			char*				Buffer() { return fBuffer; }
162 
163 			int16				Flags() const { return fNode->Flags(); }
164 
165 			xfs_fsize_t			Size() const { return fNode->Size(); }
166 
167 			uint32				DirBlockSize() const
168 									{ return fVolume->DirBlockSize(); }
169 
170 			void				GetChangeTime(struct timespec& timestamp) const
171 								{ fNode->GetChangeTime(timestamp); }
172 
173 			void				GetModificationTime(struct timespec& timestamp)
174 									const
175 								{ fNode->GetModificationTime(timestamp); }
176 
177 			void				GetAccessTime(struct timespec& timestamp) const
178 								{ fNode->GetAccessTime(timestamp); }
179 
180 			uint32				UserId() const { return fNode->UserId(); }
181 			uint32				GroupId() const { return fNode->GroupId(); }
182 			bool				HasFileTypeField() const;
183 			xfs_extnum_t		DataExtentsCount() const
184 									{ return fNode->DataExtentsCount(); }
185 
186 private:
187 			status_t			GetFromDisk();
188 			xfs_inode_t*		fNode;
189 			xfs_ino_t			fId;
190 			Volume*				fVolume;
191 			char*				fBuffer;
192 				// Contains the disk inode in BE format
193 };
194 
195 #endif
196