2 * Copyright 2009-2014, Ingo Weinhold, ingo_weinhold@gmx.de.
3 * Distributed under the terms of the MIT License.
9 #include <fs_interface.h>
11 #include <condition_variable.h>
13 #include <util/AutoLock.h>
14 #include <util/DoublyLinkedList.h>
15 #include <util/KMessage.h>
17 #include <packagefs.h>
21 #include "NodeListener.h"
23 #include "PackageLinksListener.h"
24 #include "PackagesDirectory.h"
25 #include "PackageSettings.h"
31 class PackagesDirectory
;
34 typedef IndexHashTable::Iterator IndexDirIterator
;
37 typedef PackageFSMountType MountType
;
40 class Volume
: public DoublyLinkedListLinkImpl
<Volume
>,
41 private PackageLinksListener
{
43 Volume(fs_volume
* fsVolume
);
46 inline bool ReadLock() const;
47 inline void ReadUnlock() const;
48 inline bool WriteLock();
49 inline void WriteUnlock();
51 fs_volume
* FSVolume() const { return fFSVolume
; }
52 dev_t
ID() const { return fFSVolume
->id
; }
53 Directory
* RootDirectory() const { return fRootDirectory
; }
55 ::MountType
MountType() const { return fMountType
; }
57 void SetPackageFSRoot(::PackageFSRoot
* root
)
58 { fPackageFSRoot
= root
; }
59 ::PackageFSRoot
* PackageFSRoot() const
60 { return fPackageFSRoot
; }
62 dev_t
MountPointDeviceID() const
63 { return fMountPoint
.deviceID
; }
64 ino_t
MountPointNodeID() const
65 { return fMountPoint
.nodeID
; }
67 status_t
Mount(const char* parameterString
);
70 Node
* FindNode(ino_t nodeID
) const
71 { return fNodes
.Lookup(nodeID
); }
73 status_t
IOCtl(Node
* node
, uint32 operation
,
74 void* buffer
, size_t size
);
76 // node listeners -- volume must be write-locked
77 void AddNodeListener(NodeListener
* listener
,
79 void RemoveNodeListener(NodeListener
* listener
);
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
);
89 Index
* FindIndex(const StringKey
& name
) const
90 { return fIndices
.Lookup(name
); }
91 IndexDirIterator
GetIndexDirIterator() const
92 { return fIndices
.GetIterator(); }
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
);
101 // PackageLinksListener
102 virtual void PackageLinkNodeAdded(Node
* node
);
103 virtual void PackageLinkNodeRemoved(Node
* node
);
104 virtual void PackageLinkNodeChanged(Node
* node
,
106 const OldNodeAttributes
& oldAttributes
);
109 struct ShineThroughDirectory
;
110 struct ActivationChangeRequest
;
113 status_t
_LoadOldPackagesStates(
114 const char* packagesState
);
116 status_t
_AddInitialPackages();
117 status_t
_AddInitialPackagesFromActivationFile(
118 PackagesDirectory
* packagesDirectory
);
119 status_t
_AddInitialPackagesFromDirectory();
120 status_t
_LoadAndAddInitialPackage(
121 PackagesDirectory
* packagesDirectory
,
124 inline void _AddPackage(Package
* package
);
125 inline void _RemovePackage(Package
* package
);
126 void _RemoveAllPackages();
127 inline Package
* _FindPackage(const char* fileName
) const;
129 status_t
_AddPackageContent(Package
* package
,
131 void _RemovePackageContent(Package
* package
,
132 PackageNode
* endNode
, bool notify
);
134 status_t
_AddPackageContentRootNode(Package
* package
,
135 PackageNode
* node
, bool notify
);
136 void _RemovePackageContentRootNode(Package
* package
,
137 PackageNode
* packageNode
,
138 PackageNode
* endPackageNode
, bool notify
);
140 status_t
_AddPackageNode(Directory
* directory
,
141 PackageNode
* packageNode
, bool notify
,
143 void _RemovePackageNode(Directory
* directory
,
144 PackageNode
* packageNode
, Node
* node
,
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
155 status_t
_LoadPackage(
156 PackagesDirectory
* packagesDirectory
,
157 const char* name
, Package
*& _package
);
159 status_t
_ChangeActivation(
160 ActivationChangeRequest
& request
);
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();
169 status_t
_AddPackageLinksDirectory();
170 void _RemovePackageLinksDirectory();
171 void _AddPackageLinksNode(Node
* node
);
172 void _RemovePackageLinksNode(Node
* node
);
174 inline Volume
* _SystemVolumeIfNotSelf() const;
176 void _NotifyNodeAdded(Node
* node
);
177 void _NotifyNodeRemoved(Node
* node
);
178 void _NotifyNodeChanged(Node
* node
,
180 const OldNodeAttributes
& oldAttributes
);
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
;
198 NodeIDHashTable fNodes
;
199 NodeListenerHashTable fNodeListeners
;
200 PackageFileNameHashTable fPackages
;
202 IndexHashTable fIndices
;
209 Volume::ReadLock() const
211 return rw_lock_read_lock(&fLock
) == B_OK
;
216 Volume::ReadUnlock() const
218 rw_lock_read_unlock(&fLock
);
225 return rw_lock_write_lock(&fLock
) == B_OK
;
230 Volume::WriteUnlock()
232 rw_lock_write_unlock(&fLock
);
236 typedef AutoLocker
<const Volume
, AutoLockerReadLocking
<const Volume
> >
238 typedef AutoLocker
<Volume
, AutoLockerWriteLocking
<Volume
> > VolumeWriteLocker
;