xref: /haiku/src/kits/storage/disk_device/PartitionDelegate.cpp (revision b30304acc8c37e678a1bf66976d15bdab103f931)
1 /*
2  * Copyright 2007, Ingo Weinhold, bonefish@users.sf.net.
3  * Distributed under the terms of the MIT License.
4  */
5 
6 #include "PartitionDelegate.h"
7 
8 #include <DiskSystemAddOn.h>
9 
10 #include "DiskSystemAddOnManager.h"
11 
12 
13 #undef TRACE
14 //#define TRACE(format...)
15 #define TRACE(format...)	printf(format)
16 
17 
18 // constructor
19 BPartition::Delegate::Delegate(BPartition* partition)
20 	: fPartition(partition),
21 	  fMutablePartition(this),
22 	  fDiskSystem(NULL),
23 	  fPartitionHandle(NULL)
24 {
25 }
26 
27 
28 // destructor
29 BPartition::Delegate::~Delegate()
30 {
31 }
32 
33 
34 // MutablePartition
35 BMutablePartition*
36 BPartition::Delegate::MutablePartition()
37 {
38 	return &fMutablePartition;
39 }
40 
41 
42 // MutablePartition
43 const BMutablePartition*
44 BPartition::Delegate::MutablePartition() const
45 {
46 	return &fMutablePartition;
47 }
48 
49 
50 // InitHierarchy
51 status_t
52 BPartition::Delegate::InitHierarchy(
53 	const user_partition_data* partitionData, Delegate* parent)
54 {
55 	return fMutablePartition.Init(partitionData,
56 		parent ? &parent->fMutablePartition : NULL);
57 }
58 
59 
60 // InitAfterHierarchy
61 status_t
62 BPartition::Delegate::InitAfterHierarchy()
63 {
64 	if (!fMutablePartition.ContentType())
65 		return B_OK;
66 
67 	// init disk system and handle
68 	DiskSystemAddOnManager* manager = DiskSystemAddOnManager::Default();
69 	BDiskSystemAddOn* addOn = manager->GetAddOn(
70 		fMutablePartition.ContentType());
71 	if (!addOn) {
72 		TRACE("BPartition::Delegate::InitAfterHierarchy(): add-on for disk "
73 			"system \"%s\" not found\n", fMutablePartition.ContentType());
74 		return B_ENTRY_NOT_FOUND;
75 	}
76 
77 	BPartitionHandle* handle;
78 	status_t error = addOn->CreatePartitionHandle(&fMutablePartition, &handle);
79 	if (error != B_OK) {
80 		TRACE("BPartition::Delegate::InitAfterHierarchy(): Failed to create "
81 			"partition handle for partition %ld, disk system: \"%s\": %s\n",
82 			Partition()->ID(), addOn->Name(), strerror(error));
83 		manager->PutAddOn(addOn);
84 		return error;
85 	}
86 
87 	// everything went fine -- keep the disk system add-on reference and the
88 	// handle
89 	fDiskSystem = addOn;
90 	fPartitionHandle = handle;
91 
92 	return B_OK;
93 }
94 
95 
96 // PartitionData
97 const user_partition_data*
98 BPartition::Delegate::PartitionData() const
99 {
100 	return fMutablePartition.PartitionData();
101 }
102 
103 
104 // ChildAt
105 BPartition::Delegate*
106 BPartition::Delegate::ChildAt(int32 index) const
107 {
108 	BMutablePartition* child = fMutablePartition.ChildAt(index);
109 	return child ? child->GetDelegate() : NULL;
110 }
111 
112 
113 // CountChildren
114 int32
115 BPartition::Delegate::CountChildren() const
116 {
117 	return fMutablePartition.CountChildren();
118 }
119 
120 
121 // IsModified
122 bool
123 BPartition::Delegate::IsModified() const
124 {
125 	return fMutablePartition.ChangeFlags() != 0;
126 }
127 
128 
129 // SupportedOperations
130 uint32
131 BPartition::Delegate::SupportedOperations(uint32 mask)
132 {
133 	if (!fPartitionHandle)
134 		return 0;
135 
136 	return fPartitionHandle->SupportedOperations(mask);
137 }
138 
139 
140 // SupportedChildOperations
141 uint32
142 BPartition::Delegate::SupportedChildOperations(Delegate* child,
143 	uint32 mask)
144 {
145 	if (!fPartitionHandle)
146 		return 0;
147 
148 	return fPartitionHandle->SupportedChildOperations(child->MutablePartition(),
149 		mask);
150 }
151 
152 
153 // Defragment
154 status_t
155 BPartition::Delegate::Defragment()
156 {
157 // TODO: Implement!
158 	return B_BAD_VALUE;
159 }
160 
161 
162 // Repair
163 status_t
164 BPartition::Delegate::Repair(bool checkOnly)
165 {
166 // TODO: Implement!
167 	return B_BAD_VALUE;
168 }
169 
170 
171 // ValidateResize
172 status_t
173 BPartition::Delegate::ValidateResize(off_t* size) const
174 {
175 	if (!fPartitionHandle)
176 		return B_NO_INIT;
177 
178 	return fPartitionHandle->ValidateResize(size);
179 }
180 
181 
182 // ValidateResizeChild
183 status_t
184 BPartition::Delegate::ValidateResizeChild(Delegate* child, off_t* size) const
185 {
186 	if (!fPartitionHandle || !child)
187 		return B_NO_INIT;
188 
189 	return fPartitionHandle->ValidateResizeChild(&child->fMutablePartition,
190 		size);
191 }
192 
193 
194 // Resize
195 status_t
196 BPartition::Delegate::Resize(off_t size)
197 {
198 	if (!fPartitionHandle)
199 		return B_NO_INIT;
200 
201 	return fPartitionHandle->Resize(size);
202 }
203 
204 
205 // ResizeChild
206 status_t
207 BPartition::Delegate::ResizeChild(Delegate* child, off_t size)
208 {
209 	if (!fPartitionHandle || !child)
210 		return B_NO_INIT;
211 
212 	return fPartitionHandle->ResizeChild(&child->fMutablePartition, size);
213 }
214 
215 
216 // ValidateMove
217 status_t
218 BPartition::Delegate::ValidateMove(off_t* offset) const
219 {
220 	if (!fPartitionHandle)
221 		return B_NO_INIT;
222 
223 	return fPartitionHandle->ValidateMove(offset);
224 }
225 
226 
227 // ValidateMoveChild
228 status_t
229 BPartition::Delegate::ValidateMoveChild(Delegate* child, off_t* offset) const
230 {
231 	if (!fPartitionHandle || !child)
232 		return B_NO_INIT;
233 
234 	return fPartitionHandle->ValidateMoveChild(&child->fMutablePartition,
235 		offset);
236 }
237 
238 
239 // Move
240 status_t
241 BPartition::Delegate::Move(off_t offset)
242 {
243 	if (!fPartitionHandle)
244 		return B_NO_INIT;
245 
246 	return fPartitionHandle->Move(offset);
247 }
248 
249 
250 // MoveChild
251 status_t
252 BPartition::Delegate::MoveChild(Delegate* child, off_t offset)
253 {
254 	if (!fPartitionHandle || !child)
255 		return B_NO_INIT;
256 
257 	return fPartitionHandle->MoveChild(&child->fMutablePartition, offset);
258 }
259 
260 
261 // ValidateSetContentName
262 status_t
263 BPartition::Delegate::ValidateSetContentName(BString* name) const
264 {
265 	if (!fPartitionHandle)
266 		return B_NO_INIT;
267 
268 	return fPartitionHandle->ValidateSetContentName(name);
269 }
270 
271 
272 // ValidateSetName
273 status_t
274 BPartition::Delegate::ValidateSetName(Delegate* child, BString* name) const
275 {
276 	if (!fPartitionHandle || !child)
277 		return B_NO_INIT;
278 
279 	return fPartitionHandle->ValidateSetName(&child->fMutablePartition, name);
280 }
281 
282 
283 // SetContentName
284 status_t
285 BPartition::Delegate::SetContentName(const char* name)
286 {
287 	if (!fPartitionHandle)
288 		return B_NO_INIT;
289 
290 	return fPartitionHandle->SetContentName(name);
291 }
292 
293 
294 // SetName
295 status_t
296 BPartition::Delegate::SetName(Delegate* child, const char* name)
297 {
298 	if (!fPartitionHandle || !child)
299 		return B_NO_INIT;
300 
301 	return fPartitionHandle->SetName(&child->fMutablePartition, name);
302 }
303 
304 
305 // ValidateSetType
306 status_t
307 BPartition::Delegate::ValidateSetType(Delegate* child, const char* type) const
308 {
309 	if (!fPartitionHandle || !child)
310 		return B_NO_INIT;
311 
312 	return fPartitionHandle->ValidateSetType(&child->fMutablePartition, type);
313 }
314 
315 
316 // SetType
317 status_t
318 BPartition::Delegate::SetType(Delegate* child, const char* type)
319 {
320 	if (!fPartitionHandle || !child)
321 		return B_NO_INIT;
322 
323 	return fPartitionHandle->SetType(&child->fMutablePartition, type);
324 }
325 
326 
327 // GetContentParameterEditor
328 status_t
329 BPartition::Delegate::GetContentParameterEditor(
330 	BDiskDeviceParameterEditor** editor) const
331 {
332 	if (!fPartitionHandle)
333 		return B_NO_INIT;
334 
335 	return fPartitionHandle->GetContentParameterEditor(editor);
336 }
337 
338 
339 // GetParameterEditor
340 status_t
341 BPartition::Delegate::GetParameterEditor(Delegate* child,
342 	BDiskDeviceParameterEditor** editor) const
343 {
344 	if (!fPartitionHandle || !child)
345 		return B_NO_INIT;
346 
347 	return fPartitionHandle->GetParameterEditor(&child->fMutablePartition,
348 		editor);
349 }
350 
351 
352 // SetContentParameters
353 status_t
354 BPartition::Delegate::SetContentParameters(const char* parameters)
355 {
356 	if (!fPartitionHandle)
357 		return B_NO_INIT;
358 
359 	return fPartitionHandle->SetContentParameters(parameters);
360 }
361 
362 
363 // SetParameters
364 status_t
365 BPartition::Delegate::SetParameters(Delegate* child, const char* parameters)
366 {
367 	if (!fPartitionHandle || !child)
368 		return B_NO_INIT;
369 
370 	return fPartitionHandle->SetParameters(&child->fMutablePartition,
371 		parameters);
372 }
373 
374 
375 // GetNextSupportedChildType
376 status_t
377 BPartition::Delegate::GetNextSupportedChildType(Delegate* child, int32 *cookie,
378 	BString* type) const
379 {
380 	if (!fPartitionHandle)
381 		return B_NO_INIT;
382 
383 	return fPartitionHandle->GetNextSupportedType(
384 		child ? &child->fMutablePartition : NULL, cookie, type);
385 }
386 
387 
388 // IsSubSystem
389 bool
390 BPartition::Delegate::IsSubSystem(Delegate* child, const char* diskSystem) const
391 {
392 	// get the disk system add-on
393 	DiskSystemAddOnManager* manager = DiskSystemAddOnManager::Default();
394 	BDiskSystemAddOn* addOn = manager->GetAddOn(diskSystem);
395 	if (!addOn)
396 		return false;
397 
398 	bool result = addOn->IsSubSystemFor(&child->fMutablePartition);
399 
400 	// put the add-on
401 	manager->PutAddOn(addOn);
402 
403 	return result;
404 }
405 
406 
407 // CanInitialize
408 bool
409 BPartition::Delegate::CanInitialize(const char* diskSystem) const
410 {
411 	// get the disk system add-on
412 	DiskSystemAddOnManager* manager = DiskSystemAddOnManager::Default();
413 	BDiskSystemAddOn* addOn = manager->GetAddOn(diskSystem);
414 	if (!addOn)
415 		return false;
416 
417 	bool result = addOn->CanInitialize(&fMutablePartition);
418 
419 	// put the add-on
420 	manager->PutAddOn(addOn);
421 
422 	return result;
423 }
424 
425 
426 // GetInitializationParameterEditor
427 status_t
428 BPartition::Delegate::GetInitializationParameterEditor(
429 	const char* diskSystem, BDiskDeviceParameterEditor** editor) const
430 {
431 	// get the disk system add-on
432 	DiskSystemAddOnManager* manager = DiskSystemAddOnManager::Default();
433 	BDiskSystemAddOn* addOn = manager->GetAddOn(diskSystem);
434 	if (!addOn)
435 		return B_ENTRY_NOT_FOUND;
436 
437 	status_t result = addOn->GetInitializationParameterEditor(
438 		&fMutablePartition, editor);
439 
440 	// put the add-on
441 	manager->PutAddOn(addOn);
442 
443 	return result;
444 }
445 
446 
447 // ValidateInitialize
448 status_t
449 BPartition::Delegate::ValidateInitialize(const char* diskSystem,
450 	BString* name, const char* parameters)
451 {
452 	// get the disk system add-on
453 	DiskSystemAddOnManager* manager = DiskSystemAddOnManager::Default();
454 	BDiskSystemAddOn* addOn = manager->GetAddOn(diskSystem);
455 	if (!addOn)
456 		return B_ENTRY_NOT_FOUND;
457 
458 	status_t result = addOn->ValidateInitialize(&fMutablePartition,
459 		name, parameters);
460 
461 	// put the add-on
462 	manager->PutAddOn(addOn);
463 
464 	return result;
465 }
466 
467 
468 // Initialize
469 status_t
470 BPartition::Delegate::Initialize(const char* diskSystem,
471 	const char* name, const char* parameters)
472 {
473 	// get the disk system add-on
474 	DiskSystemAddOnManager* manager = DiskSystemAddOnManager::Default();
475 	BDiskSystemAddOn* addOn = manager->GetAddOn(diskSystem);
476 	if (!addOn)
477 		return B_ENTRY_NOT_FOUND;
478 
479 	BPartitionHandle* handle;
480 	status_t result = addOn->Initialize(&fMutablePartition, name, parameters,
481 		&handle);
482 
483 	// keep the add-on or put it on error
484 	if (result == B_OK) {
485 		// TODO: This won't suffice. If this partition had children, we have
486 		// to delete them before the new disk system plays with it.
487 		_FreeHandle();
488 		fDiskSystem = addOn;
489 		fPartitionHandle = handle;
490 	} else {
491 		manager->PutAddOn(addOn);
492 	}
493 
494 	return result;
495 }
496 
497 
498 // Uninitialize
499 status_t
500 BPartition::Delegate::Uninitialize()
501 {
502 	if (fPartitionHandle) {
503 		_FreeHandle();
504 
505 		fMutablePartition.UninitializeContents();
506 	}
507 
508 	return B_OK;
509 }
510 
511 
512 // GetPartitioningInfo
513 status_t
514 BPartition::Delegate::GetPartitioningInfo(BPartitioningInfo* info)
515 {
516 	if (!fPartitionHandle)
517 		return B_NO_INIT;
518 
519 	return fPartitionHandle->GetPartitioningInfo(info);
520 }
521 
522 
523 // GetChildCreationParameterEditor
524 status_t
525 BPartition::Delegate::GetChildCreationParameterEditor(const char* type,
526 	BDiskDeviceParameterEditor** editor) const
527 {
528 	if (!fPartitionHandle)
529 		return B_NO_INIT;
530 
531 	return fPartitionHandle->GetChildCreationParameterEditor(type, editor);
532 }
533 
534 
535 // ValidateCreateChild
536 status_t
537 BPartition::Delegate::ValidateCreateChild(off_t* start, off_t* size,
538 	const char* type, BString* name, const char* parameters) const
539 {
540 	if (!fPartitionHandle)
541 		return B_NO_INIT;
542 
543 	return fPartitionHandle->ValidateCreateChild(start, size, type, name,
544 		parameters);
545 }
546 
547 
548 // CreateChild
549 status_t
550 BPartition::Delegate::CreateChild(off_t start, off_t size, const char* type,
551 	const char* name, const char* parameters, BPartition** child)
552 {
553 	if (!fPartitionHandle)
554 		return B_NO_INIT;
555 
556 	BMutablePartition* mutableChild;
557 	status_t error = fPartitionHandle->CreateChild(start, size, type, name,
558 		parameters, &mutableChild);
559 	if (error != B_OK)
560 		return error;
561 
562 	if (child)
563 		*child = mutableChild->GetDelegate()->Partition();
564 
565 	return B_OK;
566 }
567 
568 
569 // DeleteChild
570 status_t
571 BPartition::Delegate::DeleteChild(Delegate* child)
572 {
573 	if (!fPartitionHandle || !child)
574 		return B_NO_INIT;
575 
576 	return fPartitionHandle->DeleteChild(&child->fMutablePartition);
577 }
578 
579 
580 // _FreeHandle
581 void
582 BPartition::Delegate::_FreeHandle()
583 {
584 	if (fPartitionHandle) {
585 		delete fPartitionHandle;
586 		fPartitionHandle = NULL;
587 
588 		DiskSystemAddOnManager* manager = DiskSystemAddOnManager::Default();
589 		manager->PutAddOn(fDiskSystem);
590 		fDiskSystem = NULL;
591 	}
592 }
593