From 9a5e29e94b60b4733a1e4432b00b1a139fafb255 Mon Sep 17 00:00:00 2001 From: Karel Zak Date: Mon, 23 Jul 2012 13:57:58 +0200 Subject: [PATCH] fdisk: move DOS geometry code from generic part to label specific get_partition_table_geometry() should be called from DOS code Signed-off-by: Karel Zak --- fdisks/fdisk.c | 40 +++++----------------------------------- fdisks/fdisk.h | 2 -- fdisks/fdiskdoslabel.c | 38 ++++++++++++++++++++++++++++++++++++++ fdisks/utils.c | 42 ++++++++++++++++++++++-------------------- 4 files changed, 65 insertions(+), 57 deletions(-) diff --git a/fdisks/fdisk.c b/fdisks/fdisk.c index 1340ca49b..cc874a682 100644 --- a/fdisks/fdisk.c +++ b/fdisks/fdisk.c @@ -431,38 +431,6 @@ void warn_alignment(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; - int first = 1; - int bad = 0; - - if (!(valid_part_table_flag(bufp))) - return; - - hh = ss = 0; - for (i=0; i<4; i++) { - p = pt_offset(bufp, i); - if (p->sys_ind != 0) { - h = p->end_head + 1; - s = (p->end_sector & 077); - if (first) { - hh = h; - ss = s; - first = 0; - } else if (hh != h || ss != s) - bad = 1; - } - } - - if (!first && !bad) { - *ph = hh; - *ps = ss; - } -} - /* * Sets LBA of the first partition */ @@ -1746,7 +1714,8 @@ static void print_partition_table_from_option(char *device, unsigned long sector if (sector_size) /* passed -b option, override autodiscovery */ fdisk_context_force_sector_size(cxt, sector_size); - fdisk_context_set_user_geometry(cxt, user_cylinders, + if (user_cylinders || user_heads || user_sectors) + fdisk_context_set_user_geometry(cxt, user_cylinders, user_heads, user_sectors); gpt_warning(device); @@ -2044,8 +2013,9 @@ int main(int argc, char **argv) if (sector_size) /* passed -b option, override autodiscovery */ fdisk_context_force_sector_size(cxt, sector_size); - fdisk_context_set_user_geometry(cxt, user_cylinders, - user_heads, user_sectors); + if (user_cylinders || user_heads || user_sectors) + fdisk_context_set_user_geometry(cxt, user_cylinders, + user_heads, user_sectors); print_welcome(); diff --git a/fdisks/fdisk.h b/fdisks/fdisk.h index 3783f8273..95a6a4d0c 100644 --- a/fdisks/fdisk.h +++ b/fdisks/fdisk.h @@ -193,8 +193,6 @@ extern unsigned int read_int_with_suffix(struct fdisk_context *cxt, 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 diff --git a/fdisks/fdiskdoslabel.c b/fdisks/fdiskdoslabel.c index 1d1a47c3c..76798ef19 100644 --- a/fdisks/fdiskdoslabel.c +++ b/fdisks/fdiskdoslabel.c @@ -323,15 +323,53 @@ void dos_delete_partition(int i) } } +static 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; + int first = 1; + int bad = 0; + + hh = ss = 0; + for (i=0; i<4; i++) { + p = pt_offset(bufp, i); + if (p->sys_ind != 0) { + h = p->end_head + 1; + s = (p->end_sector & 077); + if (first) { + hh = h; + ss = s; + first = 0; + } else if (hh != h || ss != s) + bad = 1; + } + } + + if (!first && !bad) { + *ph = hh; + *ps = ss; + } +} + + static int dos_probe_label(struct fdisk_context *cxt) { int i; + unsigned int h = 0, s = 0; if (!valid_part_table_flag(cxt->mbr)) return 0; dos_init(cxt); + get_partition_table_geometry(cxt, &h, &s); + if (h && s) { + cxt->geom.heads = h; + cxt->geom.sectors = s; + } + for (i = 0; i < 4; i++) { struct pte *pe = &ptes[i]; diff --git a/fdisks/utils.c b/fdisks/utils.c index d8a4bd184..a01b14095 100644 --- a/fdisks/utils.c +++ b/fdisks/utils.c @@ -114,6 +114,9 @@ int fdisk_context_force_sector_size(struct fdisk_context *cxt, sector_t s) return -EINVAL; cxt->phy_sector_size = cxt->sector_size = s; + cxt->min_io_size = cxt->io_size = s; + + update_sector_offset(cxt); return 0; } @@ -146,17 +149,19 @@ int fdisk_context_set_user_geometry(struct fdisk_context *cxt, if (sectors) cxt->geom.sectors = sectors; - recount_geometry(cxt); - - if (!cxt->geom.cylinders) - /* use the user defined cylinders only as fillback */ + if (cylinders) cxt->geom.cylinders = cylinders; + else + recount_geometry(cxt); + update_sector_offset(cxt); return 0; } - -static int __discover_geometry(struct fdisk_context *cxt) +/* + * Generic (label independent) geometry + */ +static int __discover_system_geometry(struct fdisk_context *cxt) { sector_t nsects; unsigned int h = 0, s = 0; @@ -165,26 +170,19 @@ static int __discover_geometry(struct fdisk_context *cxt) 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; + if (!h && !s) { + /* unable to discover geometry, use default values */ + s = 63; + h = 255; + } - /* unable to discover geometry, use default values */ - s = 63; - h = 255; - -hs_ok: /* obtained heads and sectors */ + /* obtained heads and sectors */ cxt->geom.heads = h; cxt->geom.sectors = s; recount_geometry(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)); @@ -376,10 +374,14 @@ struct fdisk_context *fdisk_new_context_from_filename(const char *fname, int rea goto fail; __discover_topology(cxt); - __discover_geometry(cxt); + __discover_system_geometry(cxt); + /* detect labels and apply labes specific stuff (e.g geomery) + * to the context */ __probe_labels(cxt); + update_sector_offset(cxt); + DBG(CONTEXT, dbgprint("context initialized for %s [%s]", fname, readonly ? "READ-ONLY" : "READ-WRITE")); return cxt;