]> git.ipfire.org Git - thirdparty/util-linux.git/commitdiff
fdisk: API: add geometry
authorDavidlohr Bueso <dave@gnu.org>
Sun, 17 Jun 2012 16:10:33 +0000 (18:10 +0200)
committerKarel Zak <kzak@redhat.com>
Thu, 21 Jun 2012 06:05:49 +0000 (08:05 +0200)
Add device geometry to the fdisk API. While it maintains traditional behaviour, the cylinders
are changed to sector_t instead of unsigned int in order to avoid dealing with truncated cylinders.
A new helper is added to compute the amount of cylinders based on the heads and sectors - if a user passed
-H or -S to the program, it must call this function to update the corresponding values.

This patch passes regression tests.

Signed-off-by: Davidlohr Bueso <dave@gnu.org>
fdisk/fdisk.c
fdisk/fdisk.h
fdisk/fdiskaixlabel.c
fdisk/fdiskbsdlabel.c
fdisk/fdiskdoslabel.c
fdisk/fdiskmaclabel.c
fdisk/fdisksgilabel.c
fdisk/fdisksunlabel.c
fdisk/utils.c

index dedb5f8b2b4b9c267c37c28c88d2f2ef1434cf2e..748badf473f6ddc59a2134fbd36cc4de6979d3c9 100644 (file)
@@ -135,15 +135,8 @@ int        nowarn = 0,                     /* no warnings for fdisk -l/-s */
        partitions = 4;                 /* maximum partition + 1 */
 
 unsigned int   user_cylinders, user_heads, user_sectors;
-unsigned int   pt_heads, pt_sectors;
-
-sector_t sector_offset = 1, sectors;
-
-unsigned int   heads,
-       cylinders,
-       units_per_sector = 1,
-       display_in_cyl_units = 0;
-
+sector_t sector_offset = 1;
+unsigned int units_per_sector = 1, display_in_cyl_units = 0;
 unsigned long grain = DEFAULT_SECTOR_SIZE;
 enum labeltype disklabel;      /* Current disklabel */
 
@@ -365,18 +358,18 @@ sector_t align_lba(struct fdisk_context *cxt, sector_t lba, int direction)
        return res;
 }
 
-int warn_geometry(void)
+int warn_geometry(struct fdisk_context *cxt)
 {
        char *m = NULL;
        int prev = 0;
 
        if (disklabel == SGI_LABEL)     /* cannot set cylinders etc anyway */
                return 0;
-       if (!heads)
+       if (!cxt->geom.heads)
                prev = test_c(&m, _("heads"));
-       if (!sectors)
+       if (!cxt->geom.sectors)
                prev = test_c(&m, _("sectors"));
-       if (!cylinders)
+       if (!cxt->geom.cylinders)
                prev = test_c(&m, _("cylinders"));
        if (!m)
                return 0;
@@ -386,9 +379,9 @@ int warn_geometry(void)
        return 1;
 }
 
-void update_units(void)
+void update_units(struct fdisk_context *cxt)
 {
-       int cyl_units = heads * sectors;
+       int cyl_units = cxt->geom.heads * cxt->geom.sectors;
 
        if (display_in_cyl_units && cyl_units)
                units_per_sector = cyl_units;
@@ -438,8 +431,8 @@ void warn_alignment(struct fdisk_context *cxt)
 
 }
 
-static void
-get_partition_table_geometry(struct fdisk_context *cxt) {
+void
+get_partition_table_geometry(struct fdisk_context *cxt, unsigned int *ph, unsigned int *ps) {
        unsigned char *bufp = cxt->mbr;
        struct partition *p;
        int i, h, s, hh, ss;
@@ -465,8 +458,8 @@ get_partition_table_geometry(struct fdisk_context *cxt) {
        }
 
        if (!first && !bad) {
-               pt_heads = hh;
-               pt_sectors = ss;
+               *ph = hh;
+               *ps = ss;
        }
 }
 
@@ -479,7 +472,7 @@ update_sector_offset(struct fdisk_context *cxt)
        grain = cxt->io_size;
 
        if (dos_compatible_flag)
-               sector_offset = sectors;        /* usually 63 sectors */
+               sector_offset = cxt->geom.sectors;      /* usually 63 sectors */
        else {
                /*
                 * Align the begin of partitions to:
@@ -520,41 +513,6 @@ update_sector_offset(struct fdisk_context *cxt)
        }
 }
 
-void
-get_geometry(struct fdisk_context *cxt, struct geom *g)
-{
-       sector_t llcyls;
-       unsigned int kern_heads = 0, kern_sectors = 0;
-
-       heads = cylinders = sectors = 0;
-       pt_heads = pt_sectors = 0;
-
-       blkdev_get_geometry(cxt->dev_fd, &kern_heads, &kern_sectors);
-       get_partition_table_geometry(cxt);
-
-       heads = user_heads ? user_heads :
-               pt_heads ? pt_heads :
-               kern_heads ? kern_heads : 255;
-       sectors = user_sectors ? user_sectors :
-               pt_sectors ? pt_sectors :
-               kern_sectors ? kern_sectors : 63;
-
-       update_sector_offset(cxt);
-
-       llcyls = cxt->total_sectors / (heads * sectors);
-       cylinders = llcyls;
-       if (cylinders != llcyls)        /* truncated? */
-               cylinders = ~0;
-       if (!cylinders)
-               cylinders = user_cylinders;
-
-       if (g) {
-               g->heads = heads;
-               g->sectors = sectors;
-               g->cylinders = cylinders;
-       }
-}
-
 /*
  * Read MBR.  Returns:
  *   -1: no 0xaa55 flag present (possibly entire disk BSD)
@@ -564,9 +522,7 @@ get_geometry(struct fdisk_context *cxt, struct geom *g)
 static int get_boot(struct fdisk_context *cxt, int try_only) {
 
        disklabel = ANY_LABEL;
-
-       get_geometry(cxt, NULL);
-       update_units();
+       update_units(cxt);
 
        if (!check_dos_label(cxt))
                if (check_sun_label(cxt) || check_sgi_label(cxt) || check_aix_label(cxt)
@@ -752,7 +708,7 @@ read_int_with_suffix(struct fdisk_context *cxt,
                                 * Cylinders
                                 */
                                if (!display_in_cyl_units)
-                                       res *= heads * sectors;
+                                       res *= cxt->geom.heads * cxt->geom.sectors;
                        } else if (*line_ptr &&
                                   *(line_ptr + 1) == 'B' &&
                                   *(line_ptr + 2) == '\0') {
@@ -907,10 +863,10 @@ str_units(int n)
        return P_("sector", "sectors", n);
 }
 
-void change_units(void)
+void change_units(struct fdisk_context *cxt)
 {
        display_in_cyl_units = !display_in_cyl_units;
-       update_units();
+       update_units(cxt);
 
        if (display_in_cyl_units)
                printf(_("Changing display/entry units to cylinders (DEPRECATED!)\n"));
@@ -948,7 +904,7 @@ delete_partition(struct fdisk_context *cxt, int i)
        if (i < 0)
                return;
 
-       if (warn_geometry())
+       if (warn_geometry(cxt))
                return;         /* C/H/S not set */
 
        ptes[i].changed = 1;
@@ -1044,16 +1000,17 @@ static void change_sysid(struct fdisk_context *cxt)
  * Lubkin Oct.  1991). */
 
 static void
-long2chs(unsigned long ls, unsigned int *c, unsigned int *h, unsigned int *s) {
-       int spc = heads * sectors;
+long2chs(struct fdisk_context *cxt, unsigned long ls,
+        unsigned int *c, unsigned int *h, unsigned int *s) {
+       int spc = cxt->geom.heads * cxt->geom.sectors;
 
        *c = ls / spc;
        ls = ls % spc;
-       *h = ls / sectors;
-       *s = ls % sectors + 1;  /* sectors count from 1 */
+       *h = ls / cxt->geom.sectors;
+       *s = ls % cxt->geom.sectors + 1;        /* sectors count from 1 */
 }
 
-static void check_consistency(struct partition *p, int partition) {
+static void check_consistency(struct fdisk_context *cxt, struct partition *p, int partition) {
        unsigned int pbc, pbh, pbs;     /* physical beginning c, h, s */
        unsigned int pec, peh, pes;     /* physical ending c, h, s */
        unsigned int lbc, lbh, lbs;     /* logical beginning c, h, s */
@@ -1062,7 +1019,7 @@ static void check_consistency(struct partition *p, int partition) {
        if (!dos_compatible_flag)
                return;
 
-       if (!heads || !sectors || (partition >= 4))
+       if (!cxt->geom.heads || !cxt->geom.sectors || (partition >= 4))
                return;         /* do not check extended partitions */
 
 /* physical beginning c, h, s */
@@ -1076,13 +1033,13 @@ static void check_consistency(struct partition *p, int partition) {
        pes = p->end_sector & 0x3f;
 
 /* compute logical beginning (c, h, s) */
-       long2chs(get_start_sect(p), &lbc, &lbh, &lbs);
+       long2chs(cxt, get_start_sect(p), &lbc, &lbh, &lbs);
 
 /* compute logical ending (c, h, s) */
-       long2chs(get_start_sect(p) + get_nr_sects(p) - 1, &lec, &leh, &les);
+       long2chs(cxt, get_start_sect(p) + get_nr_sects(p) - 1, &lec, &leh, &les);
 
 /* Same physical / logical beginning? */
-       if (cylinders <= 1024 && (pbc != lbc || pbh != lbh || pbs != lbs)) {
+       if (cxt->geom.cylinders <= 1024 && (pbc != lbc || pbh != lbh || pbs != lbs)) {
                printf(_("Partition %d has different physical/logical "
                        "beginnings (non-Linux?):\n"), partition + 1);
                printf(_("     phys=(%d, %d, %d) "), pbc, pbh, pbs);
@@ -1090,7 +1047,7 @@ static void check_consistency(struct partition *p, int partition) {
        }
 
 /* Same physical / logical ending? */
-       if (cylinders <= 1024 && (pec != lec || peh != leh || pes != les)) {
+       if (cxt->geom.cylinders <= 1024 && (pec != lec || peh != leh || pes != les)) {
                printf(_("Partition %d has different physical/logical "
                        "endings:\n"), partition + 1);
                printf(_("     phys=(%d, %d, %d) "), pec, peh, pes);
@@ -1098,7 +1055,7 @@ static void check_consistency(struct partition *p, int partition) {
        }
 
 /* Ending on cylinder boundary? */
-       if (peh != (heads - 1) || pes != sectors) {
+       if (peh != (cxt->geom.heads - 1) || pes != cxt->geom.sectors) {
                printf(_("Partition %i does not end on cylinder boundary.\n"),
                        partition + 1);
        }
@@ -1125,8 +1082,8 @@ list_disk_geometry(struct fdisk_context *cxt) {
                printf(_("\nDisk %s: %ld.%ld GB, %llu bytes\n"),
                       cxt->dev_path, hectomega / 10, hectomega % 10, bytes);
        }
-       printf(_("%d heads, %llu sectors/track, %d cylinders"),
-              heads, sectors, cylinders);
+       printf(_("%d heads, %llu sectors/track, %llu cylinders"),
+              cxt->geom.heads, cxt->geom.sectors, cxt->geom.cylinders);
        if (units_per_sector == 1)
                printf(_(", total %llu sectors"), cxt->total_sectors);
        printf("\n");
@@ -1347,7 +1304,7 @@ list_table(struct fdisk_context *cxt, int xtra) {
 /* type id */          p->sys_ind,
 /* type name */                (type = partition_type(p->sys_ind)) ?
                        type : _("Unknown"));
-                       check_consistency(p, i);
+                       check_consistency(cxt, p, i);
                        check_alignment(cxt, get_partition_start(pe), i);
                }
        }
@@ -1366,8 +1323,8 @@ x_list_table(struct fdisk_context *cxt, int extend) {
        struct partition *p;
        int i;
 
-       printf(_("\nDisk %s: %d heads, %llu sectors, %d cylinders\n\n"),
-               cxt->dev_path, heads, sectors, cylinders);
+       printf(_("\nDisk %s: %d heads, %llu sectors, %llu cylinders\n\n"),
+               cxt->dev_path, cxt->geom.heads, cxt->geom.sectors, cxt->geom.cylinders);
         printf(_("Nr AF  Hd Sec  Cyl  Hd Sec  Cyl     Start      Size ID\n"));
        for (i = 0 ; i < partitions; i++) {
                pe = &ptes[i];
@@ -1382,7 +1339,7 @@ x_list_table(struct fdisk_context *cxt, int extend) {
                                (unsigned long) get_start_sect(p),
                                (unsigned long) get_nr_sects(p), p->sys_ind);
                        if (p->sys_ind) {
-                               check_consistency(p, i);
+                               check_consistency(cxt, p, i);
                                check_alignment(cxt, get_partition_start(pe), i);
                        }
                }
@@ -1408,26 +1365,26 @@ void fill_bounds(sector_t *first, sector_t *last)
 }
 
 static void
-check(int n, unsigned int h, unsigned int s, unsigned int c,
+check(struct fdisk_context *cxt, int n, unsigned int h, unsigned int s, unsigned int c,
       unsigned int start) {
        unsigned int total, real_s, real_c;
 
        real_s = sector(s) - 1;
        real_c = cylinder(s, c);
-       total = (real_c * sectors + real_s) * heads + h;
+       total = (real_c * cxt->geom.sectors + real_s) * cxt->geom.heads + h;
        if (!total)
                fprintf(stderr, _("Warning: partition %d contains sector 0\n"), n);
-       if (h >= heads)
+       if (h >= cxt->geom.heads)
                fprintf(stderr,
                        _("Partition %d: head %d greater than maximum %d\n"),
-                       n, h + 1, heads);
-       if (real_s >= sectors)
+                       n, h + 1, cxt->geom.heads);
+       if (real_s >= cxt->geom.sectors)
                fprintf(stderr, _("Partition %d: sector %d greater than "
-                       "maximum %llu\n"), n, s, sectors);
-       if (real_c >= cylinders)
+                       "maximum %llu\n"), n, s, cxt->geom.sectors);
+       if (real_c >= cxt->geom.cylinders)
                fprintf(stderr, _("Partitions %d: cylinder %d greater than "
-                       "maximum %d\n"), n, real_c + 1, cylinders);
-       if (cylinders <= 1024 && start != total)
+                       "maximum %llu\n"), n, real_c + 1, cxt->geom.cylinders);
+       if (cxt->geom.cylinders <= 1024 && start != total)
                fprintf(stderr,
                        _("Partition %d: previous sectors %d disagrees with "
                        "total %d\n"), n, start, total);
@@ -1440,7 +1397,7 @@ verify(struct fdisk_context *cxt) {
        unsigned long long first[partitions], last[partitions];
        struct partition *p;
 
-       if (warn_geometry())
+       if (warn_geometry(cxt))
                return;
 
        if (disklabel == SUN_LABEL) {
@@ -1459,13 +1416,13 @@ verify(struct fdisk_context *cxt) {
 
                p = pe->part_table;
                if (p->sys_ind && !IS_EXTENDED (p->sys_ind)) {
-                       check_consistency(p, i);
+                       check_consistency(cxt, p, i);
                        check_alignment(cxt, get_partition_start(pe), i);
                        if (get_partition_start(pe) < first[i])
                                printf(_("Warning: bad start-of-data in "
                                        "partition %d\n"), i + 1);
-                       check(i + 1, p->end_head, p->end_sector, p->end_cyl,
-                               last[i]);
+                       check(cxt, i + 1, p->end_head, p->end_sector, p->end_cyl,
+                             last[i]);
                        total += last[i] + 1 - first[i];
                        for (j = 0; j < i; j++)
                        if ((first[i] >= first[j] && first[i] <= last[j])
@@ -1519,7 +1476,7 @@ void print_partition_size(struct fdisk_context *cxt,
 
 static void new_partition(struct fdisk_context *cxt)
 {
-       if (warn_geometry())
+       if (warn_geometry(cxt))
                return;
 
        if (disklabel == SUN_LABEL) {
@@ -1656,7 +1613,7 @@ move_begin(struct fdisk_context *cxt, int i) {
        unsigned int new, free_start, curr_start, last;
        int x;
 
-       if (warn_geometry())
+       if (warn_geometry(cxt))
                return;
        if (!p->sys_ind || !get_nr_sects(p) || IS_EXTENDED (p->sys_ind)) {
                printf(_("Partition %d has no data area\n"), i + 1);
@@ -1723,11 +1680,11 @@ expert_command_prompt(struct fdisk_context *cxt)
                                move_begin(cxt, get_partition(cxt, 0, partitions));
                        break;
                case 'c':
-                       user_cylinders = cylinders =
-                               read_int(cxt, 1, cylinders, 1048576, 0,
+                       user_cylinders = cxt->geom.cylinders =
+                               read_int(cxt, 1, cxt->geom.cylinders, 1048576, 0,
                                         _("Number of cylinders"));
                        if (disklabel == SUN_LABEL)
-                               sun_set_ncyl(cxt, cylinders);
+                               sun_set_ncyl(cxt, cxt->geom.cylinders);
                        break;
                case 'd':
                        print_raw(cxt);
@@ -1749,9 +1706,9 @@ expert_command_prompt(struct fdisk_context *cxt)
                        create_sgilabel(cxt);
                        break;
                case 'h':
-                       user_heads = heads = read_int(cxt, 1, heads, 256, 0,
+                       user_heads = cxt->geom.heads = read_int(cxt, 1, cxt->geom.heads, 256, 0,
                                         _("Number of heads"));
-                       update_units();
+                       update_units(cxt);
                        break;
                case 'i':
                        if (disklabel == SUN_LABEL)
@@ -1774,14 +1731,14 @@ expert_command_prompt(struct fdisk_context *cxt)
                case 'r':
                        return;
                case 's':
-                       user_sectors = sectors = read_int(cxt, 1, sectors, 63, 0,
+                       user_sectors = cxt->geom.sectors = read_int(cxt, 1, cxt->geom.sectors, 63, 0,
                                           _("Number of sectors"));
                        if (dos_compatible_flag)
                                fprintf(stderr, _("Warning: setting "
                                        "sector offset for DOS "
                                        "compatiblity\n"));
                        update_sector_offset(cxt);
-                       update_units();
+                       update_units(cxt);
                        break;
                case 'v':
                        verify(cxt);
@@ -1829,6 +1786,17 @@ static void print_partition_table_from_option(char *device, unsigned long sector
                err(EXIT_FAILURE, _("unable to open %s"), device);
        if (sector_size)  /* passed -b option, override autodiscovery */
                cxt->phy_sector_size = cxt->sector_size = sector_size;
+       /* passed CHS option(s), override autodiscovery */
+       if (user_cylinders)
+               cxt->geom.cylinders = user_cylinders;
+       if (user_heads) {
+               cxt->geom.heads = user_heads;
+               fdisk_geom_set_cyls(cxt);
+       }
+       if (user_sectors) {
+               cxt->geom.sectors = user_sectors;
+               fdisk_geom_set_cyls(cxt);
+       }
 
        gpt_warning(device);
        gb = get_boot(cxt, 1);
@@ -1978,7 +1946,7 @@ static void command_prompt(struct fdisk_context *cxt)
                        change_sysid(cxt);
                        break;
                case 'u':
-                       change_units();
+                       change_units(cxt);
                        break;
                case 'v':
                        verify(cxt);
@@ -2086,8 +2054,6 @@ int main(int argc, char **argv)
                printf(_("Warning: the -b (set sector size) option should"
                         " be used with one specified device\n"));
 
-       /* init_mbr_buffer(); */
-
        if (optl) {
                nowarn = 1;
                if (argc > optind) {
@@ -2120,6 +2086,17 @@ int main(int argc, char **argv)
                        err(EXIT_FAILURE, _("unable to open %s"), argv[optind]);
                if (sector_size) /* passed -b option, override autodiscovery */
                        cxt->phy_sector_size = cxt->sector_size = sector_size;
+               /* passed CHS option(s), override autodiscovery */
+               if (user_cylinders)
+                       cxt->geom.cylinders = user_cylinders;
+               if (user_heads) {
+                       cxt->geom.heads = user_heads;
+                       fdisk_geom_set_cyls(cxt);
+               }
+               if (user_sectors) {
+                       cxt->geom.sectors = user_sectors;
+                       fdisk_geom_set_cyls(cxt);
+               }
        }
        else
                usage(stderr);
index b4f2814f9ad23890f4a822b3aef585cb70c32f8e..51a63b228adbe7127a84353183a897e431b285a1 100644 (file)
@@ -36,6 +36,7 @@
 #define FDISK_DEBUG_INIT       (1 << 1)
 #define FDISK_DEBUG_CONTEXT    (1 << 2)
 #define FDISK_DEBUG_TOPOLOGY    (1 << 3)
+#define FDISK_DEBUG_GEOMETRY    (1 << 4)
 #define FDISK_DEBUG_ALL                0xFFFF
 
 # define ON_DBG(m, x)  do { \
@@ -95,14 +96,17 @@ enum failure {
        unable_to_write
 };
 
-struct geom {
+typedef unsigned long long sector_t;
+
+/*
+ * Legacy CHS based geometry
+ */
+struct fdisk_geometry {
        unsigned int heads;
-       unsigned int sectors;
-       unsigned int cylinders;
+       sector_t sectors;
+       sector_t cylinders;
 };
 
-typedef unsigned long long sector_t;
-
 struct fdisk_context {
        int dev_fd;         /* device descriptor */
        char *dev_path;     /* device path */
@@ -118,6 +122,7 @@ struct fdisk_context {
 
        /* geometry */
        sector_t total_sectors; /* in logical sectors */
+       struct fdisk_geometry geom;
 };
 
 extern struct fdisk_context *fdisk_new_context_from_filename(const char *fname, int readonly);
@@ -125,14 +130,14 @@ extern int fdisk_dev_has_topology(struct fdisk_context *cxt);
 extern int fdisk_dev_sectsz_is_default(struct fdisk_context *cxt);
 extern void fdisk_free_context(struct fdisk_context *cxt);
 extern void fdisk_mbr_zeroize(struct fdisk_context *cxt);
+extern void fdisk_geom_set_cyls(struct fdisk_context *cxt);
 
 /* prototypes for fdisk.c */
 extern char *disk_device, *line_ptr;
 extern int fd, partitions;
 extern unsigned int display_in_cyl_units, units_per_sector;
-extern void change_units(void);
+extern void change_units(struct fdisk_context *cxt);
 extern void fatal(struct fdisk_context *cxt, enum failure why);
-extern void get_geometry(struct fdisk_context *, struct geom *);
 extern int  get_partition(struct fdisk_context *cxt, int warn, int max);
 extern void list_types(struct systypes *sys);
 extern int read_line (int *asked);
@@ -151,11 +156,11 @@ extern void fill_bounds(sector_t *first, sector_t *last);
 extern unsigned int heads, cylinders;
 extern sector_t sectors;
 extern char *partition_type(unsigned char type);
-extern void update_units(void);
+extern void update_units(struct fdisk_context *cxt);
 extern char read_chars(char *mesg);
 extern void set_changed(int);
 extern void set_all_unchanged(void);
-extern int warn_geometry(void);
+extern int warn_geometry(struct fdisk_context *cxt);
 extern void warn_limits(struct fdisk_context *cxt);
 extern void warn_alignment(struct fdisk_context *cxt);
 extern unsigned int read_int_with_suffix(struct fdisk_context *cxt,
@@ -163,6 +168,9 @@ extern unsigned int read_int_with_suffix(struct fdisk_context *cxt,
                                  unsigned int base, char *mesg, int *is_suffix_used);
 extern sector_t align_lba(struct fdisk_context *cxt, sector_t lba, int direction);
 extern int get_partition_dflt(struct fdisk_context *cxt, int warn, int max, int dflt);
+extern void update_sector_offset(struct fdisk_context *cxt);
+extern void get_partition_table_geometry(struct fdisk_context *cxt,
+                                        unsigned int *ph, unsigned int *ps);
 
 #define PLURAL 0
 #define SINGULAR 1
index c15ab749b0abeafa1d570fca41b48bb5bae35d83..fb36489e11597ed4034c6e32bc362c763e49b563 100644 (file)
@@ -57,7 +57,7 @@ int check_aix_label(struct fdisk_context *cxt)
        return 0;
     }
     other_endian = (aixlabel->magic == AIX_LABEL_MAGIC_SWAPPED);
-    update_units();
+    update_units(cxt);
     disklabel = AIX_LABEL;
     partitions= 1016;
     volumes = 15;
index b92530f5048b21791d0173f4c3617f2a07bc7393..71efd33f673784342059b72a5fdf51ee3debaa45 100644 (file)
@@ -213,7 +213,7 @@ bsd_command_prompt (struct fdisk_context *cxt)
        xbsd_change_fstype ();
        break;
       case 'u':
-       change_units();
+       change_units(cxt);
        break;
       case 'w':
        xbsd_write_disklabel (cxt);
@@ -636,9 +636,7 @@ static int
 xbsd_initlabel (struct fdisk_context *cxt, struct partition *p, struct xbsd_disklabel *d,
                int pindex __attribute__((__unused__))) {
        struct xbsd_partition *pp;
-       struct geom g;
 
-       get_geometry (cxt, &g);
        memset (d, 0, sizeof (struct xbsd_disklabel));
 
        d -> d_magic = BSD_DISKMAGIC;
@@ -658,10 +656,10 @@ xbsd_initlabel (struct fdisk_context *cxt, struct partition *p, struct xbsd_disk
        d -> d_flags = 0;
 #endif
        d -> d_secsize = SECTOR_SIZE;           /* bytes/sector  */
-       d -> d_nsectors = g.sectors;            /* sectors/track */
-       d -> d_ntracks = g.heads;               /* tracks/cylinder (heads) */
-       d -> d_ncylinders = g.cylinders;
-       d -> d_secpercyl  = g.sectors * g.heads;/* sectors/cylinder */
+       d -> d_nsectors = cxt->geom.sectors;            /* sectors/track */
+       d -> d_ntracks = cxt->geom.heads;               /* tracks/cylinder (heads) */
+       d -> d_ncylinders = cxt->geom.cylinders;
+       d -> d_secpercyl  = cxt->geom.sectors * cxt->geom.heads;/* sectors/cylinder */
        if (d -> d_secpercyl == 0)
                d -> d_secpercyl = 1;           /* avoid segfaults */
        d -> d_secperunit = d -> d_secpercyl * d -> d_ncylinders;
index abf101b32e88d88dcf1a126ca3ae8bac55254e6f..a72a432c1e8c1d1ec7b2cd8c7774f29eefbfbf92 100644 (file)
 #include "fdiskdoslabel.h"
 
 #define set_hsc(h,s,c,sector) { \
-               s = sector % sectors + 1;                       \
-               sector /= sectors;                              \
-               h = sector % heads;                             \
-               sector /= heads;                                \
-               c = sector & 0xff;                              \
-               s |= (sector >> 2) & 0xc0;                      \
+               s = sector % cxt->geom.sectors + 1;                     \
+               sector /= cxt->geom.sectors;                            \
+               h = sector % cxt->geom.heads;                           \
+               sector /= cxt->geom.heads;                              \
+               c = sector & 0xff;                                      \
+               s |= (sector >> 2) & 0xc0;                              \
        }
 
 #define alignment_required     (grain != cxt->sector_size)
@@ -115,7 +115,7 @@ void dos_init(struct fdisk_context *cxt)
                pe->changed = 0;
        }
 
-       warn_geometry();
+       warn_geometry(cxt);
        warn_limits(cxt);
        warn_alignment(cxt);
 }
@@ -389,11 +389,11 @@ static void set_partition(struct fdisk_context *cxt,
        if (!doext)
                print_partition_size(cxt, i + 1, start, stop, sysid);
 
-       if (dos_compatible_flag && (start/(sectors*heads) > 1023))
-               start = heads*sectors*1024 - 1;
+       if (dos_compatible_flag && (start/(cxt->geom.sectors*cxt->geom.heads) > 1023))
+               start = cxt->geom.heads*cxt->geom.sectors*1024 - 1;
        set_hsc(p->head, p->sector, p->cyl, start);
-       if (dos_compatible_flag && (stop/(sectors*heads) > 1023))
-               stop = heads*sectors*1024 - 1;
+       if (dos_compatible_flag && (stop/(cxt->geom.sectors*cxt->geom.heads) > 1023))
+               stop = cxt->geom.heads*cxt->geom.sectors*1024 - 1;
        set_hsc(p->end_head, p->end_sector, p->end_cyl, stop);
        ptes[i].changed = 1;
 }
@@ -449,7 +449,7 @@ void dos_add_partition(struct fdisk_context *cxt, int n, int sys)
        if (n < 4) {
                start = sector_offset;
                if (display_in_cyl_units || !cxt->total_sectors)
-                       limit = heads * sectors * cylinders - 1;
+                       limit = cxt->geom.heads * cxt->geom.sectors * cxt->geom.cylinders - 1;
                else
                        limit = cxt->total_sectors - 1;
 
index 1c2e403e7c86ddf6f6730636644ad0f98eac3e16..96fc7121e868f1b65cf023d5a22b04ed2cbad964 100644 (file)
@@ -72,7 +72,7 @@ check_mac_label(struct fdisk_context *cxt)
 
 IS_MAC:
     other_endian = (maclabel->magic == MAC_LABEL_MAGIC_SWAPPED); // =?
-    update_units();
+    update_units(cxt);
     disklabel = MAC_LABEL;
     partitions= 1016; // =?
     volumes = 15;      // =?
index 1557e2cc250589cbfdfdfabd19dcbc872087be7a..c9033cb41f7f427506f6d0b92beab1ae49075d26 100644 (file)
@@ -151,7 +151,7 @@ check_sgi_label(struct fdisk_context *cxt) {
                fprintf(stderr,
                        _("Detected sgi disklabel with wrong checksum.\n"));
        }
-       update_units();
+       update_units(cxt);
        disklabel = SGI_LABEL;
        partitions= 16;
        volumes = 15;
@@ -168,11 +168,11 @@ sgi_list_table(struct fdisk_context *cxt, int xtra) {
 
        if (xtra) {
                printf(_("\nDisk %s (SGI disk label): %d heads, %llu sectors\n"
-                        "%d cylinders, %d physical cylinders\n"
+                        "%llu cylinders, %d physical cylinders\n"
                         "%d extra sects/cyl, interleave %d:1\n"
                         "%s\n"
                         "Units = %s of %d * %ld bytes\n\n"),
-                      cxt->dev_path, heads, sectors, cylinders,
+                      cxt->dev_path, cxt->geom.heads, cxt->geom.sectors, cxt->geom.cylinders,
                       SSWAP16(sgiparam.pcylcount),
                       (int) sgiparam.sparecyl, SSWAP16(sgiparam.ilfact),
                       (char *)sgilabel,
@@ -180,9 +180,9 @@ sgi_list_table(struct fdisk_context *cxt, int xtra) {
                        cxt->sector_size);
        } else {
                printf(_("\nDisk %s (SGI disk label): "
-                        "%d heads, %llu sectors, %d cylinders\n"
+                        "%d heads, %llu sectors, %llu cylinders\n"
                         "Units = %s of %d * %ld bytes\n\n"),
-                      cxt->dev_path, heads, sectors, cylinders,
+                      cxt->dev_path, cxt->geom.heads, cxt->geom.sectors, cxt->geom.cylinders,
                       str_units(PLURAL), units_per_sector,
                        cxt->sector_size);
        }
@@ -258,8 +258,8 @@ sgi_set_bootpartition(struct fdisk_context *cxt, int i)
 }
 
 static unsigned int
-sgi_get_lastblock(void) {
-       return heads * sectors * cylinders;
+sgi_get_lastblock(struct fdisk_context *cxt) {
+       return cxt->geom.heads * cxt->geom.sectors * cxt->geom.cylinders;
 }
 
 void
@@ -445,7 +445,7 @@ verify_sgi(struct fdisk_context *cxt, int verbose)
        int entire = 0, i = 0;
        unsigned int start = 0;
        long long gap = 0;      /* count unused blocks */
-       unsigned int lastblock = sgi_get_lastblock();
+       unsigned int lastblock = sgi_get_lastblock(cxt);
 
        clearfreelist();
        for (i=0; i<16; i++) {
@@ -613,7 +613,7 @@ sgi_set_entire(struct fdisk_context *cxt) {
 
        for (n=10; n<partitions; n++) {
                if (!sgi_get_num_sectors(cxt, n)) {
-                       sgi_set_partition(cxt, n, 0, sgi_get_lastblock(), SGI_VOLUME);
+                       sgi_set_partition(cxt, n, 0, sgi_get_lastblock(cxt), SGI_VOLUME);
                        break;
                }
        }
@@ -631,7 +631,7 @@ sgi_set_volhdr(struct fdisk_context *cxt)
                         * Choose same default volume header size
                         * as IRIX fx uses.
                         */
-                       if (4096 < sgi_get_lastblock())
+                       if (4096 < sgi_get_lastblock(cxt))
                                sgi_set_partition(cxt, n, 0, 4096, SGI_VOLHDR);
                        break;
                }
@@ -677,7 +677,7 @@ sgi_add_partition(struct fdisk_context *cxt, int n, int sys)
        snprintf(mesg, sizeof(mesg), _("First %s"), str_units(SINGULAR));
        for (;;) {
                if (sys == SGI_VOLUME) {
-                       last = sgi_get_lastblock();
+                       last = sgi_get_lastblock(cxt);
                        first = read_int(cxt, 0, 0, last-1, 0, mesg);
                        if (first != 0) {
                                printf(_("It is highly recommended that eleventh partition\n"
@@ -708,7 +708,7 @@ sgi_add_partition(struct fdisk_context *cxt, int n, int sys)
                last *= units_per_sector;                                     
        /*else                                                             
                last = last; * align to cylinder if You know how ... */
-       if ((sys == SGI_VOLUME) && (first != 0 || last != sgi_get_lastblock()))
+       if ((sys == SGI_VOLUME) && (first != 0 || last != sgi_get_lastblock(cxt)))
                printf(_("It is highly recommended that eleventh partition\n"
                         "covers the entire disk and is of type `SGI volume'\n"));
        sgi_set_partition(cxt, n, first, last-first, sys);
@@ -741,23 +741,23 @@ create_sgilabel(struct fdisk_context *cxt)
        if (ioctl(cxt->dev_fd, HDIO_GETGEO, &geometry) < 0)
                err(EXIT_FAILURE, _("HDIO_GETGEO ioctl failed on %s"), cxt->dev_path);
 
-       heads = geometry.heads;
-       sectors = geometry.sectors;
+       cxt->geom.heads = geometry.heads;
+       cxt->geom.sectors = geometry.sectors;
        if (res == 0) {
                /* the get device size ioctl was successful */
                sector_t llcyls;
-               llcyls = llsectors / (heads * sectors * sec_fac);
-               cylinders = llcyls;
-               if (cylinders != llcyls)        /* truncated? */
-                       cylinders = ~0;
+               llcyls = llsectors / (cxt->geom.heads * cxt->geom.sectors * sec_fac);
+               cxt->geom.cylinders = llcyls;
+               if (cxt->geom.cylinders != llcyls)      /* truncated? */
+                       cxt->geom.cylinders = ~0;
        } else {
                /* otherwise print error and use truncated version */
-               cylinders = geometry.cylinders;
+               cxt->geom.cylinders = geometry.cylinders;
                fprintf(stderr,
                        _("Warning:  BLKGETSIZE ioctl failed on %s.  "
-                         "Using geometry cylinder value of %d.\n"
+                         "Using geometry cylinder value of %llu.\n"
                          "This value may be truncated for devices"
-                         " > 33.8 GB.\n"), cxt->dev_path, cylinders);
+                         " > 33.8 GB.\n"), cxt->dev_path, cxt->geom.cylinders);
        }
 #endif
        for (i = 0; i < 4; i++) {
index 8698682241545c6f4a7c119b9c6e2ab6270dc2ef..65cbf8f168e9b648adc9cd0f0e2c21b4395fb067 100644 (file)
@@ -65,7 +65,7 @@ static void set_sun_partition(struct fdisk_context *cxt,
        sunlabel->part_tags[i].tag = SSWAP16(sysid);
        sunlabel->part_tags[i].flag = SSWAP16(0);
        sunlabel->partitions[i].start_cylinder =
-               SSWAP32(start / (heads * sectors));
+               SSWAP32(start / (cxt->geom.heads * cxt->geom.sectors));
        sunlabel->partitions[i].num_sectors =
                SSWAP32(stop - start);
        set_changed(i);
@@ -104,9 +104,9 @@ int check_sun_label(struct fdisk_context *cxt)
        } else {
                int need_fixing = 0;
 
-               heads = SSWAP16(sunlabel->nhead);
-               cylinders = SSWAP16(sunlabel->ncyl);
-               sectors = SSWAP16(sunlabel->nsect);
+               cxt->geom.heads = SSWAP16(sunlabel->nhead);
+               cxt->geom.cylinders = SSWAP16(sunlabel->ncyl);
+               cxt->geom.sectors = SSWAP16(sunlabel->nsect);
 
                if (sunlabel->version != SSWAP32(SUN_LABEL_VERSION)) {
                        fprintf(stderr,_("Detected sun disklabel with wrong version [0x%08x].\n"),
@@ -140,7 +140,7 @@ int check_sun_label(struct fdisk_context *cxt)
                        set_changed(0);
                }
        }
-       update_units();
+       update_units(cxt);
        return 1;
 }
 
@@ -172,57 +172,57 @@ void create_sunlabel(struct fdisk_context *cxt)
 
 #ifdef HDIO_GETGEO
        if (!ioctl(cxt->dev_fd, HDIO_GETGEO, &geometry)) {
-               heads = geometry.heads;
-               sectors = geometry.sectors;
+               cxt->geom.heads = geometry.heads;
+               cxt->geom.sectors = geometry.sectors;
                if (res == 0) {
-                       llcyls = llsectors / (heads * sectors * sec_fac);
-                       cylinders = llcyls;
-                       if (cylinders != llcyls)
-                               cylinders = ~0;
+                       llcyls = llsectors / (cxt->geom.heads * cxt->geom.sectors * sec_fac);
+                       cxt->geom.cylinders = llcyls;
+                       if (cxt->geom.cylinders != llcyls)
+                               cxt->geom.cylinders = ~0;
                } else {
-                       cylinders = geometry.cylinders;
+                       cxt->geom.cylinders = geometry.cylinders;
                        fprintf(stderr,
                                _("Warning:  BLKGETSIZE ioctl failed on %s.  "
-                                 "Using geometry cylinder value of %d.\n"
+                                 "Using geometry cylinder value of %llu.\n"
                                  "This value may be truncated for devices"
-                                 " > 33.8 GB.\n"), cxt->dev_path, cylinders);
+                                 " > 33.8 GB.\n"), cxt->dev_path, cxt->geom.cylinders);
                }
        } else
 #endif
        {
-               heads = read_int(cxt, 1,1,1024,0,_("Heads"));
-               sectors = read_int(cxt, 1,1,1024,0,_("Sectors/track"));
-               cylinders = read_int(cxt, 1,1,65535,0,_("Cylinders"));
+               cxt->geom.heads = read_int(cxt, 1,1,1024,0,_("Heads"));
+               cxt->geom.sectors = read_int(cxt, 1,1,1024,0,_("Sectors/track"));
+               cxt->geom.cylinders = read_int(cxt, 1,1,65535,0,_("Cylinders"));
        }
 
        sunlabel->acyl   = SSWAP16(2);
-       sunlabel->pcyl   = SSWAP16(cylinders);
-       sunlabel->ncyl   = SSWAP16(cylinders - 2);
+       sunlabel->pcyl   = SSWAP16(cxt->geom.cylinders);
+       sunlabel->ncyl   = SSWAP16(cxt->geom.cylinders - 2);
        sunlabel->rpm    = SSWAP16(5400);
        sunlabel->intrlv = SSWAP16(1);
        sunlabel->apc    = SSWAP16(0);
 
-       sunlabel->nhead = SSWAP16(heads);
-       sunlabel->nsect = SSWAP16(sectors);
-       sunlabel->ncyl = SSWAP16(cylinders);
+       sunlabel->nhead = SSWAP16(cxt->geom.heads);
+       sunlabel->nsect = SSWAP16(cxt->geom.sectors);
+       sunlabel->ncyl = SSWAP16(cxt->geom.cylinders);
 
        snprintf(sunlabel->label_id, sizeof(sunlabel->label_id),
-                "Linux cyl %d alt %d hd %d sec %llu",
-                cylinders, SSWAP16(sunlabel->acyl), heads, sectors);
+                "Linux cyl %llu alt %d hd %d sec %llu",
+                cxt->geom.cylinders, SSWAP16(sunlabel->acyl), cxt->geom.heads, cxt->geom.sectors);
 
-       if (cylinders * heads * sectors >= 150 * 2048) {
-               ndiv = cylinders - (50 * 2048 / (heads * sectors)); /* 50M swap */
+       if (cxt->geom.cylinders * cxt->geom.heads * cxt->geom.sectors >= 150 * 2048) {
+               ndiv = cxt->geom.cylinders - (50 * 2048 / (cxt->geom.heads * cxt->geom.sectors)); /* 50M swap */
        } else
-               ndiv = cylinders * 2 / 3;
+               ndiv = cxt->geom.cylinders * 2 / 3;
 
-       set_sun_partition(cxt, 0, 0, ndiv * heads * sectors,
+       set_sun_partition(cxt, 0, 0, ndiv * cxt->geom.heads * cxt->geom.sectors,
                          SUN_TAG_LINUX_NATIVE);
-       set_sun_partition(cxt, 1, ndiv * heads * sectors,
-                         cylinders * heads * sectors,
+       set_sun_partition(cxt, 1, ndiv * cxt->geom.heads * cxt->geom.sectors,
+                         cxt->geom.cylinders * cxt->geom.heads * cxt->geom.sectors,
                          SUN_TAG_LINUX_SWAP);
        sunlabel->part_tags[1].flag |= SSWAP16(SUN_FLAG_UNMNT);
 
-       set_sun_partition(cxt, 2, 0, cylinders * heads * sectors, SUN_TAG_BACKUP);
+       set_sun_partition(cxt, 2, 0, cxt->geom.cylinders * cxt->geom.heads * cxt->geom.sectors, SUN_TAG_BACKUP);
 
        {
                unsigned short *ush = (unsigned short *)sunlabel;
@@ -251,7 +251,7 @@ static void fetch_sun(struct fdisk_context *cxt, uint32_t *starts,
        int i, continuous = 1;
 
        *start = 0;
-       *stop = cylinders * heads * sectors;
+       *stop = cxt->geom.cylinders * cxt->geom.heads * cxt->geom.sectors;
 
        for (i = 0; i < partitions; i++) {
                struct sun_partition *part = &sunlabel->partitions[i];
@@ -261,7 +261,7 @@ static void fetch_sun(struct fdisk_context *cxt, uint32_t *starts,
                    tag->tag != SSWAP16(SUN_TAG_UNASSIGNED) &&
                    tag->tag != SSWAP16(SUN_TAG_BACKUP)) {
                        starts[i] = (SSWAP32(part->start_cylinder) *
-                                    heads * sectors);
+                                    cxt->geom.heads * cxt->geom.sectors);
                        lens[i] = SSWAP32(part->num_sectors);
                        if (continuous) {
                                if (starts[i] == *start)
@@ -305,7 +305,7 @@ void verify_sun(struct fdisk_context *cxt)
 
     for (k = 0; k < 7; k++) {
        for (i = 0; i < SUN_NUM_PARTITIONS; i++) {
-           if (k && (lens[i] % (heads * sectors))) {
+           if (k && (lens[i] % (cxt->geom.heads * cxt->geom.sectors))) {
                printf(_("Partition %d doesn't end on cylinder boundary\n"), i+1);
            }
            if (lens[i]) {
@@ -347,7 +347,7 @@ void verify_sun(struct fdisk_context *cxt)
        printf(_("No partitions defined\n"));
        return;
     }
-    stop = cylinders * heads * sectors;
+    stop = cxt->geom.cylinders * cxt->geom.heads * cxt->geom.sectors;
     if (starts[array[0]])
         printf(_("Unused gap - sectors 0-%d\n"), starts[array[0]]);
     for (i = 0; i < 7 && array[i+1] != -1; i++) {
@@ -399,7 +399,7 @@ void add_sun_partition(struct fdisk_context *cxt, int n, int sys)
                        first *= units_per_sector;
                else {
                        /* Starting sector has to be properly aligned */
-                       int cs = heads * sectors;
+                       int cs = cxt->geom.heads * cxt->geom.sectors;
                        int x = first % cs;
 
                        if (x)
@@ -438,7 +438,7 @@ and is of type `Whole disk'\n"));
                } else
                        break;
        }
-       stop = cylinders * heads * sectors;     /* ancient */
+       stop = cxt->geom.cylinders * cxt->geom.heads * cxt->geom.sectors;       /* ancient */
        stop2 = stop;
        for (i = 0; i < partitions; i++) {
                if (starts[i] > first && starts[i] < stop)
@@ -490,7 +490,7 @@ void sun_delete_partition(struct fdisk_context *cxt, int i)
            tag->tag == SSWAP16(SUN_TAG_BACKUP) &&
            !part->start_cylinder &&
            (nsec = SSWAP32(part->num_sectors))
-             == heads * sectors * cylinders)
+             == cxt->geom.heads * cxt->geom.sectors * cxt->geom.cylinders)
                printf(_("If you want to maintain SunOS/Solaris compatibility, "
                       "consider leaving this\n"
                       "partition as Whole disk (5), starting at 0, with %u "
@@ -539,13 +539,13 @@ void sun_list_table(struct fdisk_context *cxt, int xtra)
        if (xtra)
                printf(
                _("\nDisk %s (Sun disk label): %u heads, %llu sectors, %d rpm\n"
-               "%u cylinders, %d alternate cylinders, %d physical cylinders\n"
+               "%llu cylinders, %d alternate cylinders, %d physical cylinders\n"
                "%d extra sects/cyl, interleave %d:1\n"
                "Label ID: %s\n"
                "Volume ID: %s\n"
                "Units = %s of %d * 512 bytes\n\n"),
-                      cxt->dev_path, heads, sectors, SSWAP16(sunlabel->rpm),
-                      cylinders, SSWAP16(sunlabel->acyl),
+                      cxt->dev_path, cxt->geom.heads, cxt->geom.sectors, SSWAP16(sunlabel->rpm),
+                      cxt->geom.cylinders, SSWAP16(sunlabel->acyl),
                       SSWAP16(sunlabel->pcyl),
                       SSWAP16(sunlabel->apc),
                       SSWAP16(sunlabel->intrlv),
@@ -554,9 +554,9 @@ void sun_list_table(struct fdisk_context *cxt, int xtra)
                       str_units(PLURAL), units_per_sector);
        else
                printf(
-       _("\nDisk %s (Sun disk label): %u heads, %llu sectors, %u cylinders\n"
+       _("\nDisk %s (Sun disk label): %u heads, %llu sectors, %llu cylinders\n"
        "Units = %s of %d * 512 bytes\n\n"),
-                      cxt->dev_path, heads, sectors, cylinders,
+                      cxt->dev_path, cxt->geom.heads, cxt->geom.sectors, cxt->geom.cylinders,
                       str_units(PLURAL), units_per_sector);
 
        printf(_("%*s Flag    Start       End    Blocks   Id  System\n"),
@@ -566,7 +566,7 @@ void sun_list_table(struct fdisk_context *cxt, int xtra)
                struct sun_tag_flag *tag = &sunlabel->part_tags[i];
 
                if (part->num_sectors) {
-                       uint32_t start = SSWAP32(part->start_cylinder) * heads * sectors;
+                       uint32_t start = SSWAP32(part->start_cylinder) * cxt->geom.heads * cxt->geom.sectors;
                        uint32_t len = SSWAP32(part->num_sectors);
                        printf(
                            "%s %c%c %9lu %9lu %9lu%c  %2x  %s\n",
@@ -598,7 +598,7 @@ void sun_set_ncyl(struct fdisk_context *cxt, int cyl)
 void sun_set_xcyl(struct fdisk_context *cxt)
 {
        sunlabel->apc =
-               SSWAP16(read_int(cxt, 0, SSWAP16(sunlabel->apc), sectors, 0,
+               SSWAP16(read_int(cxt, 0, SSWAP16(sunlabel->apc), cxt->geom.sectors, 0,
                                 _("Extra sectors per cylinder")));
 }
 
index 616fcc0dd80dae9ac1000aa1c056ee34846d9f61..b4e9c1740e7201573af67bad3df1ab03e90c73af 100644 (file)
@@ -55,13 +55,50 @@ static unsigned long __get_sector_size(int fd)
        return DEFAULT_SECTOR_SIZE;
 }
 
+/**
+ * fdisk_geom_set_cyls
+ * @cxt: fdisk context
+ *
+ * Sets the cylinders based on sectors and heads
+ */
+void fdisk_geom_set_cyls(struct fdisk_context *cxt)
+{
+       cxt->geom.cylinders = cxt->total_sectors /
+               (cxt->geom.heads * cxt->geom.sectors);
+}
+
 static int __discover_geometry(struct fdisk_context *cxt)
 {
        sector_t nsects;
+       unsigned int h = 0, s = 0;
 
        /* get number of 512-byte sectors, and convert it the real sectors */
        if (!blkdev_get_sectors(cxt->dev_fd, &nsects))
                cxt->total_sectors = (nsects / (cxt->sector_size >> 9));
+
+       get_partition_table_geometry(cxt, &h, &s);
+       if (h && s)
+               goto hs_ok;
+
+       /* what the kernel/bios thinks the geometry is */
+       blkdev_get_geometry(cxt->dev_fd, &h, &s);
+       if (h && s)
+               goto hs_ok;
+
+       /* unable to discover geometry, use default values */
+       s = 63;
+       h = 255;
+
+hs_ok: /* obtained heads and sectors */
+       cxt->geom.heads = h;
+       cxt->geom.sectors = s;
+       fdisk_geom_set_cyls(cxt);
+       update_sector_offset(cxt);
+
+       DBG(GEOMETRY, dbgprint("geometry discovered for %s: C/H/S: %lld/%d/%lld",
+                              cxt->dev_path, cxt->geom.cylinders,
+                              cxt->geom.heads, cxt->geom.sectors));
+
        return 0;
 }