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, false)) { 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, false)) { 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, false)) { 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, false)) { 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 int 158 open_partition(partition_id partitionID, int openMode) 159 { 160 KDiskDeviceManager* manager = KDiskDeviceManager::Default(); 161 KPartition* partition = manager->FindPartition(partitionID); 162 if (partition == NULL) 163 return B_BAD_VALUE; 164 165 int fd = -1; 166 status_t result = partition->Open(openMode, &fd); 167 if (result != B_OK) 168 return -1; 169 170 return fd; 171 } 172 173 174 // create_child_partition 175 partition_data* 176 create_child_partition(partition_id partitionID, int32 index, off_t offset, 177 off_t size, partition_id childID) 178 { 179 KDiskDeviceManager* manager = KDiskDeviceManager::Default(); 180 if (KPartition* partition = manager->FindPartition(partitionID)) { 181 KPartition* child = NULL; 182 if (partition->CreateChild(childID, index, offset, size, &child) 183 == B_OK) { 184 return child->PartitionData(); 185 } else { 186 DBG(OUT(" creating child (%ld, %ld) failed\n", partitionID, 187 index)); 188 } 189 } else 190 DBG(OUT(" partition %ld not found\n", partitionID)); 191 192 return NULL; 193 } 194 195 196 // delete_partition 197 bool 198 delete_partition(partition_id partitionID) 199 { 200 KDiskDeviceManager* manager = KDiskDeviceManager::Default(); 201 if (KPartition* partition = manager->FindPartition(partitionID)) { 202 if (KPartition* parent = partition->Parent()) 203 return parent->RemoveChild(partition); 204 } 205 return false; 206 } 207 208 209 // partition_modified 210 void 211 partition_modified(partition_id partitionID) 212 { 213 // TODO: implemented 214 } 215 216 217 // scan_partition 218 status_t 219 scan_partition(partition_id partitionID) 220 { 221 // get the partition 222 KDiskDeviceManager* manager = KDiskDeviceManager::Default(); 223 KPartition* partition = manager->RegisterPartition(partitionID); 224 if (partition == NULL) 225 return B_ENTRY_NOT_FOUND; 226 PartitionRegistrar _(partition, true); 227 228 // scan it 229 return manager->ScanPartition(partition); 230 } 231 232 233 // get_default_partition_content_name 234 status_t 235 get_default_partition_content_name(partition_id partitionID, 236 const char* fileSystemName, char* buffer, size_t bufferSize) 237 { 238 KDiskDeviceManager* manager = KDiskDeviceManager::Default(); 239 KPartition* partition = manager->RegisterPartition(partitionID); 240 if (partition == NULL) 241 return B_ENTRY_NOT_FOUND; 242 243 double size = partition->ContentSize(); 244 partition->Unregister(); 245 246 const char* const suffixes[] = { 247 "", "K", "M", "G", "T", "P", "E", NULL 248 }; 249 250 int index = 0; 251 while (size >= 1024 && suffixes[index + 1]) { 252 size /= 1024; 253 index++; 254 } 255 256 // Our kernel snprintf() ignores the precision argument, so we manually 257 // do one digit precision. 258 uint64 result = uint64(size * 10 + 0.5); 259 260 snprintf(buffer, bufferSize, "%s Volume (%ld.%ld %sB)", fileSystemName, 261 int32(result / 10), int32(result % 10), suffixes[index]); 262 263 return B_OK; 264 } 265 266 267 // find_disk_system 268 disk_system_id 269 find_disk_system(const char* name) 270 { 271 KDiskDeviceManager* manager = KDiskDeviceManager::Default(); 272 if (ManagerLocker locker = manager) { 273 if (KDiskSystem* diskSystem = manager->FindDiskSystem(name)) 274 return diskSystem->ID(); 275 } 276 return -1; 277 } 278 279 280 // update_disk_device_job_progress 281 bool 282 update_disk_device_job_progress(disk_job_id jobID, float progress) 283 { 284 #if 0 285 KDiskDeviceManager* manager = KDiskDeviceManager::Default(); 286 if (ManagerLocker locker = manager) { 287 if (KDiskDeviceJob* job = manager->FindJob(jobID)) { 288 job->UpdateProgress(progress); 289 return true; 290 } 291 } 292 #endif 293 return false; 294 } 295 296 297 // update_disk_device_job_extra_progress 298 bool 299 update_disk_device_job_extra_progress(disk_job_id jobID, const char* info) 300 { 301 #if 0 302 KDiskDeviceManager* manager = KDiskDeviceManager::Default(); 303 if (ManagerLocker locker = manager) { 304 if (KDiskDeviceJob* job = manager->FindJob(jobID)) { 305 job->UpdateExtraProgress(info); 306 return true; 307 } 308 } 309 #endif 310 return false; 311 } 312 313 314 // set_disk_device_job_error_message 315 bool 316 set_disk_device_job_error_message(disk_job_id jobID, const char* message) 317 { 318 #if 0 319 KDiskDeviceManager* manager = KDiskDeviceManager::Default(); 320 if (ManagerLocker locker = manager) { 321 if (KDiskDeviceJob* job = manager->FindJob(jobID)) { 322 job->SetErrorMessage(message); 323 return true; 324 } 325 } 326 #endif 327 return false; 328 } 329 330 331 // update_disk_device_job_interrupt_properties 332 uint32 333 update_disk_device_job_interrupt_properties(disk_job_id jobID, 334 uint32 interruptProperties) 335 { 336 #if 0 337 bool paused = false; 338 KDiskDeviceManager* manager = KDiskDeviceManager::Default(); 339 do { 340 sem_id pauseSemaphore = -1; 341 if (ManagerLocker locker = manager) { 342 // get the job and the respective job queue 343 if (KDiskDeviceJob* job = manager->FindJob(jobID)) { 344 if (KDiskDeviceJobQueue* jobQueue = job->JobQueue()) { 345 // terminate if canceled. 346 if (jobQueue->IsCanceled()) { 347 if (jobQueue->ShallReverse()) 348 return B_DISK_DEVICE_JOB_REVERSE; 349 return B_DISK_DEVICE_JOB_CANCEL; 350 } 351 // set the new interrupt properties only when not 352 // requested to pause 353 if (jobQueue->IsPauseRequested()) 354 pauseSemaphore = jobQueue->ReadyToPause(); 355 else 356 job->SetInterruptProperties(interruptProperties); 357 } 358 } 359 } 360 // pause, if requested; redo the loop then 361 paused = (pauseSemaphore >= 0); 362 if (paused) { 363 acquire_sem(pauseSemaphore); 364 pauseSemaphore = -1; 365 } 366 } while (paused); 367 #endif 368 return B_DISK_DEVICE_JOB_CONTINUE; 369 } 370 371