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
16namespace UserlandFSUtil {
17
18class Request;
19class RequestAllocator;
20class RequestHandler;
21class RequestPort;
22struct userlandfs_ioctl;
23
24}
25
26using UserlandFSUtil::FSVolumeCapabilities;
27using UserlandFSUtil::Request;
28using UserlandFSUtil::RequestAllocator;
29using UserlandFSUtil::RequestHandler;
30using UserlandFSUtil::RequestPort;
31using UserlandFSUtil::userlandfs_ioctl;
32
33class FileSystem;
34
35class Volume : public BReferenceable {
36public:
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
224private:
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
241private:
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
301private:
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
325inline dev_t
326Volume::GetID() const
327{
328	return fFSVolume->id;
329}
330
331
332// GetFileSystem
333inline FileSystem*
334Volume::GetFileSystem() const
335{
336	return fFileSystem;
337}
338
339
340// HasCapability
341inline bool
342Volume::HasCapability(int capability) const
343{
344	return fCapabilities.Get(capability);
345}
346
347
348// GetUserlandVolume
349inline void*
350Volume::GetUserlandVolume() const
351{
352	return fUserlandVolume;
353}
354
355
356// GetRootID
357inline ino_t
358Volume::GetRootID() const
359{
360	return fRootID;
361}
362
363
364#endif	// USERLAND_FS_VOLUME_H
365