Make bdev userland access work like cdev userland access unless

the highly non-recommended option ALLOW_BDEV_ACCESS is used.

(bdev access is evil because you don't get write errors reported.)

Kill si_bsize_best before it kills Matt :-)

Use the specfs routines rather having cloned copies in devfs.
This commit is contained in:
Poul-Henning Kamp 1999-08-30 07:56:23 +00:00
parent 9cc99e3681
commit 02e1576966
17 changed files with 78 additions and 254 deletions

View file

@ -625,6 +625,9 @@ pseudo-device vcoda 4 #coda minicache <-> venus comm.
#
options EXT2FS
#
# Only set this if you positively know why you should never do that.
options ALLOW_BDEV_ACCESS
#####################################################################

View file

@ -126,6 +126,9 @@ CD9660_ROOTDELAY opt_cd9660.h
# hidden yet.
UNION
# Options for all filesystems
ALLOW_BDEV_ACCESS opt_fs.h
# Options used only in param.c.
HZ opt_param.h
MAXFILES opt_param.h

View file

@ -634,7 +634,6 @@ ccdopen(dev, flags, fmt, p)
pmask = (1 << part);
dev->si_bsize_phys = DEV_BSIZE;
dev->si_bsize_best = BLKDEV_IOSIZE;
dev->si_bsize_max = MAXBSIZE;
/*

View file

@ -1227,7 +1227,6 @@ Fdopen(dev_t dev, int flags, int mode, struct proc *p)
fdc_p fdc;
dev->si_bsize_phys = DEV_BSIZE;
dev->si_bsize_best = BLKDEV_IOSIZE;
dev->si_bsize_max = MAXBSIZE;
/* check bounds */
if ((fd = devclass_get_softc(fd_devclass, fdu)) == 0)

View file

@ -272,7 +272,6 @@ vinumopen(dev_t dev,
devminor = minor(dev);
dev->si_bsize_phys = DEV_BSIZE;
dev->si_bsize_best = VINUM_BSIZE_BEST; /* kludge until we track drive block sizes */
dev->si_bsize_max = MAXBSIZE;
error = 0;
/* First, decide what we're looking at */

View file

@ -34,6 +34,7 @@
* $FreeBSD$
*/
#include "opt_fs.h"
#include <sys/param.h>
#include <sys/proc.h>
#include <sys/systm.h>
@ -258,6 +259,8 @@ spec_read(ap)
int error = 0;
dev_t dev;
dev = vp->v_rdev;
#ifdef DIAGNOSTIC
if (uio->uio_rw != UIO_READ)
panic("spec_read mode");
@ -269,24 +272,14 @@ spec_read(ap)
switch (vp->v_type) {
case VCHR:
VOP_UNLOCK(vp, 0, p);
error = (*devsw(vp->v_rdev)->d_read)
(vp->v_rdev, uio, ap->a_ioflag);
vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, p);
return (error);
case VBLK:
#ifdef ALLOW_BDEV_ACCESS
if (uio->uio_offset < 0)
return (EINVAL);
dev = vp->v_rdev;
/*
* Calculate block size for block device. The block size must
* be larger then the physical minimum.
*/
bsize = vp->v_rdev->si_bsize_best;
bsize = dev->si_bsize_phys;
while (bsize < dev->si_bsize_max && bsize < uio->uio_resid)
bsize <<= 1;
if ((ioctl = devsw(dev)->d_ioctl) != NULL &&
(*ioctl)(dev, DIOCGPART, (caddr_t)&dpart, FREAD, p) == 0 &&
@ -314,6 +307,12 @@ spec_read(ap)
brelse(bp);
} while (error == 0 && uio->uio_resid > 0 && n != 0);
return (error);
#endif /* ALLOW_BDEV_ACCESS */
case VCHR:
VOP_UNLOCK(vp, 0, p);
error = (*devsw(dev)->d_read) (dev, uio, ap->a_ioflag);
vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, p);
return (error);
default:
panic("spec_read type");
@ -343,36 +342,30 @@ spec_write(ap)
struct partinfo dpart;
register int n, on;
int error = 0;
dev_t dev;
dev = vp->v_rdev;
#ifdef DIAGNOSTIC
if (uio->uio_rw != UIO_WRITE)
panic("spec_write mode");
if (uio->uio_segflg == UIO_USERSPACE && uio->uio_procp != curproc)
panic("spec_write proc");
#endif
if (uio->uio_resid == 0)
return (0);
switch (vp->v_type) {
case VCHR:
VOP_UNLOCK(vp, 0, p);
error = (*devsw(vp->v_rdev)->d_write)
(vp->v_rdev, uio, ap->a_ioflag);
vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, p);
return (error);
case VBLK:
if (uio->uio_resid == 0)
return (0);
#ifdef ALLOW_BDEV_ACCESS
if (uio->uio_offset < 0)
return (EINVAL);
/*
* Calculate block size for block device. The block size must
* be larger then the physical minimum.
*/
bsize = vp->v_rdev->si_bsize_best;
bsize = dev->si_bsize_phys;
while (bsize < dev->si_bsize_max && bsize < uio->uio_resid)
bsize <<= 1;
if ((*devsw(vp->v_rdev)->d_ioctl)(vp->v_rdev, DIOCGPART,
if ((*devsw(dev)->d_ioctl)(dev, DIOCGPART,
(caddr_t)&dpart, FREAD, p) == 0) {
if (dpart.part->p_fstype == FS_BSDFFS &&
dpart.part->p_frag != 0 && dpart.part->p_fsize != 0)
@ -400,6 +393,14 @@ spec_write(ap)
bdwrite(bp);
} while (error == 0 && uio->uio_resid > 0 && n != 0);
return (error);
#endif /* ALLOW_BDEV_ACCESS */
case VCHR:
VOP_UNLOCK(vp, 0, p);
error = (*devsw(dev)->d_write)
(dev, uio, ap->a_ioflag);
vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, p);
return (error);
default:
panic("spec_write type");

View file

@ -634,7 +634,6 @@ ccdopen(dev, flags, fmt, p)
pmask = (1 << part);
dev->si_bsize_phys = DEV_BSIZE;
dev->si_bsize_best = BLKDEV_IOSIZE;
dev->si_bsize_max = MAXBSIZE;
/*

View file

@ -625,6 +625,9 @@ pseudo-device vcoda 4 #coda minicache <-> venus comm.
#
options EXT2FS
#
# Only set this if you positively know why you should never do that.
options ALLOW_BDEV_ACCESS
#####################################################################

View file

@ -625,6 +625,9 @@ pseudo-device vcoda 4 #coda minicache <-> venus comm.
#
options EXT2FS
#
# Only set this if you positively know why you should never do that.
options ALLOW_BDEV_ACCESS
#####################################################################

View file

@ -1227,7 +1227,6 @@ Fdopen(dev_t dev, int flags, int mode, struct proc *p)
fdc_p fdc;
dev->si_bsize_phys = DEV_BSIZE;
dev->si_bsize_best = BLKDEV_IOSIZE;
dev->si_bsize_max = MAXBSIZE;
/* check bounds */
if ((fd = devclass_get_softc(fd_devclass, fdu)) == 0)

View file

@ -710,7 +710,6 @@ dsopen(dev, mode, flags, sspp, lp)
int unit;
dev->si_bsize_phys = lp->d_secsize;
dev->si_bsize_best = BLKDEV_IOSIZE;
dev->si_bsize_max = MAXBSIZE;
unit = dkunit(dev);

View file

@ -436,8 +436,6 @@ vn_stat(vp, sb, p)
*/
switch (vap->va_type) {
case VBLK:
sb->st_blksize = vp->v_rdev->si_bsize_best;
break;
case VCHR:
sb->st_blksize = vp->v_rdev->si_bsize_max;
break;

View file

@ -26,7 +26,6 @@
* $FreeBSD$
*/
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/buf.h>
@ -651,7 +650,7 @@ devfs_xwrite(struct vop_write_args *ap)
case VBLK:
panic("devfs: vnode methods");
default:
panic("devfs_write(): bad file type");
panic("devfs_xwrite(): bad file type");
}
}
@ -1412,199 +1411,24 @@ devfs_open( struct vop_open_args *ap)
return (error);
}
/*
* Vnode op for read
struct vop_read_args {
struct vnode *a_vp;
struct uio *a_uio;
int a_ioflag;
struct ucred *a_cred;
}
*/
/* ARGSUSED */
static int
devfs_read( struct vop_read_args *ap)
{
struct vnode *vp = ap->a_vp;
struct uio *uio = ap->a_uio;
struct proc *p = uio->uio_procp;
struct buf *bp;
daddr_t bn, nextbn;
long bsize, bscale;
struct partinfo dpart;
int n, on;
d_ioctl_t *ioctl;
int error = 0;
dev_t dev;
dn_p dnp;
int error;
if ((error = devfs_vntodn(vp,&dnp)) != 0)
return error;
#ifdef DIAGNOSTIC
if (uio->uio_rw != UIO_READ)
panic("devfs_read mode");
if (uio->uio_segflg == UIO_USERSPACE && uio->uio_procp != curproc)
panic("devfs_read proc");
#endif
if (uio->uio_resid == 0)
return (0);
switch (vp->v_type) {
case VCHR:
VOP_UNLOCK(vp, 0, p);
error = (*vp->v_rdev->si_devsw->d_read)
(vp->v_rdev, uio, ap->a_ioflag);
vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, p);
break;
case VBLK:
if (uio->uio_offset < 0)
return (EINVAL);
/*
* Calculate block size for block device. The block size must
* be larger then the physical minimum.
*/
dev = vp->v_rdev;
bsize = dev->si_bsize_best;
/*
* This is a hack!
*/
if ( (ioctl = dev->si_devsw->d_ioctl) != NULL &&
(*ioctl)(dev, DIOCGPART, (caddr_t)&dpart, FREAD, p) == 0 &&
dpart.part->p_fstype == FS_BSDFFS &&
dpart.part->p_frag != 0 && dpart.part->p_fsize != 0)
bsize = dpart.part->p_frag * dpart.part->p_fsize;
bscale = btodb(bsize);
/*
* Get buffers with this data from the buffer cache.
* If it's not there the strategy() entrypoint will be called.
* We may do this in several chunks.
*/
do {
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) {
nextbn = bn + bscale;
error = breadn(vp, bn, (int)bsize, &nextbn,
(int *)&bsize, 1, NOCRED, &bp);
} else
error = bread(vp, bn, (int)bsize, NOCRED, &bp);
vp->v_lastr = bn;
n = min(n, bsize - bp->b_resid);
if (error) {
brelse(bp);
return (error);
}
/*
* Copy it to the user's space
*/
error = uiomove((char *)bp->b_data + on, n, uio);
brelse(bp);
} while (error == 0 && uio->uio_resid > 0 && n != 0);
break;
default:
panic("devfs_read type");
}
if (!(vp->v_mount->mnt_flag & MNT_NOATIME))
dnp->flags |= IN_ACCESS;
error = VOCALL(spec_vnodeop_p, VOFFSET(vop_read), ap);
return (error);
}
/*
* Vnode op for write
struct vop_write_args {
struct vnode *a_vp;
struct uio *a_uio;
int a_ioflag;
struct ucred *a_cred;
}
*/
/* ARGSUSED */
static int
devfs_write( struct vop_write_args *ap)
{
struct vnode *vp = ap->a_vp;
struct uio *uio = ap->a_uio;
struct proc *p = uio->uio_procp;
struct buf *bp;
daddr_t bn;
int bsize, blkmask;
struct partinfo dpart;
int n, on;
int error = 0;
dn_p dnp;
int error;
if ((error = devfs_vntodn(vp,&dnp)) != 0)
return error;
#ifdef DIAGNOSTIC
if (uio->uio_rw != UIO_WRITE)
panic("devfs_write mode");
if (uio->uio_segflg == UIO_USERSPACE && uio->uio_procp != curproc)
panic("devfs_write proc");
#endif
switch (vp->v_type) {
case VCHR:
VOP_UNLOCK(vp, 0, p);
error = (*vp->v_rdev->si_devsw->d_write)
(vp->v_rdev, uio, ap->a_ioflag);
vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, p);
return (error);
case VBLK:
if (uio->uio_resid == 0)
return (0);
if (uio->uio_offset < 0)
return (EINVAL);
/*
* Calculate block size for block device. The block size must
* be larger then the physical minimum.
*/
bsize = vp->v_rdev->si_bsize_best;
if ((vp->v_rdev->si_devsw->d_ioctl != NULL)
&& ((*vp->v_rdev->si_devsw->d_ioctl)(vp->v_rdev, DIOCGPART,
(caddr_t)&dpart, FREAD, p) == 0)
&& (dpart.part->p_fstype == FS_BSDFFS)
&& (dpart.part->p_frag != 0)
&& (dpart.part->p_fsize != 0)) {
bsize = dpart.part->p_frag * dpart.part->p_fsize;
}
blkmask = btodb(bsize) - 1;
do {
bn = btodb(uio->uio_offset) & ~blkmask;
on = uio->uio_offset % bsize;
n = min((unsigned)(bsize - on), uio->uio_resid);
if (n == bsize)
bp = getblk(vp, bn, bsize, 0, 0);
else
error = bread(vp, bn, bsize, NOCRED, &bp);
if (error) {
brelse(bp);
return (error);
}
n = min(n, bsize - bp->b_resid);
error = uiomove((char *)bp->b_data + on, n, uio);
if (n + on == bsize)
bawrite(bp);
else
bdwrite(bp);
} while (error == 0 && uio->uio_resid > 0 && n != 0);
return (error);
default:
panic("devfs_write type");
}
/* NOTREACHED */
error = VOCALL(spec_vnodeop_p, VOFFSET(vop_write), ap);
return (error);
}
/*

View file

@ -34,6 +34,7 @@
* $FreeBSD$
*/
#include "opt_fs.h"
#include <sys/param.h>
#include <sys/proc.h>
#include <sys/systm.h>
@ -258,6 +259,8 @@ spec_read(ap)
int error = 0;
dev_t dev;
dev = vp->v_rdev;
#ifdef DIAGNOSTIC
if (uio->uio_rw != UIO_READ)
panic("spec_read mode");
@ -269,24 +272,14 @@ spec_read(ap)
switch (vp->v_type) {
case VCHR:
VOP_UNLOCK(vp, 0, p);
error = (*devsw(vp->v_rdev)->d_read)
(vp->v_rdev, uio, ap->a_ioflag);
vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, p);
return (error);
case VBLK:
#ifdef ALLOW_BDEV_ACCESS
if (uio->uio_offset < 0)
return (EINVAL);
dev = vp->v_rdev;
/*
* Calculate block size for block device. The block size must
* be larger then the physical minimum.
*/
bsize = vp->v_rdev->si_bsize_best;
bsize = dev->si_bsize_phys;
while (bsize < dev->si_bsize_max && bsize < uio->uio_resid)
bsize <<= 1;
if ((ioctl = devsw(dev)->d_ioctl) != NULL &&
(*ioctl)(dev, DIOCGPART, (caddr_t)&dpart, FREAD, p) == 0 &&
@ -314,6 +307,12 @@ spec_read(ap)
brelse(bp);
} while (error == 0 && uio->uio_resid > 0 && n != 0);
return (error);
#endif /* ALLOW_BDEV_ACCESS */
case VCHR:
VOP_UNLOCK(vp, 0, p);
error = (*devsw(dev)->d_read) (dev, uio, ap->a_ioflag);
vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, p);
return (error);
default:
panic("spec_read type");
@ -343,36 +342,30 @@ spec_write(ap)
struct partinfo dpart;
register int n, on;
int error = 0;
dev_t dev;
dev = vp->v_rdev;
#ifdef DIAGNOSTIC
if (uio->uio_rw != UIO_WRITE)
panic("spec_write mode");
if (uio->uio_segflg == UIO_USERSPACE && uio->uio_procp != curproc)
panic("spec_write proc");
#endif
if (uio->uio_resid == 0)
return (0);
switch (vp->v_type) {
case VCHR:
VOP_UNLOCK(vp, 0, p);
error = (*devsw(vp->v_rdev)->d_write)
(vp->v_rdev, uio, ap->a_ioflag);
vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, p);
return (error);
case VBLK:
if (uio->uio_resid == 0)
return (0);
#ifdef ALLOW_BDEV_ACCESS
if (uio->uio_offset < 0)
return (EINVAL);
/*
* Calculate block size for block device. The block size must
* be larger then the physical minimum.
*/
bsize = vp->v_rdev->si_bsize_best;
bsize = dev->si_bsize_phys;
while (bsize < dev->si_bsize_max && bsize < uio->uio_resid)
bsize <<= 1;
if ((*devsw(vp->v_rdev)->d_ioctl)(vp->v_rdev, DIOCGPART,
if ((*devsw(dev)->d_ioctl)(dev, DIOCGPART,
(caddr_t)&dpart, FREAD, p) == 0) {
if (dpart.part->p_fstype == FS_BSDFFS &&
dpart.part->p_frag != 0 && dpart.part->p_fsize != 0)
@ -400,6 +393,14 @@ spec_write(ap)
bdwrite(bp);
} while (error == 0 && uio->uio_resid > 0 && n != 0);
return (error);
#endif /* ALLOW_BDEV_ACCESS */
case VCHR:
VOP_UNLOCK(vp, 0, p);
error = (*devsw(dev)->d_write)
(dev, uio, ap->a_ioflag);
vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, p);
return (error);
default:
panic("spec_write type");

View file

@ -69,7 +69,6 @@ struct specinfo {
struct disk *__sid_disk;
struct mount *__sid_mountpoint;
int __sid_bsize_phys; /* min physical block size */
int __sid_bsize_best; /* optimal block size */
int __sid_bsize_max; /* maximum block size */
} __si_disk;
} __si_u;
@ -79,7 +78,6 @@ struct specinfo {
#define si_disk __si_u.__si_disk.__sid_disk
#define si_mountpoint __si_u.__si_disk.__sid_mountpoint
#define si_bsize_phys __si_u.__si_disk.__sid_bsize_phys
#define si_bsize_best __si_u.__si_disk.__sid_bsize_best
#define si_bsize_max __si_u.__si_disk.__sid_bsize_max
/*

View file

@ -69,7 +69,6 @@ struct specinfo {
struct disk *__sid_disk;
struct mount *__sid_mountpoint;
int __sid_bsize_phys; /* min physical block size */
int __sid_bsize_best; /* optimal block size */
int __sid_bsize_max; /* maximum block size */
} __si_disk;
} __si_u;
@ -79,7 +78,6 @@ struct specinfo {
#define si_disk __si_u.__si_disk.__sid_disk
#define si_mountpoint __si_u.__si_disk.__sid_mountpoint
#define si_bsize_phys __si_u.__si_disk.__sid_bsize_phys
#define si_bsize_best __si_u.__si_disk.__sid_bsize_best
#define si_bsize_max __si_u.__si_disk.__sid_bsize_max
/*

View file

@ -333,7 +333,6 @@ mfs_mount(mp, path, data, ndp, p)
devvp->v_type = VBLK;
dev = make_dev(&mfs_cdevsw, mfs_minor, 0, 0, 0, "MFS%d", mfs_minor);
dev->si_bsize_phys = DEV_BSIZE;
dev->si_bsize_best = BLKDEV_IOSIZE;
dev->si_bsize_max = MAXBSIZE;
addaliasu(devvp, makeudev(253, mfs_minor++));
devvp->v_data = mfsp;
@ -495,7 +494,6 @@ mfs_init(vfsp)
rootdev = make_dev(&mfs_cdevsw, mfs_minor,
0, 0, 0, "MFS%d", mfs_minor);
rootdev->si_bsize_phys = DEV_BSIZE;
rootdev->si_bsize_best = BLKDEV_IOSIZE;
rootdev->si_bsize_max = MAXBSIZE;
mfs_minor++;
} else if (bootverbose)