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