Changeset c02d098 in mainline for uspace/lib/fdisk/src/fdisk.c
- Timestamp:
- 2015-07-29T20:35:40Z (9 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- 100b1d1
- Parents:
- c43db5f
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/lib/fdisk/src/fdisk.c
rc43db5f rc02d098 60 60 static int fdisk_part_spec_prepare(fdisk_dev_t *, fdisk_part_spec_t *, 61 61 vbd_part_spec_t *); 62 static void fdisk_pri_part_insert_lists(fdisk_dev_t *, fdisk_part_t *); 63 static void fdisk_log_part_insert_lists(fdisk_dev_t *, fdisk_part_t *); 64 static int fdisk_update_dev_info(fdisk_dev_t *); 62 65 63 66 static void fdisk_dev_info_delete(fdisk_dev_info_t *info) … … 252 255 fdisk_part_t **rpart) 253 256 { 254 fdisk_part_t *part , *p;257 fdisk_part_t *part; 255 258 vbd_part_info_t pinfo; 256 link_t *link;257 259 int rc; 258 260 … … 273 275 part->pkind = pinfo.pkind; 274 276 275 /* Insert to list by block address */ 276 link = list_first(&dev->parts_ba); 277 while (link != NULL) { 278 p = list_get_instance(link, fdisk_part_t, ldev_ba); 279 if (p->block0 > part->block0) { 280 list_insert_before(&part->ldev_ba, &p->ldev_ba); 281 break; 282 } 283 284 link = list_next(link, &dev->parts_ba); 285 } 286 287 if (link == NULL) 288 list_append(&part->ldev_ba, &dev->parts_ba); 289 290 /* Insert to list by index */ 291 link = list_first(&dev->parts_idx); 292 while (link != NULL) { 293 p = list_get_instance(link, fdisk_part_t, ldev_idx); 294 if (p->index > part->index) { 295 list_insert_before(&part->ldev_idx, &p->ldev_idx); 296 break; 297 } 298 299 link = list_next(link, &dev->parts_idx); 300 } 301 302 if (link == NULL) 303 list_append(&part->ldev_idx, &dev->parts_idx); 277 switch (part->pkind) { 278 case lpk_primary: 279 case lpk_extended: 280 fdisk_pri_part_insert_lists(dev, part); 281 break; 282 case lpk_logical: 283 fdisk_log_part_insert_lists(dev, part); 284 break; 285 } 286 287 list_append(&part->lparts, &dev->parts); 288 289 if (part->pkind == lpk_extended) 290 dev->ext_part = part; 304 291 305 292 part->capacity.cunit = cu_byte; … … 315 302 } 316 303 304 static void fdisk_pri_part_insert_lists(fdisk_dev_t *dev, fdisk_part_t *part) 305 { 306 link_t *link; 307 fdisk_part_t *p; 308 309 /* Insert to list by block address */ 310 link = list_first(&dev->pri_ba); 311 while (link != NULL) { 312 p = list_get_instance(link, fdisk_part_t, lpri_ba); 313 if (p->block0 > part->block0) { 314 list_insert_before(&part->lpri_ba, &p->lpri_ba); 315 break; 316 } 317 318 link = list_next(link, &dev->pri_ba); 319 } 320 321 if (link == NULL) 322 list_append(&part->lpri_ba, &dev->pri_ba); 323 324 /* Insert to list by index */ 325 link = list_first(&dev->pri_idx); 326 while (link != NULL) { 327 p = list_get_instance(link, fdisk_part_t, lpri_idx); 328 if (p->index > part->index) { 329 list_insert_before(&part->lpri_idx, &p->lpri_idx); 330 break; 331 } 332 333 link = list_next(link, &dev->pri_idx); 334 } 335 336 if (link == NULL) 337 list_append(&part->lpri_idx, &dev->pri_idx); 338 } 339 340 static void fdisk_log_part_insert_lists(fdisk_dev_t *dev, fdisk_part_t *part) 341 { 342 link_t *link; 343 fdisk_part_t *p; 344 345 /* Insert to list by block address */ 346 link = list_first(&dev->log_ba); 347 while (link != NULL) { 348 p = list_get_instance(link, fdisk_part_t, llog_ba); 349 if (p->block0 > part->block0) { 350 list_insert_before(&part->llog_ba, &p->llog_ba); 351 break; 352 } 353 354 link = list_next(link, &dev->log_ba); 355 } 356 357 if (link == NULL) 358 list_append(&part->llog_ba, &dev->log_ba); 359 } 317 360 318 361 int fdisk_dev_open(fdisk_t *fdisk, service_id_t sid, fdisk_dev_t **rdev) … … 330 373 dev->fdisk = fdisk; 331 374 dev->sid = sid; 332 list_initialize(&dev->parts_idx); 333 list_initialize(&dev->parts_ba); 375 list_initialize(&dev->parts); 376 list_initialize(&dev->pri_idx); 377 list_initialize(&dev->pri_ba); 378 list_initialize(&dev->log_ba); 334 379 335 380 rc = vol_disk_info(fdisk->vol, sid, &vinfo); … … 345 390 346 391 printf("get label info\n"); 347 rc = vbd_disk_info(fdisk->vbd, sid, &dev->dinfo);392 rc = fdisk_update_dev_info(dev); 348 393 if (rc != EOK) { 349 394 printf("failed\n"); … … 451 496 int fdisk_label_create(fdisk_dev_t *dev, label_type_t ltype) 452 497 { 453 return vol_label_create(dev->fdisk->vol, dev->sid, ltype); 498 int rc; 499 500 rc = vol_label_create(dev->fdisk->vol, dev->sid, ltype); 501 if (rc != EOK) 502 return rc; 503 504 rc = fdisk_update_dev_info(dev); 505 if (rc != EOK) 506 return rc; 507 508 return EOK; 454 509 } 455 510 … … 477 532 link_t *link; 478 533 479 link = list_first(&dev->parts _ba);534 link = list_first(&dev->parts); 480 535 if (link == NULL) 481 536 return NULL; 482 537 483 return list_get_instance(link, fdisk_part_t, l dev_ba);538 return list_get_instance(link, fdisk_part_t, lparts); 484 539 } 485 540 … … 488 543 link_t *link; 489 544 490 link = list_next(&part->l dev_ba, &part->dev->parts_ba);545 link = list_next(&part->lparts, &part->dev->parts); 491 546 if (link == NULL) 492 547 return NULL; 493 548 494 return list_get_instance(link, fdisk_part_t, l dev_ba);549 return list_get_instance(link, fdisk_part_t, lparts); 495 550 } 496 551 … … 552 607 return EIO; 553 608 554 list_remove(&part->ldev_ba); 555 list_remove(&part->ldev_idx); 609 list_remove(&part->lparts); 610 if (link_used(&part->lpri_ba)) 611 list_remove(&part->lpri_ba); 612 if (link_used(&part->lpri_idx)) 613 list_remove(&part->lpri_idx); 614 if (link_used(&part->llog_ba)) 615 list_remove(&part->llog_ba); 556 616 free(part); 557 617 return EOK; … … 707 767 int nidx; 708 768 709 link = list_first(&dev->p arts_idx);769 link = list_first(&dev->pri_idx); 710 770 nidx = 1; 711 771 while (link != NULL) { 712 part = list_get_instance(link, fdisk_part_t, l dev_idx);772 part = list_get_instance(link, fdisk_part_t, lpri_idx); 713 773 if (part->index > nidx) 714 774 break; 715 775 nidx = part->index + 1; 716 link = list_next(link, &dev->p arts_idx);776 link = list_next(link, &dev->pri_idx); 717 777 } 718 778 … … 737 797 int nba; 738 798 739 link = list_first(&dev->p arts_ba);799 link = list_first(&dev->pri_ba); 740 800 nba = dev->dinfo.ablock0; 741 801 while (link != NULL) { 742 part = list_get_instance(link, fdisk_part_t, l dev_ba);802 part = list_get_instance(link, fdisk_part_t, lpri_ba); 743 803 if (part->block0 - nba >= nblocks) 744 804 break; 745 805 nba = part->block0 + part->nblocks; 746 link = list_next(link, &dev->p arts_ba);806 link = list_next(link, &dev->pri_ba); 747 807 } 748 808 … … 764 824 } 765 825 826 /** Get free range of blocks in extended partition. 827 * 828 * Get free range of blocks in extended partition that can accomodate 829 * a partition of at least the specified size plus the header (EBR + padding). 830 * Returns the header size in blocks, the start and length of the partition. 831 */ 832 static int fdisk_part_get_log_free_range(fdisk_dev_t *dev, aoff64_t nblocks, 833 aoff64_t *rhdrb, aoff64_t *rblock0, aoff64_t *rnblocks) 834 { 835 link_t *link; 836 fdisk_part_t *part; 837 uint64_t avail; 838 uint64_t hdrb; 839 int nba; 840 841 /* Number of header blocks */ 842 hdrb = max(1, dev->align); 843 844 link = list_first(&dev->log_ba); 845 nba = dev->ext_part->block0; 846 while (link != NULL) { 847 part = list_get_instance(link, fdisk_part_t, llog_ba); 848 if (part->block0 - nba >= nblocks) 849 break; 850 nba = part->block0 + part->nblocks; 851 link = list_next(link, &dev->log_ba); 852 } 853 854 if (link != NULL) { 855 /* Free range before a partition */ 856 avail = part->block0 - nba; 857 } else { 858 /* Free range at the end */ 859 avail = dev->ext_part->block0 + dev->ext_part->nblocks - nba; 860 861 /* Verify that the range is large enough */ 862 if (avail < hdrb + nblocks) 863 return ELIMIT; 864 } 865 866 *rhdrb = hdrb; 867 *rblock0 = nba + hdrb; 868 *rnblocks = avail; 869 return EOK; 870 } 871 766 872 /** Prepare new partition specification for VBD. */ 767 873 static int fdisk_part_spec_prepare(fdisk_dev_t *dev, fdisk_part_spec_t *pspec, … … 770 876 uint64_t cbytes; 771 877 aoff64_t req_blocks; 878 aoff64_t fhdr; 772 879 aoff64_t fblock0; 773 880 aoff64_t fnblocks; … … 778 885 779 886 // pspec->fstype 780 printf("fdisk_part_spec_prepare()\n"); 887 printf("fdisk_part_spec_prepare() - dev=%p pspec=%p vpspec=%p\n", dev, pspec, 888 vpspec); 889 printf("fdisk_part_spec_prepare() - block size\n"); 781 890 block_size = dev->dinfo.block_size; 891 printf("fdisk_part_spec_prepare() - cbytes\n"); 782 892 cbytes = pspec->capacity.value; 893 printf("fdisk_part_spec_prepare() - cunit\n"); 783 894 for (i = 0; i < pspec->capacity.cunit; i++) 784 895 cbytes = cbytes * 1000; 785 896 897 printf("fdisk_part_spec_prepare() - req_blocks block_size=%zu\n", 898 block_size); 786 899 req_blocks = (cbytes + block_size - 1) / block_size; 787 900 788 rc = fdisk_part_get_free_idx(dev, &index); 901 printf("fdisk_part_spec_prepare() - switch\n"); 902 switch (pspec->pkind) { 903 case lpk_primary: 904 case lpk_extended: 905 printf("fdisk_part_spec_prepare() - pri/ext\n"); 906 rc = fdisk_part_get_free_idx(dev, &index); 907 if (rc != EOK) 908 return EIO; 909 910 printf("fdisk_part_spec_prepare() - get free range\n"); 911 rc = fdisk_part_get_free_range(dev, req_blocks, &fblock0, &fnblocks); 912 if (rc != EOK) 913 return EIO; 914 915 printf("fdisk_part_spec_prepare() - memset\n"); 916 memset(vpspec, 0, sizeof(vbd_part_spec_t)); 917 vpspec->index = index; 918 vpspec->block0 = fblock0; 919 vpspec->nblocks = req_blocks; 920 vpspec->pkind = pspec->pkind; 921 if (pspec->pkind != lpk_extended) 922 vpspec->ptype = 42; 923 break; 924 case lpk_logical: 925 printf("fdisk_part_spec_prepare() - log\n"); 926 rc = fdisk_part_get_log_free_range(dev, req_blocks, &fhdr, 927 &fblock0, &fnblocks); 928 if (rc != EOK) 929 return EIO; 930 931 memset(vpspec, 0, sizeof(vbd_part_spec_t)); 932 vpspec->hdr_blocks = fhdr; 933 vpspec->block0 = fblock0; 934 vpspec->nblocks = req_blocks; 935 vpspec->pkind = lpk_logical; 936 vpspec->ptype = 42; 937 break; 938 } 939 940 return EOK; 941 } 942 943 static int fdisk_update_dev_info(fdisk_dev_t *dev) 944 { 945 int rc; 946 size_t align_bytes; 947 948 rc = vbd_disk_info(dev->fdisk->vbd, dev->sid, &dev->dinfo); 789 949 if (rc != EOK) 790 950 return EIO; 791 951 792 rc = fdisk_part_get_free_range(dev, req_blocks, &fblock0, &fnblocks); 793 if (rc != EOK) 794 return EIO; 795 796 memset(vpspec, 0, sizeof(vbd_part_spec_t)); 797 vpspec->index = index; 798 vpspec->block0 = fblock0; 799 vpspec->nblocks = req_blocks; 800 vpspec->pkind = pspec->pkind; 801 if (pspec->pkind != lpk_extended) 802 vpspec->ptype = 42; 803 952 align_bytes = 512; //1024 * 1024; /* 1 MiB */ /* XXX */ 953 dev->align = align_bytes / dev->dinfo.block_size; 954 if (dev->align < 1) 955 dev->align = 1; 804 956 return EOK; 805 957 }
Note:
See TracChangeset
for help on using the changeset viewer.