1 /* 2 * Copyright 2009, Ingo Weinhold, ingo_weinhold@gmx.de. 3 * Distributed under the terms of the MIT License. 4 */ 5 #ifndef USERLAND_FS_FUSE_VOLUME_H 6 #define USERLAND_FS_FUSE_VOLUME_H 7 8 #include <AutoLocker.h> 9 #include <RWLockManager.h> 10 11 #include "Locker.h" 12 13 #include "fuse_fs.h" 14 #include "FUSEEntry.h" 15 16 #include "../Volume.h" 17 18 19 namespace UserlandFS { 20 21 class FUSEFileSystem; 22 23 24 class FUSEVolume : public Volume { 25 public: 26 FUSEVolume(FUSEFileSystem* fileSystem, 27 dev_t id); 28 virtual ~FUSEVolume(); 29 30 status_t Init(); 31 32 void SetFS(fuse_fs* fs) { fFS = fs; } 33 34 // FS 35 virtual status_t Mount(const char* device, uint32 flags, 36 const char* parameters, ino_t* rootID); 37 virtual status_t Unmount(); 38 virtual status_t Sync(); 39 virtual status_t ReadFSInfo(fs_info* info); 40 41 // vnodes 42 virtual status_t Lookup(void* dir, const char* entryName, 43 ino_t* vnid); 44 virtual status_t GetVNodeName(void* node, char* buffer, 45 size_t bufferSize); 46 virtual status_t ReadVNode(ino_t vnid, bool reenter, 47 void** node, int* type, uint32* flags, 48 FSVNodeCapabilities* _capabilities); 49 virtual status_t WriteVNode(void* node, bool reenter); 50 virtual status_t RemoveVNode(void* node, bool reenter); 51 52 // nodes 53 virtual status_t SetFlags(void* node, void* cookie, 54 int flags); 55 56 virtual status_t FSync(void* node); 57 58 virtual status_t ReadSymlink(void* node, char* buffer, 59 size_t bufferSize, size_t* bytesRead); 60 virtual status_t CreateSymlink(void* dir, const char* name, 61 const char* target, int mode); 62 63 virtual status_t Link(void* dir, const char* name, 64 void* node); 65 virtual status_t Unlink(void* dir, const char* name); 66 virtual status_t Rename(void* oldDir, const char* oldName, 67 void* newDir, const char* newName); 68 69 virtual status_t Access(void* node, int mode); 70 virtual status_t ReadStat(void* node, struct stat* st); 71 virtual status_t WriteStat(void* node, const struct stat* st, 72 uint32 mask); 73 74 // files 75 virtual status_t Create(void* dir, const char* name, 76 int openMode, int mode, void** cookie, 77 ino_t* vnid); 78 virtual status_t Open(void* node, int openMode, 79 void** cookie); 80 virtual status_t Close(void* node, void* cookie); 81 virtual status_t FreeCookie(void* node, void* cookie); 82 virtual status_t Read(void* node, void* cookie, off_t pos, 83 void* buffer, size_t bufferSize, 84 size_t* bytesRead); 85 virtual status_t Write(void* node, void* cookie, 86 off_t pos, const void* buffer, 87 size_t bufferSize, size_t* bytesWritten); 88 89 // directories 90 virtual status_t CreateDir(void* dir, const char* name, 91 int mode); 92 virtual status_t RemoveDir(void* dir, const char* name); 93 virtual status_t OpenDir(void* node, void** cookie); 94 virtual status_t CloseDir(void* node, void* cookie); 95 virtual status_t FreeDirCookie(void* node, void* cookie); 96 virtual status_t ReadDir(void* node, void* cookie, 97 void* buffer, size_t bufferSize, 98 uint32 count, uint32* countRead); 99 virtual status_t RewindDir(void* node, void* cookie); 100 101 // attribute directories 102 virtual status_t OpenAttrDir(void* node, void** cookie); 103 virtual status_t CloseAttrDir(void* node, void* cookie); 104 virtual status_t FreeAttrDirCookie(void* node, 105 void* cookie); 106 virtual status_t ReadAttrDir(void* node, void* cookie, 107 void* buffer, size_t bufferSize, 108 uint32 count, uint32* countRead); 109 virtual status_t RewindAttrDir(void* node, void* cookie); 110 111 // attributes 112 virtual status_t OpenAttr(void* node, const char* name, 113 int openMode, void** cookie); 114 virtual status_t CloseAttr(void* node, void* cookie); 115 virtual status_t FreeAttrCookie(void* node, void* cookie); 116 virtual status_t ReadAttr(void* node, void* cookie, 117 off_t pos, void* buffer, size_t bufferSize, 118 size_t* bytesRead); 119 virtual status_t ReadAttrStat(void* node, void* cookie, 120 struct stat* st); 121 122 private: 123 struct DirEntryCache; 124 struct DirCookie; 125 struct FileCookie; 126 struct AttrDirCookie; 127 struct AttrCookie; 128 struct ReadDirBuffer; 129 struct LockIterator; 130 struct RWLockableReadLocking; 131 struct RWLockableWriteLocking; 132 struct RWLockableReadLocker; 133 struct RWLockableWriteLocker; 134 struct NodeLocker; 135 struct NodeReadLocker; 136 struct NodeWriteLocker; 137 struct MultiNodeLocker; 138 139 friend struct LockIterator; 140 friend struct RWLockableReadLocking; 141 friend struct RWLockableWriteLocking; 142 friend struct NodeLocker; 143 friend struct MultiNodeLocker; 144 145 private: 146 inline FUSEFileSystem* _FileSystem() const; 147 148 ino_t _GenerateNodeID(); 149 150 bool _GetNodeID(FUSENode* dir, const char* entryName, 151 ino_t* _nodeID); 152 status_t _GetNode(FUSENode* dir, const char* entryName, 153 FUSENode** _node); 154 status_t _InternalGetNode(FUSENode* dir, 155 const char* entryName, FUSENode** _node, 156 AutoLocker<Locker>& locker); 157 void _PutNode(FUSENode* node); 158 void _PutNodes(FUSENode* const* nodes, int32 count); 159 160 void _RemoveEntry(FUSEEntry* entry); 161 status_t _RemoveEntry(FUSENode* dir, const char* name); 162 status_t _RenameEntry(FUSENode* oldDir, 163 const char* oldName, FUSENode* newDir, 164 const char* newName); 165 166 status_t _LockNodeChain(FUSENode* node, bool lockParent, 167 bool writeLock); 168 void _UnlockNodeChain(FUSENode* node, bool parent, 169 bool writeLock); 170 void _UnlockNodeChainInternal(FUSENode* node, 171 bool writeLock, FUSENode* stopNode, 172 FUSENode* stopBeforeNode); 173 174 status_t _LockNodeChains(FUSENode* node1, 175 bool lockParent1, bool writeLock1, 176 FUSENode* node2, bool lockParent2, 177 bool writeLock2); 178 status_t _LockNodeChainsInternal(FUSENode* node1, 179 bool lockParent1, bool writeLock1, 180 FUSENode* node2, bool lockParent2, 181 bool writeLock2, bool* _retry); 182 void _UnlockNodeChains(FUSENode* node1, bool parent1, 183 bool writeLock1, FUSENode* node2, 184 bool parent2, bool writeLock2); 185 186 bool _FindCommonAncestor(FUSENode* node1, 187 FUSENode* node2, FUSENode** _commonAncestor, 188 bool* _inverseLockingOrder); 189 bool _GetNodeAncestors(FUSENode* node, 190 FUSENode** ancestors, uint32* _count); 191 192 status_t _BuildPath(FUSENode* dir, const char* entryName, 193 char* path, size_t& pathLen); 194 status_t _BuildPath(FUSENode* node, char* path, 195 size_t& pathLen); 196 197 static int _AddReadDirEntry(void* buffer, const char* name, 198 const struct stat* st, off_t offset); 199 static int _AddReadDirEntryGetDir(fuse_dirh_t handle, 200 const char* name, int type, ino_t nodeID); 201 int _AddReadDirEntry(ReadDirBuffer* buffer, 202 const char* name, int type, ino_t nodeID, 203 off_t offset); 204 205 private: 206 RWLockManager fLockManager; 207 Locker fLock; 208 fuse_fs* fFS; 209 FUSEEntryTable fEntries; 210 FUSENodeTable fNodes; 211 FUSENode* fRootNode; 212 ino_t fNextNodeID; 213 bool fUseNodeIDs; // TODO: Actually read the 214 // option! 215 char fName[B_OS_NAME_LENGTH]; 216 }; 217 218 } // namespace UserlandFS 219 220 using UserlandFS::FUSEVolume; 221 222 #endif // USERLAND_FS_FUSE_VOLUME_H 223