Changeset b598460a in mainline
- Timestamp:
- 2015-10-21T09:27:06Z (9 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- 852664b9
- Parents:
- 68b5dd11
- Location:
- uspace
- Files:
-
- 5 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/app/fdisk/fdisk.c
r68b5dd11 rb598460a 338 338 fdisk_part_spec_t pspec; 339 339 fdisk_cap_t cap; 340 fdisk_cap_t mcap; 340 341 vol_fstype_t fstype = 0; 341 342 tinput_t *tinput = NULL; 343 fdisk_spc_t spc; 342 344 char *scap; 345 char *smcap = NULL; 346 347 if (pkind == lpk_logical) 348 spc = spc_log; 349 else 350 spc = spc_pri; 351 352 rc = fdisk_part_get_max_avail(dev, spc, &mcap); 353 if (rc != EOK) { 354 rc = EIO; 355 goto error; 356 } 357 358 rc = fdisk_cap_format(&mcap, &smcap); 359 if (rc != EOK) { 360 rc = ENOMEM; 361 goto error; 362 } 343 363 344 364 tinput = tinput_new(); … … 354 374 while (true) { 355 375 printf("Enter capacity of new partition.\n"); 356 rc = tinput_read (tinput, &scap);376 rc = tinput_read_i(tinput, smcap, &scap); 357 377 if (rc != EOK) 358 378 goto error; … … 365 385 tinput_destroy(tinput); 366 386 tinput = NULL; 387 free(smcap); 388 smcap = NULL; 367 389 368 390 if (pkind != lpk_extended) { … … 385 407 return EOK; 386 408 error: 409 free(smcap); 387 410 if (tinput != NULL) 388 411 tinput_destroy(tinput); -
uspace/lib/fdisk/include/fdisk.h
r68b5dd11 rb598460a 64 64 extern fdisk_part_t *fdisk_part_next(fdisk_part_t *); 65 65 extern int fdisk_part_get_info(fdisk_part_t *, fdisk_part_info_t *); 66 extern int fdisk_part_get_max_avail(fdisk_dev_t *, fdisk_ cap_t *);66 extern int fdisk_part_get_max_avail(fdisk_dev_t *, fdisk_spc_t, fdisk_cap_t *); 67 67 extern int fdisk_part_create(fdisk_dev_t *, fdisk_part_spec_t *, 68 68 fdisk_part_t **); -
uspace/lib/fdisk/include/types/fdisk.h
r68b5dd11 rb598460a 45 45 #include <vol.h> 46 46 47 /** Capacity unit */ 47 48 typedef enum { 48 49 cu_byte = 0, … … 56 57 cu_ybyte 57 58 } fdisk_cunit_t; 59 60 typedef enum { 61 /** Primary partition space */ 62 spc_pri, 63 /** Logical partition space */ 64 spc_log 65 } fdisk_spc_t; 58 66 59 67 /** Fdisk device flags */ … … 177 185 } fdisk_part_info_t; 178 186 187 /** Free range iterator */ 188 typedef struct { 189 /** Device */ 190 fdisk_dev_t *dev; 191 /** Primary or logical partition space */ 192 fdisk_spc_t spc; 193 /** First block of free range */ 194 aoff64_t b0; 195 /** Next partition following the free range or @c NULL if the range 196 * is at the end. */ 197 fdisk_part_t *npart; 198 } fdisk_free_range_t; 199 179 200 /** Fdisk instance */ 180 201 typedef struct fdisk { -
uspace/lib/fdisk/src/fdisk.c
r68b5dd11 rb598460a 67 67 static uint64_t fdisk_ba_align_up(fdisk_dev_t *, uint64_t); 68 68 static uint64_t fdisk_ba_align_down(fdisk_dev_t *, uint64_t); 69 static int fdisk_part_get_max_free_range(fdisk_dev_t *, fdisk_spc_t, aoff64_t *, 70 aoff64_t *); 71 static void fdisk_free_range_first(fdisk_dev_t *, fdisk_spc_t, fdisk_free_range_t *); 72 static bool fdisk_free_range_next(fdisk_free_range_t *); 73 static bool fdisk_free_range_get(fdisk_free_range_t *, aoff64_t *, aoff64_t *); 69 74 70 75 static void fdisk_dev_info_delete(fdisk_dev_info_t *info) … … 278 283 } 279 284 280 printf("vol_part_add(%zu)...\n", pinfo.svc_id); 281 /* 282 * Normally vol service discovers the partition asynchronously. 283 * Here we need to make sure the partition is already known to it. 284 */ 285 rc = vol_part_add(dev->fdisk->vol, pinfo.svc_id); 286 printf("vol_part_add->rc = %d\n", rc); 287 if (rc != EOK && rc != EEXIST) { 288 rc = EIO; 289 goto error; 290 } 291 292 printf("vol_part_info(%zu)\n", pinfo.svc_id); 293 rc = vol_part_info(dev->fdisk->vol, pinfo.svc_id, &vpinfo); 294 printf("vol_part_info->rc = %d\n", rc); 295 if (rc != EOK) { 296 rc = EIO; 297 goto error; 285 if (pinfo.svc_id != 0) { 286 printf("vol_part_add(%zu)...\n", pinfo.svc_id); 287 /* 288 * Normally vol service discovers the partition asynchronously. 289 * Here we need to make sure the partition is already known to it. 290 */ 291 rc = vol_part_add(dev->fdisk->vol, pinfo.svc_id); 292 printf("vol_part_add->rc = %d\n", rc); 293 if (rc != EOK && rc != EEXIST) { 294 rc = EIO; 295 goto error; 296 } 297 298 printf("vol_part_info(%zu)\n", pinfo.svc_id); 299 rc = vol_part_info(dev->fdisk->vol, pinfo.svc_id, &vpinfo); 300 printf("vol_part_info->rc = %d\n", rc); 301 if (rc != EOK) { 302 rc = EIO; 303 goto error; 304 } 305 306 part->pcnt = vpinfo.pcnt; 307 part->fstype = vpinfo.fstype; 298 308 } 299 309 … … 304 314 part->pkind = pinfo.pkind; 305 315 part->svc_id = pinfo.svc_id; 306 part->pcnt = vpinfo.pcnt;307 part->fstype = vpinfo.fstype;308 316 309 317 switch (part->pkind) { … … 620 628 { 621 629 vbd_disk_info_t vinfo; 630 uint64_t b0, nb; 631 uint64_t hdrb; 622 632 int rc; 623 633 … … 630 640 info->ltype = vinfo.ltype; 631 641 info->flags = vinfo.flags; 642 643 if ((info->flags & lf_can_create_pri) != 0 || 644 (info->flags & lf_can_create_ext) != 0) { 645 /* Verify there is enough space to create partition */ 646 647 rc = fdisk_part_get_max_free_range(dev, spc_pri, &b0, &nb); 648 if (rc != EOK) 649 info->flags &= ~(lf_can_create_pri | lf_can_create_ext); 650 } 651 652 if ((info->flags & lf_can_create_log) != 0) { 653 /* Verify there is enough space to create logical partition */ 654 hdrb = max(1, dev->align); 655 rc = fdisk_part_get_max_free_range(dev, spc_log, &b0, &nb); 656 if (rc != EOK || nb <= hdrb) 657 info->flags &= ~lf_can_create_log; 658 } 659 632 660 return EOK; 633 661 error: … … 735 763 } 736 764 737 int fdisk_part_get_max_avail(fdisk_dev_t *dev, fdisk_cap_t *cap) 738 { 765 int fdisk_part_get_max_avail(fdisk_dev_t *dev, fdisk_spc_t spc, fdisk_cap_t *cap) 766 { 767 int rc; 768 uint64_t b0; 769 uint64_t nb; 770 aoff64_t hdrb; 771 772 rc = fdisk_part_get_max_free_range(dev, spc, &b0, &nb); 773 if (rc != EOK) 774 return rc; 775 776 /* For logical partitions we need to subtract header size */ 777 if (spc == spc_log) { 778 hdrb = max(1, dev->align); 779 if (nb <= hdrb) 780 return ENOSPC; 781 nb -= hdrb; 782 } 783 784 cap->value = nb * dev->dinfo.block_size; 785 cap->cunit = cu_byte; 739 786 return EOK; 740 787 } … … 767 814 } 768 815 769 rc = vol_part_mkfs(dev->fdisk->vol, part->svc_id, pspec->fstype); 770 if (rc != EOK && rc != ENOTSUP) { 771 printf("mkfs failed\n"); 772 fdisk_part_remove(part); 773 (void) vbd_part_delete(dev->fdisk->vbd, partid); 774 return EIO; 816 if (part->svc_id != 0) { 817 rc = vol_part_mkfs(dev->fdisk->vol, part->svc_id, pspec->fstype); 818 if (rc != EOK && rc != ENOTSUP) { 819 printf("mkfs failed\n"); 820 fdisk_part_remove(part); 821 (void) vbd_part_delete(dev->fdisk->vbd, partid); 822 return EIO; 823 } 775 824 } 776 825 777 826 printf("fdisk_part_create() - done\n"); 778 part->pcnt = vpc_fs; 779 part->fstype = pspec->fstype; 827 if (part->svc_id != 0) { 828 part->pcnt = vpc_fs; 829 part->fstype = pspec->fstype; 830 } 831 780 832 part->capacity = pspec->capacity; 781 833 … … 966 1018 */ 967 1019 static int fdisk_part_get_free_range(fdisk_dev_t *dev, aoff64_t nblocks, 1020 fdisk_spc_t spc, aoff64_t *rblock0, aoff64_t *rnblocks) 1021 { 1022 fdisk_free_range_t fr; 1023 uint64_t b0; 1024 uint64_t nb; 1025 1026 fdisk_free_range_first(dev, spc, &fr); 1027 do { 1028 if (fdisk_free_range_get(&fr, &b0, &nb)) { 1029 printf("free range: [%" PRIu64 ",+%" PRIu64 "]\n", 1030 b0, nb); 1031 if (nb >= nblocks) { 1032 printf("accepted.\n"); 1033 *rblock0 = b0; 1034 *rnblocks = nb; 1035 return EOK; 1036 } 1037 } 1038 } while (fdisk_free_range_next(&fr)); 1039 1040 /* No conforming free range found */ 1041 return ENOSPC; 1042 } 1043 1044 /** Get largest free range of blocks. 1045 * 1046 * Get free range of blocks of the maximum size. 1047 */ 1048 static int fdisk_part_get_max_free_range(fdisk_dev_t *dev, fdisk_spc_t spc, 968 1049 aoff64_t *rblock0, aoff64_t *rnblocks) 969 1050 { 970 link_t *link; 971 fdisk_part_t *part; 972 uint64_t avail; 973 uint64_t pb0; 974 uint64_t nba; 975 976 printf("fdisk_part_get_free_range: align=%" PRIu64 "\n", 977 dev->align); 978 979 link = list_first(&dev->pri_ba); 980 nba = fdisk_ba_align_up(dev, dev->dinfo.ablock0); 981 while (link != NULL) { 982 part = list_get_instance(link, fdisk_part_t, lpri_ba); 983 pb0 = fdisk_ba_align_down(dev, part->block0); 984 if (pb0 >= nba && pb0 - nba >= nblocks) 985 break; 986 nba = fdisk_ba_align_up(dev, part->block0 + part->nblocks); 987 link = list_next(link, &dev->pri_ba); 988 } 989 990 if (link != NULL) { 991 printf("nba=%" PRIu64 " pb0=%" PRIu64 "\n", 992 nba, pb0); 993 /* Free range before a partition */ 994 avail = pb0 - nba; 995 } else { 996 /* Free range at the end */ 997 pb0 = fdisk_ba_align_down(dev, dev->dinfo.ablock0 + 998 dev->dinfo.anblocks); 999 if (pb0 < nba) 1000 return ELIMIT; 1001 avail = pb0 - nba; 1002 printf("nba=%" PRIu64 " avail=%" PRIu64 "\n", 1003 nba, avail); 1004 1005 } 1006 1007 /* Verify that the range is large enough */ 1008 if (avail < nblocks) 1009 return ELIMIT; 1010 1011 *rblock0 = nba; 1012 *rnblocks = avail; 1013 return EOK; 1014 } 1015 1016 /** Get free range of blocks in extended partition. 1017 * 1018 * Get free range of blocks in extended partition that can accomodate 1019 * a partition of at least the specified size plus the header (EBR + padding). 1020 * Returns the header size in blocks, the start and length of the partition. 1021 */ 1022 static int fdisk_part_get_log_free_range(fdisk_dev_t *dev, aoff64_t nblocks, 1023 aoff64_t *rhdrb, aoff64_t *rblock0, aoff64_t *rnblocks) 1024 { 1025 link_t *link; 1026 fdisk_part_t *part; 1027 uint64_t avail; 1028 uint64_t hdrb; 1029 uint64_t pb0; 1030 uint64_t nba; 1031 1032 printf("fdisk_part_get_log_free_range\n"); 1033 /* Number of header blocks */ 1034 hdrb = max(1, dev->align); 1035 1036 link = list_first(&dev->log_ba); 1037 nba = fdisk_ba_align_up(dev, dev->ext_part->block0); 1038 while (link != NULL) { 1039 part = list_get_instance(link, fdisk_part_t, llog_ba); 1040 pb0 = fdisk_ba_align_down(dev, part->block0); 1041 if (pb0 >= nba && pb0 - nba >= nblocks) 1042 break; 1043 nba = fdisk_ba_align_up(dev, part->block0 + part->nblocks); 1044 link = list_next(link, &dev->log_ba); 1045 } 1046 1047 if (link != NULL) { 1048 /* Free range before a partition */ 1049 avail = pb0 - nba; 1050 } else { 1051 /* Free range at the end */ 1052 pb0 = fdisk_ba_align_down(dev, dev->ext_part->block0 + 1053 dev->ext_part->nblocks); 1054 if (pb0 < nba) { 1055 printf("not enough space\n"); 1056 return ELIMIT; 1051 fdisk_free_range_t fr; 1052 uint64_t b0; 1053 uint64_t nb; 1054 uint64_t best_b0; 1055 uint64_t best_nb; 1056 1057 best_b0 = best_nb = 0; 1058 fdisk_free_range_first(dev, spc, &fr); 1059 do { 1060 if (fdisk_free_range_get(&fr, &b0, &nb)) { 1061 if (nb > best_nb) { 1062 best_b0 = b0; 1063 best_nb = nb; 1064 } 1057 1065 } 1058 1059 avail = pb0 - nba; 1060 1061 printf("nba=%" PRIu64 " pb0=%" PRIu64" avail=%" PRIu64 "\n", 1062 nba, pb0, avail); 1063 } 1064 /* Verify that the range is large enough */ 1065 if (avail < hdrb + nblocks) { 1066 printf("not enough space\n"); 1067 return ELIMIT; 1068 } 1069 1070 *rhdrb = hdrb; 1071 *rblock0 = nba + hdrb; 1072 *rnblocks = avail; 1073 printf("hdrb=%" PRIu64 " block0=%" PRIu64" avail=%" PRIu64 "\n", 1074 hdrb, nba + hdrb, avail); 1066 } while (fdisk_free_range_next(&fr)); 1067 1068 if (best_nb == 0) 1069 return ENOSPC; 1070 1071 *rblock0 = best_b0; 1072 *rnblocks = best_nb; 1075 1073 return EOK; 1076 1074 } … … 1082 1080 uint64_t cbytes; 1083 1081 aoff64_t req_blocks; 1084 aoff64_t fhdr;1085 1082 aoff64_t fblock0; 1086 1083 aoff64_t fnblocks; 1084 aoff64_t hdrb; 1087 1085 uint64_t block_size; 1088 1086 label_pcnt_t pcnt; … … 1136 1134 1137 1135 printf("fdisk_part_spec_prepare() - get free range\n"); 1138 rc = fdisk_part_get_free_range(dev, req_blocks, &fblock0, &fnblocks); 1136 rc = fdisk_part_get_free_range(dev, req_blocks, spc_pri, 1137 &fblock0, &fnblocks); 1139 1138 if (rc != EOK) 1140 1139 return EIO; … … 1149 1148 case lpk_logical: 1150 1149 printf("fdisk_part_spec_prepare() - log\n"); 1151 rc = fdisk_part_get_log_free_range(dev, req_blocks, &fhdr, 1150 hdrb = max(1, dev->align); 1151 rc = fdisk_part_get_free_range(dev, hdrb + req_blocks, spc_log, 1152 1152 &fblock0, &fnblocks); 1153 1153 if (rc != EOK) … … 1155 1155 1156 1156 memset(vpspec, 0, sizeof(vbd_part_spec_t)); 1157 vpspec->hdr_blocks = fhdr;1158 vpspec->block0 = fblock0 ;1157 vpspec->hdr_blocks = hdrb; 1158 vpspec->block0 = fblock0 + hdrb; 1159 1159 vpspec->nblocks = req_blocks; 1160 1160 vpspec->pkind = lpk_logical; 1161 vpspec->ptype.fmt = lptf_num;1162 vpspec->ptype.t.num = 42;1163 1161 break; 1164 1162 } … … 1209 1207 } 1210 1208 1209 static void fdisk_free_range_first(fdisk_dev_t *dev, fdisk_spc_t spc, 1210 fdisk_free_range_t *fr) 1211 { 1212 link_t *link; 1213 1214 fr->dev = dev; 1215 fr->spc = spc; 1216 1217 if (fr->spc == spc_pri) { 1218 /* Primary partitions */ 1219 fr->b0 = fdisk_ba_align_up(fr->dev, fr->dev->dinfo.ablock0); 1220 1221 link = list_first(&dev->pri_ba); 1222 if (link != NULL) 1223 fr->npart = list_get_instance(link, fdisk_part_t, lpri_ba); 1224 else 1225 fr->npart = NULL; 1226 } else { /* fr->spc == spc_log */ 1227 /* Logical partitions */ 1228 fr->b0 = fdisk_ba_align_up(fr->dev, fr->dev->ext_part->block0); 1229 1230 link = list_first(&dev->log_ba); 1231 if (link != NULL) 1232 fr->npart = list_get_instance(link, fdisk_part_t, llog_ba); 1233 else 1234 fr->npart = NULL; 1235 } 1236 } 1237 1238 static bool fdisk_free_range_next(fdisk_free_range_t *fr) 1239 { 1240 link_t *link; 1241 1242 if (fr->npart == NULL) 1243 return false; 1244 1245 fr->b0 = fdisk_ba_align_up(fr->dev, fr->npart->block0 + 1246 fr->npart->nblocks); 1247 1248 if (fr->spc == spc_pri) { 1249 /* Primary partitions */ 1250 link = list_next(&fr->npart->lpri_ba, &fr->dev->pri_ba); 1251 if (link != NULL) 1252 fr->npart = list_get_instance(link, fdisk_part_t, lpri_ba); 1253 else 1254 fr->npart = NULL; 1255 } else { /* fr->spc == spc_log */ 1256 /* Logical partitions */ 1257 link = list_next(&fr->npart->llog_ba, &fr->dev->log_ba); 1258 if (link != NULL) 1259 fr->npart = list_get_instance(link, fdisk_part_t, llog_ba); 1260 else 1261 fr->npart = NULL; 1262 } 1263 1264 return true; 1265 } 1266 1267 static bool fdisk_free_range_get(fdisk_free_range_t *fr, 1268 aoff64_t *b0, aoff64_t *nb) 1269 { 1270 aoff64_t b1; 1271 1272 if (fr->npart != NULL) { 1273 b1 = fdisk_ba_align_down(fr->dev, fr->npart->block0); 1274 } else { 1275 if (fr->spc == spc_pri) { 1276 b1 = fdisk_ba_align_down(fr->dev, 1277 fr->dev->dinfo.ablock0 + fr->dev->dinfo.anblocks); 1278 } else { /* fr->spc == spc_log */ 1279 b1 = fdisk_ba_align_down(fr->dev, 1280 fr->dev->ext_part->block0 + fr->dev->ext_part->nblocks); 1281 } 1282 } 1283 1284 if (b1 < fr->b0) 1285 return false; 1286 1287 *b0 = fr->b0; 1288 *nb = b1 - fr->b0; 1289 1290 return true; 1291 } 1292 1211 1293 /** @} 1212 1294 */ -
uspace/srv/bd/vbd/disk.c
r68b5dd11 rb598460a 669 669 } 670 670 671 log_msg(LOG_DEFAULT, LVL_NOTE, "vbds_part_crate(%zu): " 672 "index=%d block0=%" PRIu64 " nblocks=%" PRIu64 673 " hdr_blocks=%" PRIu64 " pkind=%d", 674 sid, pspec->index, pspec->block0, pspec->nblocks, pspec->hdr_blocks, 675 pspec->pkind); 676 671 677 label_pspec_init(&lpspec); 672 678 lpspec.index = pspec->index;
Note:
See TracChangeset
for help on using the changeset viewer.