diff options
author | dillon <dillon@FreeBSD.org> | 1999-09-17 06:10:27 +0000 |
---|---|---|
committer | dillon <dillon@FreeBSD.org> | 1999-09-17 06:10:27 +0000 |
commit | 2c39c80e008faac9624e07b55ab4dbb5caeeec09 (patch) | |
tree | d5fc5b7a259934fd6acd99e23c71a943d8e69834 | |
parent | 581716d4dfa79a615e2d311e2da0b1eca85bb5b6 (diff) | |
download | FreeBSD-src-2c39c80e008faac9624e07b55ab4dbb5caeeec09.zip FreeBSD-src-2c39c80e008faac9624e07b55ab4dbb5caeeec09.tar.gz |
Add vfs.enable_userblk_io sysctl to control whether user reads and writes
to buffered block devices are allowed. The default is to be backwards
compatible, i.e. reads and writes are allowed.
The idea is for a larger crowd to start running with this disabled and
see what problems, if any, crop up, and then to change the default to
off and see if any problems crop up in the next 6 months prior to
potentially removing support entirely. There are still a few people,
Julian and myself included, who believe the buffered block device
access from usermode to be useful.
Remove use of vnode->v_lastr from buffered block device I/O in
preparation for removal of vnode->v_lastr field, replacing it with
the already existing seqcount metric to detect sequential operation.
Reviewed by: Alan Cox <alc@cs.rice.edu>, David Greenman <dg@root.com>
-rw-r--r-- | sys/fs/specfs/spec_vnops.c | 13 | ||||
-rw-r--r-- | sys/kern/vfs_export.c | 3 | ||||
-rw-r--r-- | sys/kern/vfs_subr.c | 3 | ||||
-rw-r--r-- | sys/miscfs/specfs/spec_vnops.c | 13 | ||||
-rw-r--r-- | sys/sys/vnode.h | 1 |
5 files changed, 25 insertions, 8 deletions
diff --git a/sys/fs/specfs/spec_vnops.c b/sys/fs/specfs/spec_vnops.c index 7b2d712..46b4eb5 100644 --- a/sys/fs/specfs/spec_vnops.c +++ b/sys/fs/specfs/spec_vnops.c @@ -168,7 +168,6 @@ spec_open(ap) return (ENXIO); switch (vp->v_type) { - case VCHR: dsw = devsw(dev); if ( (dsw == NULL) || (dsw->d_open == NULL)) @@ -237,6 +236,7 @@ spec_open(ap) if (!dev->si_bsize_max) dev->si_bsize_max = MAXBSIZE; } + return (error); } @@ -263,6 +263,7 @@ spec_read(ap) int n, on; d_ioctl_t *ioctl; int error = 0; + int seqcount = ap->a_ioflag >> 16; dev_t dev; #ifdef DIAGNOSTIC @@ -284,6 +285,8 @@ spec_read(ap) return (error); case VBLK: + if (enable_userblk_io == 0) + return (EINVAL); if (uio->uio_offset < 0) return (EINVAL); dev = vp->v_rdev; @@ -309,13 +312,13 @@ spec_read(ap) 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) { + if (seqcount > 1) { nextbn = bn + bscale; error = breadn(vp, bn, (int)bsize, &nextbn, (int *)&bsize, 1, NOCRED, &bp); - } else + } else { error = bread(vp, bn, (int)bsize, NOCRED, &bp); - vp->v_lastr = bn; + } n = min(n, bsize - bp->b_resid); if (error) { brelse(bp); @@ -372,6 +375,8 @@ spec_write(ap) return (error); case VBLK: + if (enable_userblk_io == 0) + return (EINVAL); if (uio->uio_resid == 0) return (0); if (uio->uio_offset < 0) diff --git a/sys/kern/vfs_export.c b/sys/kern/vfs_export.c index b452cc1..757e4aa 100644 --- a/sys/kern/vfs_export.c +++ b/sys/kern/vfs_export.c @@ -113,6 +113,9 @@ SYSCTL_INT(_vfs, OID_AUTO, reassignbufsortbad, CTLFLAG_RW, &reassignbufsortbad, static int reassignbufmethod = 1; SYSCTL_INT(_vfs, OID_AUTO, reassignbufmethod, CTLFLAG_RW, &reassignbufmethod, 0, ""); +int enable_userblk_io = 1; +SYSCTL_INT(_vfs, OID_AUTO, enable_userblk_io, CTLFLAG_RW, &enable_userblk_io, 0, ""); + #ifdef ENABLE_VFS_IOOPT int vfs_ioopt = 0; SYSCTL_INT(_vfs, OID_AUTO, ioopt, CTLFLAG_RW, &vfs_ioopt, 0, ""); diff --git a/sys/kern/vfs_subr.c b/sys/kern/vfs_subr.c index b452cc1..757e4aa 100644 --- a/sys/kern/vfs_subr.c +++ b/sys/kern/vfs_subr.c @@ -113,6 +113,9 @@ SYSCTL_INT(_vfs, OID_AUTO, reassignbufsortbad, CTLFLAG_RW, &reassignbufsortbad, static int reassignbufmethod = 1; SYSCTL_INT(_vfs, OID_AUTO, reassignbufmethod, CTLFLAG_RW, &reassignbufmethod, 0, ""); +int enable_userblk_io = 1; +SYSCTL_INT(_vfs, OID_AUTO, enable_userblk_io, CTLFLAG_RW, &enable_userblk_io, 0, ""); + #ifdef ENABLE_VFS_IOOPT int vfs_ioopt = 0; SYSCTL_INT(_vfs, OID_AUTO, ioopt, CTLFLAG_RW, &vfs_ioopt, 0, ""); diff --git a/sys/miscfs/specfs/spec_vnops.c b/sys/miscfs/specfs/spec_vnops.c index 7b2d712..46b4eb5 100644 --- a/sys/miscfs/specfs/spec_vnops.c +++ b/sys/miscfs/specfs/spec_vnops.c @@ -168,7 +168,6 @@ spec_open(ap) return (ENXIO); switch (vp->v_type) { - case VCHR: dsw = devsw(dev); if ( (dsw == NULL) || (dsw->d_open == NULL)) @@ -237,6 +236,7 @@ spec_open(ap) if (!dev->si_bsize_max) dev->si_bsize_max = MAXBSIZE; } + return (error); } @@ -263,6 +263,7 @@ spec_read(ap) int n, on; d_ioctl_t *ioctl; int error = 0; + int seqcount = ap->a_ioflag >> 16; dev_t dev; #ifdef DIAGNOSTIC @@ -284,6 +285,8 @@ spec_read(ap) return (error); case VBLK: + if (enable_userblk_io == 0) + return (EINVAL); if (uio->uio_offset < 0) return (EINVAL); dev = vp->v_rdev; @@ -309,13 +312,13 @@ spec_read(ap) 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) { + if (seqcount > 1) { nextbn = bn + bscale; error = breadn(vp, bn, (int)bsize, &nextbn, (int *)&bsize, 1, NOCRED, &bp); - } else + } else { error = bread(vp, bn, (int)bsize, NOCRED, &bp); - vp->v_lastr = bn; + } n = min(n, bsize - bp->b_resid); if (error) { brelse(bp); @@ -372,6 +375,8 @@ spec_write(ap) return (error); case VBLK: + if (enable_userblk_io == 0) + return (EINVAL); if (uio->uio_resid == 0) return (0); if (uio->uio_offset < 0) diff --git a/sys/sys/vnode.h b/sys/sys/vnode.h index e78db43..75a824a 100644 --- a/sys/sys/vnode.h +++ b/sys/sys/vnode.h @@ -280,6 +280,7 @@ extern struct vm_zone *namei_zone; extern int prtactive; /* nonzero to call vprint() */ extern struct vattr va_null; /* predefined null vattr structure */ extern int vfs_ioopt; +extern int enable_userblk_io; /* * Macro/function to check for client cache inconsistency w.r.t. leasing. |