From 77392607d91b607d06ccb38e8f216bb46f4a599a Mon Sep 17 00:00:00 2001 From: krw Date: Fri, 4 Feb 2022 14:07:56 +0000 Subject: [PATCH] Remove CHS information from internal representation of MBR partitions. Generate CHS information as required when writing MBR to disk, editing a partition in CHS mode or printing MBR. No intentional functional change. --- sbin/fdisk/cmd.c | 38 +++++++--------- sbin/fdisk/gpt.c | 3 +- sbin/fdisk/mbr.c | 5 +-- sbin/fdisk/part.c | 112 ++++++++++++++++++---------------------------- sbin/fdisk/part.h | 14 +++--- 5 files changed, 71 insertions(+), 101 deletions(-) diff --git a/sbin/fdisk/cmd.c b/sbin/fdisk/cmd.c index 98aab7a6142..3aca9c75751 100644 --- a/sbin/fdisk/cmd.c +++ b/sbin/fdisk/cmd.c @@ -1,4 +1,4 @@ -/* $OpenBSD: cmd.c,v 1.150 2022/01/27 16:26:32 krw Exp $ */ +/* $OpenBSD: cmd.c,v 1.151 2022/02/04 14:07:56 krw Exp $ */ /* * Copyright (c) 1997 Tobias Weingartner @@ -190,6 +190,7 @@ parsepn(const char *pnstr) int edit(const int pn, struct mbr *mbr) { + struct chs start, end; struct prt *pp; uint64_t track; unsigned char oldid; @@ -209,39 +210,34 @@ edit(const int pn, struct mbr *mbr) } if (ask_yn("Do you wish to edit in CHS mode?")) { - pp->prt_scyl = ask_num("BIOS Starting cylinder", pp->prt_scyl, + PRT_lba_to_chs(pp, &start, &end); + start.chs_cyl = ask_num("BIOS Starting cylinder", start.chs_cyl, 0, disk.dk_cylinders - 1); - pp->prt_shead = ask_num("BIOS Starting head", pp->prt_shead, + start.chs_head = ask_num("BIOS Starting head", start.chs_head, 0, disk.dk_heads - 1); - pp->prt_ssect = ask_num("BIOS Starting sector", pp->prt_ssect, + start.chs_sect = ask_num("BIOS Starting sector", start.chs_sect, 1, disk.dk_sectors); - pp->prt_ecyl = ask_num("BIOS Ending cylinder", pp->prt_ecyl, - pp->prt_scyl, disk.dk_cylinders - 1); - pp->prt_ehead = ask_num("BIOS Ending head", pp->prt_ehead, - (pp->prt_scyl == pp->prt_ecyl) ? pp->prt_shead : 0, + end.chs_cyl = ask_num("BIOS Ending cylinder", end.chs_cyl, + start.chs_cyl, disk.dk_cylinders - 1); + end.chs_head = ask_num("BIOS Ending head", end.chs_head, + (start.chs_cyl == end.chs_cyl) ? start.chs_head : 0, disk.dk_heads - 1); - pp->prt_esect = ask_num("BIOS Ending sector", pp->prt_esect, - (pp->prt_scyl == pp->prt_ecyl && pp->prt_shead == - pp->prt_ehead) ? pp->prt_ssect : 1, disk.dk_sectors); + end.chs_sect = ask_num("BIOS Ending sector", end.chs_sect, + (start.chs_cyl == end.chs_cyl && start.chs_head == + end.chs_head) ? start.chs_sect : 1, disk.dk_sectors); /* The ATA/ATAPI spec says LBA = (C × HPC + H) × SPT + (S − 1) */ - track = (uint64_t)pp->prt_scyl * disk.dk_heads + pp->prt_shead; - pp->prt_bs = track * disk.dk_sectors + (pp->prt_ssect - 1); - track = (uint64_t)pp->prt_ecyl * disk.dk_heads + pp->prt_ehead; - pp->prt_ns = track * disk.dk_sectors + (pp->prt_esect - 1) - + track = start.chs_cyl * disk.dk_heads + start.chs_head; + pp->prt_bs = track * disk.dk_sectors + (start.chs_sect - 1); + track = end.chs_cyl * disk.dk_heads + end.chs_head; + pp->prt_ns = track * disk.dk_sectors + (end.chs_sect - 1) - pp->prt_bs + 1; - - /* Fix up CHS values for LBA */ - PRT_fix_CHS(pp); } else { pp->prt_bs = getuint64("Partition offset", pp->prt_bs, 0, disk.dk_size - 1); pp->prt_ns = getuint64("Partition size", pp->prt_ns, 1, disk.dk_size - pp->prt_bs); - - /* Fix up CHS values */ - PRT_fix_CHS(pp); } return 0; diff --git a/sbin/fdisk/gpt.c b/sbin/fdisk/gpt.c index d8354810310..fa556c0556f 100644 --- a/sbin/fdisk/gpt.c +++ b/sbin/fdisk/gpt.c @@ -1,4 +1,4 @@ -/* $OpenBSD: gpt.c,v 1.56 2022/01/02 17:26:14 krw Exp $ */ +/* $OpenBSD: gpt.c,v 1.57 2022/02/04 14:07:56 krw Exp $ */ /* * Copyright (c) 2015 Markus Muller * Copyright (c) 2015 Kenneth R Westerback @@ -491,7 +491,6 @@ init_gh(void) gmbr.mbr_prt[0].prt_id = DOSPTYP_EFI; gmbr.mbr_prt[0].prt_bs = 1; gmbr.mbr_prt[0].prt_ns = UINT32_MAX; - PRT_fix_CHS(&gmbr.mbr_prt[0]); gmbr.mbr_signature = DOSMBR_SIGNATURE; needed = sizeof(gp) / secsize + 2; diff --git a/sbin/fdisk/mbr.c b/sbin/fdisk/mbr.c index 90d2def9ea1..1fe0aa0f5ae 100644 --- a/sbin/fdisk/mbr.c +++ b/sbin/fdisk/mbr.c @@ -1,4 +1,4 @@ -/* $OpenBSD: mbr.c,v 1.115 2022/01/21 17:29:24 krw Exp $ */ +/* $OpenBSD: mbr.c,v 1.116 2022/02/04 14:07:56 krw Exp $ */ /* * Copyright (c) 1997 Tobias Weingartner @@ -91,11 +91,8 @@ MBR_init(struct mbr *mbr) obsdprt.prt_id = DOSPTYP_OPENBSD; if (bootprt.prt_flag != DOSACTIVE) obsdprt.prt_flag = DOSACTIVE; - PRT_fix_CHS(&obsdprt); } - PRT_fix_CHS(&bootprt); - memset(mbr, 0, sizeof(*mbr)); memcpy(mbr->mbr_code, default_dmbr.dmbr_boot, sizeof(mbr->mbr_code)); mbr->mbr_prt[0] = bootprt; diff --git a/sbin/fdisk/part.c b/sbin/fdisk/part.c index b95a6e76a80..89a5adff13c 100644 --- a/sbin/fdisk/part.c +++ b/sbin/fdisk/part.c @@ -1,4 +1,4 @@ -/* $OpenBSD: part.c,v 1.114 2022/02/03 13:24:04 visa Exp $ */ +/* $OpenBSD: part.c,v 1.115 2022/02/04 14:07:56 krw Exp $ */ /* * Copyright (c) 1997 Tobias Weingartner @@ -30,7 +30,6 @@ #include "disk.h" #include "misc.h" -int check_chs(const struct prt *); const char *ascii_id(const int); struct mbr_type { @@ -287,52 +286,32 @@ PRT_parse(const struct dos_partition *dp, const uint64_t lba_self, prt->prt_ns = letoh32(t); if (prt->prt_id == DOSPTYP_EFI && prt->prt_ns == UINT32_MAX) prt->prt_ns = DL_GETDSIZE(&dl) - prt->prt_bs; - - PRT_fix_CHS(prt); -} - -int -check_chs(const struct prt *prt) -{ - if ( (prt->prt_shead > 255) || - (prt->prt_ssect >63) || - (prt->prt_scyl > 1023) || - (prt->prt_ehead >255) || - (prt->prt_esect >63) || - (prt->prt_ecyl > 1023) ) - { - return -1; - } - return 0; } void PRT_make(const struct prt *prt, const uint64_t lba_self, const uint64_t lba_firstembr, struct dos_partition *dp) { + struct chs start, end; uint64_t off, t; - uint32_t ecyl, scyl; if (prt->prt_ns == 0 || prt->prt_id == DOSPTYP_UNUSED) { memset(dp, 0, sizeof(*dp)); return; } - scyl = (prt->prt_scyl > 1023) ? 1023 : prt->prt_scyl; - ecyl = (prt->prt_ecyl > 1023) ? 1023 : prt->prt_ecyl; - if ((prt->prt_id == DOSPTYP_EXTEND) || (prt->prt_id == DOSPTYP_EXTENDL)) off = lba_firstembr; else off = lba_self; - if (check_chs(prt) == 0) { - dp->dp_shd = prt->prt_shead & 0xFF; - dp->dp_ssect = (prt->prt_ssect & 0x3F) | ((scyl & 0x300) >> 2); - dp->dp_scyl = scyl & 0xFF; - dp->dp_ehd = prt->prt_ehead & 0xFF; - dp->dp_esect = (prt->prt_esect & 0x3F) | ((ecyl & 0x300) >> 2); - dp->dp_ecyl = ecyl & 0xFF; + if (PRT_lba_to_chs(prt, &start, &end) == 0) { + dp->dp_shd = start.chs_head & 0xFF; + dp->dp_ssect = (start.chs_sect & 0x3F) | ((start.chs_cyl & 0x300) >> 2); + dp->dp_scyl = start.chs_cyl & 0xFF; + dp->dp_ehd = end.chs_head & 0xFF; + dp->dp_esect = (end.chs_sect & 0x3F) | ((end.chs_cyl & 0x300) >> 2); + dp->dp_ecyl = end.chs_cyl & 0xFF; } else { memset(dp, 0xFF, sizeof(*dp)); } @@ -365,57 +344,54 @@ void PRT_print_part(const int num, const struct prt *prt, const char *units) { const struct unit_type *ut; + struct chs start, end; double size; size = units_size(units, prt->prt_ns, &ut); - printf("%c%1d: %.2X %6u %3u %3u - %6u %3u %3u " + PRT_lba_to_chs(prt, &start, &end); + + printf("%c%1d: %.2X %6llu %3u %3u - %6llu %3u %3u " "[%12llu:%12.0f%s] %s\n", (prt->prt_flag == DOSACTIVE)?'*':' ', num, prt->prt_id, - prt->prt_scyl, prt->prt_shead, prt->prt_ssect, - prt->prt_ecyl, prt->prt_ehead, prt->prt_esect, + start.chs_cyl, start.chs_head, start.chs_sect, + end.chs_cyl, end.chs_head, end.chs_sect, prt->prt_bs, size, ut->ut_abbr, ascii_id(prt->prt_id)); } -void -PRT_fix_CHS(struct prt *prt) +int +PRT_lba_to_chs(const struct prt *prt, struct chs *start, struct chs *end) { - uint32_t spt, tpc, spc; - uint32_t start, end, size; - uint32_t cyl, head, sect; + uint64_t lba; - if (prt->prt_id == DOSPTYP_UNUSED || prt->prt_ns == 0) { - memset(prt, 0, sizeof(*prt)); - return; + if (prt->prt_ns == 0 || prt->prt_id == DOSPTYP_UNUSED) { + memset(start, 0, sizeof(*start)); + memset(end, 0, sizeof(*end)); + return -1; } - spt = disk.dk_sectors; - tpc = disk.dk_heads; - spc = spt * tpc; - - start = prt->prt_bs; - size = prt->prt_ns; - end = (start + size) - 1; - - cyl = (start / spc); - start -= (cyl * spc); - head = (start / spt); - start -= (head * spt); - sect = (start + 1); - - prt->prt_scyl = cyl; - prt->prt_shead = head; - prt->prt_ssect = sect; - - cyl = (end / spc); - end -= (cyl * spc); - head = (end / spt); - end -= (head * spt); - sect = (end + 1); - - prt->prt_ecyl = cyl; - prt->prt_ehead = head; - prt->prt_esect = sect; + /* + * C = LBA ÷ (HPC × SPT) + * H = (LBA ÷ SPT) mod HPC + * S = (LBA mod SPT) + 1 + */ + + lba = prt->prt_bs; + start->chs_cyl = lba / (disk.dk_sectors * disk.dk_heads); + start->chs_head = (lba / disk.dk_sectors) % disk.dk_heads; + start->chs_sect = (lba % disk.dk_sectors) + 1; + + lba = prt->prt_bs + prt->prt_ns - 1; + end->chs_cyl = lba / (disk.dk_sectors * disk.dk_heads); + end->chs_head = (lba / disk.dk_sectors) % disk.dk_heads; + end->chs_sect = (lba % disk.dk_sectors) + 1; + + if (start->chs_head > 255 || end->chs_head > 255 || + start->chs_sect > 63 || end->chs_sect > 63 || + start->chs_cyl > 1023 || end->chs_cyl > 1023) + return -1; + + return 0; } char * diff --git a/sbin/fdisk/part.h b/sbin/fdisk/part.h index e7db6c08abf..7b20ac5c7f9 100644 --- a/sbin/fdisk/part.h +++ b/sbin/fdisk/part.h @@ -1,4 +1,4 @@ -/* $OpenBSD: part.h,v 1.33 2022/01/27 16:26:32 krw Exp $ */ +/* $OpenBSD: part.h,v 1.34 2022/02/04 14:07:56 krw Exp $ */ /* * Copyright (c) 1997 Tobias Weingartner @@ -16,11 +16,15 @@ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ +struct chs { + uint64_t chs_cyl; + uint32_t chs_head; + uint32_t chs_sect; +}; + struct prt { uint64_t prt_bs; uint64_t prt_ns; - uint32_t prt_shead, prt_scyl, prt_ssect; - uint32_t prt_ehead, prt_ecyl, prt_esect; unsigned char prt_flag; unsigned char prt_id; }; @@ -37,6 +41,4 @@ char *PRT_uuid_to_typename(const struct uuid *); int PRT_uuid_to_type(const struct uuid *); struct uuid *PRT_type_to_uuid(const int); int PRT_protected_guid(const struct uuid *); - -/* This does bs/ns -> CHS */ -void PRT_fix_CHS(struct prt *); +int PRT_lba_to_chs(const struct prt*, struct chs *, struct chs*); -- 2.20.1