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