aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDenys Vlasenko <vda.linux@googlemail.com>2010-04-06 02:32:26 +0200
committerDenys Vlasenko <vda.linux@googlemail.com>2010-04-06 02:32:26 +0200
commitd958e909cdf40bdf5379f22faaa83d255ec6dc09 (patch)
treeb3eed999aadaebafe8b814b591416be2f2a739a6
parent5ea1de2235e75d8fd4f559c7c6cca9a2d0396094 (diff)
downloadbusybox-w32-d958e909cdf40bdf5379f22faaa83d255ec6dc09.tar.gz
busybox-w32-d958e909cdf40bdf5379f22faaa83d255ec6dc09.tar.bz2
busybox-w32-d958e909cdf40bdf5379f22faaa83d255ec6dc09.zip
fdisk: make 'b' command optionally adjust C/H/S; "fdisk IMAGE_FILE" sets cylinders
function old new delta set_hsc_start_end - 189 +189 get_boot 1644 1713 +69 fdisk_main 2620 2652 +32 get_partition_start_from_dev_start - 15 +15 get_partition_start 15 - -15 set_partition 286 120 -166 ------------------------------------------------------------------------------ (add/remove: 2/1 grow/shrink: 2/1 up/down: 305/-181) Total: 124 bytes Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
-rw-r--r--util-linux/fdisk.c163
1 files changed, 89 insertions, 74 deletions
diff --git a/util-linux/fdisk.c b/util-linux/fdisk.c
index cb15bd267..06fb7f9b0 100644
--- a/util-linux/fdisk.c
+++ b/util-linux/fdisk.c
@@ -185,7 +185,7 @@ static sector_t get_nr_sects(const struct partition *p);
185struct pte { 185struct pte {
186 struct partition *part_table; /* points into sectorbuffer */ 186 struct partition *part_table; /* points into sectorbuffer */
187 struct partition *ext_pointer; /* points into sectorbuffer */ 187 struct partition *ext_pointer; /* points into sectorbuffer */
188 sector_t offset; /* disk sector number */ 188 sector_t offset_from_dev_start; /* disk sector number */
189 char *sectorbuffer; /* disk sector contents */ 189 char *sectorbuffer; /* disk sector contents */
190#if ENABLE_FEATURE_FDISK_WRITABLE 190#if ENABLE_FEATURE_FDISK_WRITABLE
191 char changed; /* boolean */ 191 char changed; /* boolean */
@@ -407,8 +407,14 @@ static sector_t bb_BLKGETSIZE_sectors(int fd)
407 return v64; 407 return v64;
408 } 408 }
409 /* Needs temp of type long */ 409 /* Needs temp of type long */
410 if (ioctl(fd, BLKGETSIZE, &longsectors)) 410 if (ioctl(fd, BLKGETSIZE, &longsectors)) {
411 /* Perhaps this is a disk image */
412 off_t sz = lseek(fd, 0, SEEK_END);
411 longsectors = 0; 413 longsectors = 0;
414 if (sz > 0)
415 longsectors = (uoff_t)sz / sector_size;
416 lseek(fd, 0, SEEK_SET);
417 }
412 if (sizeof(long) > sizeof(sector_t) 418 if (sizeof(long) > sizeof(sector_t)
413 && longsectors != (sector_t)longsectors 419 && longsectors != (sector_t)longsectors
414 ) { 420 ) {
@@ -435,16 +441,6 @@ static sector_t bb_BLKGETSIZE_sectors(int fd)
435#define hsc2sector(h,s,c) \ 441#define hsc2sector(h,s,c) \
436 (sector(s) - 1 + sectors * ((h) + heads * cylinder(s,c))) 442 (sector(s) - 1 + sectors * ((h) + heads * cylinder(s,c)))
437 443
438#define set_hsc(h,s,c,sector) \
439 do { \
440 s = sector % g_sectors + 1; \
441 sector /= g_sectors; \
442 h = sector % g_heads; \
443 sector /= g_heads; \
444 c = sector & 0xff; \
445 s |= (sector >> 2) & 0xc0; \
446 } while (0)
447
448static void 444static void
449close_dev_fd(void) 445close_dev_fd(void)
450{ 446{
@@ -603,7 +599,7 @@ read_hex(const char *const *sys)
603 unsigned long v; 599 unsigned long v;
604 while (1) { 600 while (1) {
605 read_nonempty("Hex code (type L to list codes): "); 601 read_nonempty("Hex code (type L to list codes): ");
606 if (*line_ptr == 'l' || *line_ptr == 'L') { 602 if ((line_ptr[0] | 0x20) == 'l') {
607 list_types(sys); 603 list_types(sys);
608 continue; 604 continue;
609 } 605 }
@@ -759,7 +755,7 @@ set_nr_sects(struct partition *p, unsigned nr_sects)
759static void 755static void
760read_pte(struct pte *pe, sector_t offset) 756read_pte(struct pte *pe, sector_t offset)
761{ 757{
762 pe->offset = offset; 758 pe->offset_from_dev_start = offset;
763 pe->sectorbuffer = xzalloc(sector_size); 759 pe->sectorbuffer = xzalloc(sector_size);
764 seek_sector(offset); 760 seek_sector(offset);
765 /* xread would make us abort - bad for fdisk -l */ 761 /* xread would make us abort - bad for fdisk -l */
@@ -772,9 +768,9 @@ read_pte(struct pte *pe, sector_t offset)
772} 768}
773 769
774static sector_t 770static sector_t
775get_partition_start(const struct pte *pe) 771get_partition_start_from_dev_start(const struct pte *pe)
776{ 772{
777 return pe->offset + get_start_sect(pe->part_table); 773 return pe->offset_from_dev_start + get_start_sect(pe->part_table);
778} 774}
779 775
780#if ENABLE_FEATURE_FDISK_WRITABLE 776#if ENABLE_FEATURE_FDISK_WRITABLE
@@ -1012,6 +1008,27 @@ list_types(const char *const *sys)
1012 bb_putchar('\n'); 1008 bb_putchar('\n');
1013} 1009}
1014 1010
1011#define set_hsc(h, s, c, sector) do \
1012{ \
1013 s = sector % g_sectors + 1; \
1014 sector /= g_sectors; \
1015 h = sector % g_heads; \
1016 sector /= g_heads; \
1017 c = sector & 0xff; \
1018 s |= (sector >> 2) & 0xc0; \
1019} while (0)
1020
1021static void set_hsc_start_end(struct partition *p, sector_t start, sector_t stop)
1022{
1023 if (dos_compatible_flag && (start / (g_sectors * g_heads) > 1023))
1024 start = g_heads * g_sectors * 1024 - 1;
1025 set_hsc(p->head, p->sector, p->cyl, start);
1026
1027 if (dos_compatible_flag && (stop / (g_sectors * g_heads) > 1023))
1028 stop = g_heads * g_sectors * 1024 - 1;
1029 set_hsc(p->end_head, p->end_sector, p->end_cyl, stop);
1030}
1031
1015static void 1032static void
1016set_partition(int i, int doext, sector_t start, sector_t stop, int sysid) 1033set_partition(int i, int doext, sector_t start, sector_t stop, int sysid)
1017{ 1034{
@@ -1023,18 +1040,13 @@ set_partition(int i, int doext, sector_t start, sector_t stop, int sysid)
1023 offset = extended_offset; 1040 offset = extended_offset;
1024 } else { 1041 } else {
1025 p = ptes[i].part_table; 1042 p = ptes[i].part_table;
1026 offset = ptes[i].offset; 1043 offset = ptes[i].offset_from_dev_start;
1027 } 1044 }
1028 p->boot_ind = 0; 1045 p->boot_ind = 0;
1029 p->sys_ind = sysid; 1046 p->sys_ind = sysid;
1030 set_start_sect(p, start - offset); 1047 set_start_sect(p, start - offset);
1031 set_nr_sects(p, stop - start + 1); 1048 set_nr_sects(p, stop - start + 1);
1032 if (dos_compatible_flag && (start / (g_sectors * g_heads) > 1023)) 1049 set_hsc_start_end(p, start, stop);
1033 start = g_heads * g_sectors * 1024 - 1;
1034 set_hsc(p->head, p->sector, p->cyl, start);
1035 if (dos_compatible_flag && (stop / (g_sectors * g_heads) > 1023))
1036 stop = g_heads * g_sectors * 1024 - 1;
1037 set_hsc(p->end_head, p->end_sector, p->end_cyl, stop);
1038 ptes[i].changed = 1; 1050 ptes[i].changed = 1;
1039} 1051}
1040#endif 1052#endif
@@ -1316,7 +1328,7 @@ static int get_boot(void)
1316 struct pte *pe = &ptes[i]; 1328 struct pte *pe = &ptes[i];
1317 pe->part_table = pt_offset(MBRbuffer, i); 1329 pe->part_table = pt_offset(MBRbuffer, i);
1318 pe->ext_pointer = NULL; 1330 pe->ext_pointer = NULL;
1319 pe->offset = 0; 1331 pe->offset_from_dev_start = 0;
1320 pe->sectorbuffer = MBRbuffer; 1332 pe->sectorbuffer = MBRbuffer;
1321#if ENABLE_FEATURE_FDISK_WRITABLE 1333#if ENABLE_FEATURE_FDISK_WRITABLE
1322 pe->changed = (what == CREATE_EMPTY_DOS); 1334 pe->changed = (what == CREATE_EMPTY_DOS);
@@ -1700,9 +1712,9 @@ delete_partition(int i)
1700 1712
1701 if (pe->part_table) /* prevent SEGFAULT */ 1713 if (pe->part_table) /* prevent SEGFAULT */
1702 set_start_sect(pe->part_table, 1714 set_start_sect(pe->part_table,
1703 get_partition_start(pe) - 1715 get_partition_start_from_dev_start(pe) -
1704 extended_offset); 1716 extended_offset);
1705 pe->offset = extended_offset; 1717 pe->offset_from_dev_start = extended_offset;
1706 pe->changed = 1; 1718 pe->changed = 1;
1707 } 1719 }
1708 1720
@@ -1914,7 +1926,7 @@ wrong_p_order(int *prev)
1914 pe = &ptes[i]; 1926 pe = &ptes[i];
1915 p = pe->part_table; 1927 p = pe->part_table;
1916 if (p->sys_ind) { 1928 if (p->sys_ind) {
1917 p_start_pos = get_partition_start(pe); 1929 p_start_pos = get_partition_start_from_dev_start(pe);
1918 1930
1919 if (last_p_start_pos > p_start_pos) { 1931 if (last_p_start_pos > p_start_pos) {
1920 if (prev) 1932 if (prev)
@@ -1953,11 +1965,11 @@ fix_chain_of_logicals(void)
1953 /* (Its sector is the global extended_offset.) */ 1965 /* (Its sector is the global extended_offset.) */
1954 stage1: 1966 stage1:
1955 for (j = 5; j < g_partitions - 1; j++) { 1967 for (j = 5; j < g_partitions - 1; j++) {
1956 oj = ptes[j].offset; 1968 oj = ptes[j].offset_from_dev_start;
1957 ojj = ptes[j+1].offset; 1969 ojj = ptes[j+1].offset_from_dev_start;
1958 if (oj > ojj) { 1970 if (oj > ojj) {
1959 ptes[j].offset = ojj; 1971 ptes[j].offset_from_dev_start = ojj;
1960 ptes[j+1].offset = oj; 1972 ptes[j+1].offset_from_dev_start = oj;
1961 pj = ptes[j].part_table; 1973 pj = ptes[j].part_table;
1962 set_start_sect(pj, get_start_sect(pj)+oj-ojj); 1974 set_start_sect(pj, get_start_sect(pj)+oj-ojj);
1963 pjj = ptes[j+1].part_table; 1975 pjj = ptes[j+1].part_table;
@@ -1977,8 +1989,8 @@ fix_chain_of_logicals(void)
1977 pjj = ptes[j+1].part_table; 1989 pjj = ptes[j+1].part_table;
1978 sj = get_start_sect(pj); 1990 sj = get_start_sect(pj);
1979 sjj = get_start_sect(pjj); 1991 sjj = get_start_sect(pjj);
1980 oj = ptes[j].offset; 1992 oj = ptes[j].offset_from_dev_start;
1981 ojj = ptes[j+1].offset; 1993 ojj = ptes[j+1].offset_from_dev_start;
1982 if (oj+sj > ojj+sjj) { 1994 if (oj+sj > ojj+sjj) {
1983 tmp = *pj; 1995 tmp = *pj;
1984 *pj = *pjj; 1996 *pj = *pjj;
@@ -2095,8 +2107,8 @@ list_table(int xtra)
2095 partname(disk_device, i+1, w+2), 2107 partname(disk_device, i+1, w+2),
2096 !p->boot_ind ? ' ' : p->boot_ind == ACTIVE_FLAG /* boot flag */ 2108 !p->boot_ind ? ' ' : p->boot_ind == ACTIVE_FLAG /* boot flag */
2097 ? '*' : '?', 2109 ? '*' : '?',
2098 cround(get_partition_start(pe)), /* start */ 2110 cround(get_partition_start_from_dev_start(pe)), /* start */
2099 cround(get_partition_start(pe) + psects /* end */ 2111 cround(get_partition_start_from_dev_start(pe) + psects /* end */
2100 - (psects ? 1 : 0)), 2112 - (psects ? 1 : 0)),
2101 pblocks, podd ? '+' : ' ', /* odd flag on end */ 2113 pblocks, podd ? '+' : ' ', /* odd flag on end */
2102 p->sys_ind, /* type id */ 2114 p->sys_ind, /* type id */
@@ -2158,7 +2170,7 @@ fill_bounds(sector_t *first, sector_t *last)
2158 first[i] = 0xffffffff; 2170 first[i] = 0xffffffff;
2159 last[i] = 0; 2171 last[i] = 0;
2160 } else { 2172 } else {
2161 first[i] = get_partition_start(pe); 2173 first[i] = get_partition_start_from_dev_start(pe);
2162 last[i] = first[i] + get_nr_sects(p) - 1; 2174 last[i] = first[i] + get_nr_sects(p) - 1;
2163 } 2175 }
2164 } 2176 }
@@ -2215,7 +2227,7 @@ verify(void)
2215 p = pe->part_table; 2227 p = pe->part_table;
2216 if (p->sys_ind && !IS_EXTENDED(p->sys_ind)) { 2228 if (p->sys_ind && !IS_EXTENDED(p->sys_ind)) {
2217 check_consistency(p, i); 2229 check_consistency(p, i);
2218 if (get_partition_start(pe) < first[i]) 2230 if (get_partition_start_from_dev_start(pe) < first[i])
2219 printf("Warning: bad start-of-data in " 2231 printf("Warning: bad start-of-data in "
2220 "partition %u\n", i + 1); 2232 "partition %u\n", i + 1);
2221 check(i + 1, p->end_head, p->end_sector, p->end_cyl, 2233 check(i + 1, p->end_head, p->end_sector, p->end_cyl,
@@ -2305,7 +2317,7 @@ add_partition(int n, int sys)
2305 for (i = 0; i < g_partitions; i++) { 2317 for (i = 0; i < g_partitions; i++) {
2306 int lastplusoff; 2318 int lastplusoff;
2307 2319
2308 if (start == ptes[i].offset) 2320 if (start == ptes[i].offset_from_dev_start)
2309 start += sector_offset; 2321 start += sector_offset;
2310 lastplusoff = last[i] + ((n < 4) ? 0 : sector_offset); 2322 lastplusoff = last[i] + ((n < 4) ? 0 : sector_offset);
2311 if (start >= first[i] && start <= lastplusoff) 2323 if (start >= first[i] && start <= lastplusoff)
@@ -2322,8 +2334,7 @@ add_partition(int n, int sys)
2322 sector_t saved_start; 2334 sector_t saved_start;
2323 2335
2324 saved_start = start; 2336 saved_start = start;
2325 start = read_int(cround(saved_start), cround(saved_start), cround(limit), 2337 start = read_int(cround(saved_start), cround(saved_start), cround(limit), 0, mesg);
2326 0, mesg);
2327 if (display_in_cyl_units) { 2338 if (display_in_cyl_units) {
2328 start = (start - 1) * units_per_sector; 2339 start = (start - 1) * units_per_sector;
2329 if (start < saved_start) 2340 if (start < saved_start)
@@ -2335,9 +2346,9 @@ add_partition(int n, int sys)
2335 if (n > 4) { /* NOT for fifth partition */ 2346 if (n > 4) { /* NOT for fifth partition */
2336 struct pte *pe = &ptes[n]; 2347 struct pte *pe = &ptes[n];
2337 2348
2338 pe->offset = start - sector_offset; 2349 pe->offset_from_dev_start = start - sector_offset;
2339 if (pe->offset == extended_offset) { /* must be corrected */ 2350 if (pe->offset_from_dev_start == extended_offset) { /* must be corrected */
2340 pe->offset++; 2351 pe->offset_from_dev_start++;
2341 if (sector_offset == 1) 2352 if (sector_offset == 1)
2342 start++; 2353 start++;
2343 } 2354 }
@@ -2346,8 +2357,8 @@ add_partition(int n, int sys)
2346 for (i = 0; i < g_partitions; i++) { 2357 for (i = 0; i < g_partitions; i++) {
2347 struct pte *pe = &ptes[i]; 2358 struct pte *pe = &ptes[i];
2348 2359
2349 if (start < pe->offset && limit >= pe->offset) 2360 if (start < pe->offset_from_dev_start && limit >= pe->offset_from_dev_start)
2350 limit = pe->offset - 1; 2361 limit = pe->offset_from_dev_start - 1;
2351 if (start < first[i] && limit >= first[i]) 2362 if (start < first[i] && limit >= first[i])
2352 limit = first[i] - 1; 2363 limit = first[i] - 1;
2353 } 2364 }
@@ -2363,8 +2374,7 @@ add_partition(int n, int sys)
2363 snprintf(mesg, sizeof(mesg), 2374 snprintf(mesg, sizeof(mesg),
2364 "Last %s or +size or +sizeM or +sizeK", 2375 "Last %s or +size or +sizeM or +sizeK",
2365 str_units(SINGULAR)); 2376 str_units(SINGULAR));
2366 stop = read_int(cround(start), cround(limit), cround(limit), 2377 stop = read_int(cround(start), cround(limit), cround(limit), cround(start), mesg);
2367 cround(start), mesg);
2368 if (display_in_cyl_units) { 2378 if (display_in_cyl_units) {
2369 stop = stop * units_per_sector - 1; 2379 stop = stop * units_per_sector - 1;
2370 if (stop >limit) 2380 if (stop >limit)
@@ -2374,7 +2384,7 @@ add_partition(int n, int sys)
2374 2384
2375 set_partition(n, 0, start, stop, sys); 2385 set_partition(n, 0, start, stop, sys);
2376 if (n > 4) 2386 if (n > 4)
2377 set_partition(n - 1, 1, ptes[n].offset, stop, EXTENDED); 2387 set_partition(n - 1, 1, ptes[n].offset_from_dev_start, stop, EXTENDED);
2378 2388
2379 if (IS_EXTENDED(sys)) { 2389 if (IS_EXTENDED(sys)) {
2380 struct pte *pe4 = &ptes[4]; 2390 struct pte *pe4 = &ptes[4];
@@ -2382,7 +2392,7 @@ add_partition(int n, int sys)
2382 2392
2383 ext_index = n; 2393 ext_index = n;
2384 pen->ext_pointer = p; 2394 pen->ext_pointer = p;
2385 pe4->offset = extended_offset = start; 2395 pe4->offset_from_dev_start = extended_offset = start;
2386 pe4->sectorbuffer = xzalloc(sector_size); 2396 pe4->sectorbuffer = xzalloc(sector_size);
2387 pe4->part_table = pt_offset(pe4->sectorbuffer, 0); 2397 pe4->part_table = pt_offset(pe4->sectorbuffer, 0);
2388 pe4->ext_pointer = pe4->part_table + 1; 2398 pe4->ext_pointer = pe4->part_table + 1;
@@ -2400,7 +2410,7 @@ add_logical(void)
2400 pe->sectorbuffer = xzalloc(sector_size); 2410 pe->sectorbuffer = xzalloc(sector_size);
2401 pe->part_table = pt_offset(pe->sectorbuffer, 0); 2411 pe->part_table = pt_offset(pe->sectorbuffer, 0);
2402 pe->ext_pointer = pe->part_table + 1; 2412 pe->ext_pointer = pe->part_table + 1;
2403 pe->offset = 0; 2413 pe->offset_from_dev_start = 0;
2404 pe->changed = 1; 2414 pe->changed = 1;
2405 g_partitions++; 2415 g_partitions++;
2406 } 2416 }
@@ -2454,7 +2464,7 @@ new_partition(void)
2454 "l logical (5 or over)" : "e extended")); 2464 "l logical (5 or over)" : "e extended"));
2455 while (1) { 2465 while (1) {
2456 c = read_nonempty(line); 2466 c = read_nonempty(line);
2457 if (c == 'p' || c == 'P') { 2467 if ((c | 0x20) == 'p') {
2458 i = get_nonexisting_partition(0, 4); 2468 i = get_nonexisting_partition(0, 4);
2459 if (i >= 0) 2469 if (i >= 0)
2460 add_partition(i, LINUX_NATIVE); 2470 add_partition(i, LINUX_NATIVE);
@@ -2490,7 +2500,7 @@ write_table(void)
2490 2500
2491 if (pe->changed) { 2501 if (pe->changed) {
2492 write_part_table_flag(pe->sectorbuffer); 2502 write_part_table_flag(pe->sectorbuffer);
2493 write_sector(pe->offset, pe->sectorbuffer); 2503 write_sector(pe->offset_from_dev_start, pe->sectorbuffer);
2494 } 2504 }
2495 } 2505 }
2496 } 2506 }
@@ -2579,22 +2589,26 @@ move_begin(unsigned i)
2579{ 2589{
2580 struct pte *pe = &ptes[i]; 2590 struct pte *pe = &ptes[i];
2581 struct partition *p = pe->part_table; 2591 struct partition *p = pe->part_table;
2582 sector_t new, first; 2592 sector_t new, first, nr_sects;
2583 2593
2584 if (warn_geometry()) 2594 if (warn_geometry())
2585 return; 2595 return;
2586 if (!p->sys_ind || !get_nr_sects(p) || IS_EXTENDED(p->sys_ind)) { 2596 nr_sects = get_nr_sects(p);
2597 if (!p->sys_ind || !nr_sects || IS_EXTENDED(p->sys_ind)) {
2587 printf("Partition %u has no data area\n", i + 1); 2598 printf("Partition %u has no data area\n", i + 1);
2588 return; 2599 return;
2589 } 2600 }
2590 first = get_partition_start(pe); 2601 first = get_partition_start_from_dev_start(pe);
2591 new = read_int(first, first, first + get_nr_sects(p) - 1, first, 2602 /* == pe->offset_from_dev_start + get_start_sect(p) */
2592 "New beginning of data") - pe->offset; 2603 new = read_int(0 /*was:first*/, first, first + nr_sects - 1, first, "New beginning of data");
2593 2604 if (new != first) {
2594 if (new != get_nr_sects(p)) { 2605 sector_t new_relative = new - pe->offset_from_dev_start;
2595 first = get_nr_sects(p) + get_start_sect(p) - new; 2606 nr_sects += (get_start_sect(p) - new_relative);
2596 set_nr_sects(p, first); 2607 set_start_sect(p, new_relative);
2597 set_start_sect(p, new); 2608 set_nr_sects(p, nr_sects);
2609 read_nonempty("Recalculate C/H/S values? (Y/N): ");
2610 if ((line_ptr[0] | 0x20) == 'y')
2611 set_hsc_start_end(p, new, new + nr_sects - 1);
2598 pe->changed = 1; 2612 pe->changed = 1;
2599 } 2613 }
2600} 2614}
@@ -2606,7 +2620,7 @@ xselect(void)
2606 2620
2607 while (1) { 2621 while (1) {
2608 bb_putchar('\n'); 2622 bb_putchar('\n');
2609 c = tolower(read_nonempty("Expert command (m for help): ")); 2623 c = 0x20 | read_nonempty("Expert command (m for help): ");
2610 switch (c) { 2624 switch (c) {
2611 case 'a': 2625 case 'a':
2612 if (LABEL_IS_SUN) 2626 if (LABEL_IS_SUN)
@@ -2646,8 +2660,7 @@ xselect(void)
2646#endif 2660#endif
2647 break; 2661 break;
2648 case 'h': 2662 case 'h':
2649 user_heads = g_heads = read_int(1, g_heads, 256, 0, 2663 user_heads = g_heads = read_int(1, g_heads, 256, 0, "Number of heads");
2650 "Number of heads");
2651 update_units(); 2664 update_units();
2652 break; 2665 break;
2653 case 'i': 2666 case 'i':
@@ -2672,8 +2685,7 @@ xselect(void)
2672 case 'r': 2685 case 'r':
2673 return; 2686 return;
2674 case 's': 2687 case 's':
2675 user_sectors = g_sectors = read_int(1, g_sectors, 63, 0, 2688 user_sectors = g_sectors = read_int(1, g_sectors, 63, 0, "Number of sectors");
2676 "Number of sectors");
2677 if (dos_compatible_flag) { 2689 if (dos_compatible_flag) {
2678 sector_offset = g_sectors; 2690 sector_offset = g_sectors;
2679 printf("Warning: setting sector offset for DOS " 2691 printf("Warning: setting sector offset for DOS "
@@ -2834,14 +2846,17 @@ int fdisk_main(int argc UNUSED_PARAM, char **argv)
2834 opt = getopt32(argv, "b:C:H:lS:u" IF_FEATURE_FDISK_BLKSIZE("s"), 2846 opt = getopt32(argv, "b:C:H:lS:u" IF_FEATURE_FDISK_BLKSIZE("s"),
2835 &sector_size, &user_cylinders, &user_heads, &user_sectors); 2847 &sector_size, &user_cylinders, &user_heads, &user_sectors);
2836 argv += optind; 2848 argv += optind;
2837 if (opt & OPT_b) { // -b 2849 if (opt & OPT_b) {
2838 /* Ugly: this sector size is really per device, 2850 /* Ugly: this sector size is really per device,
2839 so cannot be combined with multiple disks, 2851 * so cannot be combined with multiple disks,
2840 and the same goes for the C/H/S options. 2852 * and the same goes for the C/H/S options.
2841 */ 2853 */
2842 if (sector_size != 512 && sector_size != 1024 2854 if (sector_size < 512
2843 && sector_size != 2048) 2855 || sector_size > 0x10000
2856 || (sector_size & (sector_size-1)) /* not power of 2 */
2857 ) {
2844 bb_show_usage(); 2858 bb_show_usage();
2859 }
2845 sector_offset = 2; 2860 sector_offset = 2;
2846 user_set_sector_size = 1; 2861 user_set_sector_size = 1;
2847 } 2862 }
@@ -2912,7 +2927,7 @@ int fdisk_main(int argc UNUSED_PARAM, char **argv)
2912 while (1) { 2927 while (1) {
2913 int c; 2928 int c;
2914 bb_putchar('\n'); 2929 bb_putchar('\n');
2915 c = tolower(read_nonempty("Command (m for help): ")); 2930 c = 0x20 | read_nonempty("Command (m for help): ");
2916 switch (c) { 2931 switch (c) {
2917 case 'a': 2932 case 'a':
2918 if (LABEL_IS_DOS) 2933 if (LABEL_IS_DOS)