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_FILE_SYSTEM_H
6#define USERLAND_FS_FUSE_FILE_SYSTEM_H
7
8#include "../FileSystem.h"
9
10#include "fuse_api.h"
11#include "fuse_config.h"
12
13
14namespace UserlandFS {
15
16class FUSEFileSystem : public FileSystem {
17public:
18								FUSEFileSystem(const char* fsName,
19									int (*mainFunction)(int,
20										const char* const*));
21	virtual						~FUSEFileSystem();
22
23	static	FUSEFileSystem*		GetInstance();
24
25			void				GetVolumeCapabilities(
26									FSVolumeCapabilities& capabilities) const
27									{ capabilities = fVolumeCapabilities; }
28			void				GetNodeCapabilities(
29									FSVNodeCapabilities& capabilities) const
30									{ capabilities = fNodeCapabilities; }
31			const FSVNodeCapabilities& GetNodeCapabilities() const
32									{ return fNodeCapabilities; }
33
34			const fuse_lowlevel_ops*	GetLowlevelOps() const
35									{
36										if (fFS == NULL)
37											return &fLowLevelOps;
38										return  NULL;
39									}
40			fuse_fs*			GetFS() const	{ return fFS; }
41
42			const fuse_config&	GetFUSEConfig() const	{ return fFUSEConfig; }
43
44			bool				HasHaikuFuseExtensions() const
45									{
46										return (fConnectionInfo.want
47											& FUSE_CAP_HAIKU_FUSE_EXTENSIONS) != 0;
48									}
49
50	virtual	status_t			CreateVolume(Volume** _volume, dev_t id);
51	virtual	status_t			DeleteVolume(Volume* volume);
52
53	virtual	void				InitRequestThreadContext(
54									RequestThreadContext* context);
55
56			status_t			InitClientFS(const char* parameters);
57			void				ExitClientFS(status_t status);
58
59			status_t			FinishInitClientFS(fuse_config* config,
60									const fuse_operations* ops, size_t opSize,
61									void* userData);
62			status_t			FinishInitClientFS(fuse_config* config,
63									const fuse_lowlevel_ops* ops, size_t opSize,
64									void* userData);
65			status_t			MainLoop(bool multithreaded);
66
67private:
68			class ArgumentVector;
69
70private:
71	static	status_t			_InitializationThreadEntry(void* data);
72			status_t			_InitializationThread();
73
74			status_t			_InitClientFS(const fuse_operations* ops,
75									size_t opSize, void* userData);
76			status_t			_InitClientFS(const fuse_lowlevel_ops* ops,
77									size_t opSize, void* userData);
78
79			void				_InitCapabilities();
80
81private:
82			int					(*fMainFunction)(int, const char* const*);
83			thread_id			fInitThread;
84			status_t			fInitStatus;
85			status_t			fExitStatus;
86			sem_id				fInitSemaphore;
87			sem_id				fExitSemaphore;
88			const char*			fInitParameters;
89			fuse_lowlevel_ops	fLowLevelOps;
90			void*				fUserData;
91			fuse_fs*			fFS;
92			fuse_conn_info		fConnectionInfo;
93			fuse_config			fFUSEConfig;
94
95			FSVolumeCapabilities fVolumeCapabilities;
96			FSVNodeCapabilities	fNodeCapabilities;
97};
98
99}	// namespace UserlandFS
100
101using UserlandFS::FUSEFileSystem;
102
103
104/*static*/ inline FUSEFileSystem*
105FUSEFileSystem::GetInstance()
106{
107	return static_cast<FUSEFileSystem*>(sInstance);
108}
109
110
111#endif	// USERLAND_FS_FUSE_FILE_SYSTEM_H
112