diff options
| author | Bruce Evans <bde@FreeBSD.org> | 1994-12-16 16:50:15 +0000 |
|---|---|---|
| committer | Bruce Evans <bde@FreeBSD.org> | 1994-12-16 16:50:15 +0000 |
| commit | 9a0f1b5bd5eda9251d314bcd9d247b43d3a1d0ae (patch) | |
| tree | 8d4433650a0c4324ee1de0015f74d4e9238773a6 /sys/dev/vn | |
| parent | fb72042b5cd9317d2af235fb9ca9e4a71aacf500 (diff) | |
Notes
Diffstat (limited to 'sys/dev/vn')
| -rw-r--r-- | sys/dev/vn/vn.c | 54 |
1 files changed, 38 insertions, 16 deletions
diff --git a/sys/dev/vn/vn.c b/sys/dev/vn/vn.c index f06079600899..f7cc61aa88e5 100644 --- a/sys/dev/vn/vn.c +++ b/sys/dev/vn/vn.c @@ -78,6 +78,7 @@ #ifdef TEST_LABELLING #include <sys/disklabel.h> #include <sys/diskslice.h> +#include <sys/stat.h> #endif #include <miscfs/specfs/specdev.h> @@ -125,7 +126,7 @@ int numvnd; /* * XXX these decls should be static (without __P(())) or elsewhere. */ -void vnattach __P((int num)); +int vnclose __P((dev_t dev, int flags, int mode, struct proc *p)); int vnopen __P((dev_t dev, int flags, int mode, struct proc *p)); void vnstrategy __P((struct buf *bp)); void vnstart __P((struct vn_softc *vn)); @@ -191,10 +192,9 @@ vnopen(dev_t dev, int flags, int mode, struct proc *p) } #ifdef TEST_LABELLING if (vn->sc_flags & VNF_INITED) { - int error; struct disklabel label; - /* Build label for whole disk. */ + /* Build label for whole disk. */ bzero(&label, sizeof label); label.d_secsize = DEV_BSIZE; label.d_nsectors = vn->sc_size; @@ -204,13 +204,12 @@ vnopen(dev_t dev, int flags, int mode, struct proc *p) label.d_secperunit = label.d_partitions[RAW_PART].p_size = label.d_nsectors; - error = dsopen("vn", dev, mode, &vn->sc_slices, &label, - vnstrategy, (ds_setgeom_t *)NULL); -#if 0 - /* XXX temporary */ - return (error); -#endif + 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); #endif /* TEST_LABELLING */ return(0); } @@ -460,12 +459,14 @@ vnioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p) if (unit >= numvnd) return (ENXIO); vn = vn_softc[unit]; - if (vn->sc_slices) { - error = dsioctl(dev, cmd, data, flag, vn->sc_slices, vnstrategy, - (ds_setgeom_t *)NULL); + 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); #endif error = suser(p->p_ucred, &p->p_acflag); @@ -508,6 +509,18 @@ 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) printf("vnioctl: SET vp %x size %x\n", @@ -518,6 +531,14 @@ vnioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p) case VNIOCCLR: if ((vn->sc_flags & VNF_INITED) == 0) return(ENXIO); + /* + * XXX handle i/o in progress. Return EBUSY, or wait, or + * flush the i/o. + * XXX handle multiple opens of the device. Return EBUSY, + * or revoke the fd's. + * How are these problems handled for removable and failing + * hardware devices? + */ vnclear(vn); #ifdef DEBUG if (vndebug & VDB_INIT) @@ -526,7 +547,7 @@ vnioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p) break; default: - return(ENXIO); + return (ENOTTY); } return(0); } @@ -606,14 +627,15 @@ vnclear(struct vn_softc *vn) #endif vn->sc_flags &= ~VNF_INITED; if (vp == (struct vnode *)0) - panic("vnioctl: null vp"); + panic("vnclear: null vp"); (void) vn_close(vp, FREAD|FWRITE, vn->sc_cred, p); crfree(vn->sc_cred); vn->sc_vp = (struct vnode *)0; vn->sc_cred = (struct ucred *)0; vn->sc_size = 0; #ifdef TEST_LABELLING - vn->sc_slices = NULL; /* XXX temportary; leaks memory, maybe worse */ + if (vn->sc_slices != NULL) + dsgone(&vn->sc_slices); #endif } @@ -632,6 +654,6 @@ vnsize(dev_t dev) int vndump(dev_t dev) { - return(ENXIO); + return (ENODEV); } #endif |
