xref: /haiku/src/add-ons/kernel/file_systems/packagefs/volume/Volume.h (revision 0059775c1d6454bba41a9f0defebc4b6151838fa)
11e7416d9SIngo Weinhold /*
2aeb6fc9eSIngo Weinhold  * Copyright 2009-2014, Ingo Weinhold, ingo_weinhold@gmx.de.
31e7416d9SIngo Weinhold  * Distributed under the terms of the MIT License.
41e7416d9SIngo Weinhold  */
51e7416d9SIngo Weinhold #ifndef VOLUME_H
61e7416d9SIngo Weinhold #define VOLUME_H
71e7416d9SIngo Weinhold 
81e7416d9SIngo Weinhold 
91e7416d9SIngo Weinhold #include <fs_interface.h>
101e7416d9SIngo Weinhold 
111e7416d9SIngo Weinhold #include <condition_variable.h>
121e7416d9SIngo Weinhold #include <lock.h>
131e7416d9SIngo Weinhold #include <util/AutoLock.h>
141e7416d9SIngo Weinhold #include <util/DoublyLinkedList.h>
151e7416d9SIngo Weinhold #include <util/KMessage.h>
161e7416d9SIngo Weinhold 
171e7416d9SIngo Weinhold #include <packagefs.h>
181e7416d9SIngo Weinhold 
191e7416d9SIngo Weinhold #include "Index.h"
201e7416d9SIngo Weinhold #include "Node.h"
211e7416d9SIngo Weinhold #include "NodeListener.h"
221e7416d9SIngo Weinhold #include "Package.h"
231e7416d9SIngo Weinhold #include "PackageLinksListener.h"
245d55f327SIngo Weinhold #include "PackagesDirectory.h"
253a7e0b00SIngo Weinhold #include "PackageSettings.h"
261e7416d9SIngo Weinhold #include "Query.h"
271e7416d9SIngo Weinhold 
281e7416d9SIngo Weinhold 
291e7416d9SIngo Weinhold class Directory;
301e7416d9SIngo Weinhold class PackageFSRoot;
31aeb6fc9eSIngo Weinhold class PackagesDirectory;
321e7416d9SIngo Weinhold class UnpackingNode;
331e7416d9SIngo Weinhold 
341e7416d9SIngo Weinhold typedef IndexHashTable::Iterator IndexDirIterator;
351e7416d9SIngo Weinhold 
361e7416d9SIngo Weinhold 
371e7416d9SIngo Weinhold typedef PackageFSMountType MountType;
381e7416d9SIngo Weinhold 
391e7416d9SIngo Weinhold 
401e7416d9SIngo Weinhold class Volume : public DoublyLinkedListLinkImpl<Volume>,
411e7416d9SIngo Weinhold 	private PackageLinksListener {
421e7416d9SIngo Weinhold public:
431e7416d9SIngo Weinhold 								Volume(fs_volume* fsVolume);
441e7416d9SIngo Weinhold 								~Volume();
451e7416d9SIngo Weinhold 
461e7416d9SIngo Weinhold 	inline	bool				ReadLock() const;
471e7416d9SIngo Weinhold 	inline	void				ReadUnlock() const;
481e7416d9SIngo Weinhold 	inline	bool				WriteLock();
491e7416d9SIngo Weinhold 	inline	void				WriteUnlock();
50*0059775cSAugustin Cavalier 	inline	bool				IsWriteLocked() const;
511e7416d9SIngo Weinhold 
FSVolume()521e7416d9SIngo Weinhold 			fs_volume*			FSVolume() const	{ return fFSVolume; }
ID()531e7416d9SIngo Weinhold 			dev_t				ID() const			{ return fFSVolume->id; }
RootDirectory()541e7416d9SIngo Weinhold 			Directory*			RootDirectory() const { return fRootDirectory; }
551e7416d9SIngo Weinhold 
MountType()561e7416d9SIngo Weinhold 			::MountType			MountType() const	{ return fMountType; }
571e7416d9SIngo Weinhold 
SetPackageFSRoot(::PackageFSRoot * root)581e7416d9SIngo Weinhold 			void				SetPackageFSRoot(::PackageFSRoot* root)
591e7416d9SIngo Weinhold 									{ fPackageFSRoot = root; }
PackageFSRoot()601e7416d9SIngo Weinhold 			::PackageFSRoot*	PackageFSRoot() const
611e7416d9SIngo Weinhold 									{ return fPackageFSRoot; }
621e7416d9SIngo Weinhold 
MountPointDeviceID()631e7416d9SIngo Weinhold 			dev_t				MountPointDeviceID() const
641e7416d9SIngo Weinhold 									{ return fMountPoint.deviceID; }
MountPointNodeID()651e7416d9SIngo Weinhold 			ino_t				MountPointNodeID() const
661e7416d9SIngo Weinhold 									{ return fMountPoint.nodeID; }
671e7416d9SIngo Weinhold 
681e7416d9SIngo Weinhold 			status_t			Mount(const char* parameterString);
691e7416d9SIngo Weinhold 			void				Unmount();
701e7416d9SIngo Weinhold 
FindNode(ino_t nodeID)711e7416d9SIngo Weinhold 			Node*				FindNode(ino_t nodeID) const
721e7416d9SIngo Weinhold 									{ return fNodes.Lookup(nodeID); }
731e7416d9SIngo Weinhold 
741e7416d9SIngo Weinhold 			status_t			IOCtl(Node* node, uint32 operation,
751e7416d9SIngo Weinhold 									void* buffer, size_t size);
761e7416d9SIngo Weinhold 
771e7416d9SIngo Weinhold 			// node listeners -- volume must be write-locked
781e7416d9SIngo Weinhold 			void				AddNodeListener(NodeListener* listener,
791e7416d9SIngo Weinhold 									Node* node);
801e7416d9SIngo Weinhold 			void				RemoveNodeListener(NodeListener* listener);
811e7416d9SIngo Weinhold 
821e7416d9SIngo Weinhold 			// query support -- volume must be write-locked
831e7416d9SIngo Weinhold 			void				AddQuery(Query* query);
841e7416d9SIngo Weinhold 			void				RemoveQuery(Query* query);
851e7416d9SIngo Weinhold 			void				UpdateLiveQueries(Node* node,
861e7416d9SIngo Weinhold 									const char* attribute, int32 type,
871e7416d9SIngo Weinhold 									const void* oldKey, size_t oldLength,
881e7416d9SIngo Weinhold 									const void* newKey, size_t newLength);
891e7416d9SIngo Weinhold 
FindIndex(const StringKey & name)90d07c930cSIngo Weinhold 			Index*				FindIndex(const StringKey& name) const
911e7416d9SIngo Weinhold 									{ return fIndices.Lookup(name); }
GetIndexDirIterator()921e7416d9SIngo Weinhold 			IndexDirIterator	GetIndexDirIterator() const
931e7416d9SIngo Weinhold 									{ return fIndices.GetIterator(); }
941e7416d9SIngo Weinhold 
951e7416d9SIngo Weinhold 			// VFS wrappers
961e7416d9SIngo Weinhold 			status_t			GetVNode(ino_t nodeID, Node*& _node);
971e7416d9SIngo Weinhold 			status_t			PutVNode(ino_t nodeID);
981e7416d9SIngo Weinhold 			status_t			RemoveVNode(ino_t nodeID);
991e7416d9SIngo Weinhold 			status_t			PublishVNode(Node* node);
1001e7416d9SIngo Weinhold 
1011e7416d9SIngo Weinhold private:
1021e7416d9SIngo Weinhold 	// PackageLinksListener
1031e7416d9SIngo Weinhold 	virtual	void				PackageLinkNodeAdded(Node* node);
1041e7416d9SIngo Weinhold 	virtual	void				PackageLinkNodeRemoved(Node* node);
1051e7416d9SIngo Weinhold 	virtual	void				PackageLinkNodeChanged(Node* node,
1061e7416d9SIngo Weinhold 									uint32 statFields,
1071e7416d9SIngo Weinhold 									const OldNodeAttributes& oldAttributes);
1081e7416d9SIngo Weinhold 
1091e7416d9SIngo Weinhold private:
1101e7416d9SIngo Weinhold 			struct ShineThroughDirectory;
1111e7416d9SIngo Weinhold 			struct ActivationChangeRequest;
1121e7416d9SIngo Weinhold 
1131e7416d9SIngo Weinhold private:
1145d55f327SIngo Weinhold 			status_t			_LoadOldPackagesStates(
1155d55f327SIngo Weinhold 									const char* packagesState);
1165d55f327SIngo Weinhold 
1171e7416d9SIngo Weinhold 			status_t			_AddInitialPackages();
1185d55f327SIngo Weinhold 			status_t			_AddInitialPackagesFromActivationFile(
1195d55f327SIngo Weinhold 									PackagesDirectory* packagesDirectory);
1201e7416d9SIngo Weinhold 			status_t			_AddInitialPackagesFromDirectory();
1215d55f327SIngo Weinhold 			status_t			_LoadAndAddInitialPackage(
1225d55f327SIngo Weinhold 									PackagesDirectory* packagesDirectory,
1235d55f327SIngo Weinhold 									const char* name);
1241e7416d9SIngo Weinhold 
1251e7416d9SIngo Weinhold 	inline	void				_AddPackage(Package* package);
1261e7416d9SIngo Weinhold 	inline	void				_RemovePackage(Package* package);
1271e7416d9SIngo Weinhold 			void				_RemoveAllPackages();
1281e7416d9SIngo Weinhold 	inline	Package*			_FindPackage(const char* fileName) const;
1291e7416d9SIngo Weinhold 
1301e7416d9SIngo Weinhold 			status_t			_AddPackageContent(Package* package,
1311e7416d9SIngo Weinhold 									bool notify);
1321e7416d9SIngo Weinhold 			void				_RemovePackageContent(Package* package,
1331e7416d9SIngo Weinhold 									PackageNode* endNode, bool notify);
1341e7416d9SIngo Weinhold 
1351e7416d9SIngo Weinhold 			status_t			_AddPackageContentRootNode(Package* package,
1361e7416d9SIngo Weinhold 									PackageNode* node, bool notify);
1371e7416d9SIngo Weinhold 			void				_RemovePackageContentRootNode(Package* package,
1381e7416d9SIngo Weinhold 									PackageNode* packageNode,
1391e7416d9SIngo Weinhold 									PackageNode* endPackageNode, bool notify);
1401e7416d9SIngo Weinhold 
1411e7416d9SIngo Weinhold 			status_t			_AddPackageNode(Directory* directory,
1421e7416d9SIngo Weinhold 									PackageNode* packageNode, bool notify,
1431e7416d9SIngo Weinhold 									Node*& _node);
1441e7416d9SIngo Weinhold 			void				_RemovePackageNode(Directory* directory,
1451e7416d9SIngo Weinhold 									PackageNode* packageNode, Node* node,
1461e7416d9SIngo Weinhold 									bool notify);
1471e7416d9SIngo Weinhold 
1481e7416d9SIngo Weinhold 			status_t			_CreateUnpackingNode(mode_t mode,
149d07c930cSIngo Weinhold 									Directory* parent, const String& name,
1501e7416d9SIngo Weinhold 									UnpackingNode*& _node);
1511e7416d9SIngo Weinhold 									// does *not* return a reference
1521e7416d9SIngo Weinhold 			void				_RemoveNode(Node* node);
1531e7416d9SIngo Weinhold 			void				_RemoveNodeAndVNode(Node* node);
1541e7416d9SIngo Weinhold 									// caller must hold a reference
1551e7416d9SIngo Weinhold 
1565d55f327SIngo Weinhold 			status_t			_LoadPackage(
1575d55f327SIngo Weinhold 									PackagesDirectory* packagesDirectory,
1585d55f327SIngo Weinhold 									const char* name, Package*& _package);
1591e7416d9SIngo Weinhold 
1601e7416d9SIngo Weinhold 			status_t			_ChangeActivation(
1611e7416d9SIngo Weinhold 									ActivationChangeRequest& request);
1621e7416d9SIngo Weinhold 
1631e7416d9SIngo Weinhold 			status_t			_InitMountType(const char* mountType);
1641e7416d9SIngo Weinhold 			status_t			_CreateShineThroughDirectory(Directory* parent,
1651e7416d9SIngo Weinhold 									const char* name, Directory*& _directory);
1661e7416d9SIngo Weinhold 			status_t			_CreateShineThroughDirectories(
1671e7416d9SIngo Weinhold 									const char* shineThroughSetting);
1681e7416d9SIngo Weinhold 			status_t			_PublishShineThroughDirectories();
1691e7416d9SIngo Weinhold 
1701e7416d9SIngo Weinhold 			status_t			_AddPackageLinksDirectory();
1711e7416d9SIngo Weinhold 			void				_RemovePackageLinksDirectory();
1721e7416d9SIngo Weinhold 			void				_AddPackageLinksNode(Node* node);
1731e7416d9SIngo Weinhold 			void				_RemovePackageLinksNode(Node* node);
1741e7416d9SIngo Weinhold 
1751e7416d9SIngo Weinhold 	inline	Volume*				_SystemVolumeIfNotSelf() const;
1761e7416d9SIngo Weinhold 
1771e7416d9SIngo Weinhold 			void				_NotifyNodeAdded(Node* node);
1781e7416d9SIngo Weinhold 			void				_NotifyNodeRemoved(Node* node);
1791e7416d9SIngo Weinhold 			void				_NotifyNodeChanged(Node* node,
1801e7416d9SIngo Weinhold 									uint32 statFields,
1811e7416d9SIngo Weinhold 									const OldNodeAttributes& oldAttributes);
1821e7416d9SIngo Weinhold 
1831e7416d9SIngo Weinhold private:
1841e7416d9SIngo Weinhold 	mutable	rw_lock				fLock;
1851e7416d9SIngo Weinhold 			fs_volume*			fFSVolume;
1861e7416d9SIngo Weinhold 			Directory*			fRootDirectory;
1871e7416d9SIngo Weinhold 			::PackageFSRoot*	fPackageFSRoot;
1881e7416d9SIngo Weinhold 			::MountType			fMountType;
1891e7416d9SIngo Weinhold 			PackagesDirectory*	fPackagesDirectory;
1905d55f327SIngo Weinhold 			PackagesDirectoryList fPackagesDirectories;
1915d55f327SIngo Weinhold 			PackagesDirectoryHashTable fPackagesDirectoriesByNodeRef;
1923a7e0b00SIngo Weinhold 			PackageSettings		fPackageSettings;
1931e7416d9SIngo Weinhold 
1941e7416d9SIngo Weinhold 			struct {
1951e7416d9SIngo Weinhold 				dev_t			deviceID;
1961e7416d9SIngo Weinhold 				ino_t			nodeID;
1971e7416d9SIngo Weinhold 			} fMountPoint;
1981e7416d9SIngo Weinhold 
1991e7416d9SIngo Weinhold 			NodeIDHashTable		fNodes;
2001e7416d9SIngo Weinhold 			NodeListenerHashTable fNodeListeners;
2011e7416d9SIngo Weinhold 			PackageFileNameHashTable fPackages;
2021e7416d9SIngo Weinhold 			QueryList			fQueries;
2031e7416d9SIngo Weinhold 			IndexHashTable		fIndices;
2041e7416d9SIngo Weinhold 
2051e7416d9SIngo Weinhold 			ino_t				fNextNodeID;
2061e7416d9SIngo Weinhold };
2071e7416d9SIngo Weinhold 
2081e7416d9SIngo Weinhold 
2091e7416d9SIngo Weinhold bool
ReadLock()2101e7416d9SIngo Weinhold Volume::ReadLock() const
2111e7416d9SIngo Weinhold {
2121e7416d9SIngo Weinhold 	return rw_lock_read_lock(&fLock) == B_OK;
2131e7416d9SIngo Weinhold }
2141e7416d9SIngo Weinhold 
2151e7416d9SIngo Weinhold 
2161e7416d9SIngo Weinhold void
ReadUnlock()2171e7416d9SIngo Weinhold Volume::ReadUnlock() const
2181e7416d9SIngo Weinhold {
2191e7416d9SIngo Weinhold 	rw_lock_read_unlock(&fLock);
2201e7416d9SIngo Weinhold }
2211e7416d9SIngo Weinhold 
2221e7416d9SIngo Weinhold 
2231e7416d9SIngo Weinhold bool
WriteLock()2241e7416d9SIngo Weinhold Volume::WriteLock()
2251e7416d9SIngo Weinhold {
2261e7416d9SIngo Weinhold 	return rw_lock_write_lock(&fLock) == B_OK;
2271e7416d9SIngo Weinhold }
2281e7416d9SIngo Weinhold 
2291e7416d9SIngo Weinhold 
2301e7416d9SIngo Weinhold void
WriteUnlock()2311e7416d9SIngo Weinhold Volume::WriteUnlock()
2321e7416d9SIngo Weinhold {
2331e7416d9SIngo Weinhold 	rw_lock_write_unlock(&fLock);
2341e7416d9SIngo Weinhold }
2351e7416d9SIngo Weinhold 
2361e7416d9SIngo Weinhold 
237*0059775cSAugustin Cavalier bool
IsWriteLocked()238*0059775cSAugustin Cavalier Volume::IsWriteLocked() const
239*0059775cSAugustin Cavalier {
240*0059775cSAugustin Cavalier 	return find_thread(NULL) == fLock.holder;
241*0059775cSAugustin Cavalier }
242*0059775cSAugustin Cavalier 
243*0059775cSAugustin Cavalier 
2441e7416d9SIngo Weinhold typedef AutoLocker<const Volume, AutoLockerReadLocking<const Volume> >
2451e7416d9SIngo Weinhold 	VolumeReadLocker;
2461e7416d9SIngo Weinhold typedef AutoLocker<Volume, AutoLockerWriteLocking<Volume> > VolumeWriteLocker;
2471e7416d9SIngo Weinhold 
2481e7416d9SIngo Weinhold 
2491e7416d9SIngo Weinhold #endif	// VOLUME_H
250