diff options
author | Dale S. Rahn <rahnds@cvs.openbsd.org> | 1998-09-14 03:54:36 +0000 |
---|---|---|
committer | Dale S. Rahn <rahnds@cvs.openbsd.org> | 1998-09-14 03:54:36 +0000 |
commit | 430fb2f326b8644b48e9dfac81edad297a72017d (patch) | |
tree | 3f5611ed885aa0e2a060ca4f738794819fbb6ef5 /sbin/fdisk/part.c | |
parent | 62d203b1aea6a5195937032bb27c074afa7e2f7c (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.c | 69 |
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); |