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