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