Changes in uspace/lib/gpt/libgpt.c [9bdfde73:44c4886] in mainline
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/lib/gpt/libgpt.c
r9bdfde73 r44c4886 51 51 #include "libgpt.h" 52 52 53 static int load_and_check_header(service_id_t handle, aoff64_t addr, size_t b_size, gpt_header_t * header);53 static int load_and_check_header(service_id_t handle, aoff64_t addr, size_t b_size, gpt_header_t * header); 54 54 static gpt_partitions_t * alloc_part_array(uint32_t num); 55 static int extend_part_array(gpt_partitions_t * );56 static int reduce_part_array(gpt_partitions_t * );55 static int extend_part_array(gpt_partitions_t * p); 56 static int reduce_part_array(gpt_partitions_t * p); 57 57 static long long nearest_larger_int(double a); 58 static uint8_t get_byte(const char *); 59 static int check_overlap(gpt_part_t * p1, gpt_part_t * p2); 58 60 59 61 60 /** Allocate memory for gpt label */ … … 180 179 181 180 rc = block_init(EXCHANGE_ATOMIC, dev_handle, b_size); 182 if (rc != EOK && rc != EEXIST)181 if (rc != EOK) 183 182 return rc; 184 183 … … 291 290 292 291 /** Write GPT and partitions to device 293 * Note: also writes the header.294 292 * @param label label to write 295 293 * @param dev_handle device to write the data to … … 302 300 size_t b_size; 303 301 uint32_t e_size = uint32_t_le2host(label->gpt->header->entry_size); 304 size_t fill = label->parts->fill > GPT_MIN_PART_NUM ? label->parts->fill : GPT_MIN_PART_NUM; 305 302 306 303 label->gpt->header->pe_array_crc32 = compute_crc32( 307 304 (uint8_t *) label->parts->part_array, 308 fill * e_size);305 label->parts->fill * e_size); 309 306 310 307 /* comm_size of 4096 is ignored */ 311 308 rc = block_init(EXCHANGE_ATOMIC, dev_handle, 4096); 312 if (rc != EOK && rc != EEXIST)313 return rc; 314 309 if (rc != EOK) 310 return rc; 311 315 312 rc = block_get_bsize(dev_handle, &b_size); 316 313 if (rc != EOK) 317 314 goto fail; 318 319 aoff64_t n_blocks; 320 rc = block_get_nblocks(dev_handle, &n_blocks); 321 if (rc != EOK) 322 goto fail; 323 324 /* Write to backup GPT partition array location */ 325 //rc = block_write_direct(dev_handle, n_blocks - 1, GPT_HDR_BS, header->raw_data); 326 if (rc != EOK) 327 goto fail; 328 315 329 316 /* Write to main GPT partition array location */ 330 317 rc = block_write_direct(dev_handle, uint64_t_le2host(label->gpt->header->entry_lba), … … 333 320 if (rc != EOK) 334 321 goto fail; 335 322 323 aoff64_t n_blocks; 324 rc = block_get_nblocks(dev_handle, &n_blocks); 325 if (rc != EOK) 326 goto fail; 327 328 /* Write to backup GPT partition array location */ 329 //rc = block_write_direct(dev_handle, n_blocks - 1, GPT_HDR_BS, header->raw_data); 330 block_fini(dev_handle); 331 if (rc != EOK) 332 goto fail; 333 334 336 335 return gpt_write_header(label, dev_handle); 337 336 … … 348 347 * This returns a memory block (zero-filled) and needs gpt_add_partition() 349 348 * to be called to insert it into a partition array. 350 * Requires you to call gpt_free_partition after wards.349 * Requires you to call gpt_free_partition after use. 351 350 */ 352 351 gpt_part_t * gpt_alloc_partition(void) … … 368 367 * 369 368 * Note: use either gpt_alloc_partition or gpt_get_partition. 370 * This one return s a pointer to the first empty structure already371 * inside the array, so don't call gpt_add_partition() afterwards.369 * This one return a pointer to a structure already inside the array, so 370 * there's no need to call gpt_add_partition(). 372 371 * This is the one you will usually want. 373 372 */ 374 373 gpt_part_t * gpt_get_partition(gpt_label_t *label) 375 374 { 376 gpt_part_t *p; 377 378 /* Find the first empty entry */ 379 do { 380 if (label->parts->fill == label->parts->arr_size) { 381 if (extend_part_array(label->parts) == -1) 382 return NULL; 383 } 384 385 p = label->parts->part_array + label->parts->fill++; 386 387 } while (gpt_get_part_type(p) != GPT_PTE_UNUSED); 388 389 return p; 390 } 391 392 /** Get partition already inside the label 393 * 394 * @param label label to carrying the partition 395 * @param idx index of the partition 396 * 397 * @return returns pointer to the partition 398 * or NULL when out of range 399 * 400 * Note: For new partitions use either gpt_alloc_partition or 401 * gpt_get_partition unless you want a partition at a specific place. 402 * This returns a pointer to a structure already inside the array, 403 * so don't call gpt_add_partition() afterwards. 404 * This function is handy when you want to change already existing 405 * partition or to simply write somewhere in the middle. This works only 406 * for indexes smaller than either 128 or the actual number of filled 407 * entries. 408 */ 409 gpt_part_t * gpt_get_partition_at(gpt_label_t *label, size_t idx) 410 { 411 return NULL; 412 413 if (idx >= GPT_MIN_PART_NUM && idx >= label->parts->fill) 414 return NULL; 415 416 return label->parts->part_array + idx; 375 if (label->parts->fill == label->parts->arr_size) { 376 if (extend_part_array(label->parts) == -1) 377 return NULL; 378 } 379 380 return label->parts->part_array + label->parts->fill++; 417 381 } 418 382 … … 426 390 * Note: for use with gpt_alloc_partition() only. You will get 427 391 * duplicates with gpt_get_partition(). 428 * Note: does not call gpt_free_partition()!429 392 */ 430 393 int gpt_add_partition(gpt_label_t *label, gpt_part_t *partition) … … 435 398 } 436 399 437 /*FIXME:438 * Check dimensions and stuff! */439 gpt_part_foreach(label, p) {440 if (gpt_get_part_type(p) != GPT_PTE_UNUSED) {441 if (check_overlap(partition, p))442 return EINVAL;443 }444 }445 446 400 memcpy(label->parts->part_array + label->parts->fill++, 447 401 partition, sizeof(gpt_part_t)); 448 449 450 402 451 403 return EOK; … … 463 415 int gpt_remove_partition(gpt_label_t *label, size_t idx) 464 416 { 465 if (idx >= label->parts->fill) 466 return EINVAL; 467 468 /* FIXME! 469 * If we allow blank spots, we break the array. If we have more than 470 * 128 partitions in the array and then remove something from 471 * the first 128 partitions, we would forget to write the last one.*/ 472 memset(label->parts->part_array + idx, 0, sizeof(gpt_entry_t)); 473 474 label->parts->fill -= 1; 475 476 /* FIXME! HOPEFULLY FIXED. 477 * We cannot reduce the array so simply. We may have some partitions 478 * there since we allow blank spots. */ 479 gpt_part_t * p; 417 if (idx != label->parts->fill - 1) { 418 memmove(label->parts->part_array + idx, 419 label->parts->part_array + idx + 1, 420 (label->parts->fill - 1) * sizeof(gpt_entry_t)); 421 label->parts->fill -= 1; 422 } 423 424 /* FIXME: This probably shouldn't be here, but instead 425 * in reduce_part_array() or similar */ 480 426 if (label->parts->fill < (label->parts->arr_size / 2) - GPT_IGNORE_FILL_NUM) { 481 for (p = gpt_get_partition_at(label, label->parts->arr_size / 2);482 p < label->parts->part_array + label->parts->arr_size; ++p) {483 if (gpt_get_part_type(p) != GPT_PTE_UNUSED)484 return EOK;485 }486 487 427 if (reduce_part_array(label->parts) == ENOMEM) 488 428 return ENOMEM; … … 508 448 { 509 449 size_t i; 510 511 450 for (i = 0; gpt_ptypes[i].guid != NULL; i++) { 512 if (p->part_type[3] == get_byte(gpt_ptypes[i].guid +0) && 513 p->part_type[2] == get_byte(gpt_ptypes[i].guid +2) && 514 p->part_type[1] == get_byte(gpt_ptypes[i].guid +4) && 515 p->part_type[0] == get_byte(gpt_ptypes[i].guid +6) && 516 517 p->part_type[5] == get_byte(gpt_ptypes[i].guid +8) && 518 p->part_type[4] == get_byte(gpt_ptypes[i].guid +10) && 519 520 p->part_type[7] == get_byte(gpt_ptypes[i].guid +12) && 521 p->part_type[6] == get_byte(gpt_ptypes[i].guid +14) && 522 523 p->part_type[8] == get_byte(gpt_ptypes[i].guid +16) && 524 p->part_type[9] == get_byte(gpt_ptypes[i].guid +18) && 525 p->part_type[10] == get_byte(gpt_ptypes[i].guid +20) && 526 p->part_type[11] == get_byte(gpt_ptypes[i].guid +22) && 527 p->part_type[12] == get_byte(gpt_ptypes[i].guid +24) && 528 p->part_type[13] == get_byte(gpt_ptypes[i].guid +26) && 529 p->part_type[14] == get_byte(gpt_ptypes[i].guid +28) && 530 p->part_type[15] == get_byte(gpt_ptypes[i].guid +30)) 531 break; 532 } 533 451 if (bcmp(p->part_type, gpt_ptypes[i].guid, 16) == 0) { 452 break; 453 } 454 } 534 455 return i; 535 456 } … … 595 516 596 517 /** Copy partition name */ 597 void gpt_set_part_name(gpt_part_t * p, char *name, size_t length)518 void gpt_set_part_name(gpt_part_t * p, char * name[], size_t length) 598 519 { 599 520 if (length >= 72) … … 724 645 } 725 646 726 static uint8_t get_byte(const char * c) 727 { 728 uint8_t val = 0; 729 char hex[3] = {*c, *(c+1), 0}; 730 731 errno = str_uint8_t(hex, NULL, 16, false, &val); 732 return val; 733 } 734 735 static int check_overlap(gpt_part_t * p1, gpt_part_t * p2) 736 { 737 if (gpt_get_start_lba(p1) < gpt_get_start_lba(p2) && gpt_get_end_lba(p1) <= gpt_get_start_lba(p2)) { 738 return 0; 739 } else if (gpt_get_start_lba(p1) > gpt_get_start_lba(p2) && gpt_get_end_lba(p2) <= gpt_get_start_lba(p1)) { 740 return 0; 741 } 742 743 return 1; 744 } 745 746 647 648 649 650 651
Note:
See TracChangeset
for help on using the changeset viewer.