align dk_strategy with checks from ld.c

This commit is contained in:
mlelstv 2014-12-29 12:03:39 +00:00
parent 2e0522b1d5
commit 1674d0824b
1 changed files with 35 additions and 15 deletions

View File

@ -1,4 +1,4 @@
/* $NetBSD: dksubr.c,v 1.54 2014/11/04 07:51:54 mlelstv Exp $ */ /* $NetBSD: dksubr.c,v 1.55 2014/12/29 12:03:39 mlelstv Exp $ */
/*- /*-
* Copyright (c) 1996, 1997, 1998, 1999, 2002, 2008 The NetBSD Foundation, Inc. * Copyright (c) 1996, 1997, 1998, 1999, 2002, 2008 The NetBSD Foundation, Inc.
@ -30,7 +30,7 @@
*/ */
#include <sys/cdefs.h> #include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: dksubr.c,v 1.54 2014/11/04 07:51:54 mlelstv Exp $"); __KERNEL_RCSID(0, "$NetBSD: dksubr.c,v 1.55 2014/12/29 12:03:39 mlelstv Exp $");
#include <sys/param.h> #include <sys/param.h>
#include <sys/systm.h> #include <sys/systm.h>
@ -178,9 +178,13 @@ dk_close(struct dk_intf *di, struct dk_softc *dksc, dev_t dev,
void void
dk_strategy(struct dk_intf *di, struct dk_softc *dksc, struct buf *bp) dk_strategy(struct dk_intf *di, struct dk_softc *dksc, struct buf *bp)
{ {
int s; int s, part;
int wlabel; int wlabel;
daddr_t blkno; daddr_t blkno;
struct disklabel *lp;
struct disk *dk;
uint64_t numsecs;
unsigned secsize;
DPRINTF_FOLLOW(("dk_strategy(%s, %p, %p)\n", DPRINTF_FOLLOW(("dk_strategy(%s, %p, %p)\n",
di->di_dkname, dksc, bp)); di->di_dkname, dksc, bp));
@ -192,10 +196,25 @@ dk_strategy(struct dk_intf *di, struct dk_softc *dksc, struct buf *bp)
return; return;
} }
/* XXX look for some more errors, c.f. ld.c */ lp = dksc->sc_dkdev.dk_label;
dk = &dksc->sc_dkdev;
part = DISKPART(bp->b_dev);
numsecs = dk->dk_geom.dg_secperunit;
secsize = dk->dk_geom.dg_secsize;
bp->b_resid = bp->b_bcount; bp->b_resid = bp->b_bcount;
/*
* The transfer must be a whole number of blocks and the offset must
* not be negative.
*/
if ((bp->b_bcount % secsize) != 0 || bp->b_blkno < 0) {
bp->b_error = EINVAL;
biodone(bp);
return;
}
/* If there is nothing to do, then we are done */ /* If there is nothing to do, then we are done */
if (bp->b_bcount == 0) { if (bp->b_bcount == 0) {
biodone(bp); biodone(bp);
@ -203,20 +222,21 @@ dk_strategy(struct dk_intf *di, struct dk_softc *dksc, struct buf *bp)
} }
wlabel = dksc->sc_flags & (DKF_WLABEL|DKF_LABELLING); wlabel = dksc->sc_flags & (DKF_WLABEL|DKF_LABELLING);
if (DISKPART(bp->b_dev) != RAW_PART && if (part == RAW_PART) {
bounds_check_with_label(&dksc->sc_dkdev, bp, wlabel) <= 0) { if (bounds_check_with_mediasize(bp, DEV_BSIZE, numsecs) <= 0) {
biodone(bp); biodone(bp);
return; return;
}
} else {
if (bounds_check_with_label(&dksc->sc_dkdev, bp, wlabel) <= 0) {
biodone(bp);
return;
}
} }
blkno = bp->b_blkno; blkno = bp->b_blkno;
if (DISKPART(bp->b_dev) != RAW_PART) { if (part != RAW_PART)
struct partition *pp; blkno += lp->d_partitions[DISKPART(bp->b_dev)].p_offset;
pp =
&dksc->sc_dkdev.dk_label->d_partitions[DISKPART(bp->b_dev)];
blkno += pp->p_offset;
}
bp->b_rawblkno = blkno; bp->b_rawblkno = blkno;
/* /*