xref: /haiku/src/system/kernel/disk_device_manager/KPartitioningSystem.cpp (revision 820dca4df6c7bf955c46e8f6521b9408f50b2900)
1 /*
2  * Copyright 2003-2011, Haiku, Inc. All Rights Reserved.
3  * Distributed under the terms of the MIT License.
4  *
5  * Authors:
6  *		Ingo Weinhold <bonefish@cs.tu-berlin.de>
7  *		Lubos Kulic <lubos@radical.ed>
8  */
9 
10 /**	\file KPartitioningSystem.cpp
11  *
12  * 	\brief Implementation of \ref KPartitioningSystem class
13  */
14 
15 #include <fcntl.h>
16 #include <stdlib.h>
17 #include <unistd.h>
18 
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>
26 
27 
28 // constructor
29 KPartitioningSystem::KPartitioningSystem(const char *name)
30 	: KDiskSystem(name),
31 	  fModule(NULL)
32 {
33 }
34 
35 
36 // destructor
37 KPartitioningSystem::~KPartitioningSystem()
38 {
39 }
40 
41 
42 // Init
43 status_t
44 KPartitioningSystem::Init()
45 {
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);
55 
56 	SetFlags(fModule->flags & ~(uint32)B_DISK_SYSTEM_IS_FILE_SYSTEM);
57 	Unload();
58 	return error;
59 }
60 
61 
62 // Identify
63 //! Try to identify a given partition
64 float
65 KPartitioningSystem::Identify(KPartition *partition, void **cookie)
66 {
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 	float result = fModule->identify_partition(fd, partition->PartitionData(),
73 		cookie);
74 	close(fd);
75 	return result;
76 }
77 
78 
79 // Scan
80 //! Scan the partition
81 status_t
82 KPartitioningSystem::Scan(KPartition *partition, void *cookie)
83 {
84 	if (!partition || !fModule || !fModule->scan_partition)
85 		return B_ERROR;
86 	int fd = -1;
87 	status_t result = partition->Open(O_RDONLY, &fd);
88 	if (result != B_OK)
89 		return result;
90 	result = fModule->scan_partition(fd, partition->PartitionData(), cookie);
91 	close(fd);
92 	return result;
93 }
94 
95 
96 // FreeIdentifyCookie
97 void
98 KPartitioningSystem::FreeIdentifyCookie(KPartition *partition, void *cookie)
99 {
100 	if (!partition || !fModule || !fModule->free_identify_partition_cookie)
101 		return;
102 	fModule->free_identify_partition_cookie(partition->PartitionData(),
103 		cookie);
104 }
105 
106 
107 // FreeCookie
108 void
109 KPartitioningSystem::FreeCookie(KPartition *partition)
110 {
111 	if (!partition || !fModule || !fModule->free_partition_cookie
112 		|| partition->ParentDiskSystem() != this) {
113 		return;
114 	}
115 	fModule->free_partition_cookie(partition->PartitionData());
116 	partition->SetCookie(NULL);
117 }
118 
119 
120 // FreeContentCookie
121 void
122 KPartitioningSystem::FreeContentCookie(KPartition *partition)
123 {
124 	if (!partition || !fModule || !fModule->free_partition_content_cookie
125 		|| partition->DiskSystem() != this) {
126 		return;
127 	}
128 	fModule->free_partition_content_cookie(partition->PartitionData());
129 	partition->SetContentCookie(NULL);
130 }
131 
132 
133 // Repair
134 //! Repairs a partition
135 status_t
136 KPartitioningSystem::Repair(KPartition* partition, bool checkOnly,
137 	disk_job_id job)
138 {
139 	// to be implemented
140 	return B_ERROR;
141 }
142 
143 
144 // Resize
145 //! Resizes a partition
146 status_t
147 KPartitioningSystem::Resize(KPartition* partition, off_t size, disk_job_id job)
148 {
149 	// check parameters
150 	if (!partition || size < 0 || !fModule)
151 		return B_BAD_VALUE;
152 	if (!fModule->resize)
153 		return B_NOT_SUPPORTED;
154 
155 	// open partition device
156 	int fd = -1;
157 	status_t result = partition->Open(O_RDWR, &fd);
158 	if (result != B_OK)
159 		return result;
160 
161 	// let the module do its job
162 	result = fModule->resize(fd, partition->ID(), size, job);
163 
164 	// cleanup and return
165 	close(fd);
166 	return result;
167 }
168 
169 
170 // ResizeChild
171 //! Resizes child of a partition
172 status_t
173 KPartitioningSystem::ResizeChild(KPartition* child, off_t size, disk_job_id job)
174 {
175 	// check parameters
176 	if (!child || !child->Parent() || size < 0 || !fModule)
177 		return B_BAD_VALUE;
178 	if (!fModule->resize_child)
179 		return B_NOT_SUPPORTED;
180 
181 	// open partition device
182 	int fd = -1;
183 	status_t result = child->Parent()->Open(O_RDWR, &fd);
184 	if (result != B_OK)
185 		return result;
186 
187 	// let the module do its job
188 	result = fModule->resize_child(fd, child->ID(), size, job);
189 
190 	// cleanup and return
191 	close(fd);
192 	return result;
193 }
194 
195 
196 // Move
197 //! Moves a partition
198 status_t
199 KPartitioningSystem::Move(KPartition* partition, off_t offset, disk_job_id job)
200 {
201 	// check parameters
202 	if (!partition)
203 		return B_BAD_VALUE;
204 	if (!fModule->move)
205 		return B_NOT_SUPPORTED;
206 
207 	// open partition device
208 	int fd = -1;
209 	status_t result = partition->Open(O_RDWR, &fd);
210 	if (result != B_OK)
211 		return result;
212 
213 	// let the module do its job
214 	result = fModule->move(fd, partition->ID(), offset, job);
215 
216 	// cleanup and return
217 	close(fd);
218 	return result;
219 }
220 
221 
222 // MoveChild
223 //! Moves child of a partition
224 status_t
225 KPartitioningSystem::MoveChild(KPartition* child, off_t offset, disk_job_id job)
226 {
227 	// check parameters
228 	if (!child || !child->Parent() || !fModule)
229 		return B_BAD_VALUE;
230 	if (!fModule->move_child)
231 		return B_NOT_SUPPORTED;
232 
233 	// open partition device
234 	int fd = -1;
235 	status_t result = child->Parent()->Open(O_RDWR, &fd);
236 	if (result != B_OK)
237 		return result;
238 
239 	// let the module do its job
240 	result = fModule->move_child(fd, child->Parent()->ID(), child->ID(), offset,
241 		job);
242 
243 	// cleanup and return
244 	close(fd);
245 	return result;
246 }
247 
248 
249 // SetName
250 //! Sets name of a partition
251 status_t
252 KPartitioningSystem::SetName(KPartition* child, const char* name,
253 	disk_job_id job)
254 {
255 	// check parameters
256 	if (!child || !child->Parent() || !fModule)
257 		return B_BAD_VALUE;
258 	if (!fModule->set_name)
259 		return B_NOT_SUPPORTED;
260 
261 	// open partition device
262 	int fd = -1;
263 	status_t result = child->Parent()->Open(O_RDWR, &fd);
264 	if (result != B_OK)
265 		return result;
266 
267 	// let the module do its job
268 	result = fModule->set_name(fd, child->ID(), name, job);
269 // TODO: Change hook interface!
270 
271 	// cleanup and return
272 	close(fd);
273 	return result;
274 }
275 
276 
277 // SetContentName
278 //! Sets name of the content of a partition
279 status_t
280 KPartitioningSystem::SetContentName(KPartition* partition, const char* name,
281 	disk_job_id job)
282 {
283 	// check parameters
284 	if (!partition || !fModule)
285 		return B_BAD_VALUE;
286 	if (!fModule->set_content_name)
287 		return B_NOT_SUPPORTED;
288 
289 	// open partition device
290 	int fd = -1;
291 	status_t result = partition->Open(O_RDWR, &fd);
292 	if (result != B_OK)
293 		return result;
294 
295 	// let the module do its job
296 	result = fModule->set_content_name(fd, partition->ID(), name, job);
297 
298 	// cleanup and return
299 	close(fd);
300 	return result;
301 }
302 
303 
304 // SetType
305 //! Sets type of a partition
306 status_t
307 KPartitioningSystem::SetType(KPartition* child, const char* type,
308 	disk_job_id job)
309 {
310 	// check parameters
311 	if (!child || !child->Parent() || !type || !fModule)
312 		return B_BAD_VALUE;
313 	if (!fModule->set_type)
314 		return B_NOT_SUPPORTED;
315 
316 	// open partition device
317 	int fd = -1;
318 	status_t result = child->Parent()->Open(O_RDWR, &fd);
319 	if (result != B_OK)
320 		return result;
321 
322 	// let the module do its job
323 	result = fModule->set_type(fd, child->Parent()->ID(), type, job);
324 // TODO: Change hook interface!
325 
326 	// cleanup and return
327 	close(fd);
328 	return result;
329 }
330 
331 
332 // SetParameters
333 //! Sets parameters of a partition
334 status_t
335 KPartitioningSystem::SetParameters(KPartition* child, const char* parameters,
336 	disk_job_id job)
337 {
338 	// check parameters
339 	if (!child || !child->Parent() || !fModule)
340 		return B_BAD_VALUE;
341 	if (!fModule->set_parameters)
342 		return B_NOT_SUPPORTED;
343 
344 	// open partition device
345 	int fd = -1;
346 	status_t result = child->Parent()->Open(O_RDWR, &fd);
347 	if (result != B_OK)
348 		return result;
349 
350 	// let the module do its job
351 	result = fModule->set_parameters(fd, child->ID(), parameters, job);
352 // TODO: Change hook interface!
353 
354 	// cleanup and return
355 	close(fd);
356 	return result;
357 }
358 
359 
360 // SetContentParameters
361 //! Sets parameters of the content of a partition
362 status_t
363 KPartitioningSystem::SetContentParameters(KPartition* partition,
364 	const char* parameters, disk_job_id job)
365 {
366 	// check parameters
367 	if (!partition || !fModule)
368 		return B_BAD_VALUE;
369 	if (!fModule->set_content_parameters)
370 		return B_NOT_SUPPORTED;
371 
372 	// open partition device
373 	int fd = -1;
374 	status_t result = partition->Open(O_RDWR, &fd);
375 	if (result != B_OK)
376 		return result;
377 
378 	// let the module do its job
379 	result = fModule->set_content_parameters(fd, partition->ID(), parameters,
380 		job);
381 
382 	// cleanup and return
383 	close(fd);
384 	return result;
385 }
386 
387 
388 // Initialize
389 //! Initializes a partition with this partitioning system
390 status_t
391 KPartitioningSystem::Initialize(KPartition* partition, const char* name,
392 	const char* parameters, disk_job_id job)
393 {
394 	// check parameters
395 	if (!partition || !fModule)
396 		return B_BAD_VALUE;
397 	if (!fModule->initialize)
398 		return B_NOT_SUPPORTED;
399 
400 	// open partition device
401 	int fd = -1;
402 	status_t result = partition->Open(O_RDWR, &fd);
403 	if (result != B_OK)
404 		return result;
405 
406 	// let the module do its job
407 	result = fModule->initialize(fd, partition->ID(), name, parameters,
408 		partition->Size(), job);
409 
410 	// cleanup and return
411 	close(fd);
412 	return result;
413 }
414 
415 
416 status_t
417 KPartitioningSystem::Uninitialize(KPartition* partition, disk_job_id job)
418 {
419 	// check parameters
420 	if (partition == NULL || fModule == NULL)
421 		return B_BAD_VALUE;
422 	if (fModule->uninitialize == NULL)
423 		return B_NOT_SUPPORTED;
424 
425 	// open partition device
426 	int fd = -1;
427 	status_t result = partition->Open(O_RDWR, &fd);
428 	if (result != B_OK)
429 		return result;
430 
431 	// let the module do its job
432 	result = fModule->uninitialize(fd, partition->ID(), partition->Size(),
433 		partition->BlockSize(), job);
434 
435 	// cleanup and return
436 	close(fd);
437 	return result;
438 }
439 
440 
441 // CreateChild
442 //! Creates a child partition
443 status_t
444 KPartitioningSystem::CreateChild(KPartition* partition, off_t offset,
445 	off_t size, const char* type, const char* name, const char* parameters,
446 	disk_job_id job, KPartition** child, partition_id childID)
447 {
448 	// check parameters
449 	if (!partition || !type || !parameters || !child || !fModule)
450 		return B_BAD_VALUE;
451 	if (!fModule->create_child)
452 		return B_NOT_SUPPORTED;
453 
454 	// open partition device
455 	int fd = -1;
456 	status_t result = partition->Open(O_RDWR, &fd);
457 	if (result != B_OK)
458 		return result;
459 
460 	// let the module do its job
461 	result = fModule->create_child(fd, partition->ID(), offset, size,
462 		type, name, parameters, job, &childID);
463 
464 	// find and return the child
465 	*child = KDiskDeviceManager::Default()->FindPartition(childID);
466 
467 	// cleanup and return
468 	close(fd);
469 	return result;
470 }
471 
472 
473 // DeleteChild
474 //! Deletes a child partition
475 status_t
476 KPartitioningSystem::DeleteChild(KPartition* child, disk_job_id job)
477 {
478 	if (!child || !child->Parent())
479 		return B_BAD_VALUE;
480 	if (!fModule->delete_child)
481 		return B_NOT_SUPPORTED;
482 
483 	int fd = -1;
484 	KPartition* parent = child->Parent();
485 	status_t result = parent->Open(O_RDWR, &fd);
486 	if (result != B_OK)
487 		return result;
488 
489 	result = fModule->delete_child(fd, parent->ID(), child->ID(), job);
490 	close(fd);
491 	return result;
492 }
493 
494 
495 // LoadModule
496 status_t
497 KPartitioningSystem::LoadModule()
498 {
499 	if (fModule)		// shouldn't happen
500 		return B_OK;
501 	return get_module(Name(), (module_info**)&fModule);
502 }
503 
504 
505 // UnloadModule
506 void
507 KPartitioningSystem::UnloadModule()
508 {
509 	if (fModule) {
510 		put_module(fModule->module.name);
511 		fModule = NULL;
512 	}
513 }
514