From 72fbc81224351fd883c84967f5685ee016d791db Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Wed, 4 Feb 2026 12:03:33 +0100 Subject: [PATCH] fdisk: code shrink function old new delta new_partition 1054 1066 +12 list_table 1366 1370 +4 update_units 32 35 +3 list_disk_geometry 68 71 +3 get_geometry 535 538 +3 fdisk_fatal 38 41 +3 warn_cylinders 42 44 +2 xbsd_print_disklabel 836 834 -2 create_doslabel 110 108 -2 change_units 49 45 -4 xbsd_new_part 477 456 -21 add_partition 1278 1246 -32 .rodata 107059 107008 -51 fdisk_main 4775 4618 -157 ------------------------------------------------------------------------------ (add/remove: 0/0 grow/shrink: 7/7 up/down: 30/-269) Total: -239 bytes Signed-off-by: Denys Vlasenko --- util-linux/fdisk.c | 180 +++++++++++++++-------------------------- util-linux/fdisk_gpt.c | 8 +- util-linux/fdisk_osf.c | 8 +- util-linux/fdisk_sgi.c | 4 +- util-linux/fdisk_sun.c | 4 +- 5 files changed, 76 insertions(+), 128 deletions(-) diff --git a/util-linux/fdisk.c b/util-linux/fdisk.c index 470194af9..6611d3954 100644 --- a/util-linux/fdisk.c +++ b/util-linux/fdisk.c @@ -114,15 +114,25 @@ #endif #include /* assert */ #include +#include "libbb.h" +#include "unicode.h" #if !defined(BLKSSZGET) # define BLKSSZGET _IO(0x12, 104) #endif #if !defined(BLKGETSIZE64) # define BLKGETSIZE64 _IOR(0x12,114,size_t) #endif -#include "libbb.h" -#include "unicode.h" -#define HDIO_GETGEO 0x0301 /* get device geometry */ + +/* Get device geometry in this struct: */ +#define HDIO_GETGEO 0x0301 +struct hd_geometry { + unsigned char heads; + unsigned char sectors; + unsigned short cylinders; + unsigned long start; +}; + +typedef unsigned long long ullong; #if BB_LITTLE_ENDIAN # define inline_if_little_endian ALWAYS_INLINE @@ -155,19 +165,8 @@ #define LINUX_LVM 0x8e #define LINUX_RAID 0xfd -enum { - OPT_b = 1 << 0, - OPT_C = 1 << 1, - OPT_H = 1 << 2, - OPT_l = 1 << 3, - OPT_S = 1 << 4, - OPT_u = 1 << 5, - OPT_s = (1 << 6) * ENABLE_FEATURE_FDISK_BLKSIZE, -}; - -typedef unsigned long long ullong; /* Used for sector numbers. Partition formats we know - * do not support more than 2^32 sectors + * (except GPT!) do not support more than 2^32 sectors. */ typedef uint32_t sector_t; #if UINT_MAX == 0xffffffff @@ -180,12 +179,19 @@ typedef uint32_t sector_t; # error Cant detect sizeof(uint32_t) #endif -struct hd_geometry { - unsigned char heads; - unsigned char sectors; - unsigned short cylinders; - unsigned long start; +enum { + OPT_b = 1 << 0, + OPT_C = 1 << 1, + OPT_H = 1 << 2, + OPT_l = 1 << 3, + OPT_S = 1 << 4, + OPT_u = 1 << 5, + OPT_s = (1 << 6) * ENABLE_FEATURE_FDISK_BLKSIZE, }; +#define USER_SET_SECTOR_SIZE (option_mask32 & OPT_b) +#define NOWARN_OPT_ls (!ENABLE_FEATURE_FDISK_WRITABLE || (option_mask32 & (OPT_l|OPT_s))) +#define DISPLAY_IN_CYL_UNITS (!(option_mask32 & OPT_u)) +#define TOGGLE_DISPLAY_IN_CYL_UNITS (option_mask32 ^= OPT_u) /* TODO: just #if ENABLE_FEATURE_FDISK_WRITABLE */ /* (currently fdisk_sun/sgi.c do not have proper WRITABLE #ifs) */ @@ -421,7 +427,7 @@ enum { }; #if ENABLE_FEATURE_GPT_LABEL - struct gpt_header; +struct gpt_header; #endif /* Globals */ @@ -434,19 +440,12 @@ struct globals { unsigned sector_size; // = DEFAULT_SECTOR_SIZE; unsigned sector_offset; // = 1; unsigned g_heads, g_sectors, g_cylinders; - smallint user_set_sector_size; smallint /* enum label_type */ current_label_type; - smallint display_in_cyl_units; #if ENABLE_FEATURE_OSF_LABEL smallint possibly_osf_label; #endif - smallint listing; /* no aborts for fdisk -l */ smallint dos_compatible_flag; // = 1; -#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; @@ -486,17 +485,13 @@ struct globals { #define g_partitions (G.g_partitions ) #define units_per_sector (G.units_per_sector ) #define sector_size (G.sector_size ) -#define user_set_sector_size (G.user_set_sector_size) #define sector_offset (G.sector_offset ) #define g_heads (G.g_heads ) #define g_sectors (G.g_sectors ) #define g_cylinders (G.g_cylinders ) #define current_label_type (G.current_label_type ) -#define display_in_cyl_units (G.display_in_cyl_units) #define possibly_osf_label (G.possibly_osf_label ) -#define listing (G.listing ) #define dos_compatible_flag (G.dos_compatible_flag ) -#define nowarn (G.nowarn ) #define ext_index (G.ext_index ) #define user_cylinders (G.user_cylinders ) #define user_heads (G.user_heads ) @@ -592,7 +587,7 @@ static sector_t bb_getsize_in_sectors(int fd) #define IS_EXTENDED(i) \ ((i) == EXTENDED || (i) == WIN98_EXTENDED || (i) == LINUX_EXTENDED) -#define cround(n) (display_in_cyl_units ? ((n)/units_per_sector)+1 : (n)) +#define cround(n) (DISPLAY_IN_CYL_UNITS ? ((n)/units_per_sector)+1 : (n)) #define scround(x) (((x)+units_per_sector-1)/units_per_sector) @@ -657,7 +652,7 @@ get_part_table(int i) static ALWAYS_INLINE const char * str_units(void) { - return display_in_cyl_units ? "cylinder" : "sector"; + return DISPLAY_IN_CYL_UNITS ? "cylinder" : "sector"; } static int @@ -668,7 +663,9 @@ valid_part_table_flag(const char *mbuffer) static void fdisk_fatal(const char *why) { - if (listing) { + if (!ENABLE_FEATURE_FDISK_WRITABLE /* this assumes -l */ + || (option_mask32 & OPT_l) + ) { close_dev_fd(); longjmp(listingbuf, 1); } @@ -937,24 +934,6 @@ get_partition_start_from_dev_start(const struct pte *pe) } #if ENABLE_FEATURE_FDISK_WRITABLE -/* - * Avoid warning about DOS partitions when no DOS partition was changed. - * Here a heuristic "is probably dos partition". - * We might also do the opposite and warn in all cases except - * for "is probably nondos partition". - */ -#ifdef UNUSED -static int -is_dos_partition(int t) -{ - return (t == 1 || t == 4 || t == 6 || - t == 0x0b || t == 0x0c || t == 0x0e || - t == 0x11 || t == 0x12 || t == 0x14 || t == 0x16 || - t == 0x1b || t == 0x1c || t == 0x1e || t == 0x24 || - t == 0xc1 || t == 0xc4 || t == 0xc6); -} -#endif - static void menu(void) { @@ -1023,70 +1002,44 @@ menu(void) } #endif /* FEATURE_FDISK_WRITABLE */ - #if ENABLE_FEATURE_FDISK_ADVANCED static void xmenu(void) { puts("Command Action"); + puts("c\tchange number of cylinders"); + puts("h\tchange number of heads"); + puts("s\tchange number of sectors/track"); if (LABEL_IS_SUN) { puts("a\tchange number of alternate cylinders"); /*sun*/ - puts("c\tchange number of cylinders"); - puts("d\tprint the raw data in the partition table"); + puts("y\tchange number of physical cylinders"); /*sun*/ puts("e\tchange number of extra sectors per cylinder");/*sun*/ - puts("h\tchange number of heads"); puts("i\tchange interleave factor"); /*sun*/ puts("o\tchange rotation speed (rpm)"); /*sun*/ - puts("p\tprint the partition table"); - puts("q\tquit without saving changes"); - puts("r\treturn to main menu"); - puts("s\tchange number of sectors/track"); - puts("v\tverify the partition table"); - puts("w\twrite table to disk and exit"); - puts("y\tchange number of physical cylinders"); /*sun*/ } else if (LABEL_IS_SGI) { puts("b\tmove beginning of data in a partition"); /* !sun */ - puts("c\tchange number of cylinders"); - puts("d\tprint the raw data in the partition table"); - puts("e\tlist extended partitions"); /* !sun */ puts("g\tcreate an IRIX (SGI) partition table");/* sgi */ - puts("h\tchange number of heads"); - puts("p\tprint the partition table"); - puts("q\tquit without saving changes"); - puts("r\treturn to main menu"); - puts("s\tchange number of sectors/track"); - puts("v\tverify the partition table"); - puts("w\twrite table to disk and exit"); + puts("e\tlist extended partitions"); /* !sun */ } else if (LABEL_IS_AIX) { puts("b\tmove beginning of data in a partition"); /* !sun */ - puts("c\tchange number of cylinders"); - puts("d\tprint the raw data in the partition table"); +# if ENABLE_FEATURE_SGI_LABEL + puts("g\tcreate an IRIX (SGI) partition table"); +# endif puts("e\tlist extended partitions"); /* !sun */ - puts("g\tcreate an IRIX (SGI) partition table");/* sgi */ - puts("h\tchange number of heads"); - puts("p\tprint the partition table"); - puts("q\tquit without saving changes"); - puts("r\treturn to main menu"); - puts("s\tchange number of sectors/track"); - puts("v\tverify the partition table"); - puts("w\twrite table to disk and exit"); } else { - puts("b\tmove beginning of data in a partition"); /* !sun */ - puts("c\tchange number of cylinders"); - puts("d\tprint the raw data in the partition table"); - puts("e\tlist extended partitions"); /* !sun */ puts("f\tfix partition order"); /* !sun, !aix, !sgi */ -#if ENABLE_FEATURE_SGI_LABEL - puts("g\tcreate an IRIX (SGI) partition table");/* sgi */ -#endif - puts("h\tchange number of heads"); - puts("p\tprint the partition table"); - puts("q\tquit without saving changes"); - puts("r\treturn to main menu"); - puts("s\tchange number of sectors/track"); - puts("v\tverify the partition table"); - puts("w\twrite table to disk and exit"); + puts("b\tmove beginning of data in a partition"); /* !sun */ +# if ENABLE_FEATURE_SGI_LABEL + puts("g\tcreate an IRIX (SGI) partition table"); +# endif + puts("e\tlist extended partitions"); /* !sun */ } + puts("d\tprint the raw data in the partition table"); + puts("p\tprint the partition table"); + puts("v\tverify the partition table"); + puts("w\twrite table to disk and exit"); + puts("q\tquit without saving changes"); + puts("r\treturn to main menu"); } #endif /* ADVANCED mode */ @@ -1245,7 +1198,7 @@ update_units(void) { int cyl_units = g_heads * g_sectors; - if (display_in_cyl_units && cyl_units) + if (DISPLAY_IN_CYL_UNITS && cyl_units) units_per_sector = cyl_units; else units_per_sector = 1; /* in sectors */ @@ -1255,7 +1208,7 @@ update_units(void) static void warn_cylinders(void) { - if (LABEL_IS_DOS && g_cylinders > 1024 && !nowarn) + if (LABEL_IS_DOS && g_cylinders > 1024 && !NOWARN_OPT_ls) printf("\n" "The number of cylinders for this disk is set to %u.\n" "There is nothing wrong with that, but this is larger than 1024,\n" @@ -1384,7 +1337,7 @@ create_doslabel(void) static void get_sectorsize(void) { - if (!user_set_sector_size) { + if (!USER_SET_SECTOR_SIZE) { int arg; if (ioctl(dev_fd, BLKSSZGET, &arg) == 0 && arg >= 512) sector_size = arg; @@ -1839,7 +1792,7 @@ get_nonexisting_partition(void) static void change_units(void) { - display_in_cyl_units = !display_in_cyl_units; + TOGGLE_DISPLAY_IN_CYL_UNITS; update_units(); printf("Changing display/entry units to %ss\n", str_units()); @@ -2540,7 +2493,7 @@ add_partition(int n, int sys) fill_bounds(first, last); if (n < 4) { start = sector_offset; - if (display_in_cyl_units || !total_number_of_sectors) + if (DISPLAY_IN_CYL_UNITS || !total_number_of_sectors) limit = (sector_t) g_heads * g_sectors * g_cylinders - 1; else limit = total_number_of_sectors - 1; @@ -2553,7 +2506,7 @@ add_partition(int n, int sys) start = extended_offset + sector_offset; limit = get_start_sect(q) + get_nr_sects(q) - 1; } - if (display_in_cyl_units) + if (DISPLAY_IN_CYL_UNITS) for (i = 0; i < g_partitions; i++) first[i] = (cround(first[i]) - 1) * units_per_sector; @@ -2581,7 +2534,7 @@ add_partition(int n, int sys) saved_start = start; start = read_int(cround(saved_start), cround(saved_start), cround(limit), 0, mesg); - if (display_in_cyl_units) { + if (DISPLAY_IN_CYL_UNITS) { start = (start - 1) * units_per_sector; if (start < saved_start) start = saved_start; @@ -2622,7 +2575,7 @@ add_partition(int n, int sys) str_units() ); stop = read_int(cround(start), cround(limit), cround(limit), cround(start), mesg); - if (display_in_cyl_units) { + if (DISPLAY_IN_CYL_UNITS) { stop = stop * units_per_sector - 1; if (stop >limit) stop = limit; @@ -3112,7 +3065,7 @@ int fdisk_main(int argc UNUSED_PARAM, char **argv) close_dev_fd(); /* needed: fd 3 must not stay closed */ opt = getopt32(argv, "^" "b:+C:+H:+lS:+u"IF_FEATURE_FDISK_BLKSIZE("s")"\0" - /* among -s and -l, the last one takes preference */ + /* among -s and -l, the last one takes precedence */ IF_FEATURE_FDISK_BLKSIZE("s-l:l-s"), §or_size, &user_cylinders, &user_heads, &user_sectors); argv += optind; @@ -3122,7 +3075,6 @@ int fdisk_main(int argc UNUSED_PARAM, char **argv) if (opt & OPT_s) { int j; - nowarn = 1; if (!argv[0]) bb_show_usage(); for (j = 0; argv[j]; j++) { @@ -3141,7 +3093,7 @@ int fdisk_main(int argc UNUSED_PARAM, char **argv) } #endif - if (opt & OPT_b) { + //if (opt & OPT_b) { /* Ugly: this sector size is really per device, * so cannot be combined with multiple disks, * and the same goes for the C/H/S options. @@ -3152,22 +3104,18 @@ int fdisk_main(int argc UNUSED_PARAM, char **argv) ) { bb_show_usage(); } - sector_offset = 2; - user_set_sector_size = 1; - } + //} if (user_heads <= 0 || user_heads >= 256) user_heads = 0; if (user_sectors <= 0 || user_sectors >= 64) user_sectors = 0; - if (opt & OPT_u) - display_in_cyl_units = 0; + //if (opt & OPT_u) + // DISPLAY_IN_CYL_UNITS = 0; #if ENABLE_FEATURE_FDISK_WRITABLE if (opt & OPT_l) { - nowarn = 1; #endif if (*argv) { - listing = 1; do { open_list_and_close(*argv, 1); } while (*++argv); diff --git a/util-linux/fdisk_gpt.c b/util-linux/fdisk_gpt.c index 251c9e202..c085af79c 100644 --- a/util-linux/fdisk_gpt.c +++ b/util-linux/fdisk_gpt.c @@ -178,7 +178,7 @@ check_gpt_label(void) 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"); + puts("\nwarning: GPT header CRC is invalid"); } G.gpt_n_parts = SWAP_LE32(G.gpt_hdr->n_parts); @@ -187,7 +187,7 @@ check_gpt_label(void) || G.gpt_part_entry_len > GPT_MAX_PART_ENTRY_LEN || SWAP_LE32(G.gpt_hdr->hdr_size) > sector_size ) { - puts("\nwarning: can't parse GPT disklabel\n"); + puts("\nwarning: can't parse GPT disklabel"); current_label_type = LABEL_DOS; return 0; } @@ -201,10 +201,10 @@ check_gpt_label(void) 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"); + puts("\nwarning: GPT array CRC is invalid"); } - puts("Found valid GPT with protective MBR; using GPT\n"); + puts("Found valid GPT with protective MBR; using GPT"); current_label_type = LABEL_GPT; return 1; diff --git a/util-linux/fdisk_osf.c b/util-linux/fdisk_osf.c index 5d6b4cbcf..f34390e01 100644 --- a/util-linux/fdisk_osf.c +++ b/util-linux/fdisk_osf.c @@ -280,7 +280,7 @@ static struct bsd_globals *bsd_globals_ptr; /* Code */ #define bsd_cround(n) \ - (display_in_cyl_units ? ((n)/xbsd_dlabel.d_secpercyl) + 1 : (n)) + (DISPLAY_IN_CYL_UNITS ? ((n)/xbsd_dlabel.d_secpercyl) + 1 : (n)) /* * Test whether the whole disk has BSD disk label magic. @@ -472,7 +472,7 @@ xbsd_new_part(void) begin = read_int(bsd_cround(begin), bsd_cround(begin), bsd_cround(end), 0, mesg); - if (display_in_cyl_units) + if (DISPLAY_IN_CYL_UNITS) begin = (begin - 1) * xbsd_dlabel.d_secpercyl; snprintf(mesg, sizeof(mesg), "Last %s or +size or +sizeM or +sizeK", @@ -480,7 +480,7 @@ xbsd_new_part(void) end = read_int(bsd_cround(begin), bsd_cround(end), bsd_cround(end), bsd_cround(begin), mesg); - if (display_in_cyl_units) + if (DISPLAY_IN_CYL_UNITS) end = end * xbsd_dlabel.d_secpercyl - 1; xbsd_dlabel.d_partitions[i].p_size = end - begin + 1; @@ -541,7 +541,7 @@ xbsd_print_disklabel(int show_all) pp = lp->d_partitions; for (i = 0; i < lp->d_npartitions; i++, pp++) { if (pp->p_size) { - if (display_in_cyl_units && lp->d_secpercyl) { + if (DISPLAY_IN_CYL_UNITS && lp->d_secpercyl) { printf(" %c: %8lu%c %8lu%c %8lu%c ", 'a' + i, (unsigned long) pp->p_offset / lp->d_secpercyl + 1, diff --git a/util-linux/fdisk_sgi.c b/util-linux/fdisk_sgi.c index 656cb02fc..000178049 100644 --- a/util-linux/fdisk_sgi.c +++ b/util-linux/fdisk_sgi.c @@ -735,7 +735,7 @@ sgi_add_partition(int n, int sys) first = read_int(scround(first), scround(first), scround(last)-1, 0, mesg); } - if (display_in_cyl_units) + if (DISPLAY_IN_CYL_UNITS) first *= units_per_sector; else first = first; /* align to cylinder if you know how ... */ @@ -749,7 +749,7 @@ sgi_add_partition(int n, int sys) snprintf(mesg, sizeof(mesg), " Last %s", str_units()); last = read_int(scround(first), scround(last)-1, scround(last)-1, scround(first), mesg)+1; - if (display_in_cyl_units) + if (DISPLAY_IN_CYL_UNITS) last *= units_per_sector; else last = last; /* align to cylinder if You know how ... */ diff --git a/util-linux/fdisk_sun.c b/util-linux/fdisk_sun.c index e9b9ffd11..aab0a9825 100644 --- a/util-linux/fdisk_sun.c +++ b/util-linux/fdisk_sun.c @@ -504,7 +504,7 @@ add_sun_partition(int n, int sys) else first = read_int(scround(start), scround(stop)+1, scround(stop), 0, mesg); - if (display_in_cyl_units) { + if (DISPLAY_IN_CYL_UNITS) { first *= units_per_sector; } else { /* Starting sector has to be properly aligned */ @@ -562,7 +562,7 @@ and is of type 'Whole disk'\n"); else last = read_int(scround(first), scround(stop), scround(stop), scround(first), mesg); - if (display_in_cyl_units) + if (DISPLAY_IN_CYL_UNITS) last *= units_per_sector; if (n == 2 && !first) { if (last >= stop2) {