summaryrefslogtreecommitdiff
path: root/sbin/fdisk/part.c
diff options
context:
space:
mode:
authorDale S. Rahn <rahnds@cvs.openbsd.org>1998-09-14 03:54:36 +0000
committerDale S. Rahn <rahnds@cvs.openbsd.org>1998-09-14 03:54:36 +0000
commit430fb2f326b8644b48e9dfac81edad297a72017d (patch)
tree3f5611ed885aa0e2a060ca4f738794819fbb6ef5 /sbin/fdisk/part.c
parent62d203b1aea6a5195937032bb27c074afa7e2f7c (diff)
Since on the powerpc, the system does not supply the user with
bios valid cyl,head,sector information (the information comes from the sd driver) I have made some changes to fdisk to do the following. Allow the powerpc to specify values larger than the bios limits. All platforms now have code that will translate the LBA values in the mbr into CHS values according to the disk geometry. This occurs if the start and ending CHS values have been stored as 0xffffff. If writing to the disk and one of the values of a partition violates the bios limits, it writes the requested values in the LBA fields , and stores 0xffffff for the starting and ending CHS values. This should not change the default formatting of any existing system other than the CHS and LBA values should always match given the detected geometry of the disk.
Diffstat (limited to 'sbin/fdisk/part.c')
-rw-r--r--sbin/fdisk/part.c69
1 files changed, 58 insertions, 11 deletions
diff --git a/sbin/fdisk/part.c b/sbin/fdisk/part.c
index 53d223d4769..02763963061 100644
--- a/sbin/fdisk/part.c
+++ b/sbin/fdisk/part.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: part.c,v 1.8 1998/02/19 20:48:08 deraadt Exp $ */
+/* $OpenBSD: part.c,v 1.9 1998/09/14 03:54:35 rahnds Exp $ */
/*
* Copyright (c) 1997 Tobias Weingartner
@@ -127,7 +127,8 @@ PRT_ascii_id(id)
}
void
-PRT_parse(prt, offset, reloff, partn)
+PRT_parse(disk, prt, offset, reloff, partn)
+ disk_t *disk;
void *prt;
off_t offset;
off_t reloff;
@@ -135,7 +136,19 @@ PRT_parse(prt, offset, reloff, partn)
{
unsigned char *p = prt;
off_t off;
-
+ int need_fix_chs = 0;
+
+ /* dont check fields 0 and 4, they are flag and id, always preserved */
+ if ((p[1] == 0xff) &&
+ (p[2] == 0xff) &&
+ (p[3] == 0xff) &&
+ (p[5] == 0xff) &&
+ (p[6] == 0xff) &&
+ (p[7] == 0xff))
+ {
+ /* CHS values invalid */
+ need_fix_chs =1;
+ }
partn->flag = *p++;
partn->shead = *p++;
@@ -153,8 +166,28 @@ PRT_parse(prt, offset, reloff, partn)
partn->bs = getlong(p) + off;
partn->ns = getlong(p+4);
+
+ if (need_fix_chs == 1) {
+ printf("warning MBR CHS values invalid, translating LBA values\n");
+ PRT_fix_CHS(disk, partn);
+ }
}
+int
+PRT_check_chs(partn)
+ prt_t *partn;
+{
+ if ( (partn->shead > 255) ||
+ (partn->ssect >63) ||
+ (partn->scyl > 1023) ||
+ (partn->ehead >255) ||
+ (partn->esect >63) ||
+ (partn->ecyl > 1023) )
+ {
+ return 0;
+ }
+ return 1;
+}
void
PRT_make(partn, offset, reloff, prt)
prt_t *partn;
@@ -165,16 +198,30 @@ PRT_make(partn, offset, reloff, prt)
unsigned char *p = prt;
off_t off = partn->id != DOSPTYP_EXTEND ? offset : reloff;
- *p++ = partn->flag & 0xFF;
- *p++ = partn->shead & 0xFF;
- *p++ = (partn->ssect & 0x3F) | ((partn->scyl & 0x300) >> 2);
- *p++ = partn->scyl & 0xFF;
+ if (PRT_check_chs(partn)) {
+ *p++ = partn->flag & 0xFF;
- *p++ = partn->id & 0xFF;
+ *p++ = partn->shead & 0xFF;
+ *p++ = (partn->ssect & 0x3F) | ((partn->scyl & 0x300) >> 2);
+ *p++ = partn->scyl & 0xFF;
- *p++ = partn->ehead & 0xFF;
- *p++ = (partn->esect & 0x3F) | ((partn->ecyl & 0x300) >> 2);
- *p++ = partn->ecyl & 0xFF;
+ *p++ = partn->id & 0xFF;
+
+ *p++ = partn->ehead & 0xFF;
+ *p++ = (partn->esect & 0x3F) | ((partn->ecyl & 0x300) >> 2);
+ *p++ = partn->ecyl & 0xFF;
+ } else {
+ /* should this really keep flag, id and set others to 0xff? */
+ *p++ = partn->flag & 0xFF;
+ *p++ = 0xFF;
+ *p++ = 0xFF;
+ *p++ = 0xFF;
+ *p++ = partn->id & 0xFF;
+ *p++ = 0xFF;
+ *p++ = 0xFF;
+ *p++ = 0xFF;
+ printf("Warning CHS values out of bounds only saving LBA values\n");
+ }
putlong(p, partn->bs - off);
putlong(p+4, partn->ns);