1 // disk_device_manager.cpp 2 3 #include <KernelExport.h> 4 #include <stdio.h> 5 6 #include "disk_device_manager.h" 7 #include "KDiskDevice.h" 8 #include "KDiskDeviceJob.h" 9 #include "KDiskDeviceJobQueue.h" 10 #include "KDiskDeviceManager.h" 11 #include "KDiskDeviceUtils.h" 12 #include "KDiskSystem.h" 13 #include "KPartition.h" 14 15 // debugging 16 //#define DBG(x) 17 #define DBG(x) x 18 #define OUT dprintf 19 20 // write_lock_disk_device 21 disk_device_data * 22 write_lock_disk_device(partition_id partitionID) 23 { 24 KDiskDeviceManager *manager = KDiskDeviceManager::Default(); 25 if (KDiskDevice *device = manager->RegisterDevice(partitionID)) { 26 if (device->WriteLock()) 27 return device->DeviceData(); 28 // Only unregister, when the locking fails. The guarantees, that the 29 // lock owner also has a reference. 30 device->Unregister(); 31 } 32 return NULL; 33 } 34 35 // write_unlock_disk_device 36 void 37 write_unlock_disk_device(partition_id partitionID) 38 { 39 KDiskDeviceManager *manager = KDiskDeviceManager::Default(); 40 if (KDiskDevice *device = manager->RegisterDevice(partitionID)) { 41 bool isLocked = device->IsWriteLocked(); 42 if (isLocked) { 43 device->WriteUnlock(); 44 device->Unregister(); 45 } 46 device->Unregister(); 47 } 48 } 49 50 // read_lock_disk_device 51 disk_device_data * 52 read_lock_disk_device(partition_id partitionID) 53 { 54 KDiskDeviceManager *manager = KDiskDeviceManager::Default(); 55 if (KDiskDevice *device = manager->RegisterDevice(partitionID)) { 56 if (device->ReadLock()) 57 return device->DeviceData(); 58 // Only unregister, when the locking fails. The guarantees, that the 59 // lock owner also has a reference. 60 device->Unregister(); 61 } 62 return NULL; 63 } 64 65 // read_unlock_disk_device 66 void 67 read_unlock_disk_device(partition_id partitionID) 68 { 69 KDiskDeviceManager *manager = KDiskDeviceManager::Default(); 70 if (KDiskDevice *device = manager->RegisterDevice(partitionID)) { 71 bool isLocked = device->IsReadLocked(false); 72 if (isLocked) { 73 device->ReadUnlock(); 74 device->Unregister(); 75 } 76 device->Unregister(); 77 } 78 } 79 80 // find_disk_device 81 int32 82 find_disk_device(const char *path) 83 { 84 KDiskDeviceManager *manager = KDiskDeviceManager::Default(); 85 partition_id id = -1; 86 if (KDiskDevice *device = manager->RegisterDevice(path)) { 87 id = device->ID(); 88 device->Unregister(); 89 } 90 return id; 91 } 92 93 // find_partition 94 int32 95 find_partition(const char *path) 96 { 97 KDiskDeviceManager *manager = KDiskDeviceManager::Default(); 98 partition_id id = -1; 99 if (KPartition *partition = manager->RegisterPartition(path)) { 100 id = partition->ID(); 101 partition->Unregister(); 102 } 103 return id; 104 } 105 106 // get_disk_device 107 disk_device_data * 108 get_disk_device(partition_id partitionID) 109 { 110 KDiskDeviceManager *manager = KDiskDeviceManager::Default(); 111 KDiskDevice *device = manager->FindDevice(partitionID, false); 112 return (device ? device->DeviceData() : NULL); 113 } 114 115 // get_partition 116 partition_data * 117 get_partition(partition_id partitionID) 118 { 119 KDiskDeviceManager *manager = KDiskDeviceManager::Default(); 120 KPartition *partition = manager->FindPartition(partitionID); 121 return (partition ? partition->PartitionData() : NULL); 122 } 123 124 // get_parent_partition 125 partition_data * 126 get_parent_partition(partition_id partitionID) 127 { 128 KDiskDeviceManager *manager = KDiskDeviceManager::Default(); 129 KPartition *partition = manager->FindPartition(partitionID); 130 if (partition && partition->Parent()) 131 return partition->Parent()->PartitionData(); 132 return NULL; 133 } 134 135 // get_child_partition 136 partition_data * 137 get_child_partition(partition_id partitionID, int32 index) 138 { 139 KDiskDeviceManager *manager = KDiskDeviceManager::Default(); 140 if (KPartition *partition = manager->FindPartition(partitionID)) { 141 if (KPartition *child = partition->ChildAt(index)) 142 return child->PartitionData(); 143 } 144 return NULL; 145 } 146 147 // create_child_partition 148 partition_data * 149 create_child_partition(partition_id partitionID, int32 index, 150 partition_id childID) 151 { 152 KDiskDeviceManager *manager = KDiskDeviceManager::Default(); 153 if (KPartition *partition = manager->FindPartition(partitionID)) { 154 KPartition *child = NULL; 155 if (partition->CreateChild(childID, index, &child) == B_OK) 156 return child->PartitionData(); 157 else 158 DBG(OUT(" creating child (%ld, %ld) failed\n", partitionID, index)); 159 } 160 else 161 DBG(OUT(" partition %ld not found\n", partitionID)); 162 return NULL; 163 } 164 165 // delete_partition 166 bool 167 delete_partition(partition_id partitionID) 168 { 169 KDiskDeviceManager *manager = KDiskDeviceManager::Default(); 170 if (KPartition *partition = manager->FindPartition(partitionID)) { 171 if (KPartition *parent = partition->Parent()) 172 return parent->RemoveChild(partition); 173 } 174 return false; 175 } 176 177 // partition_modified 178 void 179 partition_modified(partition_id partitionID) 180 { 181 // not implemented 182 } 183 184 // find_disk_system 185 disk_system_id 186 find_disk_system(const char *name) 187 { 188 KDiskDeviceManager *manager = KDiskDeviceManager::Default(); 189 if (ManagerLocker locker = manager) { 190 if (KDiskSystem *diskSystem = manager->FindDiskSystem(name)) 191 return diskSystem->ID(); 192 } 193 return -1; 194 } 195 196 // update_disk_device_job_progress 197 bool 198 update_disk_device_job_progress(disk_job_id jobID, float progress) 199 { 200 KDiskDeviceManager *manager = KDiskDeviceManager::Default(); 201 if (ManagerLocker locker = manager) { 202 if (KDiskDeviceJob *job = manager->FindJob(jobID)) { 203 job->UpdateProgress(progress); 204 return true; 205 } 206 } 207 return false; 208 } 209 210 // update_disk_device_job_extra_progress 211 bool 212 update_disk_device_job_extra_progress(disk_job_id jobID, const char *info) 213 { 214 KDiskDeviceManager *manager = KDiskDeviceManager::Default(); 215 if (ManagerLocker locker = manager) { 216 if (KDiskDeviceJob *job = manager->FindJob(jobID)) { 217 job->UpdateExtraProgress(info); 218 return true; 219 } 220 } 221 return false; 222 } 223 224 // set_disk_device_job_error_message 225 bool 226 set_disk_device_job_error_message(disk_job_id jobID, const char *message) 227 { 228 KDiskDeviceManager *manager = KDiskDeviceManager::Default(); 229 if (ManagerLocker locker = manager) { 230 if (KDiskDeviceJob *job = manager->FindJob(jobID)) { 231 job->SetErrorMessage(message); 232 return true; 233 } 234 } 235 return false; 236 } 237 238 // update_disk_device_job_interrupt_properties 239 uint32 240 update_disk_device_job_interrupt_properties(disk_job_id jobID, 241 uint32 interruptProperties) 242 { 243 bool paused = false; 244 KDiskDeviceManager *manager = KDiskDeviceManager::Default(); 245 do { 246 sem_id pauseSemaphore = -1; 247 if (ManagerLocker locker = manager) { 248 // get the job and the respective job queue 249 if (KDiskDeviceJob *job = manager->FindJob(jobID)) { 250 if (KDiskDeviceJobQueue *jobQueue = job->JobQueue()) { 251 // terminate if canceled. 252 if (jobQueue->IsCanceled()) { 253 if (jobQueue->ShallReverse()) 254 return B_DISK_DEVICE_JOB_REVERSE; 255 return B_DISK_DEVICE_JOB_CANCEL; 256 } 257 // set the new interrupt properties only when not 258 // requested to pause 259 if (jobQueue->IsPauseRequested()) 260 pauseSemaphore = jobQueue->ReadyToPause(); 261 else 262 job->SetInterruptProperties(interruptProperties); 263 } 264 } 265 } 266 // pause, if requested; redo the loop then 267 paused = (pauseSemaphore >= 0); 268 if (paused) { 269 acquire_sem(pauseSemaphore); 270 pauseSemaphore = -1; 271 } 272 } while (paused); 273 return B_DISK_DEVICE_JOB_CONTINUE; 274 } 275 276