Changeset 03661d19 in mainline for uspace/lib/fdisk/src/cap.c
- Timestamp:
- 2015-10-29T10:16:08Z (8 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- 55f8c6e7
- Parents:
- 9854a8f
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
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 }
Note:
See TracChangeset
for help on using the changeset viewer.