Changeset c02d098 in mainline
- 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
- Location:
- uspace
- Files:
-
- 8 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/lib/c/include/vbd.h
rc43db5f rc02d098 69 69 /** Number of blocks */ 70 70 aoff64_t nblocks; 71 /** Number of header blocks (EBR for logical partitions) */ 72 aoff64_t hdr_blocks; 71 73 /** Partition kind */ 72 74 label_pkind_t pkind; -
uspace/lib/fdisk/include/types/fdisk.h
rc43db5f rc02d098 106 106 /** Service ID */ 107 107 service_id_t sid; 108 /** Partitions sorted by index */ 109 list_t parts_idx; /* of fdisk_part_t */ 110 /** Partitions sorted by block address */ 111 list_t parts_ba; 108 /** All partitions */ 109 list_t parts; 110 /** Primary partitions sorted by index */ 111 list_t pri_idx; /* of fdisk_part_t */ 112 /** Primary partitions sorted by block address */ 113 list_t pri_ba; 114 /** Logical partitions sorted by block address */ 115 list_t log_ba; 116 /** Extended partition or NULL */ 117 struct fdisk_part *ext_part; 112 118 /** Disk info */ 113 119 vbd_disk_info_t dinfo; 120 /** Alignment in blocks */ 121 uint64_t align; 114 122 } fdisk_dev_t; 115 123 … … 124 132 125 133 /** Partition */ 126 typedef struct {134 typedef struct fdisk_part { 127 135 /** Containing device */ 128 136 fdisk_dev_t *dev; 129 /** Link to fdisk_dev_t.parts_idx */ 130 link_t ldev_idx; 131 /** Link to fdisk_dev_t.parts_ba */ 132 link_t ldev_ba; 137 /** Link to fdisk_dev_t.parts */ 138 link_t lparts; 139 /** Link to fdisk_dev_t.pri_idx */ 140 link_t lpri_idx; 141 /** Link to fdisk_dev_t.pri_ba */ 142 link_t lpri_ba; 143 /** Link to fdisk_dev_t.log_ba */ 144 link_t llog_ba; 133 145 /** Capacity */ 134 146 fdisk_cap_t capacity; -
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 } -
uspace/lib/label/include/std/mbr.h
rc43db5f rc02d098 49 49 50 50 /** Boot record signature */ 51 mbr_br_signature = 0xAA55 51 mbr_br_signature = 0xAA55, 52 53 /** EBR PTE slot describing partition corresponding to this EBR */ 54 mbr_ebr_pte_this = 0, 55 /** EBR PTE slot describing the next EBR */ 56 mbr_ebr_pte_next = 1 52 57 }; 53 58 -
uspace/lib/label/include/types/liblabel.h
rc43db5f rc02d098 99 99 /** Index */ 100 100 int index; 101 /** Number of EBR blocks preceding a logical partition */ 102 aoff64_t hdr_blocks; 101 103 /** First block */ 102 104 aoff64_t block0; … … 117 119 /** Number of blocks */ 118 120 aoff64_t nblocks; 121 /** Number of header blocks (EBR for logical partitions) */ 122 aoff64_t hdr_blocks; 119 123 /** Partition kind */ 120 124 label_pkind_t pkind; … … 155 159 /** Number of primary partition entries */ 156 160 int pri_entries; 157 /** Index of extended partition or -1if there is none */158 int ext_part_idx;161 /** Extended partition or NULL if there is none */ 162 label_part_t *ext_part; 159 163 /** Block size */ 160 164 size_t block_size; -
uspace/lib/label/src/gpt.c
rc43db5f rc02d098 302 302 label->pri_entries = num_entries; 303 303 label->block_size = bsize; 304 label->ext_part_idx = -1;305 304 306 305 label->lt.gpt.hdr_ba[0] = gpt_hdr_ba; … … 449 448 label->pri_entries = num_entries; 450 449 label->block_size = bsize; 451 label->ext_part_idx = -1;452 450 453 451 label->lt.gpt.hdr_ba[0] = hdr_ba[0]; -
uspace/lib/label/src/mbr.c
rc43db5f rc02d098 44 44 45 45 static int mbr_open(service_id_t, label_t **); 46 static int mbr_open_ext(label_t *); 46 47 static int mbr_create(service_id_t, label_t **); 47 48 static void mbr_close(label_t *); … … 57 58 static int mbr_part_to_pte(label_part_t *, mbr_pte_t *); 58 59 static int mbr_pte_to_part(label_t *, mbr_pte_t *, int); 60 static int mbr_pte_to_log_part(label_t *, uint64_t, mbr_pte_t *); 61 static void mbr_log_part_to_ptes(label_part_t *, mbr_pte_t *, mbr_pte_t *); 59 62 static int mbr_pte_update(label_t *, mbr_pte_t *, int); 63 static int mbr_log_part_insert(label_t *, label_part_t *); 64 static int mbr_ebr_create(label_t *, label_part_t *); 65 static int mbr_ebr_delete(label_t *, label_part_t *); 66 static int mbr_ebr_update_next(label_t *, label_part_t *); 67 static void mbr_update_log_indices(label_t *); 60 68 61 69 label_ops_t mbr_label_ops = { … … 132 140 } 133 141 134 label->ext_part_idx = -1; 142 143 label->ext_part = NULL; 135 144 for (entry = 0; entry < mbr_nprimary; entry++) { 136 145 eptr = &mbr->pte[entry]; … … 150 159 label->anblocks = nblocks - mbr_ablock0; 151 160 label->pri_entries = mbr_nprimary; 161 162 if (label->ext_part != NULL) { 163 /* Open extended partition */ 164 rc = mbr_open_ext(label); 165 if (rc != EOK) 166 goto error; 167 } 168 152 169 *rlabel = label; 153 170 return EOK; 154 171 error: 155 172 free(mbr); 156 free(label); 173 mbr_close(label); 174 return rc; 175 } 176 177 /** Open extended partition */ 178 static int mbr_open_ext(label_t *label) 179 { 180 mbr_br_block_t *ebr = NULL; 181 mbr_pte_t *ethis; 182 mbr_pte_t *enext; 183 uint64_t ebr_b0; 184 uint64_t ebr_nblocks_min; 185 uint64_t ebr_nblocks_max; 186 uint64_t pebr_b0; 187 uint64_t pebr_nblocks; 188 uint64_t pb0; 189 uint64_t pnblocks; 190 uint64_t ep_b0; 191 int rc; 192 193 ebr = calloc(1, label->block_size); 194 if (ebr == NULL) { 195 rc = ENOMEM; 196 goto error; 197 } 198 199 /* First block of extended partition */ 200 ep_b0 = label->ext_part->block0; 201 202 /* First block of current EBR */ 203 ebr_b0 = label->ext_part->block0; 204 205 /* 206 * We don't have bounds for the first EBR, so for purpose of 207 * verification let's say it contains at least one block and 208 * at most all blocks from the extended partition. 209 */ 210 ebr_nblocks_min = 1; 211 ebr_nblocks_max = label->ext_part->nblocks; 212 213 while (true) { 214 /* Read EBR */ 215 rc = block_read_direct(label->svc_id, ebr_b0, 1, ebr); 216 if (rc != EOK) { 217 rc = EIO; 218 goto error; 219 } 220 221 ethis = &ebr->pte[mbr_ebr_pte_this]; 222 enext = &ebr->pte[mbr_ebr_pte_next]; 223 224 pb0 = ebr_b0 + uint32_t_le2host(ethis->first_lba); 225 pnblocks = uint32_t_le2host(ethis->length); 226 227 if (ethis->ptype == mbr_pt_unused || pnblocks == 0) 228 break; 229 230 /* Verify partition lies within the range of EBR */ 231 if (pb0 + pnblocks > ebr_b0 + ebr_nblocks_max) { 232 rc = EIO; 233 goto error; 234 } 235 236 /* Create partition structure */ 237 rc = mbr_pte_to_log_part(label, ebr_b0, ethis); 238 if (rc != EOK) { 239 rc= EIO; 240 goto error; 241 } 242 243 /* Save previous EBR range */ 244 pebr_b0 = ebr_b0; 245 pebr_nblocks = ebr_nblocks_min; 246 247 /* Proceed to next EBR */ 248 ebr_b0 = ep_b0 + uint32_t_le2host(enext->first_lba); 249 ebr_nblocks_min = uint32_t_le2host(enext->length); 250 ebr_nblocks_max = ebr_nblocks_min; 251 252 if (enext->ptype == mbr_pt_unused || ebr_nblocks_min == 0) 253 break; 254 255 /* Verify next EBR does not overlap this EBR */ 256 if (ebr_b0 < pebr_b0 + pebr_nblocks) { 257 rc = EIO; 258 goto error; 259 } 260 261 /* Verify next EBR does not extend beyond end of label */ 262 if (ebr_b0 + ebr_nblocks_max > label->ablock0 + label->anblocks) { 263 rc = EIO; 264 goto error; 265 } 266 } 267 268 free(ebr); 269 return EOK; 270 error: 271 /* Note that logical partitions need to be deleted by caller */ 272 free(ebr); 157 273 return rc; 158 274 } … … 215 331 label->anblocks = nblocks - mbr_ablock0; 216 332 label->pri_entries = mbr_nprimary; 217 label->ext_part _idx = -1;333 label->ext_part = NULL; 218 334 219 335 *rlabel = label; … … 228 344 { 229 345 label_part_t *part; 346 347 if (label == NULL) 348 return; 230 349 231 350 part = mbr_part_first(label); … … 291 410 linfo->flags |= lf_can_create_pri; 292 411 /* Can create extended if there is a free slot and no extended */ 293 if ((linfo->flags & lf_can_create_pri) != 0 && label->ext_part _idx < 0)412 if ((linfo->flags & lf_can_create_pri) != 0 && label->ext_part == NULL) 294 413 linfo->flags |= lf_can_create_ext; 295 414 /* Can create logical if there is an extended partition */ 296 if (label->ext_part _idx >= 0)415 if (label->ext_part != NULL) 297 416 linfo->flags |= lf_can_create_log; 298 417 … … 323 442 324 443 return list_get_instance(link, label_part_t, lparts); 444 } 445 446 static label_part_t *mbr_log_part_first(label_t *label) 447 { 448 link_t *link; 449 450 link = list_first(&label->log_parts); 451 if (link == NULL) 452 return NULL; 453 454 return list_get_instance(link, label_part_t, llog); 455 } 456 457 static label_part_t *mbr_log_part_next(label_part_t *part) 458 { 459 link_t *link; 460 461 link = list_next(&part->llog, &part->label->log_parts); 462 if (link == NULL) 463 return NULL; 464 465 return list_get_instance(link, label_part_t, llog); 466 } 467 468 static label_part_t *mbr_log_part_prev(label_part_t *part) 469 { 470 link_t *link; 471 472 link = list_prev(&part->llog, &part->label->log_parts); 473 if (link == NULL) 474 return NULL; 475 476 return list_get_instance(link, label_part_t, llog); 325 477 } 326 478 … … 346 498 { 347 499 label_part_t *part; 500 label_part_t *prev; 501 label_part_t *next; 348 502 mbr_pte_t pte; 349 503 int rc; … … 360 514 part->block0 = pspec->block0; 361 515 part->nblocks = pspec->nblocks; 516 part->hdr_blocks = pspec->hdr_blocks; 362 517 363 518 switch (pspec->pkind) { … … 371 526 goto error; 372 527 } 373 if (label->ext_part _idx >= 0) {528 if (label->ext_part != NULL) { 374 529 rc = EEXISTS; 375 530 goto error; … … 377 532 break; 378 533 case lpk_logical: 534 log_msg(LOG_DEFAULT, LVL_NOTE, "check index"); 379 535 part->ptype = pspec->ptype; 380 536 if (pspec->index != 0) { … … 394 550 } 395 551 552 if (pspec->hdr_blocks != 0) { 553 rc = EINVAL; 554 goto error; 555 } 556 396 557 rc = mbr_part_to_pte(part, &pte); 397 558 if (rc != EOK) { … … 410 571 411 572 if (pspec->pkind == lpk_extended) 412 label->ext_part _idx = pspec->index - 1;573 label->ext_part = part; 413 574 } else { 414 575 /* Logical partition */ 415 rc = ENOTSUP; 416 goto error; 417 } 418 576 577 log_msg(LOG_DEFAULT, LVL_NOTE, "call mbr_log_part_insert"); 578 rc = mbr_log_part_insert(label, part); 579 if (rc != EOK) 580 goto error; 581 582 log_msg(LOG_DEFAULT, LVL_NOTE, "call mbr_ebr_create"); 583 /* Create EBR for new partition */ 584 rc = mbr_ebr_create(label, part); 585 if (rc != EOK) 586 goto error; 587 588 prev = mbr_log_part_prev(part); 589 if (prev != NULL) { 590 log_msg(LOG_DEFAULT, LVL_NOTE, "update next"); 591 /* Update 'next' PTE in EBR of previous partition */ 592 rc = mbr_ebr_update_next(label, prev); 593 if (rc != EOK) { 594 log_msg(LOG_DEFAULT, LVL_NOTE, "failed to update next"); 595 goto error; 596 } 597 } else { 598 log_msg(LOG_DEFAULT, LVL_NOTE, "relocate first EBR"); 599 /* New partition is now the first one */ 600 next = mbr_log_part_next(part); 601 if (next != NULL) { 602 /* 603 * Create new, relocated EBR for the former 604 * first partition 605 */ 606 next->hdr_blocks = pspec->hdr_blocks; 607 rc = mbr_ebr_create(label, next); 608 if (rc != EOK) 609 goto error; 610 } 611 } 612 613 /* This also sets index for the new partition. */ 614 mbr_update_log_indices(label); 615 } 616 617 log_msg(LOG_DEFAULT, LVL_NOTE, "mbr_part_create success"); 419 618 *rpart = part; 420 619 return EOK; … … 427 626 { 428 627 mbr_pte_t pte; 628 label_part_t *prev; 429 629 int rc; 430 630 431 /* Prepare unused partition table entry */ 432 mbr_unused_pte(&pte); 433 434 /* Modify partition table */ 435 rc = mbr_pte_update(part->label, &pte, part->index - 1); 436 if (rc != EOK) 437 return EIO; 438 439 /* If it was the extended partition, clear ext. part. index */ 440 if (part->index - 1 == part->label->ext_part_idx) 441 part->label->ext_part_idx = -1; 631 if (link_used(&part->lpri)) { 632 /* Primary/extended partition */ 633 634 /* Prepare unused partition table entry */ 635 mbr_unused_pte(&pte); 636 637 /* Modify partition table */ 638 rc = mbr_pte_update(part->label, &pte, part->index - 1); 639 if (rc != EOK) 640 return EIO; 641 642 /* If it was the extended partition, clear ext. part. pointer */ 643 if (part == part->label->ext_part) 644 part->label->ext_part = NULL; 645 646 list_remove(&part->lpri); 647 } else { 648 /* Logical partition */ 649 650 prev = mbr_log_part_prev(part); 651 if (prev != NULL) { 652 /* Update next link in previous EBR */ 653 list_remove(&part->llog); 654 655 rc = mbr_ebr_update_next(part->label, prev); 656 if (rc != EOK) { 657 /* Roll back */ 658 list_insert_after(&part->llog, &prev->llog); 659 return EIO; 660 } 661 } else { 662 list_remove(&part->llog); 663 } 664 665 /* Delete EBR */ 666 mbr_ebr_delete(part->label, part); 667 } 442 668 443 669 list_remove(&part->lparts); 444 if (link_used(&part->lpri))445 list_remove(&part->lpri);446 if (link_used(&part->llog))447 list_remove(&part->llog);448 670 free(part); 449 671 return EOK; … … 507 729 508 730 if (pte->ptype == mbr_pt_extended) 509 label->ext_part_idx = index - 1; 510 return EOK; 731 label->ext_part = part; 732 return EOK; 733 } 734 735 static int mbr_pte_to_log_part(label_t *label, uint64_t ebr_b0, 736 mbr_pte_t *pte) 737 { 738 label_part_t *part; 739 uint32_t block0; 740 uint32_t nblocks; 741 size_t nlparts; 742 743 block0 = ebr_b0 + uint32_t_le2host(pte->first_lba); 744 nblocks = uint32_t_le2host(pte->length); 745 746 if (pte->ptype == mbr_pt_unused || nblocks == 0) 747 return EOK; 748 749 part = calloc(1, sizeof(label_part_t)); 750 if (part == NULL) 751 return ENOMEM; 752 753 nlparts = list_count(&label->log_parts); 754 755 part->ptype = pte->ptype; 756 part->index = mbr_nprimary + 1 + nlparts; 757 part->block0 = block0; 758 part->nblocks = nblocks; 759 760 part->label = label; 761 list_append(&part->lparts, &label->parts); 762 list_append(&part->llog, &label->log_parts); 763 764 return EOK; 765 } 766 #include <stdio.h> 767 static void mbr_log_part_to_ptes(label_part_t *part, mbr_pte_t *pthis, 768 mbr_pte_t *pnext) 769 { 770 label_part_t *next; 771 uint64_t ep_b0; 772 uint64_t totsize; 773 774 /* First block of extended partition */ 775 ep_b0 = part->label->ext_part->block0; 776 777 assert(link_used(&part->llog)); 778 assert(part->block0 >= ep_b0); 779 printf("part->hdr_blocks = %" PRIu64 "\n", part->hdr_blocks); 780 printf("part->block0 = %" PRIu64 "\n", part->block0); 781 printf("ep_b0 = %" PRIu64 "\n", ep_b0); 782 assert(part->hdr_blocks <= part->block0 - ep_b0); 783 784 /* 'This' EBR entry */ 785 if (pthis != NULL) { 786 memset(pthis, 0, sizeof(mbr_pte_t)); 787 pthis->ptype = part->ptype; 788 pthis->first_lba = host2uint32_t_le(part->hdr_blocks); 789 pthis->length = host2uint32_t_le(part->nblocks); 790 } 791 792 /* 'Next' EBR entry */ 793 if (pnext != NULL) { 794 next = mbr_part_next(part); 795 796 memset(pnext, 0, sizeof(mbr_pte_t)); 797 if (next != NULL) { 798 /* Total size of EBR + partition */ 799 totsize = next->hdr_blocks + next->nblocks; 800 801 pnext->ptype = mbr_pt_extended; 802 pnext->first_lba = host2uint32_t_le(next->block0 - 803 next->hdr_blocks - ep_b0); 804 pnext->length = host2uint32_t_le(totsize); 805 } 806 } 511 807 } 512 808 … … 546 842 } 547 843 844 /** Insert logical partition into logical partition list. */ 845 static int mbr_log_part_insert(label_t *label, label_part_t *part) 846 { 847 label_part_t *cur; 848 849 cur = mbr_log_part_first(label); 850 while (cur != NULL) { 851 if (cur->block0 + cur->nblocks > part->block0) 852 break; 853 cur = mbr_log_part_next(part); 854 } 855 856 if (cur != NULL) 857 list_insert_before(&part->llog, &cur->llog); 858 else 859 list_append(&part->llog, &label->log_parts); 860 861 return EOK; 862 } 863 864 /** Create EBR for partition. */ 865 static int mbr_ebr_create(label_t *label, label_part_t *part) 866 { 867 mbr_br_block_t *br; 868 uint64_t ba; 869 int rc; 870 871 br = calloc(1, label->block_size); 872 if (br == NULL) 873 return ENOMEM; 874 875 mbr_log_part_to_ptes(part, &br->pte[mbr_ebr_pte_this], 876 &br->pte[mbr_ebr_pte_next]); 877 br->signature = host2uint16_t_le(mbr_br_signature); 878 879 ba = part->block0 - part->hdr_blocks; 880 881 log_msg(LOG_DEFAULT, LVL_NOTE, "Write EBR to ba=%" PRIu64, ba); 882 rc = block_write_direct(label->svc_id, ba, 1, br); 883 if (rc != EOK) { 884 rc = EIO; 885 goto error; 886 } 887 888 free(br); 889 return EOK; 890 error: 891 free(br); 892 return rc; 893 } 894 895 static int mbr_ebr_delete(label_t *label, label_part_t *part) 896 { 897 mbr_br_block_t *br; 898 uint64_t ba; 899 int rc; 900 901 br = calloc(1, label->block_size); 902 if (br == NULL) 903 return ENOMEM; 904 905 ba = part->block0 - part->hdr_blocks; 906 907 rc = block_write_direct(label->svc_id, ba, 1, br); 908 if (rc != EOK) { 909 rc = EIO; 910 goto error; 911 } 912 913 free(br); 914 return EOK; 915 error: 916 free(br); 917 return rc; 918 } 919 920 /** Update 'next' PTE in EBR of partition. */ 921 static int mbr_ebr_update_next(label_t *label, label_part_t *part) 922 { 923 mbr_br_block_t *br; 924 uint64_t ba; 925 uint16_t sgn; 926 int rc; 927 928 ba = part->block0 - part->hdr_blocks; 929 930 log_msg(LOG_DEFAULT, LVL_NOTE, "mbr_ebr_update_next ba=%" PRIu64, 931 ba); 932 933 br = calloc(1, label->block_size); 934 if (br == NULL) 935 return ENOMEM; 936 937 log_msg(LOG_DEFAULT, LVL_NOTE, "mbr_ebr_update_next read ba=%" PRIu64, 938 ba); 939 940 rc = block_read_direct(label->svc_id, ba, 1, br); 941 if (rc != EOK) { 942 rc = EIO; 943 goto error; 944 } 945 946 /* Verify boot record signature */ 947 sgn = uint16_t_le2host(br->signature); 948 if (sgn != mbr_br_signature) { 949 log_msg(LOG_DEFAULT, LVL_NOTE, "mbr_ebr_update_next signature error"); 950 rc = EIO; 951 goto error; 952 } 953 954 mbr_log_part_to_ptes(part, NULL, &br->pte[mbr_ebr_pte_next]); 955 956 log_msg(LOG_DEFAULT, LVL_NOTE, "mbr_ebr_update_next write ba=%" PRIu64, 957 ba); 958 959 rc = block_write_direct(label->svc_id, ba, 1, br); 960 if (rc != EOK) { 961 rc = EIO; 962 goto error; 963 } 964 965 log_msg(LOG_DEFAULT, LVL_NOTE, "mbr_ebr_update_next success"); 966 967 free(br); 968 return EOK; 969 error: 970 free(br); 971 return rc; 972 } 973 974 /** Update indices of logical partitions. 975 * 976 * Logical partition indices are unstable, i.e. they can change during 977 * the lifetime of a logical partition. Since the index corresponds to the 978 * position of the partition in order of block address, anytime a partition 979 * is created or deleted, indices of all partitions at higher addresses 980 * change. 981 */ 982 static void mbr_update_log_indices(label_t *label) 983 { 984 label_part_t *part; 985 int idx; 986 987 idx = mbr_nprimary + 1; 988 989 part = mbr_log_part_first(label); 990 while (part != NULL) { 991 part->index = idx++; 992 part = mbr_log_part_next(part); 993 } 994 } 995 548 996 /** @} 549 997 */ -
uspace/srv/bd/vbd/disk.c
rc43db5f rc02d098 346 346 info->anblocks = linfo.anblocks; 347 347 info->block_size = disk->block_size; 348 log_msg(LOG_DEFAULT, LVL_NOTE, "vbds_disk_info - block_size=%zu", 349 info->block_size); 348 350 return EOK; 349 351 } … … 438 440 disk->label = label; 439 441 disk->block_size = block_size; 442 log_msg(LOG_DEFAULT, LVL_NOTE, "vbds_label_create: block_size=%zu", 443 block_size); 440 444 list_initialize(&disk->parts); 441 445 … … 519 523 lpspec.block0 = pspec->block0; 520 524 lpspec.nblocks = pspec->nblocks; 525 lpspec.hdr_blocks = pspec->hdr_blocks; 521 526 lpspec.pkind = pspec->pkind; 522 527 lpspec.ptype = pspec->ptype;
Note:
See TracChangeset
for help on using the changeset viewer.