diff options
author | Denys Vlasenko <vda.linux@googlemail.com> | 2010-04-06 02:32:26 +0200 |
---|---|---|
committer | Denys Vlasenko <vda.linux@googlemail.com> | 2010-04-06 02:32:26 +0200 |
commit | d958e909cdf40bdf5379f22faaa83d255ec6dc09 (patch) | |
tree | b3eed999aadaebafe8b814b591416be2f2a739a6 | |
parent | 5ea1de2235e75d8fd4f559c7c6cca9a2d0396094 (diff) | |
download | busybox-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.c | 163 |
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); | |||
185 | struct pte { | 185 | struct 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 | |||
448 | static void | 444 | static void |
449 | close_dev_fd(void) | 445 | close_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) | |||
759 | static void | 755 | static void |
760 | read_pte(struct pte *pe, sector_t offset) | 756 | read_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 | ||
774 | static sector_t | 770 | static sector_t |
775 | get_partition_start(const struct pte *pe) | 771 | get_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 | |||
1021 | static 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 | |||
1015 | static void | 1032 | static void |
1016 | set_partition(int i, int doext, sector_t start, sector_t stop, int sysid) | 1033 | set_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 | §or_size, &user_cylinders, &user_heads, &user_sectors); | 2847 | §or_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) |