diff --git a/headers/os/drivers/disk_device_manager.h b/headers/os/drivers/disk_device_manager.h index a36d72609e..8795742176 100644 --- a/headers/os/drivers/disk_device_manager.h +++ b/headers/os/drivers/disk_device_manager.h @@ -30,7 +30,7 @@ typedef struct partition_data { uint32 status; uint32 flags; dev_t volume; // [sys] - void *mount_cookie; // [sys] + void *mount_cookie; // [sys] char *name; // max: B_OS_NAME_LENGTH char *content_name; // char *type; // @@ -104,7 +104,7 @@ partition_data *get_child_partition(partition_id partitionID, int32 index); // partition write access // (write lock required) partition_data *create_child_partition(partition_id partitionID, int32 index, - partition_id childID); + off_t offset, off_t size, partition_id childID); // childID is an optional input parameter -- -1 to be ignored bool delete_partition(partition_id partitionID); void partition_modified(partition_id partitionID); diff --git a/headers/private/kernel/disk_device_manager/KPartition.h b/headers/private/kernel/disk_device_manager/KPartition.h index 11e009bb84..e9a8cd8492 100644 --- a/headers/private/kernel/disk_device_manager/KPartition.h +++ b/headers/private/kernel/disk_device_manager/KPartition.h @@ -75,7 +75,7 @@ public: void SetStatus(uint32 status); uint32 Status() const; bool IsUninitialized() const; - + void SetFlags(uint32 flags); // comprises the ones below void AddFlags(uint32 flags); void ClearFlags(uint32 flags); @@ -135,7 +135,7 @@ public: KPartition *Parent() const; status_t AddChild(KPartition *partition, int32 index = -1); - virtual status_t CreateChild(partition_id id, int32 index, + status_t CreateChild(partition_id id, int32 index, off_t offset, off_t size, KPartition **child = NULL); bool RemoveChild(int32 index); bool RemoveChild(KPartition *child); diff --git a/src/add-ons/kernel/partitioning_systems/amiga/amiga_rdb.cpp b/src/add-ons/kernel/partitioning_systems/amiga/amiga_rdb.cpp index f342e28d9b..0c7bdd07b0 100644 --- a/src/add-ons/kernel/partitioning_systems/amiga/amiga_rdb.cpp +++ b/src/add-ons/kernel/partitioning_systems/amiga/amiga_rdb.cpp @@ -183,14 +183,13 @@ amiga_rdb_scan_partition(int fd, partition_data *partition, void *_cookie) continue; } - partition_data *child = create_child_partition(partition->id, index++, -1); + partition_data *child = create_child_partition(partition->id, index++, + partition->offset + environment.Start(), environment.Size(), -1); if (child == NULL) { TRACE(("amiga_rdb: Creating child at index %ld failed\n", index - 1)); return B_ERROR; } - child->offset = partition->offset + environment.Start(); - child->size = environment.Size(); child->block_size = environment.BlockSize(); } diff --git a/src/add-ons/kernel/partitioning_systems/apple/apple.cpp b/src/add-ons/kernel/partitioning_systems/apple/apple.cpp index 1586a69384..828bc99ec5 100644 --- a/src/add-ons/kernel/partitioning_systems/apple/apple.cpp +++ b/src/add-ons/kernel/partitioning_systems/apple/apple.cpp @@ -67,7 +67,7 @@ get_next_partition(int fd, apple_driver_descriptor &descriptor, uint32 &cookie, if (bytesRead < (ssize_t)sizeof(apple_partition_map)) return B_ERROR; - block++; + block++; } while (cookie == 0 && block < 64 && !partition.HasValidSignature()); if (!partition.HasValidSignature()) { @@ -168,14 +168,14 @@ apple_scan_partition(int fd, partition_data *partition, void *_cookie) continue; } - partition_data *child = create_child_partition(partition->id, index++, -1); + partition_data *child = create_child_partition(partition->id, index++, + partition->offset + partitionMap.Start(descriptor), + partitionMap.Size(descriptor), -1); if (child == NULL) { TRACE(("apple: Creating child at index %ld failed\n", index - 1)); return B_ERROR; } - child->offset = partition->offset + partitionMap.Start(descriptor); - child->size = partitionMap.Size(descriptor); child->block_size = partition->block_size; } diff --git a/src/add-ons/kernel/partitioning_systems/atari/atari.cpp b/src/add-ons/kernel/partitioning_systems/atari/atari.cpp index 637042414a..5bcc1058a9 100644 --- a/src/add-ons/kernel/partitioning_systems/atari/atari.cpp +++ b/src/add-ons/kernel/partitioning_systems/atari/atari.cpp @@ -96,10 +96,10 @@ atari_identify_partition(int fd, partition_data *partition, void **_cookie) /* hope so */ if (arb->MaxPartitionSize() < 10) weight -= 20; - + if ((arb->BadSectorsStart()+arb->BadSectorsCount())*(off_t)SECTSZ > partition->size) return B_ERROR; - + /* check each partition */ for (i = 0; i < 4; i++) { struct atari_partition_entry *p = &arb->partitions[i]; @@ -136,12 +136,12 @@ atari_identify_partition(int fd, partition_data *partition, void **_cookie) if (weight > 1.0) weight = 1.0; - + if (weight > 0.0) { // copy the root block to a new piece of memory arb = new atari_root_block(); memcpy(arb, buffer, sizeof(atari_root_block)); - + *_cookie = (void *)arb; return weight; } @@ -182,8 +182,10 @@ atari_scan_partition(int fd, partition_data *partition, void *_cookie) continue; if (!isalnum(p->id[2])) continue; - - partition_data *child = create_child_partition(partition->id, index, -1); + + partition_data *child = create_child_partition(partition->id, index, + partition->offset + p->Start() * (uint64)SECTSZ, + p->Size() * (uint64)SECTSZ, -1); if (child == NULL) { TRACE(("atari: Creating child at index %ld failed\n", index - 1)); return B_ERROR; @@ -192,8 +194,6 @@ atari_scan_partition(int fd, partition_data *partition, void *_cookie) char type[] = "??? Partition"; memcpy(type, p->id, 3); child->type = strdup(type); - child->offset = partition->offset + p->Start() * (uint64)SECTSZ; - child->size = p->Size() * (uint64)SECTSZ; child->block_size = SECTSZ; status = B_OK; } 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 5df649a328..ffaae4c3cc 100644 --- a/src/add-ons/kernel/partitioning_systems/efi/efi_gpt.cpp +++ b/src/add-ons/kernel/partitioning_systems/efi/efi_gpt.cpp @@ -483,7 +483,8 @@ efi_gpt_scan_partition(int fd, partition_data *partition, void *_cookie) } partition_data *child = create_child_partition(partition->id, index++, - -1); + partition->offset + entry.StartBlock() * partition->block_size, + entry.BlockCount() * partition->block_size, -1); if (child == NULL) { TRACE(("efi_gpt: Creating child at index %ld failed\n", index - 1)); return B_ERROR; @@ -493,10 +494,6 @@ efi_gpt_scan_partition(int fd, partition_data *partition, void *_cookie) to_utf8(entry.name, EFI_PARTITION_NAME_LENGTH, name, sizeof(name)); child->name = strdup(name); child->type = strdup(get_partition_type(entry.partition_type)); - - child->offset = partition->offset + entry.StartBlock() - * partition->block_size; - child->size = entry.BlockCount() * partition->block_size; child->block_size = partition->block_size; child->cookie = (void *)i; } @@ -1119,7 +1116,7 @@ efi_gpt_create_child(int fd, partition_id partitionID, off_t offset, update_disk_device_job_progress(job, 0.0); partition_data *child = create_child_partition(partition->id, entryIndex, - *childID); + validatedOffset, validatedSize, *childID); if (child == NULL) return B_ERROR; @@ -1137,8 +1134,6 @@ efi_gpt_create_child(int fd, partition_id partitionID, off_t offset, } *childID = child->id; - child->offset = validatedOffset; - child->size = validatedSize; child->block_size = partition->block_size; child->type = strdup(type); child->parameters = strdup(parameters); diff --git a/src/add-ons/kernel/partitioning_systems/intel/intel.cpp b/src/add-ons/kernel/partitioning_systems/intel/intel.cpp index d336965884..392c118748 100644 --- a/src/add-ons/kernel/partitioning_systems/intel/intel.cpp +++ b/src/add-ons/kernel/partitioning_systems/intel/intel.cpp @@ -202,7 +202,8 @@ pm_scan_partition(int fd, partition_data *partition, void *cookie) PrimaryPartition *primary = map->PrimaryPartitionAt(i); if (!primary->IsEmpty()) { partition_data *child = create_child_partition(partition->id, - index, -1); + index, partition->offset + primary->Offset(), primary->Size(), + -1); index++; if (!child) { // something went wrong @@ -210,8 +211,6 @@ pm_scan_partition(int fd, partition_data *partition, void *cookie) break; } - child->offset = partition->offset + primary->Offset(); - child->size = primary->Size(); child->block_size = partition->block_size; // (no name) @@ -354,7 +353,8 @@ ep_scan_partition(int fd, partition_data *partition, void *cookie) int32 index = 0; for (int32 i = 0; i < primary->CountLogicalPartitions(); i++) { LogicalPartition *logical = primary->LogicalPartitionAt(i); - partition_data *child = create_child_partition(partition->id, index, -1); + partition_data *child = create_child_partition(partition->id, index, + parent->offset + logical->Offset(), logical->Size(), -1); index++; if (!child) { // something went wrong @@ -363,8 +363,6 @@ ep_scan_partition(int fd, partition_data *partition, void *cookie) error = B_ERROR; break; } - child->offset = parent->offset + logical->Offset(); - child->size = logical->Size(); child->block_size = partition->block_size; // (no name) 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 bb8088a2ff..83059481e4 100644 --- a/src/add-ons/kernel/partitioning_systems/intel/write_support.cpp +++ b/src/add-ons/kernel/partitioning_systems/intel/write_support.cpp @@ -1329,7 +1329,7 @@ pm_create_child(int fd, partition_id partitionID, off_t offset, off_t size, // creating partition update_disk_device_job_progress(job, 0.0); partition_data *child = create_child_partition(partition->id, index, - *childID); + validatedOffset, validatedSize, *childID); if (!child) return B_ERROR; @@ -1357,8 +1357,6 @@ pm_create_child(int fd, partition_id partitionID, off_t offset, off_t size, *childID = child->id; - child->offset = partition->offset + primary->Offset(); - child->size = primary->Size(); child->block_size = SECTOR_SIZE; // (no name) child->type = strdup(type); @@ -2088,7 +2086,7 @@ ep_create_child(int fd, partition_id partitionID, off_t offset, off_t size, // creating partition update_disk_device_job_progress(job, 0.0); partition_data *child = create_child_partition(partition->id, index, - *childID); + validatedOffset, validatedSize, *childID); if (!child) { delete logical; return B_ERROR; @@ -2136,8 +2134,6 @@ ep_create_child(int fd, partition_id partitionID, off_t offset, off_t size, *childID = child->id; - child->offset = partition->offset + logical->Offset(); - child->size = logical->Size(); child->block_size = SECTOR_SIZE; // (no name) child->type = strdup(type); diff --git a/src/add-ons/kernel/partitioning_systems/session/session.cpp b/src/add-ons/kernel/partitioning_systems/session/session.cpp index d320a04121..d30143c25a 100644 --- a/src/add-ons/kernel/partitioning_systems/session/session.cpp +++ b/src/add-ons/kernel/partitioning_systems/session/session.cpp @@ -76,17 +76,15 @@ scan_partition(int fd, partition_data *partition, void *cookie) Session *session = NULL; status_t error = B_OK; - for (int i = 0; (session = disc->GetSession(i)); i++) { + for (int i = 0; (session = disc->GetSession(i)); i++) { partition_data *child = create_child_partition(partition->id, - i, -1); + i, partition->offset + session->Offset(), session->Size(), -1); if (!child) { PRINT(("Unable to create child at index %d.\n", i)); // something went wrong error = B_ERROR; break; } - child->offset = partition->offset + session->Offset(); - child->size = session->Size(); child->block_size = session->BlockSize(); child->flags |= session->Flags(); child->type = strdup(session->Type()); diff --git a/src/system/boot/loader/partitions.cpp b/src/system/boot/loader/partitions.cpp index 1b6ab268b0..715e36c6e9 100644 --- a/src/system/boot/loader/partitions.cpp +++ b/src/system/boot/loader/partitions.cpp @@ -150,7 +150,7 @@ Partition::Parent() const } -ssize_t +ssize_t Partition::ReadAt(void *cookie, off_t position, void *buffer, size_t bufferSize) { if (position > this->size) @@ -165,7 +165,7 @@ Partition::ReadAt(void *cookie, off_t position, void *buffer, size_t bufferSize) } -ssize_t +ssize_t Partition::WriteAt(void *cookie, off_t position, const void *buffer, size_t bufferSize) { @@ -192,7 +192,7 @@ Partition::Size() const } -int32 +int32 Partition::Type() const { struct stat stat; @@ -223,7 +223,7 @@ status_t Partition::_Mount(file_system_module_info *module, Directory **_fileSystem) { static int fileMapDiskDepth = 0; - TRACE(("%p Partition::_Mount check for file_system: %s\n", + TRACE(("%p Partition::_Mount check for file_system: %s\n", this, module->pretty_name)); Directory *fileSystem; @@ -274,7 +274,7 @@ Partition::Mount(Directory **_fileSystem, bool isBootDevice) } -status_t +status_t Partition::Scan(bool mountFileSystems, bool isBootDevice) { // scan for partitions first (recursively all eventual children as well) @@ -398,7 +398,7 @@ Partition::Scan(bool mountFileSystems, bool isBootDevice) return Mount(); } - return B_ENTRY_NOT_FOUND; + return B_ENTRY_NOT_FOUND; } } // namespace boot @@ -458,7 +458,8 @@ add_partitions_for(Node *device, bool mountFileSystems, bool isBootDevice) partition_data * -create_child_partition(partition_id id, int32 index, partition_id childID) +create_child_partition(partition_id id, int32 index, off_t offset, off_t size, + partition_id childID) { Partition &partition = *(Partition *)id; Partition *child = partition.AddChild(); @@ -467,6 +468,9 @@ create_child_partition(partition_id id, int32 index, partition_id childID) return NULL; } + child->offset = offset; + child->size = size; + // we cannot do anything with the child here, because it was not // yet initialized by the partition module. TRACE(("new child partition!\n")); diff --git a/src/system/kernel/disk_device_manager/KPartition.cpp b/src/system/kernel/disk_device_manager/KPartition.cpp index 46ce8ae873..b05897db82 100644 --- a/src/system/kernel/disk_device_manager/KPartition.cpp +++ b/src/system/kernel/disk_device_manager/KPartition.cpp @@ -185,8 +185,11 @@ KPartition::PublishDevice() // get the path KPath path; status_t error = GetPath(&path); - if (error != B_OK) + if (error != B_OK) { + dprintf("KPartition::PublishDevice(): Failed to get path for partition " + "%ld: %s\n", ID(), strerror(error)); return error; + } // prepare a partition_info partition_info info; @@ -202,8 +205,11 @@ KPartition::PublishDevice() error = devfs_publish_partition(path.Path() + 5, &info); // we need to remove the "/dev/" part from the path - if (error != B_OK) + if (error != B_OK) { + dprintf("KPartition::PublishDevice(): Failed to publish partition " + "%ld: %s\n", ID(), strerror(error)); return error; + } fPublished = true; @@ -220,13 +226,21 @@ KPartition::UnpublishDevice() // get the path KPath path; status_t error = GetPath(&path); - if (error != B_OK) + if (error != B_OK) { + dprintf("KPartition::UnpublishDevice(): Failed to get path for " + "partition %ld: %s\n", ID(), strerror(error)); return error; + } fPublished = false; - return devfs_unpublish_partition(path.Path() + 5); + error = devfs_unpublish_partition(path.Path() + 5); // we need to remove the "/dev/" part from the path + if (error != B_OK) { + dprintf("KPartition::UnpublishDevice(): Failed to unpublish " + "partition %ld: %s\n", ID(), strerror(error)); + } + return error; } @@ -785,7 +799,8 @@ KPartition::AddChild(KPartition *partition, int32 index) // CreateChild status_t -KPartition::CreateChild(partition_id id, int32 index, KPartition **_child) +KPartition::CreateChild(partition_id id, int32 index, off_t offset, off_t size, + KPartition **_child) { // check parameters int32 count = fPartitionData.child_count; @@ -799,6 +814,9 @@ KPartition::CreateChild(partition_id id, int32 index, KPartition **_child) if (!child) return B_NO_MEMORY; + child->SetOffset(offset); + child->SetSize(size); + status_t error = AddChild(child, index); // cleanup / set result diff --git a/src/system/kernel/disk_device_manager/disk_device_manager.cpp b/src/system/kernel/disk_device_manager/disk_device_manager.cpp index 5c4cfa6a34..465981ddc3 100644 --- a/src/system/kernel/disk_device_manager/disk_device_manager.cpp +++ b/src/system/kernel/disk_device_manager/disk_device_manager.cpp @@ -156,19 +156,22 @@ get_child_partition(partition_id partitionID, int32 index) // create_child_partition partition_data * -create_child_partition(partition_id partitionID, int32 index, - partition_id childID) +create_child_partition(partition_id partitionID, int32 index, off_t offset, + off_t size, partition_id childID) { KDiskDeviceManager *manager = KDiskDeviceManager::Default(); if (KPartition *partition = manager->FindPartition(partitionID)) { KPartition *child = NULL; - if (partition->CreateChild(childID, index, &child) == B_OK) + if (partition->CreateChild(childID, index, offset, size, &child) + == B_OK) { return child->PartitionData(); -else -DBG(OUT(" creating child (%ld, %ld) failed\n", partitionID, index)); - } -else -DBG(OUT(" partition %ld not found\n", partitionID)); + } else { + DBG(OUT(" creating child (%ld, %ld) failed\n", partitionID, + index)); + } + } else + DBG(OUT(" partition %ld not found\n", partitionID)); + return NULL; }