[git commit] fdisk: eliminate static variables, fix GPT disk size (32x32->32 overflow)
Denys Vlasenko
vda.linux at googlemail.com
Sun Feb 1 12:44:54 UTC 2026
commit: https://git.busybox.net/busybox/commit/?id=7ac2bd69175d4216f0b53b16b132c1df806ac8b5
branch: https://git.busybox.net/busybox/commit/?id=refs/heads/master
function old new delta
verify_sun 481 508 +27
.rodata 107016 107022 +6
verify_sun_cmp 51 54 +3
sun_other_endian 1 - -1
scsi_disk 1 - -1
floppy 1 - -1
xbsd_print_disklabel 838 836 -2
xbsd_new_part 479 477 -2
xbsd_write_bootstrap 397 394 -3
set_sun_partition 103 100 -3
delete_partition 435 432 -3
xbsd_part_index 4 - -4
xbsd_part 4 - -4
verify_sun_starts 4 - -4
part_entry_len 4 - -4
part_array 4 - -4
n_parts 4 - -4
gpt_hdr 4 - -4
check_sun_label 214 208 -6
list_table 1433 1423 -10
fetch_sun 233 219 -14
bsd_select 1564 1546 -18
get_geometry 691 665 -26
get_boot 1539 1513 -26
fdisk_main 4737 4674 -63
------------------------------------------------------------------------------
(add/remove: 0/10 grow/shrink: 3/12 up/down: 36/-207) Total: -171 bytes
text data bss dec hex filename
1078472 555 5088 1084115 108ad3 busybox_old
1078332 555 5056 1083943 108a27 busybox_unstripped
Signed-off-by: Denys Vlasenko <vda.linux at googlemail.com>
---
util-linux/fdisk.c | 27 +++++++++++++++++-
util-linux/fdisk_gpt.c | 74 ++++++++++++++++++++++++------------------------
util-linux/fdisk_osf.c | 28 +++++++++----------
util-linux/fdisk_sun.c | 76 ++++++++++++++++++++++++++------------------------
4 files changed, 116 insertions(+), 89 deletions(-)
diff --git a/util-linux/fdisk.c b/util-linux/fdisk.c
index 96e2abffe..abd48ec9b 100644
--- a/util-linux/fdisk.c
+++ b/util-linux/fdisk.c
@@ -170,8 +170,10 @@ typedef unsigned long long ullong;
typedef uint32_t sector_t;
#if UINT_MAX == 0xffffffff
# define SECT_FMT ""
+# define SECT_TYPE unsigned
#elif ULONG_MAX == 0xffffffff
# define SECT_FMT "l"
+# define SECT_TYPE unsigned long
#else
# error Cant detect sizeof(uint32_t)
#endif
@@ -412,6 +414,10 @@ enum {
dev_fd = 3 /* the disk */
};
+#if ENABLE_FEATURE_GPT_LABEL
+ struct gpt_header;
+#endif
+
/* Globals */
struct globals {
char *line_ptr;
@@ -434,6 +440,18 @@ struct globals {
#if ENABLE_FEATURE_FDISK_WRITABLE
//int dos_changed;
smallint nowarn; /* no warnings for fdisk -l/-s */
+#endif
+#if ENABLE_FEATURE_SUN_LABEL
+ smallint sun_other_endian;
+ smallint sun_scsi_disk;
+ smallint sun_floppy;
+ unsigned *verify_sun_starts;
+#endif
+#if ENABLE_FEATURE_OSF_LABEL
+# if !defined(__alpha__)
+ struct partition *xbsd_part;
+ unsigned xbsd_part_index;
+# endif
#endif
int ext_index; /* the prime extended partition */
unsigned user_cylinders, user_heads, user_sectors;
@@ -442,6 +460,13 @@ struct globals {
sector_t extended_offset; /* offset of link pointers */
sector_t total_number_of_sectors;
+#if ENABLE_FEATURE_GPT_LABEL
+ struct gpt_header *gpt_hdr;
+ char *gpt_part_array;
+ unsigned gpt_n_parts;
+ unsigned gpt_part_entry_len;
+#endif
+
jmp_buf listingbuf;
char line_buffer[80];
/* Raw disk label. For DOS-type partition tables the MBR,
@@ -1391,7 +1416,7 @@ get_geometry(void)
get_sectorsize();
sec_fac = sector_size / 512;
#if ENABLE_FEATURE_SUN_LABEL
- guess_device_type();
+ sun_guess_device_type();
#endif
g_heads = g_cylinders = g_sectors = 0;
kern_heads = kern_sectors = 0;
diff --git a/util-linux/fdisk_gpt.c b/util-linux/fdisk_gpt.c
index 4c30f31f8..60c7c1570 100644
--- a/util-linux/fdisk_gpt.c
+++ b/util-linux/fdisk_gpt.c
@@ -13,7 +13,7 @@ enum {
GUID_LEN = 16,
};
-typedef struct {
+typedef struct gpt_header {
uint64_t magic;
uint32_t revision;
uint32_t hdr_size;
@@ -30,7 +30,7 @@ typedef struct {
uint32_t part_array_crc32;
} gpt_header;
-typedef struct {
+typedef struct gpt_partition {
uint8_t type_guid[GUID_LEN];
uint8_t part_guid[GUID_LEN];
uint64_t lba_start;
@@ -39,19 +39,13 @@ typedef struct {
uint16_t name36[36];
} gpt_partition;
-static gpt_header *gpt_hdr;
-
-static char *part_array;
-static unsigned int n_parts;
-static unsigned int part_entry_len;
-
-static inline gpt_partition *
+static gpt_partition *
gpt_part(int i)
{
- if (i >= n_parts) {
+ if (i >= G.gpt_n_parts) {
return NULL;
}
- return (gpt_partition *)&part_array[i * part_entry_len];
+ return (gpt_partition *)&G.gpt_part_array[i * G.gpt_part_entry_len];
}
static uint32_t
@@ -107,19 +101,27 @@ gpt_list_table(int xtra UNUSED_PARAM)
{
int i;
char numstr6[6];
+ unsigned long long total_bytes;
+
+ total_bytes = (unsigned long long)total_number_of_sectors * sector_size;
+ smart_ulltoa5(total_bytes, numstr6, " KMGTPEZY")[0] = '\0';
- smart_ulltoa5(total_number_of_sectors * sector_size, numstr6, " KMGTPEZY")[0] = '\0';
- printf("Disk %s: %llu sectors, %s\n", disk_device,
- (unsigned long long)total_number_of_sectors,
- numstr6);
+ printf("Disk %s: %s, %llu bytes, %"SECT_FMT"u sectors\n", disk_device,
+ skip_whitespace(numstr6),
+ total_bytes,
+ (SECT_TYPE)total_number_of_sectors
+ );
printf("Logical sector size: %u\n", sector_size);
printf("Disk identifier (GUID): ");
- gpt_print_guid(gpt_hdr->disk_guid);
+//util-linux 2.41.1 does not print " (GUID)" in above line,
+//we do: keep users less confused what kind of identifier is meant.
+ gpt_print_guid(G.gpt_hdr->disk_guid);
printf("\nPartition table holds up to %u entries\n",
- (int)SWAP_LE32(gpt_hdr->n_parts));
+ (int)SWAP_LE32(G.gpt_hdr->n_parts));
printf("First usable sector is %llu, last usable sector is %llu\n\n",
- (unsigned long long)SWAP_LE64(gpt_hdr->first_usable_lba),
- (unsigned long long)SWAP_LE64(gpt_hdr->last_usable_lba));
+ (unsigned long long)SWAP_LE64(G.gpt_hdr->first_usable_lba),
+ (unsigned long long)SWAP_LE64(G.gpt_hdr->last_usable_lba)
+ );
/* "GPT fdisk" has a concept of 16-bit extension of the original MBR 8-bit type codes,
* which it displays here: its output columns are ... Size Code Name
@@ -131,7 +133,7 @@ gpt_list_table(int xtra UNUSED_PARAM)
*/
puts("Number Start (sector) End (sector) Size Name");
// 123456 123456789012345 123456789012345 12345 abc
- for (i = 0; i < n_parts; i++) {
+ for (i = 0; i < G.gpt_n_parts; i++) {
gpt_partition *p = gpt_part(i);
if (p->lba_start) {
smart_ulltoa5((1 + SWAP_LE64(p->lba_end) - SWAP_LE64(p->lba_start)) * sector_size,
@@ -168,9 +170,9 @@ check_gpt_label(void)
/* LBA 1 contains the GPT header */
read_pte(&pe, 1);
- gpt_hdr = (void *)pe.sectorbuffer;
+ G.gpt_hdr = (void *)pe.sectorbuffer;
- if (gpt_hdr->magic != SWAP_LE64(GPT_MAGIC)) {
+ if (G.gpt_hdr->magic != SWAP_LE64(GPT_MAGIC)) {
current_label_type = LABEL_DOS;
return 0;
}
@@ -180,32 +182,32 @@ check_gpt_label(void)
global_crc32_new_table_le();
}
- crc = SWAP_LE32(gpt_hdr->hdr_crc32);
- gpt_hdr->hdr_crc32 = 0;
- if (gpt_crc32(gpt_hdr, SWAP_LE32(gpt_hdr->hdr_size)) != crc) {
+ crc = SWAP_LE32(G.gpt_hdr->hdr_crc32);
+ G.gpt_hdr->hdr_crc32 = 0;
+ if (gpt_crc32(G.gpt_hdr, SWAP_LE32(G.gpt_hdr->hdr_size)) != crc) {
/* FIXME: read the backup table */
puts("\nwarning: GPT header CRC is invalid\n");
}
- n_parts = SWAP_LE32(gpt_hdr->n_parts);
- part_entry_len = SWAP_LE32(gpt_hdr->part_entry_len);
- if (n_parts > GPT_MAX_PARTS
- || part_entry_len > GPT_MAX_PART_ENTRY_LEN
- || SWAP_LE32(gpt_hdr->hdr_size) > sector_size
+ G.gpt_n_parts = SWAP_LE32(G.gpt_hdr->n_parts);
+ G.gpt_part_entry_len = SWAP_LE32(G.gpt_hdr->part_entry_len);
+ if (G.gpt_n_parts > GPT_MAX_PARTS
+ || G.gpt_part_entry_len > GPT_MAX_PART_ENTRY_LEN
+ || SWAP_LE32(G.gpt_hdr->hdr_size) > sector_size
) {
- puts("\nwarning: unable to parse GPT disklabel\n");
+ puts("\nwarning: can't parse GPT disklabel\n");
current_label_type = LABEL_DOS;
return 0;
}
- part_array_len = n_parts * part_entry_len;
- part_array = xmalloc(part_array_len);
- seek_sector(SWAP_LE64(gpt_hdr->first_part_lba));
- if (full_read(dev_fd, part_array, part_array_len) != part_array_len) {
+ part_array_len = G.gpt_n_parts * G.gpt_part_entry_len;
+ G.gpt_part_array = xmalloc(part_array_len);
+ seek_sector(SWAP_LE64(G.gpt_hdr->first_part_lba));
+ if (full_read(dev_fd, G.gpt_part_array, part_array_len) != part_array_len) {
fdisk_fatal(unable_to_read);
}
- if (gpt_crc32(part_array, part_array_len) != gpt_hdr->part_array_crc32) {
+ if (gpt_crc32(G.gpt_part_array, part_array_len) != G.gpt_hdr->part_array_crc32) {
/* FIXME: read the backup table */
puts("\nwarning: GPT array CRC is invalid\n");
}
diff --git a/util-linux/fdisk_osf.c b/util-linux/fdisk_osf.c
index 049f0b169..5d6b4cbcf 100644
--- a/util-linux/fdisk_osf.c
+++ b/util-linux/fdisk_osf.c
@@ -260,8 +260,6 @@ static void alpha_bootblock_checksum(char *boot);
#if !defined(__alpha__)
static int xbsd_translate_fstype(int linux_type);
static void xbsd_link_part(void);
-static struct partition *xbsd_part;
-static int xbsd_part_index;
#endif
@@ -356,9 +354,9 @@ bsd_select(void)
for (t = 0; t < 4; t++) {
p = get_part_table(t);
if (p && is_bsd_partition_type(p->sys_ind)) {
- xbsd_part = p;
- xbsd_part_index = t;
- ss = get_start_sect(xbsd_part);
+ G.xbsd_part = p;
+ G.xbsd_part_index = t;
+ ss = get_start_sect(G.xbsd_part);
if (ss == 0) {
printf("Partition %s has invalid starting sector 0\n",
partname(disk_device, t+1, 0));
@@ -366,7 +364,7 @@ bsd_select(void)
}
printf("Reading disklabel of %s at sector %u\n",
partname(disk_device, t+1, 0), ss + BSD_LABELSECTOR);
- if (xbsd_readlabel(xbsd_part) == 0) {
+ if (xbsd_readlabel(G.xbsd_part) == 0) {
if (xbsd_create_disklabel() == 0)
return;
break;
@@ -463,8 +461,8 @@ xbsd_new_part(void)
return;
#if !defined(__alpha__) && !defined(__powerpc__) && !defined(__hppa__)
- begin = get_start_sect(xbsd_part);
- end = begin + get_nr_sects(xbsd_part) - 1;
+ begin = get_start_sect(G.xbsd_part);
+ end = begin + get_nr_sects(G.xbsd_part) - 1;
#else
begin = 0;
end = xbsd_dlabel.d_secperunit - 1;
@@ -503,7 +501,7 @@ xbsd_print_disklabel(int show_all)
#if defined(__alpha__)
printf("# %s:\n", disk_device);
#else
- printf("# %s:\n", partname(disk_device, xbsd_part_index+1, 0));
+ printf("# %s:\n", partname(disk_device, G.xbsd_part_index + 1, 0));
#endif
if ((unsigned) lp->d_type < ARRAY_SIZE(xbsd_dktypenames)-1)
printf("type: %s\n", xbsd_dktypenames[lp->d_type]);
@@ -593,8 +591,8 @@ xbsd_write_disklabel(void)
xbsd_writelabel(NULL);
#else
printf("Writing disklabel to %s\n",
- partname(disk_device, xbsd_part_index + 1, 0));
- xbsd_writelabel(xbsd_part);
+ partname(disk_device, G.xbsd_part_index + 1, 0));
+ xbsd_writelabel(G.xbsd_part);
#endif
reread_partition_table(0); /* no exit yet */
}
@@ -608,7 +606,7 @@ xbsd_create_disklabel(void)
printf("%s contains no disklabel\n", disk_device);
#else
printf("%s contains no disklabel\n",
- partname(disk_device, xbsd_part_index + 1, 0));
+ partname(disk_device, G.xbsd_part_index + 1, 0));
#endif
while (1) {
@@ -619,7 +617,7 @@ xbsd_create_disklabel(void)
defined(__s390__) || defined(__s390x__)
NULL
#else
- xbsd_part
+ G.xbsd_part
#endif
) == 1) {
xbsd_print_disklabel(1);
@@ -761,7 +759,7 @@ xbsd_write_bootstrap(void)
sector = 0;
alpha_bootblock_checksum(disklabelbuffer);
#else
- sector = get_start_sect(xbsd_part);
+ sector = get_start_sect(G.xbsd_part);
#endif
seek_sector(sector);
@@ -771,7 +769,7 @@ xbsd_write_bootstrap(void)
printf("Bootstrap installed on %s\n", disk_device);
#else
printf("Bootstrap installed on %s\n",
- partname(disk_device, xbsd_part_index+1, 0));
+ partname(disk_device, G.xbsd_part_index + 1, 0));
#endif
sync_disks();
diff --git a/util-linux/fdisk_sun.c b/util-linux/fdisk_sun.c
index 5b7760e8c..955ae1e5e 100644
--- a/util-linux/fdisk_sun.c
+++ b/util-linux/fdisk_sun.c
@@ -19,18 +19,14 @@
#define SUN_LABEL_MAGIC 0xDABE
#define SUN_LABEL_MAGIC_SWAPPED 0xBEDA
-#define SUN_SSWAP16(x) (sun_other_endian ? fdisk_swap16(x) : (uint16_t)(x))
-#define SUN_SSWAP32(x) (sun_other_endian ? fdisk_swap32(x) : (uint32_t)(x))
+#define SUN_SSWAP16(x) (G.sun_other_endian ? fdisk_swap16(x) : (uint16_t)(x))
+#define SUN_SSWAP32(x) (G.sun_other_endian ? fdisk_swap32(x) : (uint32_t)(x))
/* Copied from linux/major.h */
#define FLOPPY_MAJOR 2
#define SCSI_IOCTL_GET_IDLUN 0x5382
-static smallint sun_other_endian;
-static smallint scsi_disk;
-static smallint floppy;
-
#ifndef IDE0_MAJOR
#define IDE0_MAJOR 3
#endif
@@ -39,25 +35,28 @@ static smallint floppy;
#endif
static void
-guess_device_type(void)
+sun_guess_device_type(void)
{
struct stat bootstat;
- if (fstat(dev_fd, &bootstat) < 0) {
- scsi_disk = 0;
- floppy = 0;
- } else if (S_ISBLK(bootstat.st_mode)
- && (major(bootstat.st_rdev) == IDE0_MAJOR ||
- major(bootstat.st_rdev) == IDE1_MAJOR)) {
- scsi_disk = 0;
- floppy = 0;
- } else if (S_ISBLK(bootstat.st_mode)
- && major(bootstat.st_rdev) == FLOPPY_MAJOR) {
- scsi_disk = 0;
- floppy = 1;
+ G.sun_scsi_disk = 0;
+ G.sun_floppy = 0;
+ if (fstat(dev_fd, &bootstat) < 0)
+ return;
+ if (S_ISBLK(bootstat.st_mode)) {
+ //if (major(bootstat.st_rdev) == IDE0_MAJOR
+ // || major(bootstat.st_rdev) == IDE1_MAJOR
+ //) {
+ // G.sun_scsi_disk = 0;
+ // G.sun_floppy = 0;
+ //}
+ if (major(bootstat.st_rdev) == FLOPPY_MAJOR) {
+ //G.sun_scsi_disk = 0;
+ G.sun_floppy = 1;
+ }
} else {
- scsi_disk = 1;
- floppy = 0;
+ G.sun_scsi_disk = 1;
+ //G.sun_floppy = 0;
}
}
@@ -101,10 +100,10 @@ check_sun_label(void)
&& sunlabel->magic != SUN_LABEL_MAGIC_SWAPPED
) {
current_label_type = LABEL_DOS;
- sun_other_endian = 0;
+ G.sun_other_endian = 0;
return 0;
}
- sun_other_endian = (sunlabel->magic == SUN_LABEL_MAGIC_SWAPPED);
+ G.sun_other_endian = (sunlabel->magic == SUN_LABEL_MAGIC_SWAPPED);
ush = ((unsigned short *) (sunlabel + 1)) - 1;
for (csum = 0; ush >= (unsigned short *)sunlabel;) csum ^= *ush--;
if (csum) {
@@ -238,10 +237,10 @@ create_sunlabel(void)
printf(msg_building_new_label, "sun disklabel");
- sun_other_endian = BB_LITTLE_ENDIAN;
+ G.sun_other_endian = BB_LITTLE_ENDIAN;
memset(MBRbuffer, 0, sizeof(MBRbuffer));
sunlabel->magic = SUN_SSWAP16(SUN_LABEL_MAGIC);
- if (!floppy) {
+ if (!G.sun_floppy) {
unsigned i;
puts("Drive type\n"
" ? auto configure\n"
@@ -265,7 +264,7 @@ create_sunlabel(void)
p = sun_drives + c - 'A';
break;
}
- if (c == '?' && scsi_disk) {
+ if (c == '?' && G.sun_scsi_disk) {
p = sun_autoconfigure_scsi();
if (p)
break;
@@ -273,7 +272,7 @@ create_sunlabel(void)
}
}
}
- if (!p || floppy) {
+ if (!p || G.sun_floppy) {
if (!ioctl(dev_fd, HDIO_GETGEO, &geometry)) {
g_heads = geometry.heads;
g_sectors = geometry.sectors;
@@ -283,7 +282,7 @@ create_sunlabel(void)
g_sectors = 0;
g_cylinders = 0;
}
- if (floppy) {
+ if (G.sun_floppy) {
sunlabel->nacyl = 0;
sunlabel->pcylcount = SUN_SSWAP16(g_cylinders);
sunlabel->rspeed = SUN_SSWAP16(300);
@@ -320,13 +319,13 @@ create_sunlabel(void)
snprintf((char *)(sunlabel->info), sizeof(sunlabel->info),
"%s%s%s cyl %u alt %u hd %u sec %u",
p ? p->vendor : "", (p && *p->vendor) ? " " : "",
- p ? p->model : (floppy ? "3,5\" floppy" : "Linux custom"),
+ p ? p->model : (G.sun_floppy ? "3,5\" floppy" : "Linux custom"),
g_cylinders, SUN_SSWAP16(sunlabel->nacyl), g_heads, g_sectors);
sunlabel->ntrks = SUN_SSWAP16(g_heads);
sunlabel->nsect = SUN_SSWAP16(g_sectors);
sunlabel->ncyl = SUN_SSWAP16(g_cylinders);
- if (floppy)
+ if (G.sun_floppy)
set_sun_partition(0, 0, g_cylinders * g_heads * g_sectors, LINUX_NATIVE);
else {
if (g_cylinders * g_heads * g_sectors >= 150 * 2048) {
@@ -392,14 +391,15 @@ fetch_sun(unsigned *starts, unsigned *lens, unsigned *start, unsigned *stop)
}
}
-static unsigned *verify_sun_starts;
-
static int
-verify_sun_cmp(int *a, int *b)
+verify_sun_cmp(const void *aa, const void *bb)
{
+ const int *a = aa;
+ const int *b = bb;
if (*a == -1) return 1;
if (*b == -1) return -1;
- if (verify_sun_starts[*a] > verify_sun_starts[*b]) return 1;
+ if (G.verify_sun_starts[*a] > G.verify_sun_starts[*b])
+ return 1;
return -1;
}
@@ -410,7 +410,6 @@ verify_sun(void)
int i,j,k,starto,endo;
int array[8];
- verify_sun_starts = starts;
fetch_sun(starts, lens, &start, &stop);
for (k = 0; k < 7; k++) {
for (i = 0; i < 8; i++) {
@@ -449,8 +448,11 @@ verify_sun(void)
else
array[i] = -1;
}
- qsort(array, ARRAY_SIZE(array), sizeof(array[0]),
- (int (*)(const void *,const void *)) verify_sun_cmp);
+//TODO: probably can eliminate the need in G.verify_sun_starts
+//if merge starts[] and lens[] in a single array?
+ G.verify_sun_starts = starts;
+ qsort(array, ARRAY_SIZE(array), sizeof(array[0]), verify_sun_cmp);
+
if (array[0] == -1) {
printf("No partitions defined\n");
return;
More information about the busybox-cvs
mailing list