1/* 2 * Copyright 2003-2011, Haiku, Inc. All Rights Reserved. 3 * Distributed under the terms of the MIT License. 4 * 5 * Authors: 6 * Ingo Weinhold <bonefish@cs.tu-berlin.de> 7 * Lubos Kulic <lubos@radical.ed> 8 */ 9 10/** \file KPartitioningSystem.cpp 11 * 12 * \brief Implementation of \ref KPartitioningSystem class 13 */ 14 15#include <fcntl.h> 16#include <stdlib.h> 17#include <unistd.h> 18 19#include <ddm_modules.h> 20#include <KDiskDevice.h> 21//#include <KDiskDeviceJob.h> 22#include <KDiskDeviceManager.h> 23#include <KDiskDeviceUtils.h> 24#include <KPartition.h> 25#include <KPartitioningSystem.h> 26 27 28// constructor 29KPartitioningSystem::KPartitioningSystem(const char *name) 30 : KDiskSystem(name), 31 fModule(NULL) 32{ 33} 34 35 36// destructor 37KPartitioningSystem::~KPartitioningSystem() 38{ 39} 40 41 42// Init 43status_t 44KPartitioningSystem::Init() 45{ 46 status_t error = KDiskSystem::Init(); 47 if (error != B_OK) 48 return error; 49 error = Load(); 50 if (error != B_OK) 51 return error; 52 error = SetShortName(fModule->short_name); 53 if (error == B_OK) 54 error = SetPrettyName(fModule->pretty_name); 55 56 SetFlags(fModule->flags & ~(uint32)B_DISK_SYSTEM_IS_FILE_SYSTEM); 57 Unload(); 58 return error; 59} 60 61 62// Identify 63//! Try to identify a given partition 64float 65KPartitioningSystem::Identify(KPartition *partition, void **cookie) 66{ 67 if (!partition || !cookie || !fModule || !fModule->identify_partition) 68 return -1; 69 int fd = -1; 70 if (partition->Open(O_RDONLY, &fd) != B_OK) 71 return -1; 72 float result = fModule->identify_partition(fd, partition->PartitionData(), 73 cookie); 74 close(fd); 75 return result; 76} 77 78 79// Scan 80//! Scan the partition 81status_t 82KPartitioningSystem::Scan(KPartition *partition, void *cookie) 83{ 84 if (!partition || !fModule || !fModule->scan_partition) 85 return B_ERROR; 86 int fd = -1; 87 status_t result = partition->Open(O_RDONLY, &fd); 88 if (result != B_OK) 89 return result; 90 result = fModule->scan_partition(fd, partition->PartitionData(), cookie); 91 close(fd); 92 return result; 93} 94 95 96// FreeIdentifyCookie 97void 98KPartitioningSystem::FreeIdentifyCookie(KPartition *partition, void *cookie) 99{ 100 if (!partition || !fModule || !fModule->free_identify_partition_cookie) 101 return; 102 fModule->free_identify_partition_cookie(partition->PartitionData(), 103 cookie); 104} 105 106 107// FreeCookie 108void 109KPartitioningSystem::FreeCookie(KPartition *partition) 110{ 111 if (!partition || !fModule || !fModule->free_partition_cookie 112 || partition->ParentDiskSystem() != this) { 113 return; 114 } 115 fModule->free_partition_cookie(partition->PartitionData()); 116 partition->SetCookie(NULL); 117} 118 119 120// FreeContentCookie 121void 122KPartitioningSystem::FreeContentCookie(KPartition *partition) 123{ 124 if (!partition || !fModule || !fModule->free_partition_content_cookie 125 || partition->DiskSystem() != this) { 126 return; 127 } 128 fModule->free_partition_content_cookie(partition->PartitionData()); 129 partition->SetContentCookie(NULL); 130} 131 132 133// Repair 134//! Repairs a partition 135status_t 136KPartitioningSystem::Repair(KPartition* partition, bool checkOnly, 137 disk_job_id job) 138{ 139 // to be implemented 140 return B_ERROR; 141} 142 143 144// Resize 145//! Resizes a partition 146status_t 147KPartitioningSystem::Resize(KPartition* partition, off_t size, disk_job_id job) 148{ 149 // check parameters 150 if (!partition || size < 0 || !fModule) 151 return B_BAD_VALUE; 152 if (!fModule->resize) 153 return B_NOT_SUPPORTED; 154 155 // open partition device 156 int fd = -1; 157 status_t result = partition->Open(O_RDWR, &fd); 158 if (result != B_OK) 159 return result; 160 161 // let the module do its job 162 result = fModule->resize(fd, partition->ID(), size, job); 163 164 // cleanup and return 165 close(fd); 166 return result; 167} 168 169 170// ResizeChild 171//! Resizes child of a partition 172status_t 173KPartitioningSystem::ResizeChild(KPartition* child, off_t size, disk_job_id job) 174{ 175 // check parameters 176 if (!child || !child->Parent() || size < 0 || !fModule) 177 return B_BAD_VALUE; 178 if (!fModule->resize_child) 179 return B_NOT_SUPPORTED; 180 181 // open partition device 182 int fd = -1; 183 status_t result = child->Parent()->Open(O_RDWR, &fd); 184 if (result != B_OK) 185 return result; 186 187 // let the module do its job 188 result = fModule->resize_child(fd, child->ID(), size, job); 189 190 // cleanup and return 191 close(fd); 192 return result; 193} 194 195 196// Move 197//! Moves a partition 198status_t 199KPartitioningSystem::Move(KPartition* partition, off_t offset, disk_job_id job) 200{ 201 // check parameters 202 if (!partition) 203 return B_BAD_VALUE; 204 if (!fModule->move) 205 return B_NOT_SUPPORTED; 206 207 // open partition device 208 int fd = -1; 209 status_t result = partition->Open(O_RDWR, &fd); 210 if (result != B_OK) 211 return result; 212 213 // let the module do its job 214 result = fModule->move(fd, partition->ID(), offset, job); 215 216 // cleanup and return 217 close(fd); 218 return result; 219} 220 221 222// MoveChild 223//! Moves child of a partition 224status_t 225KPartitioningSystem::MoveChild(KPartition* child, off_t offset, disk_job_id job) 226{ 227 // check parameters 228 if (!child || !child->Parent() || !fModule) 229 return B_BAD_VALUE; 230 if (!fModule->move_child) 231 return B_NOT_SUPPORTED; 232 233 // open partition device 234 int fd = -1; 235 status_t result = child->Parent()->Open(O_RDWR, &fd); 236 if (result != B_OK) 237 return result; 238 239 // let the module do its job 240 result = fModule->move_child(fd, child->Parent()->ID(), child->ID(), offset, 241 job); 242 243 // cleanup and return 244 close(fd); 245 return result; 246} 247 248 249// SetName 250//! Sets name of a partition 251status_t 252KPartitioningSystem::SetName(KPartition* child, const char* name, 253 disk_job_id job) 254{ 255 // check parameters 256 if (!child || !child->Parent() || !fModule) 257 return B_BAD_VALUE; 258 if (!fModule->set_name) 259 return B_NOT_SUPPORTED; 260 261 // open partition device 262 int fd = -1; 263 status_t result = child->Parent()->Open(O_RDWR, &fd); 264 if (result != B_OK) 265 return result; 266 267 // let the module do its job 268 result = fModule->set_name(fd, child->ID(), name, job); 269// TODO: Change hook interface! 270 271 // cleanup and return 272 close(fd); 273 return result; 274} 275 276 277// SetContentName 278//! Sets name of the content of a partition 279status_t 280KPartitioningSystem::SetContentName(KPartition* partition, const char* name, 281 disk_job_id job) 282{ 283 // check parameters 284 if (!partition || !fModule) 285 return B_BAD_VALUE; 286 if (!fModule->set_content_name) 287 return B_NOT_SUPPORTED; 288 289 // open partition device 290 int fd = -1; 291 status_t result = partition->Open(O_RDWR, &fd); 292 if (result != B_OK) 293 return result; 294 295 // let the module do its job 296 result = fModule->set_content_name(fd, partition->ID(), name, job); 297 298 // cleanup and return 299 close(fd); 300 return result; 301} 302 303 304// SetType 305//! Sets type of a partition 306status_t 307KPartitioningSystem::SetType(KPartition* child, const char* type, 308 disk_job_id job) 309{ 310 // check parameters 311 if (!child || !child->Parent() || !type || !fModule) 312 return B_BAD_VALUE; 313 if (!fModule->set_type) 314 return B_NOT_SUPPORTED; 315 316 // open partition device 317 int fd = -1; 318 status_t result = child->Parent()->Open(O_RDWR, &fd); 319 if (result != B_OK) 320 return result; 321 322 // let the module do its job 323 result = fModule->set_type(fd, child->Parent()->ID(), type, job); 324// TODO: Change hook interface! 325 326 // cleanup and return 327 close(fd); 328 return result; 329} 330 331 332// SetParameters 333//! Sets parameters of a partition 334status_t 335KPartitioningSystem::SetParameters(KPartition* child, const char* parameters, 336 disk_job_id job) 337{ 338 // check parameters 339 if (!child || !child->Parent() || !fModule) 340 return B_BAD_VALUE; 341 if (!fModule->set_parameters) 342 return B_NOT_SUPPORTED; 343 344 // open partition device 345 int fd = -1; 346 status_t result = child->Parent()->Open(O_RDWR, &fd); 347 if (result != B_OK) 348 return result; 349 350 // let the module do its job 351 result = fModule->set_parameters(fd, child->ID(), parameters, job); 352// TODO: Change hook interface! 353 354 // cleanup and return 355 close(fd); 356 return result; 357} 358 359 360// SetContentParameters 361//! Sets parameters of the content of a partition 362status_t 363KPartitioningSystem::SetContentParameters(KPartition* partition, 364 const char* parameters, disk_job_id job) 365{ 366 // check parameters 367 if (!partition || !fModule) 368 return B_BAD_VALUE; 369 if (!fModule->set_content_parameters) 370 return B_NOT_SUPPORTED; 371 372 // open partition device 373 int fd = -1; 374 status_t result = partition->Open(O_RDWR, &fd); 375 if (result != B_OK) 376 return result; 377 378 // let the module do its job 379 result = fModule->set_content_parameters(fd, partition->ID(), parameters, 380 job); 381 382 // cleanup and return 383 close(fd); 384 return result; 385} 386 387 388// Initialize 389//! Initializes a partition with this partitioning system 390status_t 391KPartitioningSystem::Initialize(KPartition* partition, const char* name, 392 const char* parameters, disk_job_id job) 393{ 394 // check parameters 395 if (!partition || !fModule) 396 return B_BAD_VALUE; 397 if (!fModule->initialize) 398 return B_NOT_SUPPORTED; 399 400 // open partition device 401 int fd = -1; 402 status_t result = partition->Open(O_RDWR, &fd); 403 if (result != B_OK) 404 return result; 405 406 // let the module do its job 407 result = fModule->initialize(fd, partition->ID(), name, parameters, 408 partition->Size(), job); 409 410 // cleanup and return 411 close(fd); 412 return result; 413} 414 415 416status_t 417KPartitioningSystem::Uninitialize(KPartition* partition, disk_job_id job) 418{ 419 // check parameters 420 if (partition == NULL || fModule == NULL) 421 return B_BAD_VALUE; 422 if (fModule->uninitialize == NULL) 423 return B_NOT_SUPPORTED; 424 425 // open partition device 426 int fd = -1; 427 status_t result = partition->Open(O_RDWR, &fd); 428 if (result != B_OK) 429 return result; 430 431 // let the module do its job 432 result = fModule->uninitialize(fd, partition->ID(), partition->Size(), 433 partition->BlockSize(), job); 434 435 // cleanup and return 436 close(fd); 437 return result; 438} 439 440 441// CreateChild 442//! Creates a child partition 443status_t 444KPartitioningSystem::CreateChild(KPartition* partition, off_t offset, 445 off_t size, const char* type, const char* name, const char* parameters, 446 disk_job_id job, KPartition** child, partition_id childID) 447{ 448 // check parameters 449 if (!partition || !type || !parameters || !child || !fModule) 450 return B_BAD_VALUE; 451 if (!fModule->create_child) 452 return B_NOT_SUPPORTED; 453 454 // open partition device 455 int fd = -1; 456 status_t result = partition->Open(O_RDWR, &fd); 457 if (result != B_OK) 458 return result; 459 460 // let the module do its job 461 result = fModule->create_child(fd, partition->ID(), offset, size, 462 type, name, parameters, job, &childID); 463 464 // find and return the child 465 *child = KDiskDeviceManager::Default()->FindPartition(childID); 466 467 // cleanup and return 468 close(fd); 469 return result; 470} 471 472 473// DeleteChild 474//! Deletes a child partition 475status_t 476KPartitioningSystem::DeleteChild(KPartition* child, disk_job_id job) 477{ 478 if (!child || !child->Parent()) 479 return B_BAD_VALUE; 480 if (!fModule->delete_child) 481 return B_NOT_SUPPORTED; 482 483 int fd = -1; 484 KPartition* parent = child->Parent(); 485 status_t result = parent->Open(O_RDWR, &fd); 486 if (result != B_OK) 487 return result; 488 489 result = fModule->delete_child(fd, parent->ID(), child->ID(), job); 490 close(fd); 491 return result; 492} 493 494 495// LoadModule 496status_t 497KPartitioningSystem::LoadModule() 498{ 499 if (fModule) // shouldn't happen 500 return B_OK; 501 return get_module(Name(), (module_info**)&fModule); 502} 503 504 505// UnloadModule 506void 507KPartitioningSystem::UnloadModule() 508{ 509 if (fModule) { 510 put_module(fModule->module.name); 511 fModule = NULL; 512 } 513} 514