Changeset 03661d19 in mainline
- Timestamp:
- 2015-10-29T10:16:08Z (9 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- 55f8c6e7
- Parents:
- 9854a8f
- Location:
- uspace
- Files:
-
- 6 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/app/fdisk/fdisk.c
r9854a8f r03661d19 429 429 } 430 430 431 fdisk_cap_simplify(&mcap); 432 431 433 rc = fdisk_cap_format(&mcap, &smcap); 432 434 if (rc != EOK) { -
uspace/lib/fdisk/include/fdisk.h
r9854a8f r03661d19 75 75 extern void fdisk_cap_simplify(fdisk_cap_t *); 76 76 extern void fdisk_cap_from_blocks(uint64_t, size_t, fdisk_cap_t *); 77 extern int fdisk_cap_to_blocks(fdisk_cap_t *, size_t, uint64_t *);77 extern int fdisk_cap_to_blocks(fdisk_cap_t *, fdisk_cvsel_t, size_t, uint64_t *); 78 78 79 79 extern int fdisk_ltype_format(label_type_t, char **); -
uspace/lib/fdisk/include/types/fdisk.h
r9854a8f r03661d19 57 57 cu_ybyte 58 58 } fdisk_cunit_t; 59 60 /** Which of values within the precision of the capacity */ 61 typedef enum { 62 /** The nominal (middling) value */ 63 fcv_nom, 64 /** The minimum value */ 65 fcv_min, 66 /** The maximum value */ 67 fcv_max 68 } fdisk_cvsel_t; 59 69 60 70 typedef enum { -
uspace/lib/fdisk/src/cap.c
r9854a8f r03661d19 76 76 * of bytes is not divisible by the number of blocks, it is rounded 77 77 * up to an integer number of blocks. 78 */ 79 int fdisk_cap_to_blocks(fdisk_cap_t *cap, size_t block_size, 80 uint64_t *blocks) 78 * 79 * A capacity value entails precision, i.e. it corresponds to a range 80 * of values. @a cvsel selects the value to return. @c fcv_nom gives 81 * the nominal (middle) value, @c fcv_min gives the minimum value 82 * and @c fcv_max gives the maximum value. 83 */ 84 int fdisk_cap_to_blocks(fdisk_cap_t *cap, fdisk_cvsel_t cvsel, 85 size_t block_size, uint64_t *rblocks) 81 86 { 82 87 int exp; 83 88 uint64_t bytes; 84 89 uint64_t f; 90 uint64_t adj; 91 uint64_t blocks; 92 uint64_t rem; 85 93 int rc; 86 94 87 // XXX Check for overflow 95 printf("fdisk_cap_to_blocks: m=%" PRIu64 ", dp=%d, cunit=%d\n", 96 cap->m, cap->dp, cap->cunit); 88 97 89 98 exp = cap->cunit * 3 - cap->dp; … … 93 102 return ERANGE; 94 103 bytes = (cap->m + (f / 2)) / f; 104 if (bytes * f - (f / 2) != cap->m) 105 return ERANGE; 95 106 } else { 96 107 rc = ipow10_u64(exp, &f); 97 108 if (rc != EOK) 98 109 return ERANGE; 99 bytes = cap->m * f; 100 } 101 102 *blocks = (bytes + block_size - 1) / block_size; 110 111 adj = 0; 112 switch (cvsel) { 113 case fcv_nom: 114 adj = 0; 115 break; 116 case fcv_min: 117 adj = -(f / 2); 118 break; 119 case fcv_max: 120 adj = f / 2 - 1; 121 break; 122 } 123 124 printf("f=%" PRIu64 ", adj=%" PRId64 "\n", f, adj); 125 bytes = cap->m * f + adj; 126 printf("bytes=%" PRIu64 "\n", bytes); 127 if ((bytes - adj) / f != cap->m) 128 return ERANGE; 129 } 130 131 rem = bytes % block_size; 132 if ((bytes + rem) < bytes) 133 return ERANGE; 134 135 blocks = (bytes + rem) / block_size; 136 printf("blocks=%" PRIu64 "\n", blocks); 137 138 *rblocks = blocks; 103 139 return EOK; 104 140 } … … 185 221 } 186 222 223 static int fdisk_digit_val(char c, int *val) 224 { 225 switch (c) { 226 case '0': *val = 0; break; 227 case '1': *val = 1; break; 228 case '2': *val = 2; break; 229 case '3': *val = 3; break; 230 case '4': *val = 4; break; 231 case '5': *val = 5; break; 232 case '6': *val = 6; break; 233 case '7': *val = 7; break; 234 case '8': *val = 8; break; 235 case '9': *val = 9; break; 236 default: 237 return EINVAL; 238 } 239 240 return EOK; 241 } 242 187 243 int fdisk_cap_parse(const char *str, fdisk_cap_t *cap) 188 244 { 189 char *eptr; 190 char *p; 191 unsigned long val; 245 const char *eptr; 246 const char *p; 247 int d; 248 int dp; 249 unsigned long m; 192 250 int i; 193 251 194 val = strtoul(str, &eptr, 10); 252 m = 0; 253 254 eptr = str; 255 while (fdisk_digit_val(*eptr, &d) == EOK) { 256 m = m * 10 + d; 257 ++eptr; 258 } 259 260 if (*eptr == '.') { 261 ++eptr; 262 dp = 0; 263 while (fdisk_digit_val(*eptr, &d) == EOK) { 264 m = m * 10 + d; 265 ++dp; 266 ++eptr; 267 } 268 } else { 269 m = 0; dp = 0; 270 } 195 271 196 272 while (*eptr == ' ') … … 216 292 } 217 293 218 cap->m = val;219 cap->dp = 0;294 cap->m = m; 295 cap->dp = dp; 220 296 return EOK; 221 297 } -
uspace/lib/fdisk/src/fdisk.c
r9854a8f r03661d19 1037 1037 vbd_part_spec_t *vpspec) 1038 1038 { 1039 aoff64_t req_blocks; 1039 aoff64_t nom_blocks; 1040 aoff64_t min_blocks; 1041 aoff64_t max_blocks; 1042 aoff64_t act_blocks; 1040 1043 aoff64_t fblock0; 1041 1044 aoff64_t fnblocks; 1042 1045 aoff64_t hdrb; 1043 1046 label_pcnt_t pcnt; 1047 fdisk_spc_t spc; 1044 1048 int index; 1045 1049 int rc; … … 1047 1051 printf("fdisk_part_spec_prepare() - dev=%p pspec=%p vpspec=%p\n", dev, pspec, 1048 1052 vpspec); 1049 fdisk_cap_to_blocks(&pspec->capacity, dev->dinfo.block_size, &req_blocks); 1050 1051 req_blocks = fdisk_ba_align_up(dev, req_blocks); 1053 rc = fdisk_cap_to_blocks(&pspec->capacity, fcv_nom, dev->dinfo.block_size, 1054 &nom_blocks); 1055 if (rc != EOK) 1056 return rc; 1057 1058 rc = fdisk_cap_to_blocks(&pspec->capacity, fcv_min, dev->dinfo.block_size, 1059 &min_blocks); 1060 if (rc != EOK) 1061 return rc; 1062 1063 rc = fdisk_cap_to_blocks(&pspec->capacity, fcv_max, dev->dinfo.block_size, 1064 &max_blocks); 1065 if (rc != EOK) 1066 return rc; 1067 1068 nom_blocks = fdisk_ba_align_up(dev, nom_blocks); 1069 min_blocks = fdisk_ba_align_up(dev, min_blocks); 1070 max_blocks = fdisk_ba_align_up(dev, max_blocks); 1071 1072 printf("fdisk_part_spec_prepare: nom=%" PRIu64 ", min=%" PRIu64 1073 ", max=%" PRIu64, nom_blocks, min_blocks, max_blocks); 1052 1074 1053 1075 pcnt = -1; … … 1071 1093 return EINVAL; 1072 1094 1073 printf("fdisk_part_spec_prepare() - switch\n"); 1074 switch (pspec->pkind) { 1075 case lpk_primary: 1076 case lpk_extended: 1077 printf("fdisk_part_spec_prepare() - pri/ext\n"); 1095 if (pspec->pkind == lpk_logical) { 1096 hdrb = max(1, dev->align); 1097 spc = spc_log; 1098 } else { 1099 hdrb = 0; 1100 spc = spc_pri; 1101 } 1102 1103 rc = fdisk_part_get_free_range(dev, hdrb + nom_blocks, spc, 1104 &fblock0, &fnblocks); 1105 1106 if (rc == EOK) { 1107 /* 1108 * If the size of the free range would still give the same capacity 1109 * when rounded, allocate entire range. Otherwise allocate exactly 1110 * what we were asked for. 1111 */ 1112 if (fnblocks <= max_blocks) { 1113 act_blocks = fnblocks; 1114 } else { 1115 act_blocks = hdrb + nom_blocks; 1116 } 1117 } else { 1118 assert(rc == ENOSPC); 1119 1120 /* 1121 * There is no free range that can contain exactly the requested 1122 * capacity. Try to allocate at least such number of blocks 1123 * that would still fullfill the request within the limits 1124 * of the precision with witch the capacity was specified 1125 * (i.e. when rounded up). 1126 */ 1127 rc = fdisk_part_get_free_range(dev, hdrb + min_blocks, spc, 1128 &fblock0, &fnblocks); 1129 if (rc != EOK) 1130 return rc; 1131 1132 assert(fnblocks < hdrb + nom_blocks); 1133 act_blocks = fnblocks; 1134 } 1135 1136 if (pspec->pkind != lpk_logical) { 1078 1137 rc = fdisk_part_get_free_idx(dev, &index); 1079 1138 if (rc != EOK) 1080 1139 return EIO; 1081 1082 printf("fdisk_part_spec_prepare() - get free range\n"); 1083 rc = fdisk_part_get_free_range(dev, req_blocks, spc_pri, 1084 &fblock0, &fnblocks); 1085 if (rc != EOK) 1086 return EIO; 1087 1088 printf("fdisk_part_spec_prepare() - memset\n"); 1089 memset(vpspec, 0, sizeof(vbd_part_spec_t)); 1090 vpspec->index = index; 1091 vpspec->block0 = fblock0; 1092 vpspec->nblocks = req_blocks; 1093 vpspec->pkind = pspec->pkind; 1094 break; 1095 case lpk_logical: 1096 printf("fdisk_part_spec_prepare() - log\n"); 1097 hdrb = max(1, dev->align); 1098 rc = fdisk_part_get_free_range(dev, hdrb + req_blocks, spc_log, 1099 &fblock0, &fnblocks); 1100 if (rc != EOK) 1101 return EIO; 1102 1103 memset(vpspec, 0, sizeof(vbd_part_spec_t)); 1104 vpspec->hdr_blocks = hdrb; 1105 vpspec->block0 = fblock0 + hdrb; 1106 vpspec->nblocks = req_blocks; 1107 vpspec->pkind = lpk_logical; 1108 break; 1109 } 1140 } else { 1141 index = 0; 1142 } 1143 1144 memset(vpspec, 0, sizeof(vbd_part_spec_t)); 1145 vpspec->index = index; 1146 vpspec->hdr_blocks = hdrb; 1147 vpspec->block0 = fblock0 + hdrb; 1148 vpspec->nblocks = act_blocks; 1149 vpspec->pkind = pspec->pkind; 1110 1150 1111 1151 if (pspec->pkind != lpk_extended) { … … 1115 1155 return EIO; 1116 1156 } 1157 1158 printf("fdisk_part_spec_prepare: hdrb=%" PRIu64 ", b0=%" PRIu64 1159 ", nblocks=%" PRIu64 ", pkind=%d\n", vpspec->hdr_blocks, 1160 vpspec->block0, vpspec->nblocks, vpspec->pkind); 1117 1161 1118 1162 return EOK; -
uspace/lib/label/src/mbr.c
r9854a8f r03661d19 512 512 int rc; 513 513 514 log_msg(LOG_DEFAULT, LVL_NOTE, "mbr_part_create"); 514 515 if (pspec->ptype.fmt != lptf_num) 515 516 return EINVAL; … … 521 522 522 523 /* XXX Check if index is used */ 523 524 524 part->label = label; 525 525 part->index = pspec->index; … … 545 545 break; 546 546 case lpk_logical: 547 log_msg(LOG_DEFAULT, LVL_NOTE, "check index");548 547 part->ptype = pspec->ptype; 549 548 if (pspec->index != 0) { … … 587 586 } else { 588 587 /* Logical partition */ 589 590 log_msg(LOG_DEFAULT, LVL_NOTE, "call mbr_log_part_insert");591 588 rc = mbr_log_part_insert(label, part); 592 589 if (rc != EOK) 593 590 goto error; 594 591 595 log_msg(LOG_DEFAULT, LVL_NOTE, "call mbr_ebr_create");596 592 /* Create EBR for new partition */ 597 593 rc = mbr_ebr_create(label, part); … … 601 597 prev = mbr_log_part_prev(part); 602 598 if (prev != NULL) { 603 log_msg(LOG_DEFAULT, LVL_NOTE, "update next");604 599 /* Update 'next' PTE in EBR of previous partition */ 605 600 rc = mbr_ebr_update_next(label, prev); 606 601 if (rc != EOK) { 607 log_msg(LOG_DEFAULT, LVL_NOTE, "failed to update next");608 602 goto error; 609 603 } 610 604 } else { 611 log_msg(LOG_DEFAULT, LVL_NOTE, "relocate first EBR");612 605 /* New partition is now the first one */ 613 606 next = mbr_log_part_next(part);
Note:
See TracChangeset
for help on using the changeset viewer.