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 29 KPartitioningSystem::KPartitioningSystem(const char *name) 30 : KDiskSystem(name), 31 fModule(NULL) 32 { 33 } 34 35 36 // destructor 37 KPartitioningSystem::~KPartitioningSystem() 38 { 39 } 40 41 42 // Init 43 status_t 44 KPartitioningSystem::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 64 float 65 KPartitioningSystem::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 86 status_t 87 KPartitioningSystem::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 102 void 103 KPartitioningSystem::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 113 void 114 KPartitioningSystem::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 126 void 127 KPartitioningSystem::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 140 status_t 141 KPartitioningSystem::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 151 status_t 152 KPartitioningSystem::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 177 status_t 178 KPartitioningSystem::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 203 status_t 204 KPartitioningSystem::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 229 status_t 230 KPartitioningSystem::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 256 status_t 257 KPartitioningSystem::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 284 status_t 285 KPartitioningSystem::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 311 status_t 312 KPartitioningSystem::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->Parent()->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 339 status_t 340 KPartitioningSystem::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 367 status_t 368 KPartitioningSystem::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 395 status_t 396 KPartitioningSystem::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 421 status_t 422 KPartitioningSystem::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 448 status_t 449 KPartitioningSystem::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 480 status_t 481 KPartitioningSystem::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 501 status_t 502 KPartitioningSystem::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 511 void 512 KPartitioningSystem::UnloadModule() 513 { 514 if (fModule) { 515 put_module(fModule->module.name); 516 fModule = NULL; 517 } 518 } 519