From 285f4cf441dbc269553bee753d151cbf0074f232 Mon Sep 17 00:00:00 2001 From: Ingo Weinhold Date: Mon, 13 Jun 2011 01:27:13 +0000 Subject: [PATCH] * 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 --- .../kernel/disk_device_manager/KDiskSystem.h | 4 +- .../disk_device_manager/KPartitioningSystem.h | 4 +- .../kernel/disk_device_manager/ddm_modules.h | 8 ++-- .../partitioning_systems/efi/efi_gpt.cpp | 1 + .../partitioning_systems/intel/intel.cpp | 2 + .../intel/write_support.cpp | 43 +++++++++++++++++- .../intel/write_support.h | 2 + .../kernel/partitioning_systems/vmdk/vmdk.cpp | 44 +------------------ .../disk_device_manager/KDiskSystem.cpp | 14 +++++- .../KPartitioningSystem.cpp | 26 ++++++++++- .../ddm_userland_interface.cpp | 17 +++++-- 11 files changed, 111 insertions(+), 54 deletions(-) diff --git a/headers/private/kernel/disk_device_manager/KDiskSystem.h b/headers/private/kernel/disk_device_manager/KDiskSystem.h index 3e55a58cd9..1f1da9b749 100644 --- a/headers/private/kernel/disk_device_manager/KDiskSystem.h +++ b/headers/private/kernel/disk_device_manager/KDiskSystem.h @@ -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. * * Authors: @@ -88,6 +88,8 @@ public: virtual status_t Initialize(KPartition* partition, const char* name, const char* parameters, disk_job_id job); + virtual status_t Uninitialize(KPartition* partition, + disk_job_id job); virtual status_t CreateChild(KPartition* partition, off_t offset, off_t size, const char* type, const char* name, const char* parameters, diff --git a/headers/private/kernel/disk_device_manager/KPartitioningSystem.h b/headers/private/kernel/disk_device_manager/KPartitioningSystem.h index bbe4577033..f645e65e49 100644 --- a/headers/private/kernel/disk_device_manager/KPartitioningSystem.h +++ b/headers/private/kernel/disk_device_manager/KPartitioningSystem.h @@ -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. * * Authors: @@ -64,6 +64,8 @@ public: virtual status_t Initialize(KPartition* partition, const char* name, const char* parameters, disk_job_id job); + virtual status_t Uninitialize(KPartition* partition, + disk_job_id job); virtual status_t CreateChild(KPartition* partition, off_t offset, off_t size, const char* type, const char* name, const char* parameters, diff --git a/headers/private/kernel/disk_device_manager/ddm_modules.h b/headers/private/kernel/disk_device_manager/ddm_modules.h index eff0377bd2..6b84ca3f6b 100644 --- a/headers/private/kernel/disk_device_manager/ddm_modules.h +++ b/headers/private/kernel/disk_device_manager/ddm_modules.h @@ -1,5 +1,5 @@ /* - * Copyright 2003-2008, Haiku Inc. + * Copyright 2003-2011, Haiku, Inc. * Distributed under the terms of the MIT License. */ #ifndef _K_DISK_DEVICE_MODULES_H @@ -99,9 +99,11 @@ typedef struct partition_module_info { const char* parameters, disk_job_id job); status_t (*initialize)(int fd, partition_id partition, const char* name, 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, - off_t size, const char* type, const char* name, - const char* parameters, disk_job_id job, + off_t size, const char* type, const char* name, + const char* parameters, disk_job_id job, partition_id* childID); // childID is used for the return value, but is also an optional input // parameter -- -1 to be ignored diff --git a/src/add-ons/kernel/partitioning_systems/efi/efi_gpt.cpp b/src/add-ons/kernel/partitioning_systems/efi/efi_gpt.cpp index 4231c76c38..a80bcd7e62 100644 --- a/src/add-ons/kernel/partitioning_systems/efi/efi_gpt.cpp +++ b/src/add-ons/kernel/partitioning_systems/efi/efi_gpt.cpp @@ -1283,6 +1283,7 @@ partition_module_info gEFIPartitionModule = { NULL, // set_parameters NULL, // set_content_parameters efi_gpt_initialize, + NULL, // uninitialize efi_gpt_create_child, efi_gpt_delete_child #else diff --git a/src/add-ons/kernel/partitioning_systems/intel/intel.cpp b/src/add-ons/kernel/partitioning_systems/intel/intel.cpp index b117be93a6..a1387d6d9c 100644 --- a/src/add-ons/kernel/partitioning_systems/intel/intel.cpp +++ b/src/add-ons/kernel/partitioning_systems/intel/intel.cpp @@ -509,6 +509,7 @@ static partition_module_info intel_partition_map_module = NULL, // set_parameters NULL, // set_content_parameters pm_initialize, // initialize + pm_uninitialize, // uninitialize pm_create_child, // create_child pm_delete_child, // delete_child #else @@ -596,6 +597,7 @@ static partition_module_info intel_extended_partition_module = NULL, // set_parameters NULL, // set_content_parameters ep_initialize, // initialize + NULL, // uninitialize ep_create_child, // create_child ep_delete_child, // delete_child #else // _BOOT_MODE diff --git a/src/add-ons/kernel/partitioning_systems/intel/write_support.cpp b/src/add-ons/kernel/partitioning_systems/intel/write_support.cpp index cfbab7bce7..d369071c7d 100644 --- a/src/add-ons/kernel/partitioning_systems/intel/write_support.cpp +++ b/src/add-ons/kernel/partitioning_systems/intel/write_support.cpp @@ -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. * * Authors: - * Ingo Weinhold, bonefish@cs.tu-berlin.de + * Ingo Weinhold, ingo_weinhold@gmx.de * Tomas Kucera, kucerat@centrum.cz */ @@ -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 /*! childID is used for the return value, but is also an optional input parameter -- -1 to be ignored diff --git a/src/add-ons/kernel/partitioning_systems/intel/write_support.h b/src/add-ons/kernel/partitioning_systems/intel/write_support.h index dbf48c2818..14a5fa8995 100644 --- a/src/add-ons/kernel/partitioning_systems/intel/write_support.h +++ b/src/add-ons/kernel/partitioning_systems/intel/write_support.h @@ -48,6 +48,8 @@ status_t pm_set_type(int fd, partition_id partitionID, const char* type, disk_job_id job); status_t pm_initialize(int fd, partition_id partitionID, const char* name, 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, off_t size, const char* type, const char* name, const char* parameters, disk_job_id job, diff --git a/src/add-ons/kernel/partitioning_systems/vmdk/vmdk.cpp b/src/add-ons/kernel/partitioning_systems/vmdk/vmdk.cpp index a7c0d5fbd7..7e6962a338 100644 --- a/src/add-ons/kernel/partitioning_systems/vmdk/vmdk.cpp +++ b/src/add-ons/kernel/partitioning_systems/vmdk/vmdk.cpp @@ -1,5 +1,5 @@ /* - * Copyright 2009, Ingo Weinhold, ingo_weinhold@gmx.de. + * Copyright 2009-2011, Ingo Weinhold, ingo_weinhold@gmx.de. * 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_content_cookie, // free_partition_content_cookie -#ifndef _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 +#ifdef _BOOT_MODE NULL #endif // _BOOT_MODE }; diff --git a/src/system/kernel/disk_device_manager/KDiskSystem.cpp b/src/system/kernel/disk_device_manager/KDiskSystem.cpp index cee6c7e958..d451e21be1 100644 --- a/src/system/kernel/disk_device_manager/KDiskSystem.cpp +++ b/src/system/kernel/disk_device_manager/KDiskSystem.cpp @@ -1,4 +1,8 @@ -// KDiskSystem.cpp +/* + * Copyright 2003-2011, Ingo Weinhold, ingo_weinhold@gmx.de. + * Distributed under the terms of the MIT License. + */ + #include #include @@ -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 status_t KDiskSystem::CreateChild(KPartition* partition, off_t offset, off_t size, diff --git a/src/system/kernel/disk_device_manager/KPartitioningSystem.cpp b/src/system/kernel/disk_device_manager/KPartitioningSystem.cpp index 20ac4a797d..db27e6b8c8 100644 --- a/src/system/kernel/disk_device_manager/KPartitioningSystem.cpp +++ b/src/system/kernel/disk_device_manager/KPartitioningSystem.cpp @@ -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. * * 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 //! Creates a child partition status_t diff --git a/src/system/kernel/disk_device_manager/ddm_userland_interface.cpp b/src/system/kernel/disk_device_manager/ddm_userland_interface.cpp index 36cdefb1ec..cadb0bd0b4 100644 --- a/src/system/kernel/disk_device_manager/ddm_userland_interface.cpp +++ b/src/system/kernel/disk_device_manager/ddm_userland_interface.cpp @@ -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. * * Authors: - * Ingo Weinhold, bonefish@cs.tu-berlin.de + * Ingo Weinhold, ingo_weinhold@gmx.de * Axel Dörfler, axeld@pinc-software.de */ @@ -1251,7 +1251,18 @@ _user_uninitialize_partition(partition_id partitionID, int32* _changeCounter) // 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); partition->UnmarkBusy(true);