xref: /haiku/src/add-ons/kernel/file_systems/userlandfs/kernel_add_on/Volume.h (revision e81a954787e50e56a7f06f72705b7859b6ab06d1)
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 BReferenceable {
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 			status_t			ReadFromIORequest(int32 requestID, void* buffer,
79 									size_t size);
80 			status_t			WriteToIORequest(int32 requestID,
81 									const void* buffer, size_t size);
82 			status_t			NotifyIORequest(int32 requestID,
83 									status_t status);
84 
85 			// FS
86 			status_t			Mount(const char* device, uint32 flags,
87 									const char* parameters);
88 			status_t			Unmount();
89 			status_t			Sync();
90 			status_t			ReadFSInfo(fs_info* info);
91 			status_t			WriteFSInfo(const struct fs_info* info,
92 									uint32 mask);
93 
94 			// vnodes
95 			status_t			Lookup(void* dir, const char* entryName,
96 									ino_t* vnid);
97 			status_t			GetVNodeName(void* node, char* buffer,
98 									size_t bufferSize);
99 			status_t			ReadVNode(ino_t vnid, bool reenter,
100 									void** node, fs_vnode_ops** _ops, int* type,
101 									uint32* flags);
102 			status_t			WriteVNode(void* node, bool reenter);
103 			status_t			RemoveVNode(void* node, bool reenter);
104 
105 			// asynchronous I/O
106 			status_t			DoIO(void* node, void* cookie,
107 									io_request* ioRequest);
108 			status_t			CancelIO(void* node, void* cookie,
109 									io_request* ioRequest);
110 
111 			// nodes
112 			status_t			IOCtl(void* node, void* cookie,
113 									uint32 command, void *buffer, size_t size);
114 			status_t			SetFlags(void* node, void* cookie,
115 									int flags);
116 			status_t			Select(void* node, void* cookie, uint8 event,
117 									selectsync* sync);
118 			status_t			Deselect(void* node, void* cookie, uint8 event,
119 									selectsync* sync);
120 
121 			status_t			FSync(void* node);
122 
123 			status_t			ReadSymlink(void* node, char* buffer,
124 									size_t bufferSize, size_t* bytesRead);
125 			status_t			CreateSymlink(void* dir, const char* name,
126 									const char* target, int mode);
127 
128 			status_t			Link(void* dir, const char* name,
129 									void* node);
130 			status_t			Unlink(void* dir, const char* name);
131 			status_t			Rename(void* oldDir, const char* oldName,
132 									void* newDir, const char* newName);
133 
134 			status_t			Access(void* node, int mode);
135 			status_t			ReadStat(void* node, struct stat* st);
136 			status_t			WriteStat(void* node, const struct stat *st,
137 									uint32 mask);
138 
139 			// files
140 			status_t			Create(void* dir, const char* name,
141 									int openMode, int mode, void** cookie,
142 									ino_t* vnid);
143 			status_t			Open(void* node, int openMode,
144 									void** cookie);
145 			status_t			Close(void* node, void* cookie);
146 			status_t			FreeCookie(void* node, void* cookie);
147 			status_t			Read(void* node, void* cookie, off_t pos,
148 									void* buffer, size_t bufferSize,
149 									size_t* bytesRead);
150 			status_t			Write(void* node, void* cookie,
151 									off_t pos, const void* buffer,
152 									size_t bufferSize, size_t* bytesWritten);
153 
154 			// directories
155 			status_t			CreateDir(void* dir, const char* name,
156 									int mode);
157 			status_t			RemoveDir(void* dir, const char* name);
158 			status_t			OpenDir(void* node, void** cookie);
159 			status_t			CloseDir(void* node, void* cookie);
160 			status_t			FreeDirCookie(void* node, void* cookie);
161 			status_t			ReadDir(void* node, void* cookie,
162 									void* buffer, size_t bufferSize,
163 									uint32 count, uint32* countRead);
164 			status_t			RewindDir(void* node, void* cookie);
165 
166 			// attribute directories
167 			status_t			OpenAttrDir(void* node, void** cookie);
168 			status_t			CloseAttrDir(void* node, void* cookie);
169 			status_t			FreeAttrDirCookie(void* node,
170 									void* cookie);
171 			status_t			ReadAttrDir(void* node, void* cookie,
172 									void* buffer, size_t bufferSize,
173 									uint32 count, uint32* countRead);
174 			status_t			RewindAttrDir(void* node, void* cookie);
175 
176 			// attributes
177 			status_t			CreateAttr(void* node, const char* name,
178 									uint32 type, int openMode,
179 									void** cookie);
180 			status_t			OpenAttr(void* node, const char* name,
181 									int openMode, void** cookie);
182 			status_t			CloseAttr(void* node, void* cookie);
183 			status_t			FreeAttrCookie(void* node, void* cookie);
184 			status_t			ReadAttr(void* node, void* cookie,
185 									off_t pos, void* buffer, size_t bufferSize,
186 									size_t* bytesRead);
187 			status_t			WriteAttr(void* node, void* cookie,
188 									off_t pos, const void* buffer,
189 									size_t bufferSize, size_t* bytesWritten);
190 			status_t			ReadAttrStat(void* node, void* cookie,
191 									struct stat *st);
192 			status_t			WriteAttrStat(void* node, void* cookie,
193 									const struct stat *st, int statMask);
194 			status_t			RenameAttr(void* oldNode,
195 									const char* oldName, void* newNode,
196 									const char* newName);
197 			status_t			RemoveAttr(void* node, const char* name);
198 
199 			// indices
200 			status_t			OpenIndexDir(void** cookie);
201 			status_t			CloseIndexDir(void* cookie);
202 			status_t			FreeIndexDirCookie(void* cookie);
203 			status_t			ReadIndexDir(void* cookie, void* buffer,
204 									size_t bufferSize, uint32 count,
205 									uint32* countRead);
206 			status_t			RewindIndexDir(void* cookie);
207 			status_t			CreateIndex(const char* name, uint32 type,
208 									uint32 flags);
209 			status_t			RemoveIndex(const char* name);
210 			status_t			ReadIndexStat(const char *name,
211 									struct stat *st);
212 
213 			// queries
214 			status_t			OpenQuery(const char* queryString,
215 									uint32 flags, port_id port, uint32 token,
216 									void** cookie);
217 			status_t			CloseQuery(void* cookie);
218 			status_t			FreeQueryCookie(void* cookie);
219 			status_t			ReadQuery(void* cookie, void* buffer,
220 									size_t bufferSize, uint32 count,
221 									uint32* countRead);
222 			status_t			RewindQuery(void* cookie);
223 
224 private:
225 			struct VNode;
226 			struct VNodeHashDefinition;
227 			struct VNodeMap;
228 			struct IORequestInfo;
229 			struct IORequestIDHashDefinition;
230 			struct IORequestStructHashDefinition;
231 			struct IORequestIDMap;
232 			struct IORequestStructMap;
233 			struct IterativeFDIOCookie;
234 
235 			class AutoIncrementer;
236 			class IORequestRemover;
237 			friend class IORequestRemover;
238 			class VNodeRemover;
239 			friend class VNodeRemover;
240 
241 private:
242 			void				_InitVolumeOps();
243 
244 			status_t			_Mount(const char* device, uint32 flags,
245 									const char* parameters);
246 			status_t			_Unmount();
247 			status_t			_ReadFSInfo(fs_info* info);
248 			status_t			_Lookup(void* dir, const char* entryName,
249 									ino_t* vnid);
250 			status_t			_WriteVNode(void* node, bool reenter);
251 			status_t			_ReadStat(void* node, struct stat* st);
252 			status_t			_Close(void* node, void* cookie);
253 			status_t			_FreeCookie(void* node, void* cookie);
254 			status_t			_CloseDir(void* node, void* cookie);
255 			status_t			_FreeDirCookie(void* node, void* cookie);
256 			status_t			_CloseAttrDir(void* node, void* cookie);
257 			status_t			_FreeAttrDirCookie(void* node,
258 									void* cookie);
259 			status_t			_CloseAttr(void* node, void* cookie);
260 			status_t			_FreeAttrCookie(void* node,
261 									void* cookie);
262 			status_t			_CloseIndexDir(void* cookie);
263 			status_t			_FreeIndexDirCookie(void* cookie);
264 			status_t			_CloseQuery(void* cookie);
265 			status_t			_FreeQueryCookie(void* cookie);
266 
267 			status_t			_SendRequest(RequestPort* port,
268 									RequestAllocator* allocator,
269 									RequestHandler* handler, Request** reply);
270 			status_t			_SendReceiptAck(RequestPort* port);
271 
272 			void				_IncrementVNodeCount(ino_t vnid);
273 			void				_DecrementVNodeCount(ino_t vnid);
274 			void				_RemoveInvalidVNode(ino_t vnid);
275 
276 			status_t			_InternalIOCtl(userlandfs_ioctl* buffer,
277 									int32 bufferSize);
278 
279 			status_t			_PutAllPendingVNodes();
280 
281 			status_t			_RegisterIORequest(io_request* request,
282 									int32* requestID);
283 			status_t			_UnregisterIORequest(int32 requestID);
284 			status_t 			_FindIORequest(io_request* request,
285 									int32* requestID);
286 			status_t 			_FindIORequest(int32 requestID,
287 									io_request** request);
288 
289 	static	status_t			_IterativeFDIOGetVecs(void* cookie,
290 									io_request* request, off_t offset,
291 									size_t size, struct file_io_vec* vecs,
292 									size_t* _count);
293 	static	status_t			_IterativeFDIOFinished(void* cookie,
294 									io_request* request, status_t status,
295 									bool partialTransfer,
296 									size_t bytesTransferred);
297 
298 	inline	bool				HasVNodeCapability(VNode* vnode,
299 									int capability) const;
300 
301 private:
302 			mutex				fLock;
303 			FileSystem*			fFileSystem;
304 			fs_volume*			fFSVolume;
305 			FSVolumeCapabilities fCapabilities;
306 			fs_volume_ops		fVolumeOps;
307 			void*				fUserlandVolume;
308 			ino_t				fRootID;
309 			VNode*				fRootNode;
310 			int32				fOpenFiles;
311 			int32				fOpenDirectories;
312 			int32				fOpenAttributeDirectories;
313 			int32				fOpenAttributes;
314 			int32				fOpenIndexDirectories;
315 			int32				fOpenQueries;
316 			VNodeMap*			fVNodes;
317 			IORequestIDMap*		fIORequestInfosByID;
318 			IORequestStructMap*	fIORequestInfosByStruct;
319 			int32				fLastIORequestID;
320 	volatile bool				fVNodeCountingEnabled;
321 };
322 
323 
324 // GetID
325 inline dev_t
326 Volume::GetID() const
327 {
328 	return fFSVolume->id;
329 }
330 
331 
332 // GetFileSystem
333 inline FileSystem*
334 Volume::GetFileSystem() const
335 {
336 	return fFileSystem;
337 }
338 
339 
340 // HasCapability
341 inline bool
342 Volume::HasCapability(int capability) const
343 {
344 	return fCapabilities.Get(capability);
345 }
346 
347 
348 // GetUserlandVolume
349 inline void*
350 Volume::GetUserlandVolume() const
351 {
352 	return fUserlandVolume;
353 }
354 
355 
356 // GetRootID
357 inline ino_t
358 Volume::GetRootID() const
359 {
360 	return fRootID;
361 }
362 
363 
364 #endif	// USERLAND_FS_VOLUME_H
365