xref: /haiku/src/system/kernel/disk_device_manager/KPartitioningSystem.cpp (revision 508f54795f39c3e7552d87c95aae9dd8ec6f505b)
1 /*
2  * Copyright 2003-2007, 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 // CreateChild
417 //! Creates a child partition
418 status_t
419 KPartitioningSystem::CreateChild(KPartition* partition, off_t offset,
420 	off_t size, const char* type, const char* name, const char* parameters,
421 	disk_job_id job, KPartition** child, partition_id childID)
422 {
423 	// check parameters
424 	if (!partition || !type || !parameters || !child || !fModule)
425 		return B_BAD_VALUE;
426 	if (!fModule->create_child)
427 		return B_NOT_SUPPORTED;
428 
429 	// open partition device
430 	int fd = -1;
431 	status_t result = partition->Open(O_RDWR, &fd);
432 	if (result != B_OK)
433 		return result;
434 
435 	// let the module do its job
436 	result = fModule->create_child(fd, partition->ID(), offset, size,
437 		type, name, parameters, job, &childID);
438 
439 	// find and return the child
440 	*child = KDiskDeviceManager::Default()->FindPartition(childID);
441 
442 	// cleanup and return
443 	close(fd);
444 	return result;
445 }
446 
447 
448 // DeleteChild
449 //! Deletes a child partition
450 status_t
451 KPartitioningSystem::DeleteChild(KPartition* child, disk_job_id job)
452 {
453 	if (!child || !child->Parent())
454 		return B_BAD_VALUE;
455 	if (!fModule->delete_child)
456 		return B_NOT_SUPPORTED;
457 
458 	int fd = -1;
459 	KPartition* parent = child->Parent();
460 	status_t result = parent->Open(O_RDWR, &fd);
461 	if (result != B_OK)
462 		return result;
463 
464 	result = fModule->delete_child(fd, parent->ID(), child->ID(), job);
465 	close(fd);
466 	return result;
467 }
468 
469 
470 // LoadModule
471 status_t
472 KPartitioningSystem::LoadModule()
473 {
474 	if (fModule)		// shouldn't happen
475 		return B_OK;
476 	return get_module(Name(), (module_info**)&fModule);
477 }
478 
479 
480 // UnloadModule
481 void
482 KPartitioningSystem::UnloadModule()
483 {
484 	if (fModule) {
485 		put_module(fModule->module.name);
486 		fModule = NULL;
487 	}
488 }
489