headers/bsd: Add sys/queue.h.
[haiku.git] / src / system / kernel / disk_device_manager / disk_device_manager.cpp
blob421dc78f37a6dedac7c0e58d9a4eaa94c241c43f
1 /*
2 * Copyright 2003-2009, Ingo Weinhold, ingo_weinhold@gmx.de.
3 * Distributed under the terms of the MIT License.
4 */
7 #include "disk_device_manager.h"
9 #include <stdio.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"
20 // debugging
21 //#define DBG(x)
22 #define DBG(x) x
23 #define OUT dprintf
26 disk_device_data*
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.
35 device->Unregister();
37 return NULL;
41 void
42 write_unlock_disk_device(partition_id partitionID)
44 KDiskDeviceManager* manager = KDiskDeviceManager::Default();
45 if (KDiskDevice* device = manager->RegisterDevice(partitionID, false)) {
46 device->WriteUnlock();
47 device->Unregister();
49 device->Unregister();
54 disk_device_data*
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.
63 device->Unregister();
65 return NULL;
69 void
70 read_unlock_disk_device(partition_id partitionID)
72 KDiskDeviceManager* manager = KDiskDeviceManager::Default();
73 if (KDiskDevice* device = manager->RegisterDevice(partitionID, false)) {
74 device->ReadUnlock();
75 device->Unregister();
77 device->Unregister();
82 int32
83 find_disk_device(const char* path)
85 KDiskDeviceManager* manager = KDiskDeviceManager::Default();
86 partition_id id = -1;
87 if (KDiskDevice* device = manager->RegisterDevice(path)) {
88 id = device->ID();
89 device->Unregister();
91 return id;
95 int32
96 find_partition(const char* path)
98 KDiskDeviceManager* manager = KDiskDeviceManager::Default();
99 partition_id id = -1;
100 if (KPartition* partition = manager->RegisterPartition(path)) {
101 id = partition->ID();
102 partition->Unregister();
104 return id;
108 disk_device_data*
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);
117 partition_data*
118 get_partition(partition_id partitionID)
120 KDiskDeviceManager* manager = KDiskDeviceManager::Default();
121 KPartition* partition = manager->FindPartition(partitionID);
122 return (partition ? partition->PartitionData() : NULL);
126 partition_data*
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();
133 return NULL;
137 partition_data*
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();
145 return NULL;
150 open_partition(partition_id partitionID, int openMode)
152 KDiskDeviceManager* manager = KDiskDeviceManager::Default();
153 KPartition* partition = manager->FindPartition(partitionID);
154 if (partition == NULL)
155 return B_BAD_VALUE;
157 int fd = -1;
158 status_t result = partition->Open(openMode, &fd);
159 if (result != B_OK)
160 return -1;
162 return fd;
166 partition_data*
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)
174 == B_OK) {
175 return child->PartitionData();
176 } else {
177 DBG(OUT(" creating child (%" B_PRId32 ", %" B_PRId32 ") failed\n",
178 partitionID, index));
180 } else
181 DBG(OUT(" partition %" B_PRId32 " not found\n", partitionID));
183 return NULL;
187 bool
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);
195 return false;
199 void
200 partition_modified(partition_id partitionID)
202 // TODO: implemented
206 status_t
207 scan_partition(partition_id partitionID)
209 // get the partition
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);
216 // scan it
217 return manager->ScanPartition(partition);
221 status_t
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
237 int index = 0;
238 while (size >= 1024 && suffixes[index + 1]) {
239 size /= 1024;
240 index++;
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]);
250 return B_OK;
254 disk_system_id
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();
262 return -1;
266 bool
267 update_disk_device_job_progress(disk_job_id jobID, float progress)
269 #if 0
270 KDiskDeviceManager* manager = KDiskDeviceManager::Default();
271 if (ManagerLocker locker = manager) {
272 if (KDiskDeviceJob* job = manager->FindJob(jobID)) {
273 job->UpdateProgress(progress);
274 return true;
277 #endif
278 return false;
282 bool
283 update_disk_device_job_extra_progress(disk_job_id jobID, const char* info)
285 #if 0
286 KDiskDeviceManager* manager = KDiskDeviceManager::Default();
287 if (ManagerLocker locker = manager) {
288 if (KDiskDeviceJob* job = manager->FindJob(jobID)) {
289 job->UpdateExtraProgress(info);
290 return true;
293 #endif
294 return false;
298 bool
299 set_disk_device_job_error_message(disk_job_id jobID, const char* message)
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;
309 #endif
310 return false;
314 uint32
315 update_disk_device_job_interrupt_properties(disk_job_id jobID,
316 uint32 interruptProperties)
318 #if 0
319 bool paused = false;
320 KDiskDeviceManager* manager = KDiskDeviceManager::Default();
321 do {
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();
337 else
338 job->SetInterruptProperties(interruptProperties);
342 // pause, if requested; redo the loop then
343 paused = (pauseSemaphore >= 0);
344 if (paused) {
345 acquire_sem(pauseSemaphore);
346 pauseSemaphore = -1;
348 } while (paused);
349 #endif
350 return B_DISK_DEVICE_JOB_CONTINUE;