summaryrefslogtreecommitdiffstats
path: root/sys/dev/vn
diff options
context:
space:
mode:
authorphk <phk@FreeBSD.org>1995-03-11 09:32:45 +0000
committerphk <phk@FreeBSD.org>1995-03-11 09:32:45 +0000
commit2269686ee1f326bebf3b6140f00f55cebe9cec4e (patch)
tree2a38cbf6eb14fc0d0f84e6794f21bd8cb380f455 /sys/dev/vn
parentbf749b932cc994dab8c2931aad49aaa58eb395e8 (diff)
downloadFreeBSD-src-2269686ee1f326bebf3b6140f00f55cebe9cec4e.zip
FreeBSD-src-2269686ee1f326bebf3b6140f00f55cebe9cec4e.tar.gz
A substantial change to the way this works. Not the "TEST_LABELING" is
a option you can turn on and of on the fly, as is debugging.
Diffstat (limited to 'sys/dev/vn')
-rw-r--r--sys/dev/vn/vn.c265
1 files changed, 139 insertions, 126 deletions
diff --git a/sys/dev/vn/vn.c b/sys/dev/vn/vn.c
index 3e075ac..e1b455b 100644
--- a/sys/dev/vn/vn.c
+++ b/sys/dev/vn/vn.c
@@ -81,10 +81,8 @@
#include <sys/file.h>
#include <sys/uio.h>
#include <sys/disklabel.h>
-#ifdef TEST_LABELLING
#include <sys/diskslice.h>
#include <sys/stat.h>
-#endif
#include <miscfs/specfs/specdev.h>
@@ -98,11 +96,7 @@ int vndebug = 0x00;
#define VDB_IO 0x04
#endif
-#ifdef TEST_LABELLING
#define vnunit(dev) dkunit(dev)
-#else
-#define vnunit(x) (minor(x) >> 3)
-#endif
#define getvnbuf() \
((struct buf *)malloc(sizeof(struct buf), M_DEVBUF, M_WAITOK))
@@ -117,15 +111,17 @@ struct vn_softc {
struct ucred *sc_cred; /* credentials */
int sc_maxactive; /* max # of active requests */
struct buf sc_tab; /* transfer queue */
-#ifdef TEST_LABELLING
+ u_long sc_options; /* options */
struct diskslices *sc_slices;
-#endif
};
/* sc_flags */
#define VNF_INITED 0x01
struct vn_softc *vn_softc[NVN];
+u_long vn_options;
+
+#define IFOPT(vn,opt) if (((vn)->sc_options|vn_options) & (opt))
/*
* XXX these decls should be static (without __P(())) or elsewhere.
@@ -146,15 +142,11 @@ int vndump __P((dev_t dev));
int
vnclose(dev_t dev, int flags, int mode, struct proc *p)
{
- struct vn_softc *vn;
+ struct vn_softc *vn = vn_softc[vnunit(dev)];
- vn = vn_softc[vnunit(dev)];
-#ifdef TEST_LABELLING
- if (vn->sc_slices != NULL)
- dsclose(dev, mode, vn->sc_slices);
-#endif
- vn_softc[vnunit(dev)] = 0;
- free(vn, M_DEVBUF);
+ IFOPT(vn, VN_LABELS)
+ if (vn->sc_slices != NULL)
+ dsclose(dev, mode, vn->sc_slices);
return (0);
}
@@ -164,12 +156,12 @@ vnopen(dev_t dev, int flags, int mode, struct proc *p)
int unit = vnunit(dev),size;
struct vn_softc *vn;
-#ifdef DEBUG
- if (vndebug & VDB_FOLLOW)
- printf("vnopen(0x%lx, 0x%x, 0x%x, %p)\n", dev, flags, mode, p);
-#endif
- if (unit >= NVN)
+ if (unit >= NVN) {
+ if (vn_options & VN_FOLLOW)
+ printf("vnopen(0x%lx, 0x%x, 0x%x, %p)\n",
+ dev, flags, mode, p);
return(ENOENT);
+ }
vn = vn_softc[unit];
if (!vn) {
@@ -179,27 +171,33 @@ vnopen(dev_t dev, int flags, int mode, struct proc *p)
bzero(vn, sizeof *vn);
vn_softc[unit] = vn;
}
-#ifdef TEST_LABELLING
- if (vn->sc_flags & VNF_INITED) {
- struct disklabel label;
-
- /* Build label for whole disk. */
- bzero(&label, sizeof label);
- label.d_secsize = DEV_BSIZE;
- label.d_nsectors = 32;
- label.d_ntracks = 64;
- label.d_ncylinders = vn->sc_size / (32 * 64);
- label.d_secpercyl = 32 * 64;
- label.d_secperunit = label.d_partitions[RAW_PART].p_size
- = vn->sc_size;
-
- return (dsopen("vn", dev, mode, &vn->sc_slices, &label,
- vnstrategy, (ds_setgeom_t *)NULL));
+
+ IFOPT(vn, VN_FOLLOW)
+ printf("vnopen(0x%lx, 0x%x, 0x%x, %p)\n", dev, flags, mode, p);
+
+ IFOPT(vn, VN_LABELS) {
+ if (vn->sc_flags & VNF_INITED) {
+ struct disklabel label;
+
+ /* Build label for whole disk. */
+ bzero(&label, sizeof label);
+ label.d_secsize = DEV_BSIZE;
+ label.d_nsectors = 32;
+ label.d_ntracks = 64;
+ label.d_ncylinders = vn->sc_size / (32 * 64);
+ label.d_secpercyl = 32 * 64;
+ label.d_secperunit =
+ label.d_partitions[RAW_PART].p_size =
+ vn->sc_size;
+
+ return (dsopen("vn", dev, mode, &vn->sc_slices, &label,
+ vnstrategy, (ds_setgeom_t *)NULL));
+ }
+ if (dkslice(dev) != WHOLE_DISK_SLICE ||
+ dkpart(dev) != RAW_PART ||
+ mode != S_IFCHR)
+ return (ENXIO);
}
- if (dkslice(dev) != WHOLE_DISK_SLICE || dkpart(dev) != RAW_PART ||
- mode != S_IFCHR)
- return (ENXIO);
-#endif /* TEST_LABELLING */
return(0);
}
@@ -218,37 +216,36 @@ vnstrategy(struct buf *bp)
register caddr_t addr;
int sz, flags, error;
-#ifdef DEBUG
- if (vndebug & VDB_FOLLOW)
+ IFOPT(vn, VN_DEBUG)
printf("vnstrategy(%p): unit %d\n", bp, unit);
-#endif
+
if ((vn->sc_flags & VNF_INITED) == 0) {
bp->b_error = ENXIO;
bp->b_flags |= B_ERROR;
biodone(bp);
return;
}
-#ifdef TEST_LABELLING
- bp->b_resid = bp->b_bcount; /* XXX best place to set this? */
- if (vn->sc_slices != NULL && dscheck(bp, vn->sc_slices) <= 0) {
- biodone(bp);
- return;
- }
- bn = bp->b_pblkno;
- bp->b_resid = bp->b_bcount; /* XXX best place to set this? */
-#else /* !TEST_LABELLING */
- bn = bp->b_blkno;
- sz = howmany(bp->b_bcount, DEV_BSIZE);
- bp->b_resid = bp->b_bcount;
- if (bn < 0 || bn + sz > vn->sc_size) {
- if (bn != vn->sc_size) {
- bp->b_error = EINVAL;
- bp->b_flags |= B_ERROR;
+ IFOPT(vn, VN_LABELS) {
+ bp->b_resid = bp->b_bcount;/* XXX best place to set this? */
+ if (vn->sc_slices != NULL && dscheck(bp, vn->sc_slices) <= 0) {
+ biodone(bp);
+ return;
+ }
+ bn = bp->b_pblkno;
+ bp->b_resid = bp->b_bcount;/* XXX best place to set this? */
+ } else {
+ bn = bp->b_blkno;
+ sz = howmany(bp->b_bcount, DEV_BSIZE);
+ bp->b_resid = bp->b_bcount;
+ if (bn < 0 || bn + sz > vn->sc_size) {
+ if (bn != vn->sc_size) {
+ bp->b_error = EINVAL;
+ bp->b_flags |= B_ERROR;
+ }
+ biodone(bp);
+ return;
}
- biodone(bp);
- return;
}
-#endif /* TEST_LABELLING */
bn = dbtob(bn);
bsize = vn->sc_vp->v_mount->mnt_stat.f_iosize;
addr = bp->b_data;
@@ -262,10 +259,9 @@ vnstrategy(struct buf *bp)
error = VOP_BMAP(vn->sc_vp, bn / bsize, &vp, &nbn, &nra);
if (error == 0 && (long)nbn == -1)
error = EIO;
-#ifdef DEBUG
- if (!dovncluster)
+
+ IFOPT(vn, VN_DONTCLUSTER)
nra = 0;
-#endif
off = bn % bsize;
if (off)
@@ -274,11 +270,10 @@ vnstrategy(struct buf *bp)
sz = (1 + nra) * bsize;
if (resid < sz)
sz = resid;
-#ifdef DEBUG
- if (vndebug & VDB_IO)
+
+ IFOPT(vn,VN_IO)
printf("vnstrategy: vp %p/%p bn 0x%x/0x%lx sz 0x%x\n",
vn->sc_vp, vp, bn, nbn, sz);
-#endif
nbp = getvnbuf();
nbp->b_flags = flags;
@@ -354,12 +349,10 @@ vnstart(struct vn_softc *vn)
*/
bp = vn->sc_tab.b_actf;
vn->sc_tab.b_actf = bp->b_actf;
-#ifdef DEBUG
- if (vndebug & VDB_IO)
+ IFOPT(vn, VN_IO)
printf("vnstart(%d): bp %p vp %p blkno 0x%lx addr %p cnt 0x%lx\n",
0, bp, bp->b_vp, bp->b_blkno, bp->b_data,
bp->b_bcount);
-#endif
if ((bp->b_flags & B_READ) == 0)
bp->b_vp->v_numoutput++;
VOP_STRATEGY(bp);
@@ -373,27 +366,23 @@ vniodone(struct buf *bp)
int s;
s = splbio();
-#ifdef DEBUG
- if (vndebug & VDB_IO)
+
+ IFOPT(vn, VN_IO)
printf("vniodone(%d): bp %p vp %p blkno 0x%lx addr %p cnt 0x%lx\n",
0, bp, bp->b_vp, bp->b_blkno, bp->b_data,
bp->b_bcount);
-#endif
+
if (bp->b_error) {
-#ifdef DEBUG
- if (vndebug & VDB_IO)
+ IFOPT(vn, VN_IO)
printf("vniodone: bp %p error %d\n", bp, bp->b_error);
-#endif
pbp->b_flags |= B_ERROR;
pbp->b_error = biowait(bp);
}
pbp->b_resid -= bp->b_bcount;
putvnbuf(bp);
if (pbp->b_resid == 0) {
-#ifdef DEBUG
- if (vndebug & VDB_IO)
+ IFOPT(vn, VN_IO)
printf("vniodone: pbp %p iodone\n", pbp);
-#endif
biodone(pbp);
}
if (vn->sc_tab.b_actf)
@@ -407,40 +396,51 @@ vniodone(struct buf *bp)
int
vnioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p)
{
- int unit = vnunit(dev);
- register struct vn_softc *vn;
+ struct vn_softc *vn = vn_softc[vnunit(dev)];
struct vn_ioctl *vio;
struct vattr vattr;
struct nameidata nd;
int error;
+ u_long *f;
-#ifdef DEBUG
- if (vndebug & VDB_FOLLOW)
+
+ IFOPT(vn,VN_FOLLOW)
printf("vnioctl(0x%lx, 0x%lx, %p, 0x%x, %p): unit %d\n",
- dev, cmd, data, flag, p, unit);
-#endif
+ dev, cmd, data, flag, p, vnunit(dev));
-#ifdef TEST_LABELLING
- vn = vn_softc[unit];
- if (vn->sc_slices != NULL) {
- error = dsioctl(dev, cmd, data, flag, vn->sc_slices,
- vnstrategy, (ds_setgeom_t *)NULL);
- if (error != -1)
- return (error);
+ switch (cmd) {
+ case VNIOCATTACH:
+ case VNIOCDETACH:
+ case VNIOCGSET:
+ case VNIOCGCLEAR:
+ case VNIOCUSET:
+ case VNIOCUCLEAR:
+ goto vn_specific;
}
- if (dkslice(dev) != WHOLE_DISK_SLICE || dkpart(dev) != RAW_PART)
- return (ENOTTY);
-#endif
+
+ IFOPT(vn,VN_LABELS) {
+ if (vn->sc_slices != NULL) {
+ error = dsioctl(dev, cmd, data, flag, vn->sc_slices,
+ vnstrategy, (ds_setgeom_t *)NULL);
+ if (error != -1)
+ return (error);
+ }
+ if (dkslice(dev) != WHOLE_DISK_SLICE ||
+ dkpart(dev) != RAW_PART)
+ return (ENOTTY);
+ }
+
+ vn_specific:
error = suser(p->p_ucred, &p->p_acflag);
if (error)
return (error);
- vn = vn_softc[unit];
vio = (struct vn_ioctl *)data;
+ f = (u_long*)data;
switch (cmd) {
- case VNIOCSET:
+ case VNIOCATTACH:
if (vn->sc_flags & VNF_INITED)
return(EBUSY);
/*
@@ -470,26 +470,24 @@ vnioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p)
vnthrottle(vn, vn->sc_vp);
vio->vn_size = dbtob(vn->sc_size);
vn->sc_flags |= VNF_INITED;
-#ifdef TEST_LABELLING
- /*
- * Reopen so that `ds' knows which devices are open. If
- * this is the first VNIOCSET, then we've guaranteed that
- * the device is the cdev and that no other slices or
- * labels are open. Otherwise, we rely on VNIOCCLR not
- * being abused.
- */
- error = vnopen(dev, flag, S_IFCHR, p);
- if (error)
- vnclear(vn);
-#endif
-#ifdef DEBUG
- if (vndebug & VDB_INIT)
+ IFOPT(vn, VN_LABELS) {
+ /*
+ * Reopen so that `ds' knows which devices are open.
+ * If this is the first VNIOCSET, then we've
+ * guaranteed that the device is the cdev and that
+ * no other slices or labels are open. Otherwise,
+ * we rely on VNIOCCLR not being abused.
+ */
+ error = vnopen(dev, flag, S_IFCHR, p);
+ if (error)
+ vnclear(vn);
+ }
+ IFOPT(vn, VN_FOLLOW)
printf("vnioctl: SET vp %p size %x\n",
vn->sc_vp, vn->sc_size);
-#endif
break;
- case VNIOCCLR:
+ case VNIOCDETACH:
if ((vn->sc_flags & VNF_INITED) == 0)
return(ENXIO);
/*
@@ -501,10 +499,28 @@ vnioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p)
* hardware devices?
*/
vnclear(vn);
-#ifdef DEBUG
- if (vndebug & VDB_INIT)
+ IFOPT(vn, VN_FOLLOW)
printf("vnioctl: CLRed\n");
-#endif
+ break;
+
+ case VNIOCGSET:
+ vn_options |= *f;
+ *f = vn_options;
+ break;
+
+ case VNIOCGCLEAR:
+ vn_options &= ~(*f);
+ *f = vn_options;
+ break;
+
+ case VNIOCUSET:
+ vn->sc_options |= *f;
+ *f = vn->sc_options;
+ break;
+
+ case VNIOCUCLEAR:
+ vn->sc_options &= ~(*f);
+ *f = vn->sc_options;
break;
default:
@@ -582,10 +598,8 @@ vnclear(struct vn_softc *vn)
register struct vnode *vp = vn->sc_vp;
struct proc *p = curproc; /* XXX */
-#ifdef DEBUG
- if (vndebug & VDB_FOLLOW)
- printf("vnclear(%p): vp %p\n", vn, vp);
-#endif
+ IFOPT(vn, VN_FOLLOW)
+ printf("vnclear(%p): vp=%p\n", vn, vp);
vn->sc_flags &= ~VNF_INITED;
if (vp == (struct vnode *)0)
panic("vnclear: null vp");
@@ -594,10 +608,9 @@ vnclear(struct vn_softc *vn)
vn->sc_vp = (struct vnode *)0;
vn->sc_cred = (struct ucred *)0;
vn->sc_size = 0;
-#ifdef TEST_LABELLING
- if (vn->sc_slices != NULL)
- dsgone(&vn->sc_slices);
-#endif
+ IFOPT(vn, VN_LABELS)
+ if (vn->sc_slices != NULL)
+ dsgone(&vn->sc_slices);
}
size_t
OpenPOWER on IntegriCloud