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