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