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