xref: /haiku/src/add-ons/kernel/file_systems/xfs/Inode.h (revision 21258e2674226d6aa732321b6f8494841895af5f)
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		NoOfBlocks() const;
81 			uint32				NLink() const;
82 			uint16				Flags() const;
83 			uint32				UserId() const;
84 			uint32				GroupId() const;
85 
86 			uint16				di_magic;
87 			uint16				di_mode;
88 				// uses standard S_Ixxx
89 			int8				di_version;
90 				//This either would be 1 or 2
91 			int8				di_format;
92 			uint16				di_onlink;
93 			uint32				di_uid;
94 			uint32				di_gid;
95 			uint32				di_nlink;
96 			uint16				di_projid;
97 			uint8				di_pad[8];
98 			uint16				di_flushiter;
99 			xfs_timestamp_t		di_atime;
100 			xfs_timestamp_t		di_mtime;
101 			xfs_timestamp_t		di_ctime;
102 			xfs_fsize_t			di_size;
103 				// size in bytes or length if link
104 			xfs_rfsblock_t		di_nblocks;
105 				// blocks used including metadata
106 				// extended attributes not included
107 			xfs_extlen_t		di_extsize;
108 				// extent size
109 			xfs_extnum_t		di_nextents;
110 				// number of data extents
111 			xfs_aextnum_t		di_anextents;
112 				// number of EA extents
113 			uint8				di_forkoff;
114 				// decides where di_a starts
115 			int8				di_aformat;
116 				// similar to di_format
117 			uint32				di_dmevmask;
118 			uint16				di_dmstate;
119 			uint16				di_flags;
120 			uint32				di_gen;
121 
122 			uint32				di_next_unlinked;
123 };
124 
125 
126 class Inode {
127 public:
128 								Inode(Volume* volume, xfs_ino_t id);
129 								~Inode();
130 			status_t			Init();
131 
132 			xfs_ino_t			ID() const { return fId; }
133 
134 			bool				IsDirectory() const
135 									{ return S_ISDIR(Mode()); }
136 
137 			bool				IsFile() const
138 									{ return S_ISREG(Mode()); }
139 
140 			bool				IsSymLink() const
141 									{ return S_ISLNK(Mode()); }
142 
143 			mode_t				Mode() const { return fNode->Mode(); }
144 
145 			Volume*				GetVolume() { return fVolume;}
146 
147 			int8				Format() const { return fNode->Format(); }
148 
149 			bool				IsLocal() const
150 									{ return
151 										Format() == XFS_DINODE_FMT_LOCAL; }
152 
153 			uint32				NLink() const { return fNode->NLink(); }
154 
155 			int8				Version() const { return fNode->Version(); }
156 
157 			xfs_rfsblock_t		NoOfBlocks() const
158 									{ return fNode->NoOfBlocks(); }
159 
160 			char*				Buffer() { return fBuffer; }
161 
162 			int16				Flags() const { return fNode->Flags(); }
163 
164 			xfs_fsize_t			Size() const { return fNode->Size(); }
165 
166 			uint32				DirBlockSize() const
167 									{ return fVolume->DirBlockSize(); }
168 
169 			void				GetChangeTime(struct timespec& timestamp) const
170 								{ fNode->GetChangeTime(timestamp); }
171 
172 			void				GetModificationTime(struct timespec& timestamp)
173 									const
174 								{ fNode->GetModificationTime(timestamp); }
175 
176 			void				GetAccessTime(struct timespec& timestamp) const
177 								{ fNode->GetAccessTime(timestamp); }
178 
179 			uint32				UserId() const { return fNode->UserId(); }
180 			uint32				GroupId() const { return fNode->GroupId(); }
181 
182 private:
183 			status_t			GetFromDisk();
184 			xfs_inode_t*		fNode;
185 			xfs_ino_t			fId;
186 			Volume*				fVolume;
187 			char*				fBuffer;
188 				// Contains the disk inode in BE format
189 };
190 
191 #endif
192