/* * Copyright 2001-2009, Ingo Weinhold, ingo_weinhold@gmx.de. * Distributed under the terms of the MIT License. */ #ifndef USERLAND_FS_VOLUME_H #define USERLAND_FS_VOLUME_H #include #include #include #include "FSCapabilities.h" namespace UserlandFSUtil { class Request; class RequestAllocator; class RequestHandler; class RequestPort; struct userlandfs_ioctl; } using UserlandFSUtil::FSVolumeCapabilities; using UserlandFSUtil::Request; using UserlandFSUtil::RequestAllocator; using UserlandFSUtil::RequestHandler; using UserlandFSUtil::RequestPort; using UserlandFSUtil::userlandfs_ioctl; class FileSystem; class Volume : public BReferenceable { public: Volume(FileSystem* fileSystem, fs_volume* fsVolume); ~Volume(); inline FileSystem* GetFileSystem() const; inline dev_t GetID() const; inline fs_volume_ops* GetVolumeOps() { return &fVolumeOps; } inline bool HasCapability(int capability) const; inline void* GetUserlandVolume() const; inline ino_t GetRootID() const; // client methods status_t GetVNode(ino_t vnid, void** node); status_t PutVNode(ino_t vnid); status_t AcquireVNode(ino_t vnid); status_t NewVNode(ino_t vnid, void* node, const FSVNodeCapabilities& capabilities); status_t PublishVNode(ino_t vnid, void* node, int type, uint32 flags, const FSVNodeCapabilities& capabilities); status_t RemoveVNode(ino_t vnid); status_t UnremoveVNode(ino_t vnid); status_t GetVNodeRemoved(ino_t vnid, bool* removed); status_t CreateFileCache(ino_t vnodeID, off_t size); status_t DeleteFileCache(ino_t vnodeID); status_t SetFileCacheEnabled(ino_t vnodeID, bool enabled); status_t SetFileCacheSize(ino_t vnodeID, off_t size); status_t SyncFileCache(ino_t vnodeID); status_t ReadFileCache(ino_t vnodeID, void* cookie, off_t offset, void* buffer, size_t* _size); status_t WriteFileCache(ino_t vnodeID, void* cookie, off_t offset, const void* buffer, size_t* _size); status_t DoIterativeFDIO(int fd, int32 requestID, void* cookie, const file_io_vec* vecs, uint32 vecCount); status_t ReadFromIORequest(int32 requestID, void* buffer, size_t size); status_t WriteToIORequest(int32 requestID, const void* buffer, size_t size); status_t NotifyIORequest(int32 requestID, status_t status); // FS status_t Mount(const char* device, uint32 flags, const char* parameters); status_t Unmount(); status_t Sync(); status_t ReadFSInfo(fs_info* info); status_t WriteFSInfo(const struct fs_info* info, uint32 mask); // vnodes status_t Lookup(void* dir, const char* entryName, ino_t* vnid); status_t GetVNodeName(void* node, char* buffer, size_t bufferSize); status_t ReadVNode(ino_t vnid, bool reenter, void** node, fs_vnode_ops** _ops, int* type, uint32* flags); status_t WriteVNode(void* node, bool reenter); status_t RemoveVNode(void* node, bool reenter); // asynchronous I/O status_t DoIO(void* node, void* cookie, io_request* ioRequest); status_t CancelIO(void* node, void* cookie, io_request* ioRequest); // nodes status_t IOCtl(void* node, void* cookie, uint32 command, void *buffer, size_t size); status_t SetFlags(void* node, void* cookie, int flags); status_t Select(void* node, void* cookie, uint8 event, selectsync* sync); status_t Deselect(void* node, void* cookie, uint8 event, selectsync* sync); status_t FSync(void* node); status_t ReadSymlink(void* node, char* buffer, size_t bufferSize, size_t* bytesRead); status_t CreateSymlink(void* dir, const char* name, const char* target, int mode); status_t Link(void* dir, const char* name, void* node); status_t Unlink(void* dir, const char* name); status_t Rename(void* oldDir, const char* oldName, void* newDir, const char* newName); status_t Access(void* node, int mode); status_t ReadStat(void* node, struct stat* st); status_t WriteStat(void* node, const struct stat *st, uint32 mask); // files status_t Create(void* dir, const char* name, int openMode, int mode, void** cookie, ino_t* vnid); status_t Open(void* node, int openMode, void** cookie); status_t Close(void* node, void* cookie); status_t FreeCookie(void* node, void* cookie); status_t Read(void* node, void* cookie, off_t pos, void* buffer, size_t bufferSize, size_t* bytesRead); status_t Write(void* node, void* cookie, off_t pos, const void* buffer, size_t bufferSize, size_t* bytesWritten); // directories status_t CreateDir(void* dir, const char* name, int mode); status_t RemoveDir(void* dir, const char* name); status_t OpenDir(void* node, void** cookie); status_t CloseDir(void* node, void* cookie); status_t FreeDirCookie(void* node, void* cookie); status_t ReadDir(void* node, void* cookie, void* buffer, size_t bufferSize, uint32 count, uint32* countRead); status_t RewindDir(void* node, void* cookie); // attribute directories status_t OpenAttrDir(void* node, void** cookie); status_t CloseAttrDir(void* node, void* cookie); status_t FreeAttrDirCookie(void* node, void* cookie); status_t ReadAttrDir(void* node, void* cookie, void* buffer, size_t bufferSize, uint32 count, uint32* countRead); status_t RewindAttrDir(void* node, void* cookie); // attributes status_t CreateAttr(void* node, const char* name, uint32 type, int openMode, void** cookie); status_t OpenAttr(void* node, const char* name, int openMode, void** cookie); status_t CloseAttr(void* node, void* cookie); status_t FreeAttrCookie(void* node, void* cookie); status_t ReadAttr(void* node, void* cookie, off_t pos, void* buffer, size_t bufferSize, size_t* bytesRead); status_t WriteAttr(void* node, void* cookie, off_t pos, const void* buffer, size_t bufferSize, size_t* bytesWritten); status_t ReadAttrStat(void* node, void* cookie, struct stat *st); status_t WriteAttrStat(void* node, void* cookie, const struct stat *st, int statMask); status_t RenameAttr(void* oldNode, const char* oldName, void* newNode, const char* newName); status_t RemoveAttr(void* node, const char* name); // indices status_t OpenIndexDir(void** cookie); status_t CloseIndexDir(void* cookie); status_t FreeIndexDirCookie(void* cookie); status_t ReadIndexDir(void* cookie, void* buffer, size_t bufferSize, uint32 count, uint32* countRead); status_t RewindIndexDir(void* cookie); status_t CreateIndex(const char* name, uint32 type, uint32 flags); status_t RemoveIndex(const char* name); status_t ReadIndexStat(const char *name, struct stat *st); // queries status_t OpenQuery(const char* queryString, uint32 flags, port_id port, uint32 token, void** cookie); status_t CloseQuery(void* cookie); status_t FreeQueryCookie(void* cookie); status_t ReadQuery(void* cookie, void* buffer, size_t bufferSize, uint32 count, uint32* countRead); status_t RewindQuery(void* cookie); private: struct VNode; struct VNodeHashDefinition; struct VNodeMap; struct IORequestInfo; struct IORequestIDHashDefinition; struct IORequestStructHashDefinition; struct IORequestIDMap; struct IORequestStructMap; struct IterativeFDIOCookie; class AutoIncrementer; class IORequestRemover; friend class IORequestRemover; class VNodeRemover; friend class VNodeRemover; private: void _InitVolumeOps(); status_t _Mount(const char* device, uint32 flags, const char* parameters); status_t _Unmount(); status_t _ReadFSInfo(fs_info* info); status_t _Lookup(void* dir, const char* entryName, ino_t* vnid); status_t _WriteVNode(void* node, bool reenter); status_t _ReadStat(void* node, struct stat* st); status_t _Close(void* node, void* cookie); status_t _FreeCookie(void* node, void* cookie); status_t _CloseDir(void* node, void* cookie); status_t _FreeDirCookie(void* node, void* cookie); status_t _CloseAttrDir(void* node, void* cookie); status_t _FreeAttrDirCookie(void* node, void* cookie); status_t _CloseAttr(void* node, void* cookie); status_t _FreeAttrCookie(void* node, void* cookie); status_t _CloseIndexDir(void* cookie); status_t _FreeIndexDirCookie(void* cookie); status_t _CloseQuery(void* cookie); status_t _FreeQueryCookie(void* cookie); status_t _SendRequest(RequestPort* port, RequestAllocator* allocator, RequestHandler* handler, Request** reply); status_t _SendReceiptAck(RequestPort* port); void _IncrementVNodeCount(ino_t vnid); void _DecrementVNodeCount(ino_t vnid); void _RemoveInvalidVNode(ino_t vnid); status_t _InternalIOCtl(userlandfs_ioctl* buffer, int32 bufferSize); status_t _PutAllPendingVNodes(); status_t _RegisterIORequest(io_request* request, int32* requestID); status_t _UnregisterIORequest(int32 requestID); status_t _FindIORequest(io_request* request, int32* requestID); status_t _FindIORequest(int32 requestID, io_request** request); static status_t _IterativeFDIOGetVecs(void* cookie, io_request* request, off_t offset, size_t size, struct file_io_vec* vecs, size_t* _count); static status_t _IterativeFDIOFinished(void* cookie, io_request* request, status_t status, bool partialTransfer, size_t bytesTransferred); inline bool HasVNodeCapability(VNode* vnode, int capability) const; private: mutex fLock; FileSystem* fFileSystem; fs_volume* fFSVolume; FSVolumeCapabilities fCapabilities; fs_volume_ops fVolumeOps; void* fUserlandVolume; ino_t fRootID; VNode* fRootNode; int32 fOpenFiles; int32 fOpenDirectories; int32 fOpenAttributeDirectories; int32 fOpenAttributes; int32 fOpenIndexDirectories; int32 fOpenQueries; VNodeMap* fVNodes; IORequestIDMap* fIORequestInfosByID; IORequestStructMap* fIORequestInfosByStruct; int32 fLastIORequestID; volatile bool fVNodeCountingEnabled; }; // GetID inline dev_t Volume::GetID() const { return fFSVolume->id; } // GetFileSystem inline FileSystem* Volume::GetFileSystem() const { return fFileSystem; } // HasCapability inline bool Volume::HasCapability(int capability) const { return fCapabilities.Get(capability); } // GetUserlandVolume inline void* Volume::GetUserlandVolume() const { return fUserlandVolume; } // GetRootID inline ino_t Volume::GetRootID() const { return fRootID; } #endif // USERLAND_FS_VOLUME_H