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