summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKenneth R Westerback <krw@cvs.openbsd.org>2006-11-29 14:30:31 +0000
committerKenneth R Westerback <krw@cvs.openbsd.org>2006-11-29 14:30:31 +0000
commit35f9fc4e975026f44900b0ec0cd101ae34acee18 (patch)
tree9b0a5e7c1e69591d190809e7e1c4bb55e5d5458d
parent5ab7e8e41c4ae7c4062030f6957f03417e15336b (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@
-rw-r--r--sys/kern/spec_vnops.c20
-rw-r--r--sys/miscfs/specfs/spec_vnops.c20
2 files changed, 14 insertions, 26 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);
diff --git a/sys/miscfs/specfs/spec_vnops.c b/sys/miscfs/specfs/spec_vnops.c
index 4b8c38995a7..2411f00f705 100644
--- a/sys/miscfs/specfs/spec_vnops.c
+++ b/sys/miscfs/specfs/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);