xref: /haiku/src/add-ons/kernel/file_systems/userlandfs/server/fuse/FUSEVolume.h (revision 68ea01249e1e2088933cb12f9c28d4e5c5d1c9ef)
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