1 /* 2 * Copyright 2003-2007, 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 // CreateChild 417 //! Creates a child partition 418 status_t 419 KPartitioningSystem::CreateChild(KPartition* partition, off_t offset, 420 off_t size, const char* type, const char* name, const char* parameters, 421 disk_job_id job, KPartition** child, partition_id childID) 422 { 423 // check parameters 424 if (!partition || !type || !parameters || !child || !fModule) 425 return B_BAD_VALUE; 426 if (!fModule->create_child) 427 return B_NOT_SUPPORTED; 428 429 // open partition device 430 int fd = -1; 431 status_t result = partition->Open(O_RDWR, &fd); 432 if (result != B_OK) 433 return result; 434 435 // let the module do its job 436 result = fModule->create_child(fd, partition->ID(), offset, size, 437 type, name, parameters, job, &childID); 438 439 // find and return the child 440 *child = KDiskDeviceManager::Default()->FindPartition(childID); 441 442 // cleanup and return 443 close(fd); 444 return result; 445 } 446 447 448 // DeleteChild 449 //! Deletes a child partition 450 status_t 451 KPartitioningSystem::DeleteChild(KPartition* child, disk_job_id job) 452 { 453 if (!child || !child->Parent()) 454 return B_BAD_VALUE; 455 if (!fModule->delete_child) 456 return B_NOT_SUPPORTED; 457 458 int fd = -1; 459 KPartition* parent = child->Parent(); 460 status_t result = parent->Open(O_RDWR, &fd); 461 if (result != B_OK) 462 return result; 463 464 result = fModule->delete_child(fd, parent->ID(), child->ID(), job); 465 close(fd); 466 return result; 467 } 468 469 470 // LoadModule 471 status_t 472 KPartitioningSystem::LoadModule() 473 { 474 if (fModule) // shouldn't happen 475 return B_OK; 476 return get_module(Name(), (module_info**)&fModule); 477 } 478 479 480 // UnloadModule 481 void 482 KPartitioningSystem::UnloadModule() 483 { 484 if (fModule) { 485 put_module(fModule->module.name); 486 fModule = NULL; 487 } 488 } 489