Changeset 52f2c89 in mainline for uspace/lib/gpt/libgpt.c
- Timestamp:
- 2013-06-24T22:29:44Z (11 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- 9bdfde73
- Parents:
- 44c4886 (diff), 6317b33 (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the(diff)
links above to see all the changes relative to each parent. - File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/lib/gpt/libgpt.c
r44c4886 r52f2c89 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 * 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 * p);56 static int reduce_part_array(gpt_partitions_t * p);55 static int extend_part_array(gpt_partitions_t *); 56 static int reduce_part_array(gpt_partitions_t *); 57 57 static long long nearest_larger_int(double a); 58 58 static uint8_t get_byte(const char *); 59 59 60 60 /** Allocate memory for gpt label */ … … 179 179 180 180 rc = block_init(EXCHANGE_ATOMIC, dev_handle, b_size); 181 if (rc != EOK )181 if (rc != EOK && rc != EEXIST) 182 182 return rc; 183 183 … … 300 300 size_t b_size; 301 301 uint32_t e_size = uint32_t_le2host(label->gpt->header->entry_size); 302 302 size_t fill = label->parts->fill > GPT_MIN_PART_NUM ? label->parts->fill : GPT_MIN_PART_NUM; 303 303 304 label->gpt->header->pe_array_crc32 = compute_crc32( 304 305 (uint8_t *) label->parts->part_array, 305 label->parts->fill * e_size);306 fill * e_size); 306 307 307 308 /* comm_size of 4096 is ignored */ 308 309 rc = block_init(EXCHANGE_ATOMIC, dev_handle, 4096); 309 if (rc != EOK )310 return rc; 311 310 if (rc != EOK && rc != EEXIST) 311 return rc; 312 312 313 rc = block_get_bsize(dev_handle, &b_size); 313 314 if (rc != EOK) 314 315 goto fail; 315 316 317 aoff64_t n_blocks; 318 rc = block_get_nblocks(dev_handle, &n_blocks); 319 if (rc != EOK) 320 goto fail; 321 322 /* Write to backup GPT partition array location */ 323 //rc = block_write_direct(dev_handle, n_blocks - 1, GPT_HDR_BS, header->raw_data); 324 if (rc != EOK) 325 goto fail; 326 316 327 /* Write to main GPT partition array location */ 317 328 rc = block_write_direct(dev_handle, uint64_t_le2host(label->gpt->header->entry_lba), … … 320 331 if (rc != EOK) 321 332 goto fail; 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 333 335 334 return gpt_write_header(label, dev_handle); 336 335 … … 347 346 * This returns a memory block (zero-filled) and needs gpt_add_partition() 348 347 * to be called to insert it into a partition array. 349 * Requires you to call gpt_free_partition after use.348 * Requires you to call gpt_free_partition afterwards. 350 349 */ 351 350 gpt_part_t * gpt_alloc_partition(void) … … 367 366 * 368 367 * Note: use either gpt_alloc_partition or gpt_get_partition. 369 * This one return a pointer to a structure already inside the array, so370 * there's no need to call gpt_add_partition().368 * This one returns a pointer to the first empty structure already 369 * inside the array, so don't call gpt_add_partition() afterwards. 371 370 * This is the one you will usually want. 372 371 */ 373 372 gpt_part_t * gpt_get_partition(gpt_label_t *label) 374 373 { 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++; 374 gpt_part_t *p; 375 376 /* Find the first empty entry */ 377 do { 378 if (label->parts->fill == label->parts->arr_size) { 379 if (extend_part_array(label->parts) == -1) 380 return NULL; 381 } 382 383 p = label->parts->part_array + label->parts->fill++; 384 385 } while (gpt_get_part_type(p) != GPT_PTE_UNUSED); 386 387 return p; 388 } 389 390 /** Get partition already inside the label 391 * 392 * @param label label to carrying the partition 393 * @param idx index of the partition 394 * 395 * @return returns pointer to the partition 396 * or NULL when out of range 397 * 398 * Note: For new partitions use either gpt_alloc_partition or 399 * gpt_get_partition unless you want a partition at a specific place. 400 * This returns a pointer to a structure already inside the array, 401 * so don't call gpt_add_partition() afterwards. 402 * This function is handy when you want to change already existing 403 * partition or to simply write somewhere in the middle. This works only 404 * for indexes smaller than either 128 or the actual number of filled 405 * entries. 406 */ 407 gpt_part_t * gpt_get_partition_at(gpt_label_t *label, size_t idx) 408 { 409 return NULL; 410 411 if (idx >= GPT_MIN_PART_NUM && idx >= label->parts->fill) 412 return NULL; 413 414 return label->parts->part_array + idx; 381 415 } 382 416 … … 415 449 int gpt_remove_partition(gpt_label_t *label, size_t idx) 416 450 { 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 */ 451 if (idx >= label->parts->fill) 452 return EINVAL; 453 454 /* FIXME! 455 * If we allow blank spots, we break the array. If we have more than 456 * 128 partitions in the array and then remove something from 457 * the first 128 partitions, we would forget to write the last one.*/ 458 memset(label->parts->part_array + idx, 0, sizeof(gpt_entry_t)); 459 460 label->parts->fill -= 1; 461 462 /* FIXME! 463 * We cannot reduce the array so simply. We may have some partitions 464 * there since we allow blank spots.*/ 426 465 if (label->parts->fill < (label->parts->arr_size / 2) - GPT_IGNORE_FILL_NUM) { 427 466 if (reduce_part_array(label->parts) == ENOMEM) … … 448 487 { 449 488 size_t i; 489 450 490 for (i = 0; gpt_ptypes[i].guid != NULL; i++) { 451 if (bcmp(p->part_type, gpt_ptypes[i].guid, 16) == 0) { 452 break; 453 } 454 } 491 if (p->part_type[3] == get_byte(gpt_ptypes[i].guid +0) && 492 p->part_type[2] == get_byte(gpt_ptypes[i].guid +2) && 493 p->part_type[1] == get_byte(gpt_ptypes[i].guid +4) && 494 p->part_type[0] == get_byte(gpt_ptypes[i].guid +6) && 495 496 p->part_type[5] == get_byte(gpt_ptypes[i].guid +8) && 497 p->part_type[4] == get_byte(gpt_ptypes[i].guid +10) && 498 499 p->part_type[7] == get_byte(gpt_ptypes[i].guid +12) && 500 p->part_type[6] == get_byte(gpt_ptypes[i].guid +14) && 501 502 p->part_type[8] == get_byte(gpt_ptypes[i].guid +16) && 503 p->part_type[9] == get_byte(gpt_ptypes[i].guid +18) && 504 p->part_type[10] == get_byte(gpt_ptypes[i].guid +20) && 505 p->part_type[11] == get_byte(gpt_ptypes[i].guid +22) && 506 p->part_type[12] == get_byte(gpt_ptypes[i].guid +24) && 507 p->part_type[13] == get_byte(gpt_ptypes[i].guid +26) && 508 p->part_type[14] == get_byte(gpt_ptypes[i].guid +28) && 509 p->part_type[15] == get_byte(gpt_ptypes[i].guid +30)) 510 break; 511 } 512 455 513 return i; 456 514 } … … 516 574 517 575 /** Copy partition name */ 518 void gpt_set_part_name(gpt_part_t * p, char * name[], size_t length)576 void gpt_set_part_name(gpt_part_t *p, char *name, size_t length) 519 577 { 520 578 if (length >= 72) … … 645 703 } 646 704 647 648 649 650 651 705 static uint8_t get_byte(const char * c) 706 { 707 uint8_t val = 0; 708 char hex[3] = {*c, *(c+1), 0}; 709 710 errno = str_uint8_t(hex, NULL, 16, false, &val); 711 return val; 712 } 713 714 715 716
Note:
See TracChangeset
for help on using the changeset viewer.