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