* KDiskDeviceManager::RescanDiskSystems() now also rescans all partitions with

the newly found disk systems.
* _ScanPartition() now allows to restrict the disk systems to a predefined set.
* _ScanPartition() now even scans partitions that already have a disk system
  assigned; if a better one is found, the existing one is replaced. It will
  ignore mounted or partitions with children, though.
* KPartition now also stores the priority of the disk system assigned to it.


git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@26177 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Axel Dörfler
2008-06-30 10:36:47 +00:00
parent 781420cc0e
commit 8531599a27
4 changed files with 91 additions and 42 deletions
@@ -98,10 +98,16 @@ public:
status_t StartMonitoring(); status_t StartMonitoring();
private: private:
struct DeviceMap;
struct DiskSystemMap;
struct PartitionMap;
struct PartitionSet;
class DeviceWatcher;
static status_t _CheckMediaStatusDaemon(void* self); static status_t _CheckMediaStatusDaemon(void* self);
status_t _CheckMediaStatus(); status_t _CheckMediaStatus();
status_t _RescanDiskSystems(bool fileSystems); status_t _RescanDiskSystems(DiskSystemMap& addedSystems, bool fileSystems);
status_t _AddPartitioningSystem(const char *name); status_t _AddPartitioningSystem(const char *name);
status_t _AddFileSystem(const char *name); status_t _AddFileSystem(const char *name);
@@ -111,19 +117,14 @@ private:
bool _RemoveDevice(KDiskDevice *device); bool _RemoveDevice(KDiskDevice *device);
status_t _Scan(const char *path); status_t _Scan(const char *path);
status_t _ScanPartition(KPartition *partition, bool async); status_t _ScanPartition(KPartition *partition, bool async,
DiskSystemMap* restrictScan = NULL);
// the manager must be locked and the device write locked // the manager must be locked and the device write locked
status_t _ScanPartition(KPartition *partition); status_t _ScanPartition(KPartition *partition,
// used by the other _ScanPartition() version only DiskSystemMap* restrictScan);
status_t _AddRemoveMonitoring(const char *path, bool add); status_t _AddRemoveMonitoring(const char *path, bool add);
struct DeviceMap;
struct DiskSystemMap;
struct PartitionMap;
struct PartitionSet;
class DeviceWatcher;
BLocker fLock; BLocker fLock;
DeviceMap *fDevices; DeviceMap *fDevices;
PartitionMap *fPartitions; PartitionMap *fPartitions;
@@ -148,8 +148,9 @@ public:
// DiskSystem // DiskSystem
void SetDiskSystem(KDiskSystem *diskSystem); void SetDiskSystem(KDiskSystem *diskSystem, float priority = 0.0f);
KDiskSystem *DiskSystem() const; KDiskSystem *DiskSystem() const;
float DiskSystemPriority() const;
KDiskSystem *ParentDiskSystem() const; KDiskSystem *ParentDiskSystem() const;
// When setting a disk system, it must already be loaded. // When setting a disk system, it must already be loaded.
// The partition will load it too, hence it won't be unloaded before // The partition will load it too, hence it won't be unloaded before
@@ -218,6 +219,7 @@ protected:
KDiskDevice *fDevice; KDiskDevice *fDevice;
KPartition *fParent; KPartition *fParent;
KDiskSystem *fDiskSystem; KDiskSystem *fDiskSystem;
float fDiskSystemPriority;
ListenerSet *fListeners; ListenerSet *fListeners;
uint32 fChangeFlags; uint32 fChangeFlags;
int32 fChangeCounter; int32 fChangeCounter;
@@ -1,5 +1,5 @@
/* /*
* Copyright 2004-2007, Haiku, Inc. All rights reserved. * Copyright 2004-2008, Haiku, Inc. All rights reserved.
* Copyright 2003-2004, Ingo Weinhold, [email protected]. All rights reserved. * Copyright 2003-2004, Ingo Weinhold, [email protected]. All rights reserved.
* *
* Distributed under the terms of the MIT License. * Distributed under the terms of the MIT License.
@@ -159,14 +159,6 @@ class KDiskDeviceManager::DeviceWatcher : public NotificationListener {
}; };
static bool
is_active_job_status(uint32 status)
{
return (status == B_DISK_DEVICE_JOB_SCHEDULED
|| status == B_DISK_DEVICE_JOB_IN_PROGRESS);
}
// #pragma mark - // #pragma mark -
@@ -919,9 +911,9 @@ KDiskDeviceManager::StartMonitoring()
} }
// _RescanDiskSystems
status_t status_t
KDiskDeviceManager::_RescanDiskSystems(bool fileSystems) KDiskDeviceManager::_RescanDiskSystems(DiskSystemMap& addedSystems,
bool fileSystems)
{ {
void *cookie = open_module_list(fileSystems void *cookie = open_module_list(fileSystems
? kFileSystemPrefix : kPartitioningSystemPrefix); ? kFileSystemPrefix : kPartitioningSystemPrefix);
@@ -949,19 +941,43 @@ KDiskDeviceManager::_RescanDiskSystems(bool fileSystems)
DBG(OUT("partitioning system: %s\n", name.Path())); DBG(OUT("partitioning system: %s\n", name.Path()));
_AddPartitioningSystem(name.Path()); _AddPartitioningSystem(name.Path());
} }
if (KDiskSystem* system = FindDiskSystem(name.Path()))
addedSystems.Put(system->ID(), system);
} }
close_module_list(cookie); close_module_list(cookie);
return B_OK; return B_OK;
} }
// RescanDiskSystems
/*! Rescan the existing disk systems. This is called after the boot device
has become available.
*/
status_t status_t
KDiskDeviceManager::RescanDiskSystems() KDiskDeviceManager::RescanDiskSystems()
{ {
DiskSystemMap addedSystems;
// rescan for partitioning and file systems // rescan for partitioning and file systems
_RescanDiskSystems(false); _RescanDiskSystems(addedSystems, false);
_RescanDiskSystems(true); _RescanDiskSystems(addedSystems, true);
// rescan existing devices with the new disk systems
int32 cookie = 0;
while (KDiskDevice *device = RegisterNextDevice(&cookie)) {
PartitionRegistrar _(device, true);
if (DeviceWriteLocker deviceLocker = device) {
if (ManagerLocker locker = this) {
status_t status = _ScanPartition(device, false, &addedSystems);
device->UnmarkBusy(true);
if (status != B_OK)
break;
} else
return B_ERROR;
} else
return B_ERROR;
}
return B_OK; return B_OK;
} }
@@ -1158,7 +1174,8 @@ DBG(OUT(" found device: %s\n", path));
The device must be write locked, the manager must be locked. The device must be write locked, the manager must be locked.
*/ */
status_t status_t
KDiskDeviceManager::_ScanPartition(KPartition *partition, bool async) KDiskDeviceManager::_ScanPartition(KPartition *partition, bool async,
DiskSystemMap* restrictScan)
{ {
// TODO: There's no reason why the manager needs to be locked anymore. // TODO: There's no reason why the manager needs to be locked anymore.
if (!partition) if (!partition)
@@ -1197,22 +1214,26 @@ KDiskDeviceManager::_ScanPartition(KPartition *partition, bool async)
// scan synchronously // scan synchronously
return _ScanPartition(partition); return _ScanPartition(partition, restrictScan);
} }
status_t status_t
KDiskDeviceManager::_ScanPartition(KPartition *partition) KDiskDeviceManager::_ScanPartition(KPartition* partition,
DiskSystemMap* restrictScan)
{ {
// the partition's device must be write-locked // the partition's device must be write-locked
if (!partition) if (partition == NULL)
return B_BAD_VALUE; return B_BAD_VALUE;
if (!partition->Device()->HasMedia()) if (!partition->Device()->HasMedia() || partition->IsMounted())
return B_OK; return B_OK;
if (partition->DiskSystem() != NULL) {
// TODO: this is more or less a hack to allow rescanning a partition if (partition->CountChildren() > 0) {
for (int32 i = 0; KPartition *child = partition->ChildAt(i); i++) // Since this partition has already children, we don't scan it
_ScanPartition(child); // again, but only its children.
for (int32 i = 0; KPartition* child = partition->ChildAt(i); i++) {
_ScanPartition(child, restrictScan);
}
return B_OK; return B_OK;
} }
@@ -1230,12 +1251,20 @@ KDiskDeviceManager::_ScanPartition(KPartition *partition)
return error; return error;
} }
DiskSystemMap* diskSystems = restrictScan;
if (diskSystems == NULL)
diskSystems = fDiskSystems;
// find the disk system that returns the best priority for this partition // find the disk system that returns the best priority for this partition
float bestPriority = -1; float bestPriority = partition->DiskSystemPriority();
KDiskSystem *bestDiskSystem = NULL; KDiskSystem *bestDiskSystem = NULL;
void *bestCookie = NULL; void *bestCookie = NULL;
int32 itCookie = 0; for (DiskSystemMap::Iterator iterator = diskSystems->Begin();
while (KDiskSystem *diskSystem = LoadNextDiskSystem(&itCookie)) { iterator != diskSystems->End(); iterator++) {
KDiskSystem* diskSystem = iterator->Value();
if (diskSystem->Load() != B_OK)
continue;
DBG(OUT(" trying: %s\n", diskSystem->Name())); DBG(OUT(" trying: %s\n", diskSystem->Name()));
void *cookie = NULL; void *cookie = NULL;
@@ -1267,9 +1296,9 @@ KDiskDeviceManager::_ScanPartition(KPartition *partition)
error = bestDiskSystem->Scan(partition, bestCookie); error = bestDiskSystem->Scan(partition, bestCookie);
bestDiskSystem->FreeIdentifyCookie(partition, bestCookie); bestDiskSystem->FreeIdentifyCookie(partition, bestCookie);
if (error == B_OK) { if (error == B_OK) {
partition->SetDiskSystem(bestDiskSystem); partition->SetDiskSystem(bestDiskSystem, bestPriority);
for (int32 i = 0; KPartition *child = partition->ChildAt(i); i++) for (int32 i = 0; KPartition *child = partition->ChildAt(i); i++)
_ScanPartition(child); _ScanPartition(child, restrictScan);
} else { } else {
// TODO: Handle the error. // TODO: Handle the error.
DBG(OUT(" scanning failed: %s\n", strerror(error))); DBG(OUT(" scanning failed: %s\n", strerror(error)));
@@ -1,4 +1,10 @@
// KPartition.cpp /*
* Copyright 2004-2008, Haiku, Inc. All rights reserved.
* Copyright 2003-2004, Ingo Weinhold, [email protected]. All rights reserved.
*
* Distributed under the terms of the MIT License.
*/
#include <errno.h> #include <errno.h>
#include <fcntl.h> #include <fcntl.h>
@@ -44,6 +50,7 @@ KPartition::KPartition(partition_id id)
fDevice(NULL), fDevice(NULL),
fParent(NULL), fParent(NULL),
fDiskSystem(NULL), fDiskSystem(NULL),
fDiskSystemPriority(-1),
fListeners(NULL), fListeners(NULL),
fChangeFlags(0), fChangeFlags(0),
fChangeCounter(0), fChangeCounter(0),
@@ -52,7 +59,7 @@ KPartition::KPartition(partition_id id)
fObsolete(false), fObsolete(false),
fPublished(false) fPublished(false)
{ {
fPartitionData.id = (id >= 0 ? id : _NextID()); fPartitionData.id = id >= 0 ? id : _NextID();
fPartitionData.offset = 0; fPartitionData.offset = 0;
fPartitionData.size = 0; fPartitionData.size = 0;
fPartitionData.content_size = 0; fPartitionData.content_size = 0;
@@ -895,13 +902,14 @@ KPartition::VisitEachDescendant(KPartitionVisitor *visitor)
// SetDiskSystem // SetDiskSystem
void void
KPartition::SetDiskSystem(KDiskSystem *diskSystem) KPartition::SetDiskSystem(KDiskSystem *diskSystem, float priority)
{ {
// unload former disk system // unload former disk system
if (fDiskSystem) { if (fDiskSystem) {
fPartitionData.content_type = NULL; fPartitionData.content_type = NULL;
fDiskSystem->Unload(); fDiskSystem->Unload();
fDiskSystem = NULL; fDiskSystem = NULL;
fDiskSystemPriority = -1;
} }
// set and load new one // set and load new one
fDiskSystem = diskSystem; fDiskSystem = diskSystem;
@@ -910,6 +918,7 @@ KPartition::SetDiskSystem(KDiskSystem *diskSystem)
// update concerned partition flags // update concerned partition flags
if (fDiskSystem) { if (fDiskSystem) {
fPartitionData.content_type = fDiskSystem->PrettyName(); fPartitionData.content_type = fDiskSystem->PrettyName();
fDiskSystemPriority = priority;
if (fDiskSystem->IsFileSystem()) if (fDiskSystem->IsFileSystem())
AddFlags(B_PARTITION_FILE_SYSTEM); AddFlags(B_PARTITION_FILE_SYSTEM);
else else
@@ -926,6 +935,14 @@ KPartition::DiskSystem() const
return fDiskSystem; return fDiskSystem;
} }
float
KPartition::DiskSystemPriority() const
{
return fDiskSystemPriority;
}
// ParentDiskSystem // ParentDiskSystem
KDiskSystem * KDiskSystem *
KPartition::ParentDiskSystem() const KPartition::ParentDiskSystem() const