1// VolumeManager.h
2
3#ifndef NET_FS_VOLUME_MANAGER_H
4#define NET_FS_VOLUME_MANAGER_H
5
6#include <AutoLocker.h>
7#include <Entry.h>
8#include <Locker.h>
9#include <util/DoublyLinkedList.h>
10
11#include "BlockingQueue.h"
12#include "NodeMonitor.h"
13#include "NodeMonitoringEvent.h"
14
15class ClientVolume;
16class Directory;
17class Entry;
18class Node;
19class Path;
20class QueryHandle;
21class QueryDomain;
22class Volume;
23
24// VolumeManager
25class VolumeManager : private NodeMonitorListener {
26private:
27								VolumeManager();
28								~VolumeManager();
29
30			status_t			Init();
31
32public:
33	static	status_t			CreateDefault();
34	static	void				DeleteDefault();
35	static	VolumeManager*		GetDefault();
36
37			bool				Lock();
38			void				Unlock();
39
40			int64				GetRevision() const;
41
42			Volume*				GetVolume(dev_t volumeID, bool add = false);
43			Volume*				GetRootVolume() const;
44
45			status_t			AddClientVolume(ClientVolume* clientVolume);
46			void				RemoveClientVolume(ClientVolume* clientVolume);
47
48			status_t			AddNode(Node* node);
49			void				RemoveNode(Node* node);
50			Node*				GetNode(dev_t volumeID, ino_t nodeID);
51			status_t			LoadNode(const struct stat& st, Node** node);
52
53			Directory*			GetDirectory(dev_t volumeID, ino_t nodeID);
54			Directory*			GetRootDirectory() const;
55			Directory*			GetParentDirectory(Directory* directory);
56			status_t			LoadDirectory(dev_t volumeID, ino_t directoryID,
57									Directory** directory);
58
59			status_t			AddEntry(Entry* entry);
60			void				RemoveEntry(Entry* entry);
61			void				DeleteEntry(Entry* entry, bool keepNode);
62			Entry*				GetEntry(dev_t volumeID, ino_t directoryID,
63									const char* name);
64			Entry*				GetEntry(const entry_ref& ref);
65			status_t			LoadEntry(dev_t volumeID, ino_t directoryID,
66									const char* name, bool loadDir,
67									Entry** entry);
68
69			status_t			OpenQuery(QueryDomain* queryDomain,
70									const char* queryString, uint32 flags,
71									port_id remotePort, int32 remoteToken,
72									QueryHandle** handle);
73
74			status_t			CompletePathToRoot(Directory* directory);
75
76			status_t			GetPath(Entry* entry, Path* path);
77			status_t			GetPath(Node* node, Path* path);
78
79			bool				DirectoryContains(Directory* directory,
80									Entry* entry);
81			bool				DirectoryContains(Directory* directory,
82									Directory* descendant, bool reflexive);
83			bool				DirectoryContains(Directory* directory,
84									Node* descendant, bool reflexive);
85
86private:
87	virtual	void				ProcessNodeMonitoringEvent(
88									NodeMonitoringEvent* event);
89
90			status_t			_AddVolume(dev_t volumeID,
91									Volume** volume = NULL);
92
93			void				_EntryCreated(EntryCreatedEvent* event);
94			void				_EntryRemoved(EntryRemovedEvent* event,
95									bool keepNode);
96			void				_EntryMoved(EntryMovedEvent* event);
97			void				_NodeStatChanged(StatChangedEvent* event);
98			void				_NodeAttributeChanged(
99									AttributeChangedEvent* event);
100			void				_VolumeMounted(VolumeMountedEvent* event);
101			void				_VolumeUnmounted(VolumeUnmountedEvent* event);
102
103			void				_QueryEntryCreated(EntryCreatedEvent* event);
104			void				_QueryEntryRemoved(EntryRemovedEvent* event);
105			void				_QueryEntryMoved(EntryMovedEvent* event);
106
107			bool				_IsRecentEvent(
108									NodeMonitoringEvent* event) const;
109
110			status_t			_GenerateEntryCreatedEvent(const entry_ref& ref,
111									bigtime_t time,
112									EntryCreatedEvent** event = NULL);
113			status_t			_GenerateEntryRemovedEvent(Entry* entry,
114									bigtime_t time,
115									EntryRemovedEvent** event = NULL);
116
117			void				_CheckVolumeRootMoved(EntryMovedEvent* event);
118
119	static	int32				_NodeMonitoringProcessorEntry(void* data);
120			int32				_NodeMonitoringProcessor();
121
122private:
123			class QueryHandler;
124			struct VolumeMap;
125			struct ClientVolumeMap;
126			typedef BlockingQueue<NodeMonitoringEvent> NodeMonitoringEventQueue;
127			typedef DoublyLinkedList<NodeMonitoringEvent>
128				NodeMonitoringEventList;
129			struct EntryCreatedEventMap;
130			struct EntryRemovedEventMap;
131			struct EntryMovedEventMap;
132			struct NodeStatChangedEventMap;
133			struct NodeAttributeChangedEventMap;
134
135			BLocker				fLock;
136			VolumeMap*			fVolumes;
137			Volume*				fRootVolume;
138			ClientVolumeMap*	fClientVolumes;
139			NodeMonitor*		fNodeMonitor;
140			thread_id			fNodeMonitoringProcessor;
141			NodeMonitoringEventQueue fNodeMonitoringEvents;
142			NodeMonitoringEventList fRecentNodeMonitoringEvents;
143			EntryCreatedEventMap* fEntryCreatedEvents;
144			EntryRemovedEventMap* fEntryRemovedEvents;
145			EntryMovedEventMap*	fEntryMovedEvents;
146			NodeStatChangedEventMap* fNodeStatChangedEvents;
147			NodeAttributeChangedEventMap* fNodeAttributeChangedEvents;
148			int64				fRevision;
149			bool				fTerminating;
150
151	static	VolumeManager*		sManager;
152};
153
154// VolumeManagerLocker
155struct VolumeManagerLocker : AutoLocker<VolumeManager> {
156	VolumeManagerLocker()
157		: AutoLocker<VolumeManager>(VolumeManager::GetDefault())
158	{
159	}
160};
161
162#endif	// NET_FS_VOLUME_MANAGER_H
163