Changeset 30440ed in mainline for uspace/lib/mbr/libmbr.c
- Timestamp:
- 2013-04-08T23:15:42Z (11 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- 256cbfe
- Parents:
- 271e24a
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/lib/mbr/libmbr.c
r271e24a r30440ed 150 150 return NULL; 151 151 } 152 list_append(&(p->link), &(parts->list));152 //list_append(&(p->link), &(parts->list)); 153 153 p->ebr = NULL; 154 if (decode_part(&(mbr->raw_data.pte[i]), p, 0)) 154 if (decode_part(&(mbr->raw_data.pte[i]), p, 0)) { 155 155 ext = p; 156 parts->l_extended = list_last(&(parts->list)); 157 } 158 mbr_set_flag(p, ST_LOGIC, false); 159 mbr_add_partition(parts, p); 156 160 } 157 161 … … 183 187 184 188 br_block_t * last_ebr = NULL; 185 186 189 link_t * it; 190 191 DEBUG_PRINT_3(LIBMBR_NAME "Writing partitions: n_primary: %u, n_logical:%u, l_extended:%p", parts->n_primary, parts->n_logical, parts->l_extended); 192 187 193 rc = block_init(EXCHANGE_ATOMIC, dev_handle, 512); 188 194 if (rc != EOK) { 195 DEBUG_PRINT_2(LIBMBR_NAME ": Error (%d): %s.\n", rc, str_error(rc)); 189 196 return rc; 190 197 } … … 193 200 goto no_extended; 194 201 195 aoff64_t addr = ext->start_addr; 202 uint32_t base = ext->start_addr; 203 uint32_t addr = base; 204 uint32_t prev_addr; 196 205 mbr_part_t * prev_part = NULL; 197 206 198 list_foreach(parts->list, it ) {199 p = list_get_instance(it , mbr_part_t, link);207 list_foreach(parts->list, iter) { 208 p = list_get_instance(iter, mbr_part_t, link); 200 209 if (mbr_get_flag(p, ST_LOGIC)) { 201 210 // writing logical partition 202 211 212 if (p->start_addr < base || p->start_addr + p->length > base + ext->length) { 213 // out of bounds 214 return EINVAL; 215 } 216 217 203 218 if (p->ebr == NULL) { 204 219 p->ebr = alloc_br(); … … 210 225 } 211 226 212 213 encode_part(p, &(p->ebr->pte[0]), addr); 227 228 229 214 230 if (prev_part != NULL) { 215 encode_part(p, &(prev_part->ebr->pte[1]), ext->start_addr); 216 rc = block_write_direct(dev_handle, p->start_addr, 1, prev_part->ebr); 217 if (rc != EOK) 231 // addr is the address of EBR 232 addr = p->start_addr - base; 233 // base-1 means start_lba+1 234 encode_part(p, &(p->ebr->pte[0]), addr - 1); 235 encode_part(p, &(prev_part->ebr->pte[1]), base); 236 rc = block_write_direct(dev_handle, prev_addr, 1, prev_part->ebr); 237 if (rc != EOK) { 238 DEBUG_PRINT_2(LIBMBR_NAME ": Error (%d): %s.\n", rc, str_error(rc)); 218 239 goto end; 240 } 241 } else { 242 // addr is the address of EBR 243 addr = base; 244 // base-1 means start_lba+1 245 encode_part(p, &(p->ebr->pte[0]), base - 1); 219 246 } 220 247 221 addr = p->start_addr; 248 //addr = p->start_addr; 249 prev_addr = addr; 222 250 prev_part = p; 223 251 } else { … … 261 289 } 262 290 263 if (rc != EOK) 291 if (rc != EOK) { 292 DEBUG_PRINT_2(LIBMBR_NAME ": Error (%d): %s.\n", rc, str_error(rc)); 264 293 goto end; 294 } 265 295 266 296 goto skip; … … 268 298 no_extended: 269 299 270 list_foreach(parts->list, it) {300 /*list_foreach(parts->list, it) { 271 301 p = list_get_instance(it, mbr_part_t, link); 272 302 if (mbr_get_flag(p, ST_LOGIC)) { … … 282 312 ++i; 283 313 } 284 } 314 }*/ 315 316 it = parts->list.head.next; 317 for (i = 0; i < N_PRIMARY; i++) { 318 if (it != &parts->list.head) { 319 p = list_get_instance(it, mbr_part_t, link); 320 if (mbr_get_flag(p, ST_LOGIC)) { 321 // extended does not exist, fail 322 return EINVAL; 323 } else { 324 // writing primary partition 325 if (i >= 4) 326 return EINVAL; 327 328 encode_part(p, &(mbr->raw_data.pte[i]), 0); 329 330 } 331 332 it = it->next; 333 } else { 334 encode_part(NULL, &(mbr->raw_data.pte[i]), 0); 335 } 336 } 337 285 338 286 339 skip: 287 340 rc = block_write_direct(dev_handle, 0, 1, &(mbr->raw_data)); 288 if (rc != EOK) 341 if (rc != EOK) { 342 DEBUG_PRINT_2(LIBMBR_NAME ": Error (%d): %s.\n", rc, str_error(rc)); 289 343 goto end; 344 } 290 345 291 346 /* … … 382 437 383 438 list_initialize(&(parts->list)); 439 440 parts->n_primary = 0; 441 parts->n_logical = 0; 442 parts->l_extended = NULL; 384 443 385 444 return parts; … … 387 446 388 447 /** Add partition */ 389 int mbr_add_partition(mbr_partitions_t * parts, mbr_part_t * partition) 390 { 391 list_append(&(partition->link), &(parts->list)); 448 int mbr_add_partition(mbr_partitions_t * parts, mbr_part_t * p) 449 { 450 list_append(&(p->link), &(parts->list)); 451 if (mbr_get_flag(p, ST_LOGIC)) { 452 parts->n_logical += 1; 453 } else { 454 parts->n_primary += 1; 455 } 456 /* if we're adding new logical partition, we need 1 sector for the EBR 457 * for that partition (including the next one); we'd better make sure here 458 * before writing */ 459 if (mbr_get_flag(p, ST_LOGIC) && p->ebr == NULL) { 460 p->start_addr += 1; 461 p->length -= 1; 462 } 463 //FIXME: we can have multiple extended partitions! :-( 464 392 465 return EOK; 393 466 } … … 396 469 int mbr_remove_partition(mbr_partitions_t * parts, size_t idx) 397 470 { 471 DEBUG_PRINT_1(LIBMBR_NAME "Removing partition: %d\n", idx); 398 472 link_t * l = list_nth(&(parts->list), idx); 473 if (l == parts->l_extended) { 474 DEBUG_PRINT_0(LIBMBR_NAME "Removing extended partition.\n"); 475 parts->l_extended = NULL; 476 } 399 477 list_remove(l); 400 478 mbr_part_t * p = list_get_instance(l, mbr_part_t, link); 479 if (mbr_get_flag(p, ST_LOGIC)) { 480 parts->n_logical -= 1; 481 } else { 482 parts->n_primary -= 1; 483 } 484 485 401 486 mbr_free_partition(p); 402 487 … … 448 533 mbr_free_partition(p); 449 534 } 535 536 free(parts); 450 537 } 451 538 … … 465 552 } 466 553 467 /** Parse partition entry to mbr_part_t */ 554 /** Parse partition entry to mbr_part_t 555 * @return returns 1, if extended partition, 0 otherwise 556 * */ 468 557 static int decode_part(pt_entry_t * src, mbr_part_t * trgt, uint32_t base) 469 558 { … … 480 569 } 481 570 482 /** Parse MBR contents to mbr_part_t list 483 * parameter 'p' is allocated for only used primary partitions 484 */ 571 /** Parse MBR contents to mbr_part_t list */ 485 572 static int decode_logical(mbr_t * mbr, mbr_partitions_t * parts, mbr_part_t * ext) 486 573 { … … 496 583 497 584 498 uint32_t addr= ext->start_addr;499 //uint32_t base = ext->start_addr;585 uint32_t base = ext->start_addr; 586 uint32_t addr = base; 500 587 br_block_t * ebr; 501 588 … … 503 590 if (rc != EOK) 504 591 return rc; 505 506 do { 592 593 ebr = alloc_br(); 594 if (ebr == NULL) { 595 rc = ENOMEM; 596 goto end; 597 } 598 599 rc = block_read_direct(mbr->device, addr, 1, ebr); 600 if (rc != EOK) { 601 goto free_ebr_end; 602 } 603 604 if (uint16_t_le2host(ebr->signature) != BR_SIGNATURE) { 605 rc = EINVAL; 606 goto free_ebr_end; 607 } 608 609 if (ebr->pte[0].ptype == PT_UNUSED) { 610 rc = EOK; 611 goto free_ebr_end; 612 } 613 614 p = mbr_alloc_partition(); 615 if (p == NULL) { 616 rc = ENOMEM; 617 goto free_ebr_end; 618 } 619 620 621 decode_part(&(ebr->pte[0]), p, base); 622 mbr_set_flag(p, ST_LOGIC, true); 623 p->ebr = ebr; 624 mbr_add_partition(parts, p); 625 626 addr = uint32_t_le2host(ebr->pte[1].first_lba) + base; 627 628 while (ebr->pte[1].ptype != PT_UNUSED) { 507 629 ebr = alloc_br(); 508 630 if (ebr == NULL) { 509 return ENOMEM; 631 rc = ENOMEM; 632 goto end; 510 633 } 511 634 512 635 rc = block_read_direct(mbr->device, addr, 1, ebr); 513 636 if (rc != EOK) { 514 return rc; 515 } 516 517 //FIXME: is this the right way? 637 goto free_ebr_end; 638 } 639 518 640 if (uint16_t_le2host(ebr->signature) != BR_SIGNATURE) { 519 return EINVAL; 641 rc = EINVAL; 642 goto free_ebr_end; 520 643 } 521 644 522 645 p = mbr_alloc_partition(); 523 524 decode_part(&(ebr->pte[0]), p, addr); 646 if (p == NULL) { 647 rc = ENOMEM; 648 goto free_ebr_end; 649 } 650 651 decode_part(&(ebr->pte[0]), p, base); 525 652 mbr_set_flag(p, ST_LOGIC, true); 526 653 p->ebr = ebr; 527 654 mbr_add_partition(parts, p); 528 655 529 //TODO: Check this code 530 addr = ebr->pte[1].first_lba + ext->start_addr; 531 } while (ebr->pte[1].ptype != PT_UNUSED); 532 533 656 addr = uint32_t_le2host(ebr->pte[1].first_lba) + base; 657 } 658 659 rc = EOK; 660 661 free_ebr_end: 662 free(ebr); 663 664 end: 534 665 block_fini(mbr->device); 535 666 536 return EOK;667 return rc; 537 668 } 538 669 … … 543 674 trgt->status = mbr_get_flag(src, ST_BOOT) ? B_ACTIVE : B_INACTIVE; 544 675 trgt->ptype = src->type; 545 trgt->first_lba = host2uint32_t_le(src->start_addr - base + 63); //63 sectors skipped546 trgt->length = host2uint32_t_le(src->length - 64); //63 + 1 (EBR)676 trgt->first_lba = host2uint32_t_le(src->start_addr - base); 677 trgt->length = host2uint32_t_le(src->length); 547 678 } else { 548 679 trgt->status = 0;
Note:
See TracChangeset
for help on using the changeset viewer.