headers/bsd: Add sys/queue.h.
[haiku.git] / src / system / kernel / disk_device_manager / KPartitioningSystem.cpp
blob4d350d57356aabb898b8650c5046250ffa5c7eee
1 /*
2 * Copyright 2003-2011, Haiku, Inc. All Rights Reserved.
3 * Distributed under the terms of the MIT License.
5 * Authors:
6 * Ingo Weinhold <bonefish@cs.tu-berlin.de>
7 * Lubos Kulic <lubos@radical.ed>
8 */
10 /** \file KPartitioningSystem.cpp
12 * \brief Implementation of \ref KPartitioningSystem class
15 #include <fcntl.h>
16 #include <stdlib.h>
17 #include <unistd.h>
19 #include <ddm_modules.h>
20 #include <KDiskDevice.h>
21 //#include <KDiskDeviceJob.h>
22 #include <KDiskDeviceManager.h>
23 #include <KDiskDeviceUtils.h>
24 #include <KPartition.h>
25 #include <KPartitioningSystem.h>
28 // constructor
29 KPartitioningSystem::KPartitioningSystem(const char *name)
30 : KDiskSystem(name),
31 fModule(NULL)
36 // destructor
37 KPartitioningSystem::~KPartitioningSystem()
42 // Init
43 status_t
44 KPartitioningSystem::Init()
46 status_t error = KDiskSystem::Init();
47 if (error != B_OK)
48 return error;
49 error = Load();
50 if (error != B_OK)
51 return error;
52 error = SetShortName(fModule->short_name);
53 if (error == B_OK)
54 error = SetPrettyName(fModule->pretty_name);
56 SetFlags(fModule->flags & ~(uint32)B_DISK_SYSTEM_IS_FILE_SYSTEM);
57 Unload();
58 return error;
62 // Identify
63 //! Try to identify a given partition
64 float
65 KPartitioningSystem::Identify(KPartition *partition, void **cookie)
67 if (!partition || !cookie || !fModule || !fModule->identify_partition)
68 return -1;
69 int fd = -1;
70 if (partition->Open(O_RDONLY, &fd) != B_OK)
71 return -1;
72 if (partition->BlockSize() == 0) {
73 close(fd);
74 return -1;
77 float result = fModule->identify_partition(fd, partition->PartitionData(),
78 cookie);
79 close(fd);
80 return result;
84 // Scan
85 //! Scan the partition
86 status_t
87 KPartitioningSystem::Scan(KPartition *partition, void *cookie)
89 if (!partition || !fModule || !fModule->scan_partition)
90 return B_ERROR;
91 int fd = -1;
92 status_t result = partition->Open(O_RDONLY, &fd);
93 if (result != B_OK)
94 return result;
95 result = fModule->scan_partition(fd, partition->PartitionData(), cookie);
96 close(fd);
97 return result;
101 // FreeIdentifyCookie
102 void
103 KPartitioningSystem::FreeIdentifyCookie(KPartition *partition, void *cookie)
105 if (!partition || !fModule || !fModule->free_identify_partition_cookie)
106 return;
107 fModule->free_identify_partition_cookie(partition->PartitionData(),
108 cookie);
112 // FreeCookie
113 void
114 KPartitioningSystem::FreeCookie(KPartition *partition)
116 if (!partition || !fModule || !fModule->free_partition_cookie
117 || partition->ParentDiskSystem() != this) {
118 return;
120 fModule->free_partition_cookie(partition->PartitionData());
121 partition->SetCookie(NULL);
125 // FreeContentCookie
126 void
127 KPartitioningSystem::FreeContentCookie(KPartition *partition)
129 if (!partition || !fModule || !fModule->free_partition_content_cookie
130 || partition->DiskSystem() != this) {
131 return;
133 fModule->free_partition_content_cookie(partition->PartitionData());
134 partition->SetContentCookie(NULL);
138 // Repair
139 //! Repairs a partition
140 status_t
141 KPartitioningSystem::Repair(KPartition* partition, bool checkOnly,
142 disk_job_id job)
144 // to be implemented
145 return B_ERROR;
149 // Resize
150 //! Resizes a partition
151 status_t
152 KPartitioningSystem::Resize(KPartition* partition, off_t size, disk_job_id job)
154 // check parameters
155 if (!partition || size < 0 || !fModule)
156 return B_BAD_VALUE;
157 if (!fModule->resize)
158 return B_NOT_SUPPORTED;
160 // open partition device
161 int fd = -1;
162 status_t result = partition->Open(O_RDWR, &fd);
163 if (result != B_OK)
164 return result;
166 // let the module do its job
167 result = fModule->resize(fd, partition->ID(), size, job);
169 // cleanup and return
170 close(fd);
171 return result;
175 // ResizeChild
176 //! Resizes child of a partition
177 status_t
178 KPartitioningSystem::ResizeChild(KPartition* child, off_t size, disk_job_id job)
180 // check parameters
181 if (!child || !child->Parent() || size < 0 || !fModule)
182 return B_BAD_VALUE;
183 if (!fModule->resize_child)
184 return B_NOT_SUPPORTED;
186 // open partition device
187 int fd = -1;
188 status_t result = child->Parent()->Open(O_RDWR, &fd);
189 if (result != B_OK)
190 return result;
192 // let the module do its job
193 result = fModule->resize_child(fd, child->ID(), size, job);
195 // cleanup and return
196 close(fd);
197 return result;
201 // Move
202 //! Moves a partition
203 status_t
204 KPartitioningSystem::Move(KPartition* partition, off_t offset, disk_job_id job)
206 // check parameters
207 if (!partition)
208 return B_BAD_VALUE;
209 if (!fModule->move)
210 return B_NOT_SUPPORTED;
212 // open partition device
213 int fd = -1;
214 status_t result = partition->Open(O_RDWR, &fd);
215 if (result != B_OK)
216 return result;
218 // let the module do its job
219 result = fModule->move(fd, partition->ID(), offset, job);
221 // cleanup and return
222 close(fd);
223 return result;
227 // MoveChild
228 //! Moves child of a partition
229 status_t
230 KPartitioningSystem::MoveChild(KPartition* child, off_t offset, disk_job_id job)
232 // check parameters
233 if (!child || !child->Parent() || !fModule)
234 return B_BAD_VALUE;
235 if (!fModule->move_child)
236 return B_NOT_SUPPORTED;
238 // open partition device
239 int fd = -1;
240 status_t result = child->Parent()->Open(O_RDWR, &fd);
241 if (result != B_OK)
242 return result;
244 // let the module do its job
245 result = fModule->move_child(fd, child->Parent()->ID(), child->ID(), offset,
246 job);
248 // cleanup and return
249 close(fd);
250 return result;
254 // SetName
255 //! Sets name of a partition
256 status_t
257 KPartitioningSystem::SetName(KPartition* child, const char* name,
258 disk_job_id job)
260 // check parameters
261 if (!child || !child->Parent() || !fModule)
262 return B_BAD_VALUE;
263 if (!fModule->set_name)
264 return B_NOT_SUPPORTED;
266 // open partition device
267 int fd = -1;
268 status_t result = child->Parent()->Open(O_RDWR, &fd);
269 if (result != B_OK)
270 return result;
272 // let the module do its job
273 result = fModule->set_name(fd, child->ID(), name, job);
274 // TODO: Change hook interface!
276 // cleanup and return
277 close(fd);
278 return result;
282 // SetContentName
283 //! Sets name of the content of a partition
284 status_t
285 KPartitioningSystem::SetContentName(KPartition* partition, const char* name,
286 disk_job_id job)
288 // check parameters
289 if (!partition || !fModule)
290 return B_BAD_VALUE;
291 if (!fModule->set_content_name)
292 return B_NOT_SUPPORTED;
294 // open partition device
295 int fd = -1;
296 status_t result = partition->Open(O_RDWR, &fd);
297 if (result != B_OK)
298 return result;
300 // let the module do its job
301 result = fModule->set_content_name(fd, partition->ID(), name, job);
303 // cleanup and return
304 close(fd);
305 return result;
309 // SetType
310 //! Sets type of a partition
311 status_t
312 KPartitioningSystem::SetType(KPartition* child, const char* type,
313 disk_job_id job)
315 // check parameters
316 if (!child || !child->Parent() || !type || !fModule)
317 return B_BAD_VALUE;
318 if (!fModule->set_type)
319 return B_NOT_SUPPORTED;
321 // open partition device
322 int fd = -1;
323 status_t result = child->Parent()->Open(O_RDWR, &fd);
324 if (result != B_OK)
325 return result;
327 // let the module do its job
328 result = fModule->set_type(fd, child->Parent()->ID(), type, job);
329 // TODO: Change hook interface!
331 // cleanup and return
332 close(fd);
333 return result;
337 // SetParameters
338 //! Sets parameters of a partition
339 status_t
340 KPartitioningSystem::SetParameters(KPartition* child, const char* parameters,
341 disk_job_id job)
343 // check parameters
344 if (!child || !child->Parent() || !fModule)
345 return B_BAD_VALUE;
346 if (!fModule->set_parameters)
347 return B_NOT_SUPPORTED;
349 // open partition device
350 int fd = -1;
351 status_t result = child->Parent()->Open(O_RDWR, &fd);
352 if (result != B_OK)
353 return result;
355 // let the module do its job
356 result = fModule->set_parameters(fd, child->ID(), parameters, job);
357 // TODO: Change hook interface!
359 // cleanup and return
360 close(fd);
361 return result;
365 // SetContentParameters
366 //! Sets parameters of the content of a partition
367 status_t
368 KPartitioningSystem::SetContentParameters(KPartition* partition,
369 const char* parameters, disk_job_id job)
371 // check parameters
372 if (!partition || !fModule)
373 return B_BAD_VALUE;
374 if (!fModule->set_content_parameters)
375 return B_NOT_SUPPORTED;
377 // open partition device
378 int fd = -1;
379 status_t result = partition->Open(O_RDWR, &fd);
380 if (result != B_OK)
381 return result;
383 // let the module do its job
384 result = fModule->set_content_parameters(fd, partition->ID(), parameters,
385 job);
387 // cleanup and return
388 close(fd);
389 return result;
393 // Initialize
394 //! Initializes a partition with this partitioning system
395 status_t
396 KPartitioningSystem::Initialize(KPartition* partition, const char* name,
397 const char* parameters, disk_job_id job)
399 // check parameters
400 if (!partition || !fModule)
401 return B_BAD_VALUE;
402 if (!fModule->initialize)
403 return B_NOT_SUPPORTED;
405 // open partition device
406 int fd = -1;
407 status_t result = partition->Open(O_RDWR, &fd);
408 if (result != B_OK)
409 return result;
411 // let the module do its job
412 result = fModule->initialize(fd, partition->ID(), name, parameters,
413 partition->Size(), job);
415 // cleanup and return
416 close(fd);
417 return result;
421 status_t
422 KPartitioningSystem::Uninitialize(KPartition* partition, disk_job_id job)
424 // check parameters
425 if (partition == NULL || fModule == NULL)
426 return B_BAD_VALUE;
427 if (fModule->uninitialize == NULL)
428 return B_NOT_SUPPORTED;
430 // open partition device
431 int fd = -1;
432 status_t result = partition->Open(O_RDWR, &fd);
433 if (result != B_OK)
434 return result;
436 // let the module do its job
437 result = fModule->uninitialize(fd, partition->ID(), partition->Size(),
438 partition->BlockSize(), job);
440 // cleanup and return
441 close(fd);
442 return result;
446 // CreateChild
447 //! Creates a child partition
448 status_t
449 KPartitioningSystem::CreateChild(KPartition* partition, off_t offset,
450 off_t size, const char* type, const char* name, const char* parameters,
451 disk_job_id job, KPartition** child, partition_id childID)
453 // check parameters
454 if (!partition || !type || !parameters || !child || !fModule)
455 return B_BAD_VALUE;
456 if (!fModule->create_child)
457 return B_NOT_SUPPORTED;
459 // open partition device
460 int fd = -1;
461 status_t result = partition->Open(O_RDWR, &fd);
462 if (result != B_OK)
463 return result;
465 // let the module do its job
466 result = fModule->create_child(fd, partition->ID(), offset, size,
467 type, name, parameters, job, &childID);
469 // find and return the child
470 *child = KDiskDeviceManager::Default()->FindPartition(childID);
472 // cleanup and return
473 close(fd);
474 return result;
478 // DeleteChild
479 //! Deletes a child partition
480 status_t
481 KPartitioningSystem::DeleteChild(KPartition* child, disk_job_id job)
483 if (!child || !child->Parent())
484 return B_BAD_VALUE;
485 if (!fModule->delete_child)
486 return B_NOT_SUPPORTED;
488 int fd = -1;
489 KPartition* parent = child->Parent();
490 status_t result = parent->Open(O_RDWR, &fd);
491 if (result != B_OK)
492 return result;
494 result = fModule->delete_child(fd, parent->ID(), child->ID(), job);
495 close(fd);
496 return result;
500 // LoadModule
501 status_t
502 KPartitioningSystem::LoadModule()
504 if (fModule) // shouldn't happen
505 return B_OK;
506 return get_module(Name(), (module_info**)&fModule);
510 // UnloadModule
511 void
512 KPartitioningSystem::UnloadModule()
514 if (fModule) {
515 put_module(fModule->module.name);
516 fModule = NULL;