DriveSetup: Implement ability to change partition type

* Implement functionality so that changing the partition type via the
   "Change parameters..." option will now work.
 * Implement changing partition type for Intel extended partitions. This
   included fixing the existing code so that changing partition type
   results in the updated EBR being written to the correct location.
 * Fix changing parameters of GPT partitions.

Fixes #19194

Change-Id: I4c8a2cbee25342acbab125b0b36b0106a872ea4b
Reviewed-on: https://review.haiku-os.org/c/haiku/+/11266
Tested-by: Commit checker robot <[email protected]>
Reviewed-by: waddlesplash <[email protected]>
This commit is contained in:
Nathan Patrizi
2026-07-18 18:48:54 +00:00
committed by waddlesplash
parent 59ea9704f6
commit a98cea3558
8 changed files with 59 additions and 12 deletions
@@ -101,7 +101,6 @@ GPTPartitionHandle::SupportedChildOperations(const BMutablePartition* child,
| B_DISK_SYSTEM_SUPPORTS_RESIZING_CHILD
| B_DISK_SYSTEM_SUPPORTS_MOVING_CHILD
| B_DISK_SYSTEM_SUPPORTS_SETTING_TYPE
| B_DISK_SYSTEM_SUPPORTS_SETTING_PARAMETERS
| B_DISK_SYSTEM_SUPPORTS_DELETING_CHILD;
}
@@ -220,7 +220,8 @@ uint32
ExtendedPartitionHandle::SupportedChildOperations(
const BMutablePartition* child, uint32 mask)
{
return B_DISK_SYSTEM_SUPPORTS_DELETING_CHILD;
return B_DISK_SYSTEM_SUPPORTS_DELETING_CHILD
| B_DISK_SYSTEM_SUPPORTS_SETTING_TYPE;
}
@@ -285,6 +286,21 @@ ExtendedPartitionHandle::GetPartitioningInfo(BPartitioningInfo* info)
}
status_t
ExtendedPartitionHandle::ValidateSetType(const BMutablePartition* child,
const char* type)
{
return B_OK;
}
status_t
ExtendedPartitionHandle::SetType(BMutablePartition* child, const char* type)
{
return child->SetType(type);
}
status_t
ExtendedPartitionHandle::GetParameterEditor(B_PARAMETER_EDITOR_TYPE type,
BPartitionParameterEditor** editor)
@@ -49,6 +49,11 @@ public:
virtual status_t GetPartitioningInfo(BPartitioningInfo* info);
virtual status_t ValidateSetType(const BMutablePartition* child,
const char* type);
virtual status_t SetType(BMutablePartition* child,
const char* type);
virtual status_t GetParameterEditor(
B_PARAMETER_EDITOR_TYPE type,
BPartitionParameterEditor** editor);
@@ -214,6 +214,7 @@ PartitionMapHandle::SupportedChildOperations(const BMutablePartition* child,
{
return B_DISK_SYSTEM_SUPPORTS_RESIZING_CHILD
| B_DISK_SYSTEM_SUPPORTS_MOVING_CHILD
| B_DISK_SYSTEM_SUPPORTS_SETTING_TYPE
| B_DISK_SYSTEM_SUPPORTS_SETTING_PARAMETERS
| B_DISK_SYSTEM_SUPPORTS_DELETING_CHILD;
}
@@ -272,6 +273,21 @@ PartitionMapHandle::GetPartitioningInfo(BPartitioningInfo* info)
}
status_t
PartitionMapHandle::ValidateSetType(const BMutablePartition* child,
const char* type)
{
return B_OK;
}
status_t
PartitionMapHandle::SetType(BMutablePartition* child, const char* type)
{
return child->SetType(type);
}
status_t
PartitionMapHandle::ValidateSetParameters(const BMutablePartition* child,
const char* parameters)
@@ -49,6 +49,11 @@ public:
virtual status_t GetPartitioningInfo(BPartitioningInfo* info);
virtual status_t ValidateSetType(const BMutablePartition* child,
const char* type);
virtual status_t SetType(BMutablePartition* child,
const char* type);
virtual status_t ValidateSetParameters(
const BMutablePartition* child,
const char* parameters);
@@ -1219,8 +1219,7 @@ pm_set_type(int fd, partition_id partitionID, const char* type, disk_job_id job)
ptype.SetType(type);
// this is impossible
if (!ptype.IsValid() || ptype.IsEmpty())
return false;
// TODO: Incompatible return value!
return B_BAD_VALUE;
// setting type to the partition
update_disk_device_job_progress(job, 0.0);
@@ -2086,7 +2085,8 @@ ep_set_type(int fd, partition_id partitionID, const char* type, disk_job_id job)
// get partition, child and LogicalPartition structure
partition_data* partition = get_parent_partition(partitionID);
partition_data* child = get_partition(partitionID);
if (!partition || !child)
disk_device_data* disk = get_disk_device(partitionID);
if (!partition || !child || !disk)
return B_BAD_VALUE;
LogicalPartition* logical = (LogicalPartition*)child->cookie;
PrimaryPartition* primary = (PrimaryPartition*)partition->cookie;
@@ -2105,16 +2105,22 @@ ep_set_type(int fd, partition_id partitionID, const char* type, disk_job_id job)
ptype.SetType(type);
// this is impossible
if (!ptype.IsValid() || ptype.IsEmpty() || ptype.IsExtended())
return false;
return B_BAD_VALUE;
// setting type to the partition
update_disk_device_job_progress(job, 0.0);
uint8 oldType = logical->Type();
logical->SetType(ptype.Type());
PartitionMapWriter writer(fd, partition->block_size);
int parentFD = open_partition(disk->id, O_RDWR);
if (parentFD < 0)
return B_IO_ERROR;
PartitionMapWriter writer(parentFD, partition->block_size);
// TODO: The partition is not supposed to be locked here!
status_t error = writer.WriteLogical(logical, primary, false);
close(parentFD);
if (error != B_OK) {
// something went wrong - putting into previous state
logical->SetType(oldType);
+4 -4
View File
@@ -1257,6 +1257,8 @@ MainWindow::_UpdateMenus(BDiskDevice* disk,
bool writable = !partition->IsReadOnly()
&& partition->Device()->HasMedia();
bool notMountedAndWritable = !partition->IsMounted() && writable;
bool canChangeParameters = partition->CanEditParameters()
|| partition->CanSetType() || partition->CanSetName();
fFormatMenu->SetEnabled(writable && fFormatMenu->CountItems() > 0);
@@ -1264,10 +1266,8 @@ MainWindow::_UpdateMenus(BDiskDevice* disk,
&& partition->IsDevice()
&& fDiskInitMenu->CountItems() > 0);
fChangeMenuItem->SetEnabled(writable
&& partition->CanEditParameters());
fChangeContextMenuItem->SetEnabled(writable
&& partition->CanEditParameters());
fChangeMenuItem->SetEnabled(writable && canChangeParameters);
fChangeContextMenuItem->SetEnabled(writable && canChangeParameters);
fDeleteMenuItem->SetEnabled(notMountedAndWritable
&& !partition->IsDevice());
@@ -433,7 +433,7 @@ DiskDeviceJobGenerator::_GenerateRemainingJobs(BPartition* parent,
// partition not (re-)initialized, set content properties
// content name
if ((changeFlags & B_PARTITION_CHANGED_NAME)
if ((changeFlags & B_PARTITION_CHANGED_CONTENT_NAME)
|| compare_string(partition->RawContentName(),
partitionData->content_name)) {
status_t error = _GenerateSetContentNameJob(partition);