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