2 * Copyright 2003-2009, Ingo Weinhold, ingo_weinhold@gmx.de.
3 * Distributed under the terms of the MIT License.
7 #include "disk_device_manager.h"
11 #include <KernelExport.h>
13 #include "KDiskDevice.h"
14 #include "KDiskDeviceManager.h"
15 #include "KDiskDeviceUtils.h"
16 #include "KDiskSystem.h"
17 #include "KPartition.h"
27 write_lock_disk_device(partition_id partitionID
)
29 KDiskDeviceManager
* manager
= KDiskDeviceManager::Default();
30 if (KDiskDevice
* device
= manager
->RegisterDevice(partitionID
, false)) {
31 if (device
->WriteLock())
32 return device
->DeviceData();
33 // Only unregister, when the locking fails. The guarantees, that the
34 // lock owner also has a reference.
42 write_unlock_disk_device(partition_id partitionID
)
44 KDiskDeviceManager
* manager
= KDiskDeviceManager::Default();
45 if (KDiskDevice
* device
= manager
->RegisterDevice(partitionID
, false)) {
46 device
->WriteUnlock();
55 read_lock_disk_device(partition_id partitionID
)
57 KDiskDeviceManager
* manager
= KDiskDeviceManager::Default();
58 if (KDiskDevice
* device
= manager
->RegisterDevice(partitionID
, false)) {
59 if (device
->ReadLock())
60 return device
->DeviceData();
61 // Only unregister, when the locking fails. The guarantees, that the
62 // lock owner also has a reference.
70 read_unlock_disk_device(partition_id partitionID
)
72 KDiskDeviceManager
* manager
= KDiskDeviceManager::Default();
73 if (KDiskDevice
* device
= manager
->RegisterDevice(partitionID
, false)) {
83 find_disk_device(const char* path
)
85 KDiskDeviceManager
* manager
= KDiskDeviceManager::Default();
87 if (KDiskDevice
* device
= manager
->RegisterDevice(path
)) {
96 find_partition(const char* path
)
98 KDiskDeviceManager
* manager
= KDiskDeviceManager::Default();
100 if (KPartition
* partition
= manager
->RegisterPartition(path
)) {
101 id
= partition
->ID();
102 partition
->Unregister();
109 get_disk_device(partition_id partitionID
)
111 KDiskDeviceManager
* manager
= KDiskDeviceManager::Default();
112 KDiskDevice
* device
= manager
->FindDevice(partitionID
, false);
113 return (device
? device
->DeviceData() : NULL
);
118 get_partition(partition_id partitionID
)
120 KDiskDeviceManager
* manager
= KDiskDeviceManager::Default();
121 KPartition
* partition
= manager
->FindPartition(partitionID
);
122 return (partition
? partition
->PartitionData() : NULL
);
127 get_parent_partition(partition_id partitionID
)
129 KDiskDeviceManager
* manager
= KDiskDeviceManager::Default();
130 KPartition
* partition
= manager
->FindPartition(partitionID
);
131 if (partition
&& partition
->Parent())
132 return partition
->Parent()->PartitionData();
138 get_child_partition(partition_id partitionID
, int32 index
)
140 KDiskDeviceManager
* manager
= KDiskDeviceManager::Default();
141 if (KPartition
* partition
= manager
->FindPartition(partitionID
)) {
142 if (KPartition
* child
= partition
->ChildAt(index
))
143 return child
->PartitionData();
150 open_partition(partition_id partitionID
, int openMode
)
152 KDiskDeviceManager
* manager
= KDiskDeviceManager::Default();
153 KPartition
* partition
= manager
->FindPartition(partitionID
);
154 if (partition
== NULL
)
158 status_t result
= partition
->Open(openMode
, &fd
);
167 create_child_partition(partition_id partitionID
, int32 index
, off_t offset
,
168 off_t size
, partition_id childID
)
170 KDiskDeviceManager
* manager
= KDiskDeviceManager::Default();
171 if (KPartition
* partition
= manager
->FindPartition(partitionID
)) {
172 KPartition
* child
= NULL
;
173 if (partition
->CreateChild(childID
, index
, offset
, size
, &child
)
175 return child
->PartitionData();
177 DBG(OUT(" creating child (%" B_PRId32
", %" B_PRId32
") failed\n",
178 partitionID
, index
));
181 DBG(OUT(" partition %" B_PRId32
" not found\n", partitionID
));
188 delete_partition(partition_id partitionID
)
190 KDiskDeviceManager
* manager
= KDiskDeviceManager::Default();
191 if (KPartition
* partition
= manager
->FindPartition(partitionID
)) {
192 if (KPartition
* parent
= partition
->Parent())
193 return parent
->RemoveChild(partition
);
200 partition_modified(partition_id partitionID
)
207 scan_partition(partition_id partitionID
)
210 KDiskDeviceManager
* manager
= KDiskDeviceManager::Default();
211 KPartition
* partition
= manager
->RegisterPartition(partitionID
);
212 if (partition
== NULL
)
213 return B_ENTRY_NOT_FOUND
;
214 PartitionRegistrar
_(partition
, true);
217 return manager
->ScanPartition(partition
);
222 get_default_partition_content_name(partition_id partitionID
,
223 const char* fileSystemName
, char* buffer
, size_t bufferSize
)
225 KDiskDeviceManager
* manager
= KDiskDeviceManager::Default();
226 KPartition
* partition
= manager
->RegisterPartition(partitionID
);
227 if (partition
== NULL
)
228 return B_ENTRY_NOT_FOUND
;
230 double size
= partition
->ContentSize();
231 partition
->Unregister();
233 const char* const suffixes
[] = {
234 "", "K", "M", "G", "T", "P", "E", NULL
238 while (size
>= 1024 && suffixes
[index
+ 1]) {
243 // Our kernel snprintf() ignores the precision argument, so we manually
244 // do one digit precision.
245 uint64 result
= uint64(size
* 10 + 0.5);
247 snprintf(buffer
, bufferSize
, "%s Volume (%" B_PRId32
".%" B_PRId32
" %sB)",
248 fileSystemName
, int32(result
/ 10), int32(result
% 10), suffixes
[index
]);
255 find_disk_system(const char* name
)
257 KDiskDeviceManager
* manager
= KDiskDeviceManager::Default();
258 if (ManagerLocker locker
= manager
) {
259 if (KDiskSystem
* diskSystem
= manager
->FindDiskSystem(name
))
260 return diskSystem
->ID();
267 update_disk_device_job_progress(disk_job_id jobID
, float progress
)
270 KDiskDeviceManager
* manager
= KDiskDeviceManager::Default();
271 if (ManagerLocker locker
= manager
) {
272 if (KDiskDeviceJob
* job
= manager
->FindJob(jobID
)) {
273 job
->UpdateProgress(progress
);
283 update_disk_device_job_extra_progress(disk_job_id jobID
, const char* info
)
286 KDiskDeviceManager
* manager
= KDiskDeviceManager::Default();
287 if (ManagerLocker locker
= manager
) {
288 if (KDiskDeviceJob
* job
= manager
->FindJob(jobID
)) {
289 job
->UpdateExtraProgress(info
);
299 set_disk_device_job_error_message(disk_job_id jobID
, const char* message
)
302 KDiskDeviceManager
* manager
= KDiskDeviceManager::Default();
303 if (ManagerLocker locker
= manager
) {
304 if (KDiskDeviceJob
* job
= manager
->FindJob(jobID
)) {
305 job
->SetErrorMessage(message
);
315 update_disk_device_job_interrupt_properties(disk_job_id jobID
,
316 uint32 interruptProperties
)
320 KDiskDeviceManager
* manager
= KDiskDeviceManager::Default();
322 sem_id pauseSemaphore
= -1;
323 if (ManagerLocker locker
= manager
) {
324 // get the job and the respective job queue
325 if (KDiskDeviceJob
* job
= manager
->FindJob(jobID
)) {
326 if (KDiskDeviceJobQueue
* jobQueue
= job
->JobQueue()) {
327 // terminate if canceled.
328 if (jobQueue
->IsCanceled()) {
329 if (jobQueue
->ShallReverse())
330 return B_DISK_DEVICE_JOB_REVERSE
;
331 return B_DISK_DEVICE_JOB_CANCEL
;
333 // set the new interrupt properties only when not
334 // requested to pause
335 if (jobQueue
->IsPauseRequested())
336 pauseSemaphore
= jobQueue
->ReadyToPause();
338 job
->SetInterruptProperties(interruptProperties
);
342 // pause, if requested; redo the loop then
343 paused
= (pauseSemaphore
>= 0);
345 acquire_sem(pauseSemaphore
);
350 return B_DISK_DEVICE_JOB_CONTINUE
;