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 "KDiskDeviceManager.h" 9 #include "KDiskDeviceUtils.h" 10 #include "KDiskSystem.h" 11 #include "KPartition.h" 12 13 14 // debugging 15 //#define DBG(x) 16 #define DBG(x) x 17 #define OUT dprintf 18 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 36 // write_unlock_disk_device 37 void 38 write_unlock_disk_device(partition_id partitionID) 39 { 40 KDiskDeviceManager *manager = KDiskDeviceManager::Default(); 41 if (KDiskDevice *device = manager->RegisterDevice(partitionID)) { 42 bool isLocked = device->IsWriteLocked(); 43 if (isLocked) { 44 device->WriteUnlock(); 45 device->Unregister(); 46 } 47 device->Unregister(); 48 } 49 } 50 51 52 // read_lock_disk_device 53 disk_device_data * 54 read_lock_disk_device(partition_id partitionID) 55 { 56 KDiskDeviceManager *manager = KDiskDeviceManager::Default(); 57 if (KDiskDevice *device = manager->RegisterDevice(partitionID)) { 58 if (device->ReadLock()) 59 return device->DeviceData(); 60 // Only unregister, when the locking fails. The guarantees, that the 61 // lock owner also has a reference. 62 device->Unregister(); 63 } 64 return NULL; 65 } 66 67 68 // read_unlock_disk_device 69 void 70 read_unlock_disk_device(partition_id partitionID) 71 { 72 KDiskDeviceManager *manager = KDiskDeviceManager::Default(); 73 if (KDiskDevice *device = manager->RegisterDevice(partitionID)) { 74 bool isLocked = device->IsReadLocked(false); 75 if (isLocked) { 76 device->ReadUnlock(); 77 device->Unregister(); 78 } 79 device->Unregister(); 80 } 81 } 82 83 84 // find_disk_device 85 int32 86 find_disk_device(const char *path) 87 { 88 KDiskDeviceManager *manager = KDiskDeviceManager::Default(); 89 partition_id id = -1; 90 if (KDiskDevice *device = manager->RegisterDevice(path)) { 91 id = device->ID(); 92 device->Unregister(); 93 } 94 return id; 95 } 96 97 98 // find_partition 99 int32 100 find_partition(const char *path) 101 { 102 KDiskDeviceManager *manager = KDiskDeviceManager::Default(); 103 partition_id id = -1; 104 if (KPartition *partition = manager->RegisterPartition(path)) { 105 id = partition->ID(); 106 partition->Unregister(); 107 } 108 return id; 109 } 110 111 112 // get_disk_device 113 disk_device_data * 114 get_disk_device(partition_id partitionID) 115 { 116 KDiskDeviceManager *manager = KDiskDeviceManager::Default(); 117 KDiskDevice *device = manager->FindDevice(partitionID, false); 118 return (device ? device->DeviceData() : NULL); 119 } 120 121 122 // get_partition 123 partition_data * 124 get_partition(partition_id partitionID) 125 { 126 KDiskDeviceManager *manager = KDiskDeviceManager::Default(); 127 KPartition *partition = manager->FindPartition(partitionID); 128 return (partition ? partition->PartitionData() : NULL); 129 } 130 131 132 // get_parent_partition 133 partition_data * 134 get_parent_partition(partition_id partitionID) 135 { 136 KDiskDeviceManager *manager = KDiskDeviceManager::Default(); 137 KPartition *partition = manager->FindPartition(partitionID); 138 if (partition && partition->Parent()) 139 return partition->Parent()->PartitionData(); 140 return NULL; 141 } 142 143 144 // get_child_partition 145 partition_data * 146 get_child_partition(partition_id partitionID, int32 index) 147 { 148 KDiskDeviceManager *manager = KDiskDeviceManager::Default(); 149 if (KPartition *partition = manager->FindPartition(partitionID)) { 150 if (KPartition *child = partition->ChildAt(index)) 151 return child->PartitionData(); 152 } 153 return NULL; 154 } 155 156 157 // create_child_partition 158 partition_data * 159 create_child_partition(partition_id partitionID, int32 index, off_t offset, 160 off_t size, partition_id childID) 161 { 162 KDiskDeviceManager *manager = KDiskDeviceManager::Default(); 163 if (KPartition *partition = manager->FindPartition(partitionID)) { 164 KPartition *child = NULL; 165 if (partition->CreateChild(childID, index, offset, size, &child) 166 == B_OK) { 167 return child->PartitionData(); 168 } else { 169 DBG(OUT(" creating child (%ld, %ld) failed\n", partitionID, 170 index)); 171 } 172 } else 173 DBG(OUT(" partition %ld not found\n", partitionID)); 174 175 return NULL; 176 } 177 178 179 // delete_partition 180 bool 181 delete_partition(partition_id partitionID) 182 { 183 KDiskDeviceManager *manager = KDiskDeviceManager::Default(); 184 if (KPartition *partition = manager->FindPartition(partitionID)) { 185 if (KPartition *parent = partition->Parent()) 186 return parent->RemoveChild(partition); 187 } 188 return false; 189 } 190 191 192 // partition_modified 193 void 194 partition_modified(partition_id partitionID) 195 { 196 // TODO: implemented 197 } 198 199 200 // scan_partition 201 status_t 202 scan_partition(partition_id partitionID) 203 { 204 // get the partition 205 KDiskDeviceManager* manager = KDiskDeviceManager::Default(); 206 KPartition* partition = manager->RegisterPartition(partitionID); 207 if (partition == NULL) 208 return B_ENTRY_NOT_FOUND; 209 PartitionRegistrar _(partition, true); 210 211 // scan it 212 return manager->ScanPartition(partition); 213 } 214 215 216 // get_default_partition_content_name 217 status_t 218 get_default_partition_content_name(partition_id partitionID, 219 const char* fileSystemName, char* buffer, size_t bufferSize) 220 { 221 KDiskDeviceManager *manager = KDiskDeviceManager::Default(); 222 KPartition *partition = manager->RegisterPartition(partitionID); 223 if (partition == NULL) 224 return B_ENTRY_NOT_FOUND; 225 226 double size = partition->ContentSize(); 227 partition->Unregister(); 228 229 const char* const suffixes[] = { 230 "", "K", "M", "G", "T", "P", "E", NULL 231 }; 232 233 int index = 0; 234 while (size >= 1024 && suffixes[index + 1]) { 235 size /= 1024; 236 index++; 237 } 238 239 // Our kernel snprintf() ignores the precision argument, so we manually 240 // do one digit precision. 241 uint64 result = uint64(size * 10 + 0.5); 242 243 snprintf(buffer, bufferSize, "%s Volume (%ld.%ld %sB)", fileSystemName, 244 int32(result / 10), int32(result % 10), suffixes[index]); 245 246 return B_OK; 247 } 248 249 250 // find_disk_system 251 disk_system_id 252 find_disk_system(const char *name) 253 { 254 KDiskDeviceManager *manager = KDiskDeviceManager::Default(); 255 if (ManagerLocker locker = manager) { 256 if (KDiskSystem *diskSystem = manager->FindDiskSystem(name)) 257 return diskSystem->ID(); 258 } 259 return -1; 260 } 261 262 263 // update_disk_device_job_progress 264 bool 265 update_disk_device_job_progress(disk_job_id jobID, float progress) 266 { 267 #if 0 268 KDiskDeviceManager *manager = KDiskDeviceManager::Default(); 269 if (ManagerLocker locker = manager) { 270 if (KDiskDeviceJob *job = manager->FindJob(jobID)) { 271 job->UpdateProgress(progress); 272 return true; 273 } 274 } 275 #endif 276 return false; 277 } 278 279 280 // update_disk_device_job_extra_progress 281 bool 282 update_disk_device_job_extra_progress(disk_job_id jobID, const char *info) 283 { 284 #if 0 285 KDiskDeviceManager *manager = KDiskDeviceManager::Default(); 286 if (ManagerLocker locker = manager) { 287 if (KDiskDeviceJob *job = manager->FindJob(jobID)) { 288 job->UpdateExtraProgress(info); 289 return true; 290 } 291 } 292 #endif 293 return false; 294 } 295 296 297 // set_disk_device_job_error_message 298 bool 299 set_disk_device_job_error_message(disk_job_id jobID, const char *message) 300 { 301 #if 0 302 KDiskDeviceManager *manager = KDiskDeviceManager::Default(); 303 if (ManagerLocker locker = manager) { 304 if (KDiskDeviceJob *job = manager->FindJob(jobID)) { 305 job->SetErrorMessage(message); 306 return true; 307 } 308 } 309 #endif 310 return false; 311 } 312 313 314 // update_disk_device_job_interrupt_properties 315 uint32 316 update_disk_device_job_interrupt_properties(disk_job_id jobID, 317 uint32 interruptProperties) 318 { 319 #if 0 320 bool paused = false; 321 KDiskDeviceManager *manager = KDiskDeviceManager::Default(); 322 do { 323 sem_id pauseSemaphore = -1; 324 if (ManagerLocker locker = manager) { 325 // get the job and the respective job queue 326 if (KDiskDeviceJob *job = manager->FindJob(jobID)) { 327 if (KDiskDeviceJobQueue *jobQueue = job->JobQueue()) { 328 // terminate if canceled. 329 if (jobQueue->IsCanceled()) { 330 if (jobQueue->ShallReverse()) 331 return B_DISK_DEVICE_JOB_REVERSE; 332 return B_DISK_DEVICE_JOB_CANCEL; 333 } 334 // set the new interrupt properties only when not 335 // requested to pause 336 if (jobQueue->IsPauseRequested()) 337 pauseSemaphore = jobQueue->ReadyToPause(); 338 else 339 job->SetInterruptProperties(interruptProperties); 340 } 341 } 342 } 343 // pause, if requested; redo the loop then 344 paused = (pauseSemaphore >= 0); 345 if (paused) { 346 acquire_sem(pauseSemaphore); 347 pauseSemaphore = -1; 348 } 349 } while (paused); 350 #endif 351 return B_DISK_DEVICE_JOB_CONTINUE; 352 } 353 354