xref: /haiku/src/kits/storage/disk_device/PartitionDelegate.cpp (revision 1e60bdeab63fa7a57bc9a55b032052e95a18bd2c)
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 	// get the disk system add-on
404 	DiskSystemAddOnManager* manager = DiskSystemAddOnManager::Default();
405 	BDiskSystemAddOn* addOn = manager->GetAddOn(diskSystem);
406 	if (!addOn)
407 		return false;
408 
409 	bool result = addOn->CanInitialize(&fMutablePartition);
410 
411 	// put the add-on
412 	manager->PutAddOn(addOn);
413 
414 	return result;
415 }
416 
417 
418 // ValidateInitialize
419 status_t
420 BPartition::Delegate::ValidateInitialize(const char* diskSystem,
421 	BString* name, const char* parameters)
422 {
423 	// get the disk system add-on
424 	DiskSystemAddOnManager* manager = DiskSystemAddOnManager::Default();
425 	BDiskSystemAddOn* addOn = manager->GetAddOn(diskSystem);
426 	if (!addOn)
427 		return B_ENTRY_NOT_FOUND;
428 
429 	status_t result = addOn->ValidateInitialize(&fMutablePartition,
430 		name, parameters);
431 
432 	// put the add-on
433 	manager->PutAddOn(addOn);
434 
435 	return result;
436 }
437 
438 
439 // Initialize
440 status_t
441 BPartition::Delegate::Initialize(const char* diskSystem,
442 	const char* name, const char* parameters)
443 {
444 	// get the disk system add-on
445 	DiskSystemAddOnManager* manager = DiskSystemAddOnManager::Default();
446 	BDiskSystemAddOn* addOn = manager->GetAddOn(diskSystem);
447 	if (!addOn)
448 		return B_ENTRY_NOT_FOUND;
449 
450 	BPartitionHandle* handle;
451 	status_t result = addOn->Initialize(&fMutablePartition, name, parameters,
452 		&handle);
453 
454 	// keep the add-on or put it on error
455 	if (result == B_OK) {
456 		// TODO: This won't suffice. If this partition had children, we have
457 		// to delete them before the new disk system plays with it.
458 		_FreeHandle();
459 		fDiskSystem = addOn;
460 		fPartitionHandle = handle;
461 	} else {
462 		manager->PutAddOn(addOn);
463 	}
464 
465 	return result;
466 }
467 
468 
469 // Uninitialize
470 status_t
471 BPartition::Delegate::Uninitialize()
472 {
473 	if (fPartitionHandle) {
474 		_FreeHandle();
475 
476 		fMutablePartition.UninitializeContents();
477 	}
478 
479 	return B_OK;
480 }
481 
482 
483 // GetPartitioningInfo
484 status_t
485 BPartition::Delegate::GetPartitioningInfo(BPartitioningInfo* info)
486 {
487 	if (!fPartitionHandle)
488 		return B_NO_INIT;
489 
490 	return fPartitionHandle->GetPartitioningInfo(info);
491 }
492 
493 
494 // GetParameterEditor
495 status_t
496 BPartition::Delegate::GetParameterEditor(B_PARAMETER_EDITOR_TYPE type,
497 	BPartitionParameterEditor** editor) const
498 {
499 	if (!fPartitionHandle)
500 		return B_NO_INIT;
501 
502 	return fPartitionHandle->GetParameterEditor(type, editor);
503 }
504 
505 
506 // ValidateCreateChild
507 status_t
508 BPartition::Delegate::ValidateCreateChild(off_t* start, off_t* size,
509 	const char* type, BString* name, const char* parameters) const
510 {
511 	if (!fPartitionHandle)
512 		return B_NO_INIT;
513 
514 	return fPartitionHandle->ValidateCreateChild(start, size, type, name,
515 		parameters);
516 }
517 
518 
519 // CreateChild
520 status_t
521 BPartition::Delegate::CreateChild(off_t start, off_t size, const char* type,
522 	const char* name, const char* parameters, BPartition** child)
523 {
524 	if (!fPartitionHandle)
525 		return B_NO_INIT;
526 
527 	BMutablePartition* mutableChild;
528 	status_t error = fPartitionHandle->CreateChild(start, size, type, name,
529 		parameters, &mutableChild);
530 	if (error != B_OK)
531 		return error;
532 
533 	if (child)
534 		*child = mutableChild->GetDelegate()->Partition();
535 
536 	return B_OK;
537 }
538 
539 
540 // DeleteChild
541 status_t
542 BPartition::Delegate::DeleteChild(Delegate* child)
543 {
544 	if (!fPartitionHandle || !child)
545 		return B_NO_INIT;
546 
547 	return fPartitionHandle->DeleteChild(&child->fMutablePartition);
548 }
549 
550 
551 // _FreeHandle
552 void
553 BPartition::Delegate::_FreeHandle()
554 {
555 	if (fPartitionHandle) {
556 		delete fPartitionHandle;
557 		fPartitionHandle = NULL;
558 
559 		DiskSystemAddOnManager* manager = DiskSystemAddOnManager::Default();
560 		manager->PutAddOn(fDiskSystem);
561 		fDiskSystem = NULL;
562 	}
563 }
564