* KDiskDeviceManager::_ScanPartition() can now run synchronously (and execute the
scan job in the calling thread). * KDiskDeviceManager::InitialDeviceScan() now runs synchronously, so that get_boot_partitions() doesn't need to do this ugly wait hack. * KDiskDeviceManager::CreateFileDevice() can now run synchronously as well, which fixes a deadlock in fs_mount() - note, mounting file devices still doesn't work, though as Haiku's BFS doesn't allow this right now. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@17334 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
parent
b02b72c448
commit
65bd831cbb
@ -1,11 +1,17 @@
|
||||
// KDiskDeviceManager.h
|
||||
|
||||
/*
|
||||
* Copyright 2004-2006, Haiku, Inc. All rights reserved.
|
||||
* Copyright 2003-2004, Ingo Weinhold, bonefish@cs.tu-berlin.de. All rights reserved.
|
||||
*
|
||||
* Distributed under the terms of the MIT License.
|
||||
*/
|
||||
#ifndef _K_DISK_DEVICE_MANAGER_H
|
||||
#define _K_DISK_DEVICE_MANAGER_H
|
||||
|
||||
|
||||
#include "disk_device_manager.h"
|
||||
#include "Locker.h"
|
||||
|
||||
|
||||
namespace BPrivate {
|
||||
namespace DiskDevice {
|
||||
|
||||
@ -61,7 +67,7 @@ public:
|
||||
// unregistered by the caller.
|
||||
|
||||
partition_id CreateFileDevice(const char *filePath,
|
||||
bool *newlyCreated = NULL);
|
||||
bool *newlyCreated = NULL, bool async = true);
|
||||
status_t DeleteFileDevice(const char *filePath);
|
||||
status_t DeleteFileDevice(partition_id id);
|
||||
|
||||
@ -130,7 +136,7 @@ private:
|
||||
bool updateBusyPartitions);
|
||||
|
||||
status_t _Scan(const char *path);
|
||||
status_t _ScanPartition(KPartition *partition);
|
||||
status_t _ScanPartition(KPartition *partition, bool async);
|
||||
// the manager must be locked and the device write locked
|
||||
|
||||
struct DeviceMap;
|
||||
|
@ -1,23 +1,11 @@
|
||||
/*
|
||||
** Copyright 2003-2004, Ingo Weinhold, bonefish@cs.tu-berlin.de. All rights reserved.
|
||||
** Distributed under the terms of the Haiku License.
|
||||
*/
|
||||
/*
|
||||
* Copyright 2004-2006, Haiku, Inc. All rights reserved.
|
||||
* Copyright 2003-2004, Ingo Weinhold, bonefish@cs.tu-berlin.de. All rights reserved.
|
||||
*
|
||||
* Distributed under the terms of the MIT License.
|
||||
*/
|
||||
|
||||
|
||||
#include <KernelExport.h>
|
||||
#include <util/kernel_cpp.h>
|
||||
|
||||
#include <dirent.h>
|
||||
#include <errno.h>
|
||||
#include <module.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <sys/stat.h>
|
||||
|
||||
#include <VectorMap.h>
|
||||
#include <VectorSet.h>
|
||||
|
||||
#include "KDiskDevice.h"
|
||||
#include "KDiskDeviceJob.h"
|
||||
#include "KDiskDeviceJobFactory.h"
|
||||
@ -33,6 +21,20 @@
|
||||
#include "KPath.h"
|
||||
#include "KShadowPartition.h"
|
||||
|
||||
#include <VectorMap.h>
|
||||
#include <VectorSet.h>
|
||||
|
||||
#include <KernelExport.h>
|
||||
#include <util/kernel_cpp.h>
|
||||
|
||||
#include <dirent.h>
|
||||
#include <errno.h>
|
||||
#include <module.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <sys/stat.h>
|
||||
|
||||
// debugging
|
||||
//#define DBG(x)
|
||||
#define DBG(x) x
|
||||
@ -515,7 +517,7 @@ KDiskDeviceManager::WriteLockPartition(partition_id id)
|
||||
|
||||
// CreateFileDevice
|
||||
partition_id
|
||||
KDiskDeviceManager::CreateFileDevice(const char *filePath, bool *newlyCreated)
|
||||
KDiskDeviceManager::CreateFileDevice(const char *filePath, bool *newlyCreated, bool async)
|
||||
{
|
||||
if (!filePath)
|
||||
return B_BAD_VALUE;
|
||||
@ -543,6 +545,7 @@ KDiskDeviceManager::CreateFileDevice(const char *filePath, bool *newlyCreated)
|
||||
|
||||
// initialize and add the device
|
||||
error = device->SetTo(filePath);
|
||||
|
||||
// Note: Here we are allowed to lock a device although already having
|
||||
// the manager locked, since it is not yet added to the manager.
|
||||
DeviceWriteLocker deviceLocker(device);
|
||||
@ -553,7 +556,7 @@ KDiskDeviceManager::CreateFileDevice(const char *filePath, bool *newlyCreated)
|
||||
|
||||
// scan device
|
||||
if (error == B_OK) {
|
||||
_ScanPartition(device);
|
||||
_ScanPartition(device, async);
|
||||
|
||||
if (newlyCreated)
|
||||
*newlyCreated = true;
|
||||
@ -901,19 +904,21 @@ status_t
|
||||
KDiskDeviceManager::InitialDeviceScan()
|
||||
{
|
||||
status_t error = B_ERROR;
|
||||
|
||||
// scan for devices
|
||||
if (ManagerLocker locker = this) {
|
||||
error = _Scan("/dev/disk");
|
||||
if (error != B_OK)
|
||||
return error;
|
||||
}
|
||||
|
||||
// scan the devices for partitions
|
||||
int32 cookie = 0;
|
||||
while (KDiskDevice *device = RegisterNextDevice(&cookie)) {
|
||||
PartitionRegistrar _(device, true);
|
||||
if (DeviceWriteLocker deviceLocker = device) {
|
||||
if (ManagerLocker locker = this) {
|
||||
error = _ScanPartition(device);
|
||||
error = _ScanPartition(device, false);
|
||||
if (error != B_OK)
|
||||
break;
|
||||
} else
|
||||
@ -1152,30 +1157,43 @@ DBG(OUT(" found device: %s\n", path));
|
||||
The device must be write locked, the manager must be locked.
|
||||
*/
|
||||
status_t
|
||||
KDiskDeviceManager::_ScanPartition(KPartition *partition)
|
||||
KDiskDeviceManager::_ScanPartition(KPartition *partition, bool async)
|
||||
{
|
||||
if (!partition)
|
||||
return B_BAD_VALUE;
|
||||
// create a new job queue for the device
|
||||
KDiskDeviceJobQueue *jobQueue = new(nothrow) KDiskDeviceJobQueue;
|
||||
if (!jobQueue)
|
||||
return B_NO_MEMORY;
|
||||
jobQueue->SetDevice(partition->Device());
|
||||
// create a job for scanning the device and add it to the job queue
|
||||
|
||||
if (async) {
|
||||
// create a new job queue for the device
|
||||
KDiskDeviceJobQueue *jobQueue = new(nothrow) KDiskDeviceJobQueue;
|
||||
if (!jobQueue)
|
||||
return B_NO_MEMORY;
|
||||
jobQueue->SetDevice(partition->Device());
|
||||
// create a job for scanning the device and add it to the job queue
|
||||
KDiskDeviceJob *job = fJobFactory->CreateScanPartitionJob(partition->ID());
|
||||
if (!job) {
|
||||
delete jobQueue;
|
||||
return B_NO_MEMORY;
|
||||
}
|
||||
if (!jobQueue->AddJob(job)) {
|
||||
delete jobQueue;
|
||||
delete job;
|
||||
return B_NO_MEMORY;
|
||||
}
|
||||
// add the job queue
|
||||
status_t error = AddJobQueue(jobQueue);
|
||||
if (error != B_OK)
|
||||
delete jobQueue;
|
||||
return error;
|
||||
}
|
||||
|
||||
KDiskDeviceJob *job = fJobFactory->CreateScanPartitionJob(partition->ID());
|
||||
if (!job) {
|
||||
delete jobQueue;
|
||||
if (job == NULL)
|
||||
return B_NO_MEMORY;
|
||||
}
|
||||
if (!jobQueue->AddJob(job)) {
|
||||
delete jobQueue;
|
||||
delete job;
|
||||
return B_NO_MEMORY;
|
||||
}
|
||||
// add the job queue
|
||||
status_t error = AddJobQueue(jobQueue);
|
||||
if (error != B_OK)
|
||||
delete jobQueue;
|
||||
return error;
|
||||
|
||||
status_t status = job->Do();
|
||||
UpdateBusyPartitions(partition->Device());
|
||||
|
||||
delete job;
|
||||
return status;
|
||||
}
|
||||
|
||||
|
@ -5152,13 +5152,12 @@ fs_mount(char *path, const char *device, const char *fsName, uint32 flags,
|
||||
// Partition not found: This either means, the user supplied
|
||||
// an invalid path, or the path refers to an image file. We try
|
||||
// to let the DDM create a file device for the path.
|
||||
partition_id deviceID = ddm->CreateFileDevice(
|
||||
normalizedDevice.Path(), &newlyCreatedFileDevice);
|
||||
partition_id deviceID = ddm->CreateFileDevice(normalizedDevice.Path(),
|
||||
&newlyCreatedFileDevice, false);
|
||||
if (deviceID >= 0) {
|
||||
partition = ddm->RegisterPartition(deviceID, true);
|
||||
if (newlyCreatedFileDevice)
|
||||
fileDeviceDeleter.id = deviceID;
|
||||
// TODO: We must wait here, until the partition scan job is done.
|
||||
}
|
||||
}
|
||||
|
||||
@ -5182,7 +5181,9 @@ fs_mount(char *path, const char *device, const char *fsName, uint32 flags,
|
||||
return B_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
DeviceWriteLocker writeLocker(diskDevice, true);
|
||||
// this takes over the write lock acquired before
|
||||
|
||||
if (partition) {
|
||||
// make sure, that the partition is not busy
|
||||
|
@ -206,14 +206,7 @@ get_boot_partitions(kernel_args *args, PartitionStack &partitions)
|
||||
KDiskDeviceManager *manager = KDiskDeviceManager::Default();
|
||||
|
||||
status_t status = manager->InitialDeviceScan();
|
||||
if (status == B_OK) {
|
||||
// ToDo: do this for real... (no hacks allowed :))
|
||||
for (;;) {
|
||||
snooze(500000);
|
||||
if (manager->CountJobs() == 0)
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
if (status != B_OK) {
|
||||
dprintf("KDiskDeviceManager::InitialDeviceScan() failed: %s\n", strerror(status));
|
||||
return status;
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user