xref: /haiku/src/add-ons/kernel/file_systems/packagefs/volume/Volume.h (revision 04a0e9c7b68cbe3a43d38e2bca8e860fd80936fb)
1 /*
2  * Copyright 2009-2013, Ingo Weinhold, ingo_weinhold@gmx.de.
3  * Distributed under the terms of the MIT License.
4  */
5 #ifndef VOLUME_H
6 #define VOLUME_H
7 
8 
9 #include <fs_interface.h>
10 
11 #include <condition_variable.h>
12 #include <lock.h>
13 #include <util/AutoLock.h>
14 #include <util/DoublyLinkedList.h>
15 #include <util/KMessage.h>
16 
17 #include <packagefs.h>
18 
19 #include "Index.h"
20 #include "Node.h"
21 #include "NodeListener.h"
22 #include "Package.h"
23 #include "PackageLinksListener.h"
24 #include "PackageSettings.h"
25 #include "Query.h"
26 
27 
28 class Directory;
29 class PackageFSRoot;
30 class UnpackingNode;
31 
32 typedef IndexHashTable::Iterator IndexDirIterator;
33 
34 
35 typedef PackageFSMountType MountType;
36 
37 
38 class Volume : public DoublyLinkedListLinkImpl<Volume>,
39 	private PackageLinksListener {
40 public:
41 								Volume(fs_volume* fsVolume);
42 								~Volume();
43 
44 	inline	bool				ReadLock() const;
45 	inline	void				ReadUnlock() const;
46 	inline	bool				WriteLock();
47 	inline	void				WriteUnlock();
48 
49 			fs_volume*			FSVolume() const	{ return fFSVolume; }
50 			dev_t				ID() const			{ return fFSVolume->id; }
51 			Directory*			RootDirectory() const { return fRootDirectory; }
52 
53 			::MountType			MountType() const	{ return fMountType; }
54 
55 			int					PackagesDirectoryFD() const;
56 
57 			void				SetPackageFSRoot(::PackageFSRoot* root)
58 									{ fPackageFSRoot = root; }
59 			::PackageFSRoot*	PackageFSRoot() const
60 									{ return fPackageFSRoot; }
61 
62 			dev_t				MountPointDeviceID() const
63 									{ return fMountPoint.deviceID; }
64 			ino_t				MountPointNodeID() const
65 									{ return fMountPoint.nodeID; }
66 
67 			status_t			Mount(const char* parameterString);
68 			void				Unmount();
69 
70 			Node*				FindNode(ino_t nodeID) const
71 									{ return fNodes.Lookup(nodeID); }
72 
73 			status_t			IOCtl(Node* node, uint32 operation,
74 									void* buffer, size_t size);
75 
76 			// node listeners -- volume must be write-locked
77 			void				AddNodeListener(NodeListener* listener,
78 									Node* node);
79 			void				RemoveNodeListener(NodeListener* listener);
80 
81 			// query support -- volume must be write-locked
82 			void				AddQuery(Query* query);
83 			void				RemoveQuery(Query* query);
84 			void				UpdateLiveQueries(Node* node,
85 									const char* attribute, int32 type,
86 									const void* oldKey, size_t oldLength,
87 									const void* newKey, size_t newLength);
88 
89 			Index*				FindIndex(const StringKey& name) const
90 									{ return fIndices.Lookup(name); }
91 			IndexDirIterator	GetIndexDirIterator() const
92 									{ return fIndices.GetIterator(); }
93 
94 			// VFS wrappers
95 			status_t			GetVNode(ino_t nodeID, Node*& _node);
96 			status_t			PutVNode(ino_t nodeID);
97 			status_t			RemoveVNode(ino_t nodeID);
98 			status_t			PublishVNode(Node* node);
99 
100 private:
101 	// PackageLinksListener
102 	virtual	void				PackageLinkNodeAdded(Node* node);
103 	virtual	void				PackageLinkNodeRemoved(Node* node);
104 	virtual	void				PackageLinkNodeChanged(Node* node,
105 									uint32 statFields,
106 									const OldNodeAttributes& oldAttributes);
107 
108 private:
109 			struct PackagesDirectory;
110 			struct ShineThroughDirectory;
111 			struct ActivationChangeRequest;
112 
113 private:
114 			status_t			_AddInitialPackages();
115 			status_t			_AddInitialPackagesFromActivationFile();
116 			status_t			_AddInitialPackagesFromDirectory();
117 			status_t			_LoadAndAddInitialPackage(const char* name);
118 
119 	inline	void				_AddPackage(Package* package);
120 	inline	void				_RemovePackage(Package* package);
121 			void				_RemoveAllPackages();
122 	inline	Package*			_FindPackage(const char* fileName) const;
123 
124 			status_t			_AddPackageContent(Package* package,
125 									bool notify);
126 			void				_RemovePackageContent(Package* package,
127 									PackageNode* endNode, bool notify);
128 
129 			status_t			_AddPackageContentRootNode(Package* package,
130 									PackageNode* node, bool notify);
131 			void				_RemovePackageContentRootNode(Package* package,
132 									PackageNode* packageNode,
133 									PackageNode* endPackageNode, bool notify);
134 
135 			status_t			_AddPackageNode(Directory* directory,
136 									PackageNode* packageNode, bool notify,
137 									Node*& _node);
138 			void				_RemovePackageNode(Directory* directory,
139 									PackageNode* packageNode, Node* node,
140 									bool notify);
141 
142 			status_t			_CreateUnpackingNode(mode_t mode,
143 									Directory* parent, const String& name,
144 									UnpackingNode*& _node);
145 									// does *not* return a reference
146 			void				_RemoveNode(Node* node);
147 			void				_RemoveNodeAndVNode(Node* node);
148 									// caller must hold a reference
149 
150 			status_t			_LoadPackage(const char* name,
151 									Package*& _package);
152 
153 			status_t			_ChangeActivation(
154 									ActivationChangeRequest& request);
155 
156 			status_t			_InitMountType(const char* mountType);
157 			status_t			_CreateShineThroughDirectory(Directory* parent,
158 									const char* name, Directory*& _directory);
159 			status_t			_CreateShineThroughDirectories(
160 									const char* shineThroughSetting);
161 			status_t			_PublishShineThroughDirectories();
162 
163 			status_t			_AddPackageLinksDirectory();
164 			void				_RemovePackageLinksDirectory();
165 			void				_AddPackageLinksNode(Node* node);
166 			void				_RemovePackageLinksNode(Node* node);
167 
168 	inline	Volume*				_SystemVolumeIfNotSelf() const;
169 
170 			void				_NotifyNodeAdded(Node* node);
171 			void				_NotifyNodeRemoved(Node* node);
172 			void				_NotifyNodeChanged(Node* node,
173 									uint32 statFields,
174 									const OldNodeAttributes& oldAttributes);
175 
176 private:
177 	mutable	rw_lock				fLock;
178 			fs_volume*			fFSVolume;
179 			Directory*			fRootDirectory;
180 			::PackageFSRoot*	fPackageFSRoot;
181 			::MountType			fMountType;
182 			PackagesDirectory*	fPackagesDirectory;
183 			PackageSettings		fPackageSettings;
184 
185 			struct {
186 				dev_t			deviceID;
187 				ino_t			nodeID;
188 			} fMountPoint;
189 
190 			NodeIDHashTable		fNodes;
191 			NodeListenerHashTable fNodeListeners;
192 			PackageFileNameHashTable fPackages;
193 			QueryList			fQueries;
194 			IndexHashTable		fIndices;
195 
196 			ino_t				fNextNodeID;
197 };
198 
199 
200 bool
201 Volume::ReadLock() const
202 {
203 	return rw_lock_read_lock(&fLock) == B_OK;
204 }
205 
206 
207 void
208 Volume::ReadUnlock() const
209 {
210 	rw_lock_read_unlock(&fLock);
211 }
212 
213 
214 bool
215 Volume::WriteLock()
216 {
217 	return rw_lock_write_lock(&fLock) == B_OK;
218 }
219 
220 
221 void
222 Volume::WriteUnlock()
223 {
224 	rw_lock_write_unlock(&fLock);
225 }
226 
227 
228 typedef AutoLocker<const Volume, AutoLockerReadLocking<const Volume> >
229 	VolumeReadLocker;
230 typedef AutoLocker<Volume, AutoLockerWriteLocking<Volume> > VolumeWriteLocker;
231 
232 
233 #endif	// VOLUME_H
234