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