1/*
2 * Copyright 2001-2009, Ingo Weinhold, ingo_weinhold@gmx.de.
3 * Distributed under the terms of the MIT License.
4 */
5#ifndef USERLAND_FS_FILE_SYSTEM_H
6#define USERLAND_FS_FILE_SYSTEM_H
7
8
9#include <fs_interface.h>
10
11#include <util/OpenHashTable.h>
12
13#include <lock.h>
14
15#include "FSCapabilities.h"
16#include "LazyInitializable.h"
17#include "Locker.h"
18#include "RequestPort.h"
19#include "RequestPortPool.h"
20#include "String.h"
21#include "Vector.h"
22
23
24struct IOCtlInfo;
25namespace BPrivate { class KMessage; }
26using BPrivate::KMessage;
27class Settings;
28class Volume;
29
30
31struct VNodeOps {
32	int32				refCount;
33	FSVNodeCapabilities	capabilities;
34	fs_vnode_ops*		ops;
35	VNodeOps*			hash_link;
36
37	VNodeOps(const FSVNodeCapabilities& capabilities, fs_vnode_ops* ops)
38		:
39		refCount(1),
40		capabilities(capabilities),
41		ops(ops)
42	{
43	}
44
45	~VNodeOps()
46	{
47		delete ops;
48	}
49};
50
51
52struct VNodeOpsHashDefinition {
53	typedef FSVNodeCapabilities	KeyType;
54	typedef	VNodeOps			ValueType;
55
56	size_t HashKey(const FSVNodeCapabilities& key) const
57		{ return key.GetHashCode(); }
58	size_t Hash(const VNodeOps* value) const
59		{ return HashKey(value->capabilities); }
60	bool Compare(const FSVNodeCapabilities& key, const VNodeOps* value) const
61		{ return value->capabilities == key; }
62	VNodeOps*& GetLink(VNodeOps* value) const
63		{ return value->hash_link; }
64};
65
66
67class FileSystem {
68public:
69								FileSystem();
70								~FileSystem();
71
72			status_t			Init(const char* name, team_id team,
73									Port::Info* infos, int32 infoCount,
74									const FSCapabilities& capabilities);
75
76			const char*			GetName() const;
77			team_id				GetTeam() const	{ return fTeam; }
78
79			const FSCapabilities& GetCapabilities() const;
80	inline	bool				HasCapability(uint32 capability) const;
81
82			RequestPortPool*	GetPortPool();
83
84			status_t			Mount(fs_volume* fsVolume, const char* device,
85									uint32 flags, const char* parameters,
86									Volume** volume);
87//			status_t			Initialize(const char* deviceName,
88//									const char* parameters, size_t len);
89			void				VolumeUnmounted(Volume* volume);
90
91			Volume*				GetVolume(dev_t id);
92
93			const IOCtlInfo*	GetIOCtlInfo(int command) const;
94
95			status_t			AddSelectSyncEntry(selectsync* sync);
96			void				RemoveSelectSyncEntry(selectsync* sync);
97			bool				KnowsSelectSyncEntry(selectsync* sync);
98
99			status_t			AddNodeListener(dev_t device, ino_t node,
100									uint32 flags, void* listener);
101			status_t			RemoveNodeListener(dev_t device, ino_t node,
102									void* listener);
103
104			VNodeOps*			GetVNodeOps(
105									const FSVNodeCapabilities& capabilities);
106			void				PutVNodeOps(VNodeOps* ops);
107
108			bool				IsUserlandServerThread() const;
109
110private:
111			struct SelectSyncMap;
112			struct NodeListenerKey;
113			struct NodeListenerProxy;
114			struct NodeListenerHashDefinition;
115
116			friend class KernelDebug;
117			friend struct NodeListenerProxy;
118
119			typedef BOpenHashTable<VNodeOpsHashDefinition> VNodeOpsMap;
120			typedef BOpenHashTable<NodeListenerHashDefinition> NodeListenerMap;
121
122
123private:
124			void				_InitVNodeOpsVector(fs_vnode_ops* ops,
125									const FSVNodeCapabilities& capabilities);
126
127			void				_NodeListenerEventOccurred(
128									NodeListenerProxy* proxy,
129									const KMessage* event);
130
131	static	int32				_NotificationThreadEntry(void* data);
132			int32				_NotificationThread();
133
134private:
135			Vector<Volume*>		fVolumes;
136			mutex				fVolumeLock;
137			VNodeOpsMap			fVNodeOps;
138			mutex				fVNodeOpsLock;
139			String				fName;
140			team_id				fTeam;
141			FSCapabilities		fCapabilities;
142			RequestPort*		fNotificationPort;
143			thread_id			fNotificationThread;
144			RequestPortPool		fPortPool;
145			SelectSyncMap*		fSelectSyncs;
146			mutex				fNodeListenersLock;
147			NodeListenerMap*	fNodeListeners;
148			Settings*			fSettings;
149			team_id				fUserlandServerTeam;
150			bool				fInitialized;
151	volatile bool				fTerminating;
152};
153
154
155// HasCapability
156inline bool
157FileSystem::HasCapability(uint32 capability) const
158{
159	return fCapabilities.Get(capability);
160}
161
162#endif	// USERLAND_FS_FILE_SYSTEM_H
163