aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorvda <vda@69ca8d6d-28ef-0310-b511-8ec308f3f277>2007-06-02 12:46:55 +0000
committervda <vda@69ca8d6d-28ef-0310-b511-8ec308f3f277>2007-06-02 12:46:55 +0000
commit95a9140eceb43d5dba205e171d7a5e09f67331ff (patch)
treee23f7695f19b8a57a5482656d8930a0b842de692
parentff570eb12ef446c0e85ab81697e6a81771c7d6da (diff)
downloadbusybox-w32-95a9140eceb43d5dba205e171d7a5e09f67331ff.tar.gz
busybox-w32-95a9140eceb43d5dba205e171d7a5e09f67331ff.tar.bz2
busybox-w32-95a9140eceb43d5dba205e171d7a5e09f67331ff.zip
fdisk: make it work with big disks (read: typical today's disks)
even if CONFIG_LFS is unset. git-svn-id: svn://busybox.net/trunk/busybox@18727 69ca8d6d-28ef-0310-b511-8ec308f3f277
-rw-r--r--util-linux/fdisk.c141
1 files changed, 58 insertions, 83 deletions
diff --git a/util-linux/fdisk.c b/util-linux/fdisk.c
index a1893c66e..ed5abe956 100644
--- a/util-linux/fdisk.c
+++ b/util-linux/fdisk.c
@@ -7,6 +7,10 @@
7 * Licensed under the GPL v2 or later, see the file LICENSE in this tarball. 7 * Licensed under the GPL v2 or later, see the file LICENSE in this tarball.
8 */ 8 */
9 9
10#ifndef _LARGEFILE64_SOURCE
11/* For lseek64 */
12#define _LARGEFILE64_SOURCE
13#endif
10#include <assert.h> /* assert */ 14#include <assert.h> /* assert */
11#include "libbb.h" 15#include "libbb.h"
12 16
@@ -34,6 +38,9 @@
34#define LINUX_LVM 0x8e 38#define LINUX_LVM 0x8e
35#define LINUX_RAID 0xfd 39#define LINUX_RAID 0xfd
36 40
41/* Used for sector numbers. Today's disk sizes make it necessary */
42typedef unsigned long long ullong;
43
37struct hd_geometry { 44struct hd_geometry {
38 unsigned char heads; 45 unsigned char heads;
39 unsigned char sectors; 46 unsigned char sectors;
@@ -77,10 +84,12 @@ struct partition {
77 unsigned char size4[4]; /* nr of sectors in partition */ 84 unsigned char size4[4]; /* nr of sectors in partition */
78} ATTRIBUTE_PACKED; 85} ATTRIBUTE_PACKED;
79 86
80enum failure { 87static const char unable_to_open[] = "cannot open %s";
81 ioctl_error, unable_to_open, unable_to_read, unable_to_seek, 88static const char unable_to_read[] = "cannot read from %s";
82 unable_to_write 89static const char unable_to_seek[] = "cannot seek on %s";
83}; 90static const char unable_to_write[] = "cannot write to %s";
91static const char ioctl_error[] = "BLKGETSIZE ioctl failed on %s";
92static void fdisk_fatal(const char *why) ATTRIBUTE_NORETURN;
84 93
85enum label_type { 94enum label_type {
86 label_dos, label_sun, label_sgi, label_aix, label_osf 95 label_dos, label_sun, label_sgi, label_aix, label_osf
@@ -138,7 +147,6 @@ static void list_types(const char *const *sys);
138static unsigned read_int(unsigned low, unsigned dflt, unsigned high, unsigned base, const char *mesg); 147static unsigned read_int(unsigned low, unsigned dflt, unsigned high, unsigned base, const char *mesg);
139#endif 148#endif
140static const char *partition_type(unsigned char type); 149static const char *partition_type(unsigned char type);
141static void fdisk_fatal(enum failure why) ATTRIBUTE_NORETURN;
142static void get_geometry(void); 150static void get_geometry(void);
143static int get_boot(enum action what); 151static int get_boot(enum action what);
144 152
@@ -159,7 +167,7 @@ static unsigned get_nr_sects(const struct partition *p);
159struct pte { 167struct pte {
160 struct partition *part_table; /* points into sectorbuffer */ 168 struct partition *part_table; /* points into sectorbuffer */
161 struct partition *ext_pointer; /* points into sectorbuffer */ 169 struct partition *ext_pointer; /* points into sectorbuffer */
162 off_t offset; /* disk sector number */ 170 ullong offset; /* disk sector number */
163 char *sectorbuffer; /* disk sector contents */ 171 char *sectorbuffer; /* disk sector contents */
164#if ENABLE_FEATURE_FDISK_WRITABLE 172#if ENABLE_FEATURE_FDISK_WRITABLE
165 char changed; /* boolean */ 173 char changed; /* boolean */
@@ -604,69 +612,41 @@ get_nr_sects(const struct partition *p)
604/* normally O_RDWR, -l option gives O_RDONLY */ 612/* normally O_RDWR, -l option gives O_RDONLY */
605static int type_open = O_RDWR; 613static int type_open = O_RDWR;
606 614
607
608static int ext_index; /* the prime extended partition */ 615static int ext_index; /* the prime extended partition */
609static int listing; /* no aborts for fdisk -l */ 616static int listing; /* no aborts for fdisk -l */
610static int dos_compatible_flag = ~0; 617static int dos_compatible_flag = ~0;
611#if ENABLE_FEATURE_FDISK_WRITABLE 618#if ENABLE_FEATURE_FDISK_WRITABLE
612static int dos_changed; 619static int dos_changed;
613static int nowarn; /* no warnings for fdisk -l/-s */ 620static int nowarn; /* no warnings for fdisk -l/-s */
614#endif 621#endif
615 622
616
617
618static unsigned user_cylinders, user_heads, user_sectors; 623static unsigned user_cylinders, user_heads, user_sectors;
619static unsigned pt_heads, pt_sectors; 624static unsigned pt_heads, pt_sectors;
620static unsigned kern_heads, kern_sectors; 625static unsigned kern_heads, kern_sectors;
621 626
622static off_t extended_offset; /* offset of link pointers */ 627static ullong extended_offset; /* offset of link pointers */
623 628static ullong total_number_of_sectors;
624static unsigned long long total_number_of_sectors;
625 629
626 630static void fdisk_fatal(const char *why)
627static void fdisk_fatal(enum failure why)
628{ 631{
629 const char *message;
630
631 if (listing) { 632 if (listing) {
632 close(fd); 633 close(fd);
633 longjmp(listingbuf, 1); 634 longjmp(listingbuf, 1);
634 } 635 }
635 636 bb_error_msg_and_die(why, disk_device);
636 switch (why) {
637 case unable_to_open:
638 message = "cannot open %s";
639 break;
640 case unable_to_read:
641 message = "cannot read from %s";
642 break;
643 case unable_to_seek:
644 message = "cannot seek on %s";
645 break;
646 case unable_to_write:
647 message = "cannot write to %s";
648 break;
649 case ioctl_error:
650 message = "BLKGETSIZE ioctl failed on %s";
651 break;
652 default:
653 message = "fatal error";
654 }
655
656 bb_error_msg_and_die(message, disk_device);
657} 637}
658 638
659static void 639static void
660seek_sector(off_t secno) 640seek_sector(ullong secno)
661{ 641{
662 off_t offset = secno * sector_size; 642 secno *= sector_size;
663 if (lseek(fd, offset, SEEK_SET) == (off_t) -1) 643 if (lseek64(fd, (off64_t)secno, SEEK_SET) == (off64_t) -1)
664 fdisk_fatal(unable_to_seek); 644 fdisk_fatal(unable_to_seek);
665} 645}
666 646
667#if ENABLE_FEATURE_FDISK_WRITABLE 647#if ENABLE_FEATURE_FDISK_WRITABLE
668static void 648static void
669write_sector(off_t secno, char *buf) 649write_sector(ullong secno, char *buf)
670{ 650{
671 seek_sector(secno); 651 seek_sector(secno);
672 if (write(fd, buf, sector_size) != sector_size) 652 if (write(fd, buf, sector_size) != sector_size)
@@ -676,7 +656,7 @@ write_sector(off_t secno, char *buf)
676 656
677/* Allocate a buffer and read a partition table sector */ 657/* Allocate a buffer and read a partition table sector */
678static void 658static void
679read_pte(struct pte *pe, off_t offset) 659read_pte(struct pte *pe, ullong offset)
680{ 660{
681 pe->offset = offset; 661 pe->offset = offset;
682 pe->sectorbuffer = xmalloc(sector_size); 662 pe->sectorbuffer = xmalloc(sector_size);
@@ -928,10 +908,10 @@ clear_partition(struct partition *p)
928 908
929#if ENABLE_FEATURE_FDISK_WRITABLE 909#if ENABLE_FEATURE_FDISK_WRITABLE
930static void 910static void
931set_partition(int i, int doext, off_t start, off_t stop, int sysid) 911set_partition(int i, int doext, ullong start, ullong stop, int sysid)
932{ 912{
933 struct partition *p; 913 struct partition *p;
934 off_t offset; 914 ullong offset;
935 915
936 if (doext) { 916 if (doext) {
937 p = ptes[i].ext_pointer; 917 p = ptes[i].ext_pointer;
@@ -1182,7 +1162,7 @@ static void
1182get_geometry(void) 1162get_geometry(void)
1183{ 1163{
1184 int sec_fac; 1164 int sec_fac;
1185 unsigned long long bytes; /* really u64 */ 1165 uint64_t v64;
1186 1166
1187 get_sectorsize(); 1167 get_sectorsize();
1188 sec_fac = sector_size / 512; 1168 sec_fac = sector_size / 512;
@@ -1202,18 +1182,16 @@ get_geometry(void)
1202 sectors = user_sectors ? user_sectors : 1182 sectors = user_sectors ? user_sectors :
1203 pt_sectors ? pt_sectors : 1183 pt_sectors ? pt_sectors :
1204 kern_sectors ? kern_sectors : 63; 1184 kern_sectors ? kern_sectors : 63;
1205 if (ioctl(fd, BLKGETSIZE64, &bytes) == 0) { 1185 if (ioctl(fd, BLKGETSIZE64, &v64) == 0) {
1206 /* got bytes */ 1186 /* got bytes, convert to 512 byte sectors */
1187 total_number_of_sectors = (v64 >> 9);
1207 } else { 1188 } else {
1208 unsigned long longsectors; 1189 unsigned long longsectors; /* need temp of type long */
1209 1190 if (ioctl(fd, BLKGETSIZE, &longsectors))
1210 if (ioctl(fd, BLKGETSIZE, &longsectors)) 1191 longsectors = 0;
1211 longsectors = 0; 1192 total_number_of_sectors = longsectors;
1212 bytes = ((unsigned long long) longsectors) << 9;
1213 } 1193 }
1214 1194
1215 total_number_of_sectors = (bytes >> 9);
1216
1217 sector_offset = 1; 1195 sector_offset = 1;
1218 if (dos_compatible_flag) 1196 if (dos_compatible_flag)
1219 sector_offset = sectors; 1197 sector_offset = sectors;
@@ -1447,10 +1425,10 @@ read_int(unsigned low, unsigned dflt, unsigned high, unsigned base, const char *
1447 break; 1425 break;
1448 } 1426 }
1449 if (absolute) { 1427 if (absolute) {
1450 unsigned long long bytes; 1428 ullong bytes;
1451 unsigned long unit; 1429 unsigned long unit;
1452 1430
1453 bytes = (unsigned long long) i * absolute; 1431 bytes = (ullong) i * absolute;
1454 unit = sector_size * units_per_sector; 1432 unit = sector_size * units_per_sector;
1455 bytes += unit/2; /* round */ 1433 bytes += unit/2; /* round */
1456 bytes /= unit; 1434 bytes /= unit;
@@ -1844,7 +1822,7 @@ wrong_p_order(int *prev)
1844{ 1822{
1845 const struct pte *pe; 1823 const struct pte *pe;
1846 const struct partition *p; 1824 const struct partition *p;
1847 off_t last_p_start_pos = 0, p_start_pos; 1825 ullong last_p_start_pos = 0, p_start_pos;
1848 int i, last_i = 0; 1826 int i, last_i = 0;
1849 1827
1850 for (i = 0 ; i < partitions; i++) { 1828 for (i = 0 ; i < partitions; i++) {
@@ -2012,8 +1990,8 @@ list_table(int xtra)
2012 1990
2013 for (i = 0; i < partitions; i++) { 1991 for (i = 0; i < partitions; i++) {
2014 const struct pte *pe = &ptes[i]; 1992 const struct pte *pe = &ptes[i];
2015 off_t psects; 1993 ullong psects;
2016 off_t pblocks; 1994 ullong pblocks;
2017 unsigned podd; 1995 unsigned podd;
2018 1996
2019 p = pe->part_table; 1997 p = pe->part_table;
@@ -2035,10 +2013,10 @@ list_table(int xtra)
2035 partname(disk_device, i+1, w+2), 2013 partname(disk_device, i+1, w+2),
2036 !p->boot_ind ? ' ' : p->boot_ind == ACTIVE_FLAG /* boot flag */ 2014 !p->boot_ind ? ' ' : p->boot_ind == ACTIVE_FLAG /* boot flag */
2037 ? '*' : '?', 2015 ? '*' : '?',
2038 (unsigned long long) cround(get_partition_start(pe)), /* start */ 2016 (ullong) cround(get_partition_start(pe)), /* start */
2039 (unsigned long long) cround(get_partition_start(pe) + psects /* end */ 2017 (ullong) cround(get_partition_start(pe) + psects /* end */
2040 - (psects ? 1 : 0)), 2018 - (psects ? 1 : 0)),
2041 (unsigned long long) pblocks, podd ? '+' : ' ', /* odd flag on end */ 2019 (ullong) pblocks, podd ? '+' : ' ', /* odd flag on end */
2042 p->sys_ind, /* type id */ 2020 p->sys_ind, /* type id */
2043 partition_type(p->sys_ind)); /* type name */ 2021 partition_type(p->sys_ind)); /* type name */
2044 2022
@@ -2085,7 +2063,7 @@ x_list_table(int extend)
2085 2063
2086#if ENABLE_FEATURE_FDISK_WRITABLE 2064#if ENABLE_FEATURE_FDISK_WRITABLE
2087static void 2065static void
2088fill_bounds(off_t *first, off_t *last) 2066fill_bounds(ullong *first, ullong *last)
2089{ 2067{
2090 int i; 2068 int i;
2091 const struct pte *pe = &ptes[0]; 2069 const struct pte *pe = &ptes[0];
@@ -2104,9 +2082,9 @@ fill_bounds(off_t *first, off_t *last)
2104} 2082}
2105 2083
2106static void 2084static void
2107check(int n, unsigned h, unsigned s, unsigned c, off_t start) 2085check(int n, unsigned h, unsigned s, unsigned c, ullong start)
2108{ 2086{
2109 off_t total, real_s, real_c; 2087 ullong total, real_s, real_c;
2110 2088
2111 real_s = sector(s) - 1; 2089 real_s = sector(s) - 1;
2112 real_c = cylinder(s, c); 2090 real_c = cylinder(s, c);
@@ -2120,11 +2098,11 @@ check(int n, unsigned h, unsigned s, unsigned c, off_t start)
2120 printf("Partition %d: sector %d greater than " 2098 printf("Partition %d: sector %d greater than "
2121 "maximum %d\n", n, s, sectors); 2099 "maximum %d\n", n, s, sectors);
2122 if (real_c >= cylinders) 2100 if (real_c >= cylinders)
2123 printf("Partition %d: cylinder %"OFF_FMT"u greater than " 2101 printf("Partition %d: cylinder %llu greater than "
2124 "maximum %d\n", n, real_c + 1, cylinders); 2102 "maximum %d\n", n, real_c + 1, cylinders);
2125 if (cylinders <= 1024 && start != total) 2103 if (cylinders <= 1024 && start != total)
2126 printf("Partition %d: previous sectors %"OFF_FMT"u disagrees with " 2104 printf("Partition %d: previous sectors %llu disagrees with "
2127 "total %"OFF_FMT"u\n", n, start, total); 2105 "total %llu\n", n, start, total);
2128} 2106}
2129 2107
2130static void 2108static void
@@ -2132,7 +2110,7 @@ verify(void)
2132{ 2110{
2133 int i, j; 2111 int i, j;
2134 unsigned total = 1; 2112 unsigned total = 1;
2135 off_t first[partitions], last[partitions]; 2113 ullong first[partitions], last[partitions];
2136 struct partition *p; 2114 struct partition *p;
2137 2115
2138 if (warn_geometry()) 2116 if (warn_geometry())
@@ -2176,7 +2154,7 @@ verify(void)
2176 2154
2177 if (extended_offset) { 2155 if (extended_offset) {
2178 struct pte *pex = &ptes[ext_index]; 2156 struct pte *pex = &ptes[ext_index];
2179 off_t e_last = get_start_sect(pex->part_table) + 2157 ullong e_last = get_start_sect(pex->part_table) +
2180 get_nr_sects(pex->part_table) - 1; 2158 get_nr_sects(pex->part_table) - 1;
2181 2159
2182 for (i = 4; i < partitions; i++) { 2160 for (i = 4; i < partitions; i++) {
@@ -2210,9 +2188,9 @@ add_partition(int n, int sys)
2210 int i, num_read = 0; 2188 int i, num_read = 0;
2211 struct partition *p = ptes[n].part_table; 2189 struct partition *p = ptes[n].part_table;
2212 struct partition *q = ptes[ext_index].part_table; 2190 struct partition *q = ptes[ext_index].part_table;
2213 long long llimit; 2191 ullong limit, temp;
2214 off_t start, stop = 0, limit, temp, 2192 ullong start, stop = 0;
2215 first[partitions], last[partitions]; 2193 ullong first[partitions], last[partitions];
2216 2194
2217 if (p && p->sys_ind) { 2195 if (p && p->sys_ind) {
2218 printf(msg_part_already_defined, n + 1); 2196 printf(msg_part_already_defined, n + 1);
@@ -2222,12 +2200,9 @@ add_partition(int n, int sys)
2222 if (n < 4) { 2200 if (n < 4) {
2223 start = sector_offset; 2201 start = sector_offset;
2224 if (display_in_cyl_units || !total_number_of_sectors) 2202 if (display_in_cyl_units || !total_number_of_sectors)
2225 llimit = heads * sectors * cylinders - 1; 2203 limit = (ullong) heads * sectors * cylinders - 1;
2226 else 2204 else
2227 llimit = total_number_of_sectors - 1; 2205 limit = total_number_of_sectors - 1;
2228 limit = llimit;
2229 if (limit != llimit)
2230 limit = 0x7fffffff;
2231 if (extended_offset) { 2206 if (extended_offset) {
2232 first[ext_index] = extended_offset; 2207 first[ext_index] = extended_offset;
2233 last[ext_index] = get_start_sect(q) + 2208 last[ext_index] = get_start_sect(q) +
@@ -2256,12 +2231,12 @@ add_partition(int n, int sys)
2256 if (start > limit) 2231 if (start > limit)
2257 break; 2232 break;
2258 if (start >= temp+units_per_sector && num_read) { 2233 if (start >= temp+units_per_sector && num_read) {
2259 printf("Sector %"OFF_FMT"d is already allocated\n", temp); 2234 printf("Sector %lld is already allocated\n", temp);
2260 temp = start; 2235 temp = start;
2261 num_read = 0; 2236 num_read = 0;
2262 } 2237 }
2263 if (!num_read && start == temp) { 2238 if (!num_read && start == temp) {
2264 off_t saved_start; 2239 ullong saved_start;
2265 2240
2266 saved_start = start; 2241 saved_start = start;
2267 start = read_int(cround(saved_start), cround(saved_start), cround(limit), 2242 start = read_int(cround(saved_start), cround(saved_start), cround(limit),
@@ -2534,7 +2509,7 @@ move_begin(int i)
2534{ 2509{
2535 struct pte *pe = &ptes[i]; 2510 struct pte *pe = &ptes[i];
2536 struct partition *p = pe->part_table; 2511 struct partition *p = pe->part_table;
2537 off_t new, first; 2512 ullong new, first;
2538 2513
2539 if (warn_geometry()) 2514 if (warn_geometry())
2540 return; 2515 return;