partition_id _user_find_partition(const char *_filename, size_t *neededSize) { UserStringParameter<false> filename; status_t error = filename.Init(_filename, B_PATH_NAME_LENGTH); if (error != B_OK) return error; KDiskDeviceManager *manager = KDiskDeviceManager::Default(); // find the partition KPartition *partition = manager->RegisterPartition(filename); if (partition == NULL) return B_ENTRY_NOT_FOUND; PartitionRegistrar _(partition, true); partition_id id = partition->ID(); if (neededSize != NULL) { // get and lock the partition's device KDiskDevice *device = manager->RegisterDevice(partition->ID(), false); if (device == NULL) return B_ENTRY_NOT_FOUND; PartitionRegistrar _2(device, true); if (DeviceReadLocker locker = device) { // get the needed size UserDataWriter writer; device->WriteUserData(writer); error = copy_to_user_value(neededSize, writer.AllocatedSize()); if (error != B_OK) return error; } else return B_ERROR; } return id; }
status_t _user_create_child_partition(partition_id partitionID, int32* _changeCounter, off_t offset, off_t size, const char* _type, const char* _name, const char* _parameters, partition_id* childID, int32* childChangeCounter) { // copy parameters in UserStringParameter<false> type; UserStringParameter<true> name; UserStringParameter<true> parameters; int32 changeCounter; status_t error = type.Init(_type, B_DISK_DEVICE_TYPE_LENGTH); if (error == B_OK) error = name.Init(_name, B_DISK_DEVICE_NAME_LENGTH); if (error == B_OK) error = parameters.Init(_parameters, B_DISK_DEVICE_MAX_PARAMETER_SIZE); if (error == B_OK) error = copy_from_user_value(changeCounter, _changeCounter); if (error != B_OK) return error; // get the partition KDiskDeviceManager* manager = KDiskDeviceManager::Default(); KPartition* partition = manager->WriteLockPartition(partitionID); if (partition == NULL) return B_ENTRY_NOT_FOUND; PartitionRegistrar registrar1(partition, true); PartitionRegistrar registrar2(partition->Device(), true); DeviceWriteLocker locker(partition->Device(), true); // check change counter if (changeCounter != partition->ChangeCounter()) return B_BAD_VALUE; // the partition must be initialized KDiskSystem* diskSystem = partition->DiskSystem(); if (diskSystem == NULL) return B_BAD_VALUE; // mark the partition busy and unlock if (!partition->CheckAndMarkBusy(false)) return B_BUSY; locker.Unlock(); // create the child KPartition *child = NULL; error = diskSystem->CreateChild(partition, offset, size, type.value, name.value, parameters.value, DUMMY_JOB_ID, &child, -1); // re-lock and unmark busy locker.Lock(); partition->UnmarkBusy(false); if (error != B_OK) return error; if (child == NULL) return B_ERROR; child->UnmarkBusy(true); // return change counter and child ID error = copy_to_user_value(_changeCounter, partition->ChangeCounter()); if (error == B_OK) error = copy_to_user_value(childID, child->ID()); return error; }