xref: /haiku/src/add-ons/kernel/file_systems/userlandfs/kernel_add_on/Volume.h (revision d157bf8522d5dc449602bec43f10ecdedc9943cd)
1 /*
2  * Copyright 2001-2009, Ingo Weinhold, ingo_weinhold@gmx.de.
3  * Distributed under the terms of the MIT License.
4  */
5 #ifndef USERLAND_FS_VOLUME_H
6 #define USERLAND_FS_VOLUME_H
7 
8 #include <fs_interface.h>
9 
10 #include <Referenceable.h>
11 
12 #include <kernel/lock.h>
13 
14 #include "FSCapabilities.h"
15 
16 namespace UserlandFSUtil {
17 
18 class Request;
19 class RequestAllocator;
20 class RequestHandler;
21 class RequestPort;
22 struct userlandfs_ioctl;
23 
24 }
25 
26 using UserlandFSUtil::FSVolumeCapabilities;
27 using UserlandFSUtil::Request;
28 using UserlandFSUtil::RequestAllocator;
29 using UserlandFSUtil::RequestHandler;
30 using UserlandFSUtil::RequestPort;
31 using UserlandFSUtil::userlandfs_ioctl;
32 
33 class FileSystem;
34 
35 class Volume : public Referenceable {
36 public:
37 								Volume(FileSystem* fileSystem,
38 									fs_volume* fsVolume);
39 								~Volume();
40 
41 	inline	FileSystem*			GetFileSystem() const;
42 	inline	dev_t				GetID() const;
43 
44 	inline	fs_volume_ops*		GetVolumeOps()		{ return &fVolumeOps; }
45 	inline	bool				HasCapability(int capability) const;
46 
47 	inline	void*				GetUserlandVolume() const;
48 	inline	ino_t				GetRootID() const;
49 
50 			// client methods
51 			status_t			GetVNode(ino_t vnid, void** node);
52 			status_t			PutVNode(ino_t vnid);
53 			status_t			AcquireVNode(ino_t vnid);
54 			status_t			NewVNode(ino_t vnid, void* node,
55 									const FSVNodeCapabilities& capabilities);
56 			status_t			PublishVNode(ino_t vnid, void* node,
57 									int type, uint32 flags,
58 									const FSVNodeCapabilities& capabilities);
59 			status_t			RemoveVNode(ino_t vnid);
60 			status_t			UnremoveVNode(ino_t vnid);
61 			status_t			GetVNodeRemoved(ino_t vnid, bool* removed);
62 
63 			status_t			CreateFileCache(ino_t vnodeID, off_t size);
64 			status_t			DeleteFileCache(ino_t vnodeID);
65 			status_t			SetFileCacheEnabled(ino_t vnodeID,
66 									bool enabled);
67 			status_t			SetFileCacheSize(ino_t vnodeID, off_t size);
68 			status_t			SyncFileCache(ino_t vnodeID);
69 			status_t			ReadFileCache(ino_t vnodeID, void* cookie,
70 									off_t offset, void* buffer, size_t* _size);
71 			status_t			WriteFileCache(ino_t vnodeID, void* cookie,
72 									off_t offset, const void* buffer,
73 									size_t* _size);
74 
75 			status_t			DoIterativeFDIO(int fd, int32 requestID,
76 									void* cookie, const file_io_vec* vecs,
77 									uint32 vecCount);
78 
79 			// FS
80 			status_t			Mount(const char* device, uint32 flags,
81 									const char* parameters);
82 			status_t			Unmount();
83 			status_t			Sync();
84 			status_t			ReadFSInfo(fs_info* info);
85 			status_t			WriteFSInfo(const struct fs_info* info,
86 									uint32 mask);
87 
88 			// vnodes
89 			status_t			Lookup(void* dir, const char* entryName,
90 									ino_t* vnid);
91 			status_t			GetVNodeName(void* node, char* buffer,
92 									size_t bufferSize);
93 			status_t			ReadVNode(ino_t vnid, bool reenter,
94 									void** node, fs_vnode_ops** _ops, int* type,
95 									uint32* flags);
96 			status_t			WriteVNode(void* node, bool reenter);
97 			status_t			RemoveVNode(void* node, bool reenter);
98 
99 			// asynchronous I/O
100 			status_t			DoIO(void* node, void* cookie,
101 									io_request* ioRequest);
102 			status_t			CancelIO(void* node, void* cookie,
103 									io_request* ioRequest);
104 
105 			// nodes
106 			status_t			IOCtl(void* node, void* cookie,
107 									uint32 command, void *buffer, size_t size);
108 			status_t			SetFlags(void* node, void* cookie,
109 									int flags);
110 			status_t			Select(void* node, void* cookie, uint8 event,
111 									selectsync* sync);
112 			status_t			Deselect(void* node, void* cookie, uint8 event,
113 									selectsync* sync);
114 
115 			status_t			FSync(void* node);
116 
117 			status_t			ReadSymlink(void* node, char* buffer,
118 									size_t bufferSize, size_t* bytesRead);
119 			status_t			CreateSymlink(void* dir, const char* name,
120 									const char* target, int mode);
121 
122 			status_t			Link(void* dir, const char* name,
123 									void* node);
124 			status_t			Unlink(void* dir, const char* name);
125 			status_t			Rename(void* oldDir, const char* oldName,
126 									void* newDir, const char* newName);
127 
128 			status_t			Access(void* node, int mode);
129 			status_t			ReadStat(void* node, struct stat* st);
130 			status_t			WriteStat(void* node, const struct stat *st,
131 									uint32 mask);
132 
133 			// files
134 			status_t			Create(void* dir, const char* name,
135 									int openMode, int mode, void** cookie,
136 									ino_t* vnid);
137 			status_t			Open(void* node, int openMode,
138 									void** cookie);
139 			status_t			Close(void* node, void* cookie);
140 			status_t			FreeCookie(void* node, void* cookie);
141 			status_t			Read(void* node, void* cookie, off_t pos,
142 									void* buffer, size_t bufferSize,
143 									size_t* bytesRead);
144 			status_t			Write(void* node, void* cookie,
145 									off_t pos, const void* buffer,
146 									size_t bufferSize, size_t* bytesWritten);
147 
148 			// directories
149 			status_t			CreateDir(void* dir, const char* name,
150 									int mode);
151 			status_t			RemoveDir(void* dir, const char* name);
152 			status_t			OpenDir(void* node, void** cookie);
153 			status_t			CloseDir(void* node, void* cookie);
154 			status_t			FreeDirCookie(void* node, void* cookie);
155 			status_t			ReadDir(void* node, void* cookie,
156 									void* buffer, size_t bufferSize,
157 									uint32 count, uint32* countRead);
158 			status_t			RewindDir(void* node, void* cookie);
159 
160 			// attribute directories
161 			status_t			OpenAttrDir(void* node, void** cookie);
162 			status_t			CloseAttrDir(void* node, void* cookie);
163 			status_t			FreeAttrDirCookie(void* node,
164 									void* cookie);
165 			status_t			ReadAttrDir(void* node, void* cookie,
166 									void* buffer, size_t bufferSize,
167 									uint32 count, uint32* countRead);
168 			status_t			RewindAttrDir(void* node, void* cookie);
169 
170 			// attributes
171 			status_t			CreateAttr(void* node, const char* name,
172 									uint32 type, int openMode,
173 									void** cookie);
174 			status_t			OpenAttr(void* node, const char* name,
175 									int openMode, void** cookie);
176 			status_t			CloseAttr(void* node, void* cookie);
177 			status_t			FreeAttrCookie(void* node, void* cookie);
178 			status_t			ReadAttr(void* node, void* cookie,
179 									off_t pos, void* buffer, size_t bufferSize,
180 									size_t* bytesRead);
181 			status_t			WriteAttr(void* node, void* cookie,
182 									off_t pos, const void* buffer,
183 									size_t bufferSize, size_t* bytesWritten);
184 			status_t			ReadAttrStat(void* node, void* cookie,
185 									struct stat *st);
186 			status_t			WriteAttrStat(void* node, void* cookie,
187 									const struct stat *st, int statMask);
188 			status_t			RenameAttr(void* oldNode,
189 									const char* oldName, void* newNode,
190 									const char* newName);
191 			status_t			RemoveAttr(void* node, const char* name);
192 
193 			// indices
194 			status_t			OpenIndexDir(void** cookie);
195 			status_t			CloseIndexDir(void* cookie);
196 			status_t			FreeIndexDirCookie(void* cookie);
197 			status_t			ReadIndexDir(void* cookie, void* buffer,
198 									size_t bufferSize, uint32 count,
199 									uint32* countRead);
200 			status_t			RewindIndexDir(void* cookie);
201 			status_t			CreateIndex(const char* name, uint32 type,
202 									uint32 flags);
203 			status_t			RemoveIndex(const char* name);
204 			status_t			ReadIndexStat(const char *name,
205 									struct stat *st);
206 
207 			// queries
208 			status_t			OpenQuery(const char* queryString,
209 									uint32 flags, port_id port, uint32 token,
210 									void** cookie);
211 			status_t			CloseQuery(void* cookie);
212 			status_t			FreeQueryCookie(void* cookie);
213 			status_t			ReadQuery(void* cookie, void* buffer,
214 									size_t bufferSize, uint32 count,
215 									uint32* countRead);
216 			status_t			RewindQuery(void* cookie);
217 
218 private:
219 			struct VNode;
220 			struct VNodeHashDefinition;
221 			struct VNodeMap;
222 			struct IORequestInfo;
223 			struct IORequestIDHashDefinition;
224 			struct IORequestStructHashDefinition;
225 			struct IORequestIDMap;
226 			struct IORequestStructMap;
227 			struct IterativeFDIOCookie;
228 
229 			class AutoIncrementer;
230 			class IORequestRemover;
231 			friend class IORequestRemover;
232 			class VNodeRemover;
233 			friend class VNodeRemover;
234 
235 private:
236 			void				_InitVolumeOps();
237 
238 			status_t			_Mount(const char* device, uint32 flags,
239 									const char* parameters);
240 			status_t			_Unmount();
241 			status_t			_ReadFSInfo(fs_info* info);
242 			status_t			_Lookup(void* dir, const char* entryName,
243 									ino_t* vnid);
244 			status_t			_WriteVNode(void* node, bool reenter);
245 			status_t			_ReadStat(void* node, struct stat* st);
246 			status_t			_Close(void* node, void* cookie);
247 			status_t			_FreeCookie(void* node, void* cookie);
248 			status_t			_CloseDir(void* node, void* cookie);
249 			status_t			_FreeDirCookie(void* node, void* cookie);
250 			status_t			_CloseAttrDir(void* node, void* cookie);
251 			status_t			_FreeAttrDirCookie(void* node,
252 									void* cookie);
253 			status_t			_CloseAttr(void* node, void* cookie);
254 			status_t			_FreeAttrCookie(void* node,
255 									void* cookie);
256 			status_t			_CloseIndexDir(void* cookie);
257 			status_t			_FreeIndexDirCookie(void* cookie);
258 			status_t			_CloseQuery(void* cookie);
259 			status_t			_FreeQueryCookie(void* cookie);
260 
261 			status_t			_SendRequest(RequestPort* port,
262 									RequestAllocator* allocator,
263 									RequestHandler* handler, Request** reply);
264 			status_t			_SendReceiptAck(RequestPort* port);
265 
266 			void				_IncrementVNodeCount(ino_t vnid);
267 			void				_DecrementVNodeCount(ino_t vnid);
268 			void				_RemoveInvalidVNode(ino_t vnid);
269 
270 			status_t			_InternalIOCtl(userlandfs_ioctl* buffer,
271 									int32 bufferSize);
272 
273 			status_t			_PutAllPendingVNodes();
274 
275 			status_t			_RegisterIORequest(io_request* request,
276 									int32* requestID);
277 			status_t			_UnregisterIORequest(int32 requestID);
278 			status_t 			_FindIORequest(io_request* request,
279 									int32* requestID);
280 			status_t 			_FindIORequest(int32 requestID,
281 									io_request** request);
282 
283 	static	status_t			_IterativeFDIOGetVecs(void* cookie,
284 									io_request* request, off_t offset,
285 									size_t size, struct file_io_vec* vecs,
286 									size_t* _count);
287 	static	status_t			_IterativeFDIOFinished(void* cookie,
288 									io_request* request, status_t status,
289 									bool partialTransfer,
290 									size_t bytesTransferred);
291 
292 	inline	bool				HasVNodeCapability(VNode* vnode,
293 									int capability) const;
294 
295 private:
296 			mutex				fLock;
297 			FileSystem*			fFileSystem;
298 			fs_volume*			fFSVolume;
299 			FSVolumeCapabilities fCapabilities;
300 			fs_volume_ops		fVolumeOps;
301 			void*				fUserlandVolume;
302 			ino_t				fRootID;
303 			VNode*				fRootNode;
304 			vint32				fOpenFiles;
305 			vint32				fOpenDirectories;
306 			vint32				fOpenAttributeDirectories;
307 			vint32				fOpenAttributes;
308 			vint32				fOpenIndexDirectories;
309 			vint32				fOpenQueries;
310 			VNodeMap*			fVNodes;
311 			IORequestIDMap*		fIORequestInfosByID;
312 			IORequestStructMap*	fIORequestInfosByStruct;
313 			int32				fLastIORequestID;
314 	volatile bool				fVNodeCountingEnabled;
315 };
316 
317 
318 // GetID
319 inline dev_t
320 Volume::GetID() const
321 {
322 	return fFSVolume->id;
323 }
324 
325 
326 // GetFileSystem
327 inline FileSystem*
328 Volume::GetFileSystem() const
329 {
330 	return fFileSystem;
331 }
332 
333 
334 // HasCapability
335 inline bool
336 Volume::HasCapability(int capability) const
337 {
338 	return fCapabilities.Get(capability);
339 }
340 
341 
342 // GetUserlandVolume
343 inline void*
344 Volume::GetUserlandVolume() const
345 {
346 	return fUserlandVolume;
347 }
348 
349 
350 // GetRootID
351 inline ino_t
352 Volume::GetRootID() const
353 {
354 	return fRootID;
355 }
356 
357 
358 #endif	// USERLAND_FS_VOLUME_H
359