diff options
author | Kenneth R Westerback <krw@cvs.openbsd.org> | 2006-11-29 14:30:31 +0000 |
---|---|---|
committer | Kenneth R Westerback <krw@cvs.openbsd.org> | 2006-11-29 14:30:31 +0000 |
commit | 35f9fc4e975026f44900b0ec0cd101ae34acee18 (patch) | |
tree | 9b0a5e7c1e69591d190809e7e1c4bb55e5d5458d /sys/kern/spec_vnops.c | |
parent | 5ab7e8e41c4ae7c4062030f6957f03417e15336b (diff) |
Correct the calculation of block address for specfs block i/o on
devices with sectorsizes other than 512. e.g. cd's. Fixes PR #5235
from Paul Stoeber with a slightly tweaked diff. NetBSD did the same
with their r1.59 in 2001, closing their PR#3261 and PR#14026.
tweak suggestions and ok pedro@
Diffstat (limited to 'sys/kern/spec_vnops.c')
-rw-r--r-- | sys/kern/spec_vnops.c | 20 |
1 files changed, 7 insertions, 13 deletions
diff --git a/sys/kern/spec_vnops.c b/sys/kern/spec_vnops.c index 4b8c38995a7..2411f00f705 100644 --- a/sys/kern/spec_vnops.c +++ b/sys/kern/spec_vnops.c @@ -1,4 +1,4 @@ -/* $OpenBSD: spec_vnops.c,v 1.36 2006/10/16 11:27:53 pedro Exp $ */ +/* $OpenBSD: spec_vnops.c,v 1.37 2006/11/29 14:30:30 krw Exp $ */ /* $NetBSD: spec_vnops.c,v 1.29 1996/04/22 01:42:38 christos Exp $ */ /* @@ -237,7 +237,7 @@ spec_read(v) struct proc *p = uio->uio_procp; struct buf *bp; daddr64_t bn, nextbn; - long bsize, bscale, ssize; + long bsize, bscale; struct partinfo dpart; int n, on, majordev; int (*ioctl)(dev_t, u_long, caddr_t, int, struct proc *); @@ -267,7 +267,6 @@ spec_read(v) if (uio->uio_offset < 0) return (EINVAL); bsize = BLKDEV_IOSIZE; - ssize = DEV_BSIZE; if ((majordev = major(vp->v_rdev)) < nblkdev && (ioctl = bdevsw[majordev].d_ioctl) != NULL && (*ioctl)(vp->v_rdev, DIOCGPART, (caddr_t)&dpart, FREAD, p) == 0) { @@ -275,12 +274,10 @@ spec_read(v) dpart.part->p_frag != 0 && dpart.part->p_fsize != 0) bsize = dpart.part->p_frag * dpart.part->p_fsize; - if (dpart.disklab->d_secsize != 0) - ssize = dpart.disklab->d_secsize; } - bscale = bsize / ssize; + bscale = btodb(bsize); do { - bn = (uio->uio_offset / ssize) &~ (bscale - 1); + bn = btodb(uio->uio_offset) & ~(bscale - 1); on = uio->uio_offset % bsize; n = min((unsigned)(bsize - on), uio->uio_resid); if (vp->v_lastr + bscale == bn) { @@ -338,7 +335,7 @@ spec_write(v) struct proc *p = uio->uio_procp; struct buf *bp; daddr_t bn; - long bsize, bscale, ssize; + long bsize, bscale; struct partinfo dpart; int n, on, majordev; int (*ioctl)(dev_t, u_long, caddr_t, int, struct proc *); @@ -366,7 +363,6 @@ spec_write(v) if (uio->uio_offset < 0) return (EINVAL); bsize = BLKDEV_IOSIZE; - ssize = DEV_BSIZE; if ((majordev = major(vp->v_rdev)) < nblkdev && (ioctl = bdevsw[majordev].d_ioctl) != NULL && (*ioctl)(vp->v_rdev, DIOCGPART, (caddr_t)&dpart, FREAD, p) == 0) { @@ -374,12 +370,10 @@ spec_write(v) dpart.part->p_frag != 0 && dpart.part->p_fsize != 0) bsize = dpart.part->p_frag * dpart.part->p_fsize; - if (dpart.disklab->d_secsize != 0) - ssize = dpart.disklab->d_secsize; } - bscale = bsize / ssize; + bscale = btodb(bsize); do { - bn = (uio->uio_offset / ssize) &~ (bscale - 1); + bn = btodb(uio->uio_offset) & ~(bscale - 1); on = uio->uio_offset % bsize; n = min((unsigned)(bsize - on), uio->uio_resid); error = bread(vp, bn, bsize, NOCRED, &bp); |