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