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;
}