* Added optional partition_module_info::uninitialize() hook. It is supposed to

destroy the partitioning system's on-disk structure.
* Adjusted the existing partitioning system implementations accordingly.
  Actually implemented the hook for the intel partitioning system.
* Added Uninitialize() method to KDiskSystem and KPartitioningSystem. The latter
  implements the method calling the new module hook.
* _user_uninitialize_partition(): Also let the disk system uninitialize the
  on-disk structure.

This fixes the failure to initialize a disk device with BFS, when it contains a
valid partition map with at least one partition.


git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@42140 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Ingo Weinhold
2011-06-13 01:27:13 +00:00
parent f84387d6c4
commit 285f4cf441
11 changed files with 111 additions and 54 deletions
@@ -1,5 +1,5 @@
/* /*
* Copyright 2003-2008, Haiku, Inc. All Rights Reserved. * Copyright 2003-2011, Haiku, Inc. All Rights Reserved.
* Distributed under the terms of the MIT License. * Distributed under the terms of the MIT License.
* *
* Authors: * Authors:
@@ -88,6 +88,8 @@ public:
virtual status_t Initialize(KPartition* partition, virtual status_t Initialize(KPartition* partition,
const char* name, const char* parameters, const char* name, const char* parameters,
disk_job_id job); disk_job_id job);
virtual status_t Uninitialize(KPartition* partition,
disk_job_id job);
virtual status_t CreateChild(KPartition* partition, off_t offset, virtual status_t CreateChild(KPartition* partition, off_t offset,
off_t size, const char* type, off_t size, const char* type,
const char* name, const char* parameters, const char* name, const char* parameters,
@@ -1,5 +1,5 @@
/* /*
* Copyright 2003-2007, Haiku, Inc. All Rights Reserved. * Copyright 2003-2011, Haiku, Inc. All Rights Reserved.
* Distributed under the terms of the MIT License. * Distributed under the terms of the MIT License.
* *
* Authors: * Authors:
@@ -64,6 +64,8 @@ public:
virtual status_t Initialize(KPartition* partition, virtual status_t Initialize(KPartition* partition,
const char* name, const char* parameters, const char* name, const char* parameters,
disk_job_id job); disk_job_id job);
virtual status_t Uninitialize(KPartition* partition,
disk_job_id job);
virtual status_t CreateChild(KPartition* partition, off_t offset, virtual status_t CreateChild(KPartition* partition, off_t offset,
off_t size, const char* type, off_t size, const char* type,
const char* name, const char* parameters, const char* name, const char* parameters,
@@ -1,5 +1,5 @@
/* /*
* Copyright 2003-2008, Haiku Inc. * Copyright 2003-2011, Haiku, Inc.
* Distributed under the terms of the MIT License. * Distributed under the terms of the MIT License.
*/ */
#ifndef _K_DISK_DEVICE_MODULES_H #ifndef _K_DISK_DEVICE_MODULES_H
@@ -99,9 +99,11 @@ typedef struct partition_module_info {
const char* parameters, disk_job_id job); const char* parameters, disk_job_id job);
status_t (*initialize)(int fd, partition_id partition, const char* name, status_t (*initialize)(int fd, partition_id partition, const char* name,
const char *parameters, off_t partitionSize, disk_job_id job); const char *parameters, off_t partitionSize, disk_job_id job);
status_t (*uninitialize)(int fd, partition_id partition,
off_t partitionSize, disk_job_id job);
status_t (*create_child)(int fd, partition_id partition, off_t offset, status_t (*create_child)(int fd, partition_id partition, off_t offset,
off_t size, const char* type, const char* name, off_t size, const char* type, const char* name,
const char* parameters, disk_job_id job, const char* parameters, disk_job_id job,
partition_id* childID); partition_id* childID);
// childID is used for the return value, but is also an optional input // childID is used for the return value, but is also an optional input
// parameter -- -1 to be ignored // parameter -- -1 to be ignored
@@ -1283,6 +1283,7 @@ partition_module_info gEFIPartitionModule = {
NULL, // set_parameters NULL, // set_parameters
NULL, // set_content_parameters NULL, // set_content_parameters
efi_gpt_initialize, efi_gpt_initialize,
NULL, // uninitialize
efi_gpt_create_child, efi_gpt_create_child,
efi_gpt_delete_child efi_gpt_delete_child
#else #else
@@ -509,6 +509,7 @@ static partition_module_info intel_partition_map_module =
NULL, // set_parameters NULL, // set_parameters
NULL, // set_content_parameters NULL, // set_content_parameters
pm_initialize, // initialize pm_initialize, // initialize
pm_uninitialize, // uninitialize
pm_create_child, // create_child pm_create_child, // create_child
pm_delete_child, // delete_child pm_delete_child, // delete_child
#else #else
@@ -596,6 +597,7 @@ static partition_module_info intel_extended_partition_module =
NULL, // set_parameters NULL, // set_parameters
NULL, // set_content_parameters NULL, // set_content_parameters
ep_initialize, // initialize ep_initialize, // initialize
NULL, // uninitialize
ep_create_child, // create_child ep_create_child, // create_child
ep_delete_child, // delete_child ep_delete_child, // delete_child
#else // _BOOT_MODE #else // _BOOT_MODE
@@ -1,9 +1,9 @@
/* /*
* Copyright 2003-2009, Haiku, Inc. All Rights Reserved. * Copyright 2003-2011, Haiku, Inc. All Rights Reserved.
* Distributed under the terms of the MIT License. * Distributed under the terms of the MIT License.
* *
* Authors: * Authors:
* Ingo Weinhold, [email protected].de * Ingo Weinhold, ingo_weinhold@gmx.de
* Tomas Kucera, [email protected] * Tomas Kucera, [email protected]
*/ */
@@ -1285,6 +1285,45 @@ pm_initialize(int fd, partition_id partitionID, const char* name,
} }
status_t
pm_uninitialize(int fd, partition_id partitionID, off_t partitionSize,
disk_job_id job)
{
// get partition's block size
size_t blockSize;
{
PartitionReadLocker locker(partitionID);
if (!locker.IsLocked())
return B_ERROR;
partition_data* partition = get_partition(partitionID);
if (partition == NULL)
return B_BAD_VALUE;
update_disk_device_job_progress(job, 0.0);
blockSize = partition->block_size;
if (blockSize == 0)
return B_BAD_VALUE;
}
// We overwrite the first block, which contains the partition table.
// Allocate a buffer, we can clear and write.
void* block = malloc(blockSize);
if (block == NULL)
return B_NO_MEMORY;
MemoryDeleter blockDeleter(block);
memset(block, 0, blockSize);
if (write_pos(fd, 0, block, blockSize) < 0)
return errno;
update_disk_device_job_progress(job, 1.0);
return B_OK;
}
// pm_create_child // pm_create_child
/*! childID is used for the return value, but is also an optional input /*! childID is used for the return value, but is also an optional input
parameter -- -1 to be ignored parameter -- -1 to be ignored
@@ -48,6 +48,8 @@ status_t pm_set_type(int fd, partition_id partitionID, const char* type,
disk_job_id job); disk_job_id job);
status_t pm_initialize(int fd, partition_id partitionID, const char* name, status_t pm_initialize(int fd, partition_id partitionID, const char* name,
const char* parameters, off_t partitionSize, disk_job_id job); const char* parameters, off_t partitionSize, disk_job_id job);
status_t pm_uninitialize(int fd, partition_id partitionID,
off_t partitionSize, disk_job_id job);
status_t pm_create_child(int fd, partition_id partitionID, off_t offset, status_t pm_create_child(int fd, partition_id partitionID, off_t offset,
off_t size, const char* type, const char* name, off_t size, const char* type, const char* name,
const char* parameters, disk_job_id job, const char* parameters, disk_job_id job,
@@ -1,5 +1,5 @@
/* /*
* Copyright 2009, Ingo Weinhold, [email protected]. * Copyright 2009-2011, Ingo Weinhold, [email protected].
* Distributed under the terms of the MIT License. * Distributed under the terms of the MIT License.
*/ */
@@ -461,47 +461,7 @@ static partition_module_info vmdk_partition_module =
vmdk_free_partition_cookie, // free_partition_cookie vmdk_free_partition_cookie, // free_partition_cookie
vmdk_free_partition_content_cookie, // free_partition_content_cookie vmdk_free_partition_content_cookie, // free_partition_content_cookie
#ifndef _BOOT_MODE #ifdef _BOOT_MODE
// querying (obsolete)
NULL, // get_supported_operations
NULL, // get_supported_child_operations
NULL, // supports_initializing_child
NULL, // is_sub_system_for
// validation hooks (obsolete)
NULL, // validate_resize
NULL, // validate_resize_child
NULL, // validate_move
NULL, // validate_move_child
NULL, // validate_set_name
NULL, // validate_set_content_name
NULL, // validate_set_type
NULL, // validate_set_parameters
NULL, // validate_set_content_parameters
NULL, // validate_initialize
NULL, // validate_create_child
NULL, // get_partitionable_spaces
NULL, // get_next_supported_type
NULL, // get_type_for_content_type
// shadow partition modification (obsolete)
NULL, // shadow_changed
// writing
NULL, // repair
NULL, // resize
NULL, // resize_child
NULL, // move
NULL, // move_child
NULL, // set_name
NULL, // set_content_name
NULL, // set_type
NULL, // set_parameters
NULL, // set_content_parameters
NULL, // initialize
NULL, // create_child
NULL, // delete_child
#else
NULL NULL
#endif // _BOOT_MODE #endif // _BOOT_MODE
}; };
@@ -1,4 +1,8 @@
// KDiskSystem.cpp /*
* Copyright 2003-2011, Ingo Weinhold, [email protected].
* Distributed under the terms of the MIT License.
*/
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
@@ -318,6 +322,14 @@ KDiskSystem::Initialize(KPartition* partition, const char* name,
} }
status_t
KDiskSystem::Uninitialize(KPartition* partition, disk_job_id job)
{
// to be implemented by derived classes
return B_NOT_SUPPORTED;
}
// CreateChild // CreateChild
status_t status_t
KDiskSystem::CreateChild(KPartition* partition, off_t offset, off_t size, KDiskSystem::CreateChild(KPartition* partition, off_t offset, off_t size,
@@ -1,5 +1,5 @@
/* /*
* Copyright 2003-2007, Haiku, Inc. All Rights Reserved. * Copyright 2003-2011, Haiku, Inc. All Rights Reserved.
* Distributed under the terms of the MIT License. * Distributed under the terms of the MIT License.
* *
* Authors: * Authors:
@@ -413,6 +413,30 @@ KPartitioningSystem::Initialize(KPartition* partition, const char* name,
} }
status_t
KPartitioningSystem::Uninitialize(KPartition* partition, disk_job_id job)
{
// check parameters
if (partition == NULL || fModule == NULL)
return B_BAD_VALUE;
if (fModule->uninitialize == NULL)
return B_NOT_SUPPORTED;
// open partition device
int fd = -1;
status_t result = partition->Open(O_RDWR, &fd);
if (result != B_OK)
return result;
// let the module do its job
result = fModule->uninitialize(fd, partition->ID(), partition->Size(), job);
// cleanup and return
close(fd);
return result;
}
// CreateChild // CreateChild
//! Creates a child partition //! Creates a child partition
status_t status_t
@@ -1,9 +1,9 @@
/* /*
* Copyright 2003-2009, Haiku, Inc. All Rights Reserved. * Copyright 2003-2011, Haiku, Inc. All Rights Reserved.
* Distributed under the terms of the MIT License. * Distributed under the terms of the MIT License.
* *
* Authors: * Authors:
* Ingo Weinhold, [email protected].de * Ingo Weinhold, ingo_weinhold@gmx.de
* Axel Dörfler, [email protected] * Axel Dörfler, [email protected]
*/ */
@@ -1251,7 +1251,18 @@ _user_uninitialize_partition(partition_id partitionID, int32* _changeCounter)
// TODO: We should also check, if any partition is mounted! // TODO: We should also check, if any partition is mounted!
// uninitialize KDiskSystem* diskSystem = partition->DiskSystem();
locker.Unlock();
// Let the disk system uninitialize the partition. This operation is not
// mandatory. If implemented, it will destroy the on-disk structures, so
// that the disk system cannot accidentally identify the partition later on.
if (diskSystem != NULL)
diskSystem->Uninitialize(partition, DUMMY_JOB_ID);
// re-lock and uninitialize the partition object
locker.Lock();
error = partition->UninitializeContents(true); error = partition->UninitializeContents(true);
partition->UnmarkBusy(true); partition->UnmarkBusy(true);