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