summaryrefslogtreecommitdiff
path: root/sbin/fdisk/part.c
diff options
context:
space:
mode:
authorKenneth R Westerback <krw@cvs.openbsd.org>2022-02-04 14:07:57 +0000
committerKenneth R Westerback <krw@cvs.openbsd.org>2022-02-04 14:07:57 +0000
commit051800f19896c12fc09d1869d6d539c0288afa19 (patch)
treecc600d4f22916dd910e1df2ad13c3c1921bb3da9 /sbin/fdisk/part.c
parent88842f43f8d5d30e4eec62daaaac224dc7273f37 (diff)
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.
Diffstat (limited to 'sbin/fdisk/part.c')
-rw-r--r--sbin/fdisk/part.c112
1 files changed, 44 insertions, 68 deletions
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 *