xref: /haiku/src/add-ons/kernel/file_systems/packagefs/volume/Volume.h (revision e81a954787e50e56a7f06f72705b7859b6ab06d1)
1 /*
2  * Copyright 2009-2014, 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 "PackagesDirectory.h"
25 #include "PackageSettings.h"
26 #include "Query.h"
27 
28 
29 class Directory;
30 class PackageFSRoot;
31 class PackagesDirectory;
32 class UnpackingNode;
33 
34 typedef IndexHashTable::Iterator IndexDirIterator;
35 
36 
37 typedef PackageFSMountType MountType;
38 
39 
40 class Volume : public DoublyLinkedListLinkImpl<Volume>,
41 	private PackageLinksListener {
42 public:
43 								Volume(fs_volume* fsVolume);
44 								~Volume();
45 
46 	inline	bool				ReadLock() const;
47 	inline	void				ReadUnlock() const;
48 	inline	bool				WriteLock();
49 	inline	void				WriteUnlock();
50 
51 			fs_volume*			FSVolume() const	{ return fFSVolume; }
52 			dev_t				ID() const			{ return fFSVolume->id; }
53 			Directory*			RootDirectory() const { return fRootDirectory; }
54 
55 			::MountType			MountType() const	{ return fMountType; }
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 ShineThroughDirectory;
110 			struct ActivationChangeRequest;
111 
112 private:
113 			status_t			_LoadOldPackagesStates(
114 									const char* packagesState);
115 
116 			status_t			_AddInitialPackages();
117 			status_t			_AddInitialPackagesFromActivationFile(
118 									PackagesDirectory* packagesDirectory);
119 			status_t			_AddInitialPackagesFromDirectory();
120 			status_t			_LoadAndAddInitialPackage(
121 									PackagesDirectory* packagesDirectory,
122 									const char* name);
123 
124 	inline	void				_AddPackage(Package* package);
125 	inline	void				_RemovePackage(Package* package);
126 			void				_RemoveAllPackages();
127 	inline	Package*			_FindPackage(const char* fileName) const;
128 
129 			status_t			_AddPackageContent(Package* package,
130 									bool notify);
131 			void				_RemovePackageContent(Package* package,
132 									PackageNode* endNode, bool notify);
133 
134 			status_t			_AddPackageContentRootNode(Package* package,
135 									PackageNode* node, bool notify);
136 			void				_RemovePackageContentRootNode(Package* package,
137 									PackageNode* packageNode,
138 									PackageNode* endPackageNode, bool notify);
139 
140 			status_t			_AddPackageNode(Directory* directory,
141 									PackageNode* packageNode, bool notify,
142 									Node*& _node);
143 			void				_RemovePackageNode(Directory* directory,
144 									PackageNode* packageNode, Node* node,
145 									bool notify);
146 
147 			status_t			_CreateUnpackingNode(mode_t mode,
148 									Directory* parent, const String& name,
149 									UnpackingNode*& _node);
150 									// does *not* return a reference
151 			void				_RemoveNode(Node* node);
152 			void				_RemoveNodeAndVNode(Node* node);
153 									// caller must hold a reference
154 
155 			status_t			_LoadPackage(
156 									PackagesDirectory* packagesDirectory,
157 									const char* name, Package*& _package);
158 
159 			status_t			_ChangeActivation(
160 									ActivationChangeRequest& request);
161 
162 			status_t			_InitMountType(const char* mountType);
163 			status_t			_CreateShineThroughDirectory(Directory* parent,
164 									const char* name, Directory*& _directory);
165 			status_t			_CreateShineThroughDirectories(
166 									const char* shineThroughSetting);
167 			status_t			_PublishShineThroughDirectories();
168 
169 			status_t			_AddPackageLinksDirectory();
170 			void				_RemovePackageLinksDirectory();
171 			void				_AddPackageLinksNode(Node* node);
172 			void				_RemovePackageLinksNode(Node* node);
173 
174 	inline	Volume*				_SystemVolumeIfNotSelf() const;
175 
176 			void				_NotifyNodeAdded(Node* node);
177 			void				_NotifyNodeRemoved(Node* node);
178 			void				_NotifyNodeChanged(Node* node,
179 									uint32 statFields,
180 									const OldNodeAttributes& oldAttributes);
181 
182 private:
183 	mutable	rw_lock				fLock;
184 			fs_volume*			fFSVolume;
185 			Directory*			fRootDirectory;
186 			::PackageFSRoot*	fPackageFSRoot;
187 			::MountType			fMountType;
188 			PackagesDirectory*	fPackagesDirectory;
189 			PackagesDirectoryList fPackagesDirectories;
190 			PackagesDirectoryHashTable fPackagesDirectoriesByNodeRef;
191 			PackageSettings		fPackageSettings;
192 
193 			struct {
194 				dev_t			deviceID;
195 				ino_t			nodeID;
196 			} fMountPoint;
197 
198 			NodeIDHashTable		fNodes;
199 			NodeListenerHashTable fNodeListeners;
200 			PackageFileNameHashTable fPackages;
201 			QueryList			fQueries;
202 			IndexHashTable		fIndices;
203 
204 			ino_t				fNextNodeID;
205 };
206 
207 
208 bool
209 Volume::ReadLock() const
210 {
211 	return rw_lock_read_lock(&fLock) == B_OK;
212 }
213 
214 
215 void
216 Volume::ReadUnlock() const
217 {
218 	rw_lock_read_unlock(&fLock);
219 }
220 
221 
222 bool
223 Volume::WriteLock()
224 {
225 	return rw_lock_write_lock(&fLock) == B_OK;
226 }
227 
228 
229 void
230 Volume::WriteUnlock()
231 {
232 	rw_lock_write_unlock(&fLock);
233 }
234 
235 
236 typedef AutoLocker<const Volume, AutoLockerReadLocking<const Volume> >
237 	VolumeReadLocker;
238 typedef AutoLocker<Volume, AutoLockerWriteLocking<Volume> > VolumeWriteLocker;
239 
240 
241 #endif	// VOLUME_H
242