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