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 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 81 status_t 82 KPartitioningSystem::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 97 void 98 KPartitioningSystem::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 108 void 109 KPartitioningSystem::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 121 void 122 KPartitioningSystem::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 135 status_t 136 KPartitioningSystem::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 146 status_t 147 KPartitioningSystem::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 172 status_t 173 KPartitioningSystem::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 198 status_t 199 KPartitioningSystem::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 224 status_t 225 KPartitioningSystem::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 251 status_t 252 KPartitioningSystem::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 279 status_t 280 KPartitioningSystem::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 306 status_t 307 KPartitioningSystem::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 334 status_t 335 KPartitioningSystem::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 362 status_t 363 KPartitioningSystem::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 390 status_t 391 KPartitioningSystem::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 416 status_t 417 KPartitioningSystem::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 443 status_t 444 KPartitioningSystem::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 475 status_t 476 KPartitioningSystem::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 496 status_t 497 KPartitioningSystem::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 506 void 507 KPartitioningSystem::UnloadModule() 508 { 509 if (fModule) { 510 put_module(fModule->module.name); 511 fModule = NULL; 512 } 513 } 514