summaryrefslogtreecommitdiff
path: root/sys/kern
diff options
context:
space:
mode:
authorKenneth R Westerback <krw@cvs.openbsd.org>2015-08-24 23:03:12 +0000
committerKenneth R Westerback <krw@cvs.openbsd.org>2015-08-24 23:03:12 +0000
commit9653a62608467bfc6a6065591822692d9a32177e (patch)
tree98365b772423500a87407f24436357912c782ad3 /sys/kern
parentec1c24011d8acaf0a39824f31ead16d43933b2c4 (diff)
Fix GPT code to work with non-DEV_BSIZE disks.
Part of GPT refactoring that was backed out at c2k15. ok deraadt@
Diffstat (limited to 'sys/kern')
-rw-r--r--sys/kern/subr_disk.c38
1 files changed, 17 insertions, 21 deletions
diff --git a/sys/kern/subr_disk.c b/sys/kern/subr_disk.c
index adc5de72876..4fc92de0bba 100644
--- a/sys/kern/subr_disk.c
+++ b/sys/kern/subr_disk.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: subr_disk.c,v 1.188 2015/08/12 22:37:32 krw Exp $ */
+/* $OpenBSD: subr_disk.c,v 1.189 2015/08/24 23:03:11 krw Exp $ */
/* $NetBSD: subr_disk.c,v 1.17 1996/03/16 23:17:08 christos Exp $ */
/*
@@ -647,15 +647,12 @@ readgptlabel(struct buf *bp, void (*strat)(struct buf *),
if (lp->d_secsize == 0)
return (ENOSPC); /* disk too small */
- /*
- * XXX: We should not trust the primary header and instead
- * use the last LBA of the disk, as defined in the standard.
- */
- for (part_blkno = GPTSECTOR; ; part_blkno = gh.gh_lba_alt,
- altheader = 1) {
+ for (part_blkno = DL_SECTOBLK(lp, GPTSECTOR); ;
+ part_blkno = DL_SECTOBLK(lp, DL_GETDSIZE(lp)-1), altheader = 1) {
uint32_t ghsize;
uint32_t ghpartsize;
uint32_t ghpartnum;
+ uint32_t ghpartspersec;
/* read header record */
bp->b_blkno = DL_BLKTOSEC(lp, part_blkno) * DL_BLKSPERSEC(lp);
@@ -677,6 +674,7 @@ readgptlabel(struct buf *bp, void (*strat)(struct buf *),
bcopy(bp->b_data + offset, &gh, sizeof(gh));
ghsize = letoh32(gh.gh_size);
ghpartsize = letoh32(gh.gh_part_size);
+ ghpartspersec = lp->d_secsize / ghpartsize;
ghpartnum = letoh32(gh.gh_part_num);
if (letoh64(gh.gh_sig) != GPTSIGNATURE)
@@ -706,7 +704,7 @@ readgptlabel(struct buf *bp, void (*strat)(struct buf *),
* Header size must be greater than or equal to 92 and less
* than or equal to the logical block size.
*/
- if (ghsize < GPTMINHDRSIZE || ghsize > DEV_BSIZE)
+ if (ghsize < GPTMINHDRSIZE || ghsize > lp->d_secsize)
return (EINVAL);
if (letoh64(gh.gh_lba_start) >= DL_GETDSIZE(lp) ||
@@ -718,33 +716,32 @@ readgptlabel(struct buf *bp, void (*strat)(struct buf *),
* Size per partition entry shall be 128*(2**n) with n >= 0.
* We don't support partition entries larger than block size.
*/
- if (ghpartsize % GPTMINPARTSIZE
- || ghpartsize > DEV_BSIZE
- || GPT_PARTSPERSEC(&gh) == 0) {
+ if (ghpartsize % GPTMINPARTSIZE || ghpartsize > lp->d_secsize
+ || ghpartspersec == 0) {
DPRINTF("invalid partition size\n");
return (EINVAL);
}
/* XXX: we don't support multiples of GPTMINPARTSIZE yet */
- if (letoh32(gh.gh_part_size) != GPTMINPARTSIZE) {
+ if (ghpartsize != GPTMINPARTSIZE) {
DPRINTF("partition sizes larger than %d bytes are not "
"supported", GPTMINPARTSIZE);
return (EINVAL);
}
/* read GPT partition entry array */
- gp = mallocarray(ghpartnum, sizeof(struct gpt_partition), M_DEVBUF, M_NOWAIT|M_ZERO);
+ gp = mallocarray(ghpartnum, sizeof(struct gpt_partition),
+ M_DEVBUF, M_NOWAIT|M_ZERO);
if (gp == NULL)
return (ENOMEM);
gpsz = ghpartnum * sizeof(struct gpt_partition);
/*
- * XXX: Fails if # of partition entries is no multiple of
- * GPT_PARTSPERSEC(&gh)
+ * XXX: Fails if # of partition entries is not a multiple of
+ * ghpartspersec.
*/
- for (i = 0; i < ghpartnum / GPT_PARTSPERSEC(&gh);
- i++) {
- part_blkno = letoh64(gh.gh_part_lba) + i;
+ for (i = 0; i < ghpartnum / ghpartspersec; i++) {
+ part_blkno = DL_SECTOBLK(lp, letoh64(gh.gh_part_lba)+i);
/* read partition record */
bp->b_blkno = DL_BLKTOSEC(lp, part_blkno) *
DL_BLKSPERSEC(lp);
@@ -763,9 +760,8 @@ readgptlabel(struct buf *bp, void (*strat)(struct buf *),
return (error);
}
- bcopy(bp->b_data + offset, gp +
- i * GPT_PARTSPERSEC(&gh), GPT_PARTSPERSEC(&gh) *
- sizeof(struct gpt_partition));
+ bcopy(bp->b_data + offset, gp + i * ghpartspersec,
+ ghpartspersec * sizeof(struct gpt_partition));
}
if (gpt_chk_parts(&gh, gp)) {