status_t _user_initialize_partition(partition_id partitionID, int32* _changeCounter, const char* _diskSystemName, const char* _name, const char* _parameters) { // copy parameters in UserStringParameter<false> diskSystemName; UserStringParameter<true> name; UserStringParameter<true> parameters; int32 changeCounter; status_t error = diskSystemName.Init(_diskSystemName, B_DISK_SYSTEM_NAME_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 uninitialized if (partition->DiskSystem() != NULL) return B_BAD_VALUE; // load the new disk system KDiskSystem *diskSystem = manager->LoadDiskSystem(diskSystemName.value, true); if (diskSystem == NULL) return B_ENTRY_NOT_FOUND; DiskSystemLoader loader(diskSystem, true); // mark the partition busy and unlock if (!partition->CheckAndMarkBusy(true)) return B_BUSY; locker.Unlock(); // let the disk system initialize the partition error = diskSystem->Initialize(partition, name.value, parameters.value, DUMMY_JOB_ID); // re-lock and unmark busy locker.Lock(); partition->UnmarkBusy(true); if (error != B_OK) return error; // Set the disk system. Re-check whether a disk system is already set on the // partition. Some disk systems just write the on-disk structures and let // the DDM rescan the partition, in which case the disk system will already // be set. In very unfortunate cases the on-disk structure of the previous // disk system has not been destroyed and the previous disk system has a // higher priority than the new one. The old disk system will thus prevail. // Not setting the new disk system will at least prevent that the partition // object gets into an inconsistent state. if (partition->DiskSystem() == NULL) partition->SetDiskSystem(diskSystem); // return change counter return copy_to_user_value(_changeCounter, partition->ChangeCounter()); }