diff options
| author | Matthew Dillon <dillon@FreeBSD.org> | 1999-09-17 05:34:00 +0000 |
|---|---|---|
| committer | Matthew Dillon <dillon@FreeBSD.org> | 1999-09-17 05:34:00 +0000 |
| commit | 447deba3dadf866766beba0745bb6868241eaef6 (patch) | |
| tree | 37fa135dd798e2d6da46a6c58ec698acf8936440 /sys | |
| parent | 24579ca1d7a4ffaa220af5bd7593aa759e1d9c38 (diff) | |
Notes
Diffstat (limited to 'sys')
| -rw-r--r-- | sys/dev/vn/vn.c | 58 | ||||
| -rw-r--r-- | sys/sys/mdioctl.h | 3 | ||||
| -rw-r--r-- | sys/sys/vnioctl.h | 3 |
3 files changed, 54 insertions, 10 deletions
diff --git a/sys/dev/vn/vn.c b/sys/dev/vn/vn.c index 199c8046d4603..54914b24f7958 100644 --- a/sys/dev/vn/vn.c +++ b/sys/dev/vn/vn.c @@ -157,6 +157,7 @@ static SLIST_HEAD(, vn_softc) vn_list; static u_long vn_options; #define IFOPT(vn,opt) if (((vn)->sc_options|vn_options) & (opt)) +#define TESTOPT(vn,opt) (((vn)->sc_options|vn_options) & (opt)) static int vnsetcred (struct vn_softc *vn, struct ucred *cred); static void vnclear (struct vn_softc *vn); @@ -208,14 +209,23 @@ vnfindvn(dev_t dev) static int vnopen(dev_t dev, int flags, int mode, struct proc *p) { - int unit; struct vn_softc *vn; - unit = dkunit(dev); - vn = dev->si_drv1; - if (!vn) + /* + * Locate preexisting device + */ + + if ((vn = dev->si_drv1) == NULL) vn = vnfindvn(dev); + /* + * Update si_bsize fields for device. This data will be overriden by + * the slice/parition code for vn accesses through partitions, and + * used directly if you open the 'whole disk' device. + */ + dev->si_bsize_phys = vn->sc_secsize; + dev->si_bsize_best = vn->sc_secsize; + if (flags & FWRITE && vn->sc_flags & VNF_READONLY) return (EACCES); @@ -223,6 +233,10 @@ vnopen(dev_t dev, int flags, int mode, struct proc *p) printf("vnopen(%s, 0x%x, 0x%x, %p)\n", devtoname(dev), flags, mode, (void *)p); + /* + * Initialize label + */ + IFOPT(vn, VN_LABELS) { if (vn->sc_flags & VNF_INITED) { struct disklabel label; @@ -241,8 +255,9 @@ vnopen(dev_t dev, int flags, int mode, struct proc *p) } if (dkslice(dev) != WHOLE_DISK_SLICE || dkpart(dev) != RAW_PART || - mode != S_IFCHR) + mode != S_IFCHR) { return (ENXIO); + } } return(0); } @@ -295,9 +310,9 @@ vnstrategy(struct buf *bp) return; } } else { - int pbn; + int pbn; /* in sc_secsize chunks */ - pbn = bp->b_blkno * (vn->sc_secsize / DEV_BSIZE); + pbn = bp->b_blkno / (vn->sc_secsize / DEV_BSIZE); sz = howmany(bp->b_bcount, vn->sc_secsize); if (pbn < 0 || pbn + sz > vn->sc_size) { @@ -356,8 +371,17 @@ vnstrategy(struct buf *bp) * OBJT_SWAP I/O * * ( handles read, write, freebuf ) + * + * Note: if we pre-reserved swap, B_FREEBUF is disabled */ - vm_pager_strategy(vn->sc_object, bp); + KASSERT((bp->b_bufsize & (vn->sc_secsize - 1)) == 0, + ("vnstrategy: buffer %p to small for physio", bp)); + + if ((bp->b_flags & B_FREEBUF) && TESTOPT(vn, VN_RESERVE)) { + biodone(bp); + } else { + vm_pager_strategy(vn->sc_object, bp); + } } else { bp->b_flags |= B_ERROR; bp->b_error = EINVAL; @@ -504,13 +528,20 @@ vniocattach_file(vn, vio, dev, flag, p) VOP_UNLOCK(nd.ni_vp, 0, p); vn->sc_secsize = DEV_BSIZE; vn->sc_vp = nd.ni_vp; - vn->sc_size = vattr.va_size / vn->sc_secsize; /* note truncation */ + + /* + * If the size is specified, override the file attributes. Note that + * the vn_size argument is in PAGE_SIZE sized blocks. + */ + if (vio->vn_size) + vn->sc_size = (quad_t)vio->vn_size * PAGE_SIZE / vn->sc_secsize; + else + vn->sc_size = vattr.va_size / vn->sc_secsize; error = vnsetcred(vn, p->p_ucred); if (error) { (void) vn_close(nd.ni_vp, flags, p->p_ucred, p); return(error); } - dev->si_bsize_phys = vn->sc_secsize; vn->sc_flags |= VNF_INITED; if (flags == FREAD) vn->sc_flags |= VNF_READONLY; @@ -571,6 +602,13 @@ vniocattach_swap(vn, vio, dev, flag, p) vn->sc_size = vio->vn_size; vn->sc_object = vm_pager_allocate(OBJT_SWAP, NULL, vn->sc_secsize * (vm_ooffset_t)vio->vn_size, VM_PROT_DEFAULT, 0); + IFOPT(vn, VN_RESERVE) { + if (swap_pager_reserve(vn->sc_object, 0, vn->sc_size) < 0) { + vm_pager_deallocate(vn->sc_object); + vn->sc_object = NULL; + return(EDOM); + } + } vn->sc_flags |= VNF_INITED; error = vnsetcred(vn, p->p_ucred); diff --git a/sys/sys/mdioctl.h b/sys/sys/mdioctl.h index 4f2e9371ce967..b283741828210 100644 --- a/sys/sys/mdioctl.h +++ b/sys/sys/mdioctl.h @@ -38,6 +38,8 @@ * from: Utah $Hdr: fdioctl.h 1.1 90/07/09$ * * @(#)vnioctl.h 8.1 (Berkeley) 6/10/93 + * + * $FreeBSD$ */ #ifndef _SYS_VNIOCTL_H_ @@ -72,5 +74,6 @@ struct vn_ioctl { #define VN_DEBUG 0x4 /* Debug data in vn driver */ #define VN_IO 0x8 /* Debug I/O in vn driver */ #define VN_DONTCLUSTER 0x10 /* Don't cluster */ +#define VN_RESERVE 0x20 /* Pre-reserve swap */ #endif /* _SYS_VNIOCTL_H_*/ diff --git a/sys/sys/vnioctl.h b/sys/sys/vnioctl.h index 4f2e9371ce967..b283741828210 100644 --- a/sys/sys/vnioctl.h +++ b/sys/sys/vnioctl.h @@ -38,6 +38,8 @@ * from: Utah $Hdr: fdioctl.h 1.1 90/07/09$ * * @(#)vnioctl.h 8.1 (Berkeley) 6/10/93 + * + * $FreeBSD$ */ #ifndef _SYS_VNIOCTL_H_ @@ -72,5 +74,6 @@ struct vn_ioctl { #define VN_DEBUG 0x4 /* Debug data in vn driver */ #define VN_IO 0x8 /* Debug I/O in vn driver */ #define VN_DONTCLUSTER 0x10 /* Don't cluster */ +#define VN_RESERVE 0x20 /* Pre-reserve swap */ #endif /* _SYS_VNIOCTL_H_*/ |
