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
GetVolumeOps()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
GetID()326 Volume::GetID() const
327 {
328 return fFSVolume->id;
329 }
330
331
332 // GetFileSystem
333 inline FileSystem*
GetFileSystem()334 Volume::GetFileSystem() const
335 {
336 return fFileSystem;
337 }
338
339
340 // HasCapability
341 inline bool
HasCapability(int capability)342 Volume::HasCapability(int capability) const
343 {
344 return fCapabilities.Get(capability);
345 }
346
347
348 // GetUserlandVolume
349 inline void*
GetUserlandVolume()350 Volume::GetUserlandVolume() const
351 {
352 return fUserlandVolume;
353 }
354
355
356 // GetRootID
357 inline ino_t
GetRootID()358 Volume::GetRootID() const
359 {
360 return fRootID;
361 }
362
363
364 #endif // USERLAND_FS_VOLUME_H
365