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