From b07b491ee68d156b2162c24f16fd4667d1c6700f Mon Sep 17 00:00:00 2001 From: dfr Date: Mon, 19 May 1997 14:36:56 +0000 Subject: [PATCH] Fix a few bugs with NFS and mmap caused by NFS' use of b_validoff and b_validend. The changes to vfs_bio.c are a bit ugly but hopefully can be tidied up later by a slight redesign. PR: kern/2573, kern/2754, kern/3046 (possibly) Reviewed by: dyson --- sys/kern/vfs_bio.c | 152 +++++++++++++++++++++++++------------ sys/nfs/nfs.h | 4 +- sys/nfs/nfs_bio.c | 85 ++++++++++++++++++++- sys/nfs/nfs_vnops.c | 9 ++- sys/nfs/nfsnode.h | 3 +- sys/nfsclient/nfs.h | 4 +- sys/nfsclient/nfs_bio.c | 85 ++++++++++++++++++++- sys/nfsclient/nfs_vnops.c | 9 ++- sys/nfsclient/nfsargs.h | 4 +- sys/nfsclient/nfsnode.h | 3 +- sys/nfsclient/nfsstats.h | 4 +- sys/nfsserver/nfs.h | 4 +- sys/nfsserver/nfsrvstats.h | 4 +- sys/vm/vm_fault.c | 4 +- sys/vm/vnode_pager.c | 7 +- 15 files changed, 302 insertions(+), 79 deletions(-) diff --git a/sys/kern/vfs_bio.c b/sys/kern/vfs_bio.c index d5f6a9d047b4..0023dcad97c9 100644 --- a/sys/kern/vfs_bio.c +++ b/sys/kern/vfs_bio.c @@ -18,7 +18,7 @@ * 5. Modifications may be freely made to this file if the above conditions * are met. * - * $Id: vfs_bio.c,v 1.114 1997/04/13 03:33:25 dyson Exp $ + * $Id: vfs_bio.c,v 1.115 1997/05/10 09:09:42 joerg Exp $ */ /* @@ -77,6 +77,10 @@ static void vm_hold_free_pages(struct buf * bp, vm_offset_t from, vm_offset_t to); static void vm_hold_load_pages(struct buf * bp, vm_offset_t from, vm_offset_t to); +static void vfs_buf_set_valid(struct buf *bp, vm_ooffset_t foff, + vm_offset_t off, vm_offset_t size, + vm_page_t m); +static void vfs_page_set_valid(struct buf *bp, vm_offset_t off, vm_page_t m); static void vfs_clean_pages(struct buf * bp); static void vfs_setdirty(struct buf *bp); static void vfs_vmio_release(struct buf *bp); @@ -501,8 +505,19 @@ brelse(struct buf * bp) * constituted, so the B_INVAL flag is used to *invalidate* the buffer, * but the VM object is kept around. The B_NOCACHE flag is used to * invalidate the pages in the VM object. + * + * If the buffer is a partially filled NFS buffer, keep it + * since invalidating it now will lose informatio. The valid + * flags in the vm_pages have only DEV_BSIZE resolution but + * the b_validoff, b_validend fields have byte resolution. + * This can avoid unnecessary re-reads of the buffer. */ - if (bp->b_flags & B_VMIO) { + if ((bp->b_flags & B_VMIO) + && (bp->b_vp->v_tag != VT_NFS + || (bp->b_flags & (B_NOCACHE | B_INVAL | B_ERROR)) + || bp->b_validend == 0 + || (bp->b_validoff == 0 + && bp->b_validend == bp->b_bufsize))) { vm_ooffset_t foff; vm_object_t obj; int i, resid; @@ -1418,6 +1433,7 @@ allocbuf(struct buf * bp, int size) curbpnpages = bp->b_npages; doretry: bp->b_flags |= B_CACHE; + bp->b_validoff = bp->b_validend = 0; for (toff = 0; toff < newbsize; toff += tinc) { int bytesinpage; @@ -1433,12 +1449,8 @@ allocbuf(struct buf * bp, int size) bytesinpage = tinc; if (tinc > (newbsize - toff)) bytesinpage = newbsize - toff; - if ((bp->b_flags & B_CACHE) && - !vm_page_is_valid(m, - (vm_offset_t) ((toff + off) & PAGE_MASK), - bytesinpage)) { - bp->b_flags &= ~B_CACHE; - } + if (bp->b_flags & B_CACHE) + vfs_buf_set_valid(bp, off, toff, bytesinpage, m); continue; } m = vm_page_lookup(obj, objoff); @@ -1474,17 +1486,15 @@ allocbuf(struct buf * bp, int size) bytesinpage = tinc; if (tinc > (newbsize - toff)) bytesinpage = newbsize - toff; - if ((bp->b_flags & B_CACHE) && - !vm_page_is_valid(m, - (vm_offset_t) ((toff + off) & PAGE_MASK), - bytesinpage)) { - bp->b_flags &= ~B_CACHE; - } + if (bp->b_flags & B_CACHE) + vfs_buf_set_valid(bp, off, toff, bytesinpage, m); vm_page_wire(m); } bp->b_pages[pageindex] = m; curbpnpages = pageindex + 1; } + if (vp->v_tag == VT_NFS && bp->b_validend == 0) + bp->b_flags &= ~B_CACHE; bp->b_data = (caddr_t) trunc_page(bp->b_data); bp->b_npages = curbpnpages; pmap_qenter((vm_offset_t) bp->b_data, @@ -1562,7 +1572,7 @@ biodone(register struct buf * bp) } if (bp->b_flags & B_VMIO) { int i, resid; - vm_ooffset_t foff; + vm_ooffset_t foff, bfoff; vm_page_t m; vm_object_t obj; int iosize; @@ -1572,6 +1582,7 @@ biodone(register struct buf * bp) foff = (vm_ooffset_t) DEV_BSIZE * bp->b_lblkno; else foff = (vm_ooffset_t) vp->v_mount->mnt_stat.f_iosize * bp->b_lblkno; + bfoff = foff; obj = vp->v_object; if (!obj) { panic("biodone: no object"); @@ -1613,8 +1624,7 @@ biodone(register struct buf * bp) * here in the read case. */ if ((bp->b_flags & B_READ) && !bogusflag && resid > 0) { - vm_page_set_validclean(m, - (vm_offset_t) (foff & PAGE_MASK), resid); + vfs_page_set_valid(bp, foff - bfoff, m); } /* @@ -1760,6 +1770,73 @@ vfs_unbusy_pages(struct buf * bp) } } +/* + * Set NFS' b_validoff and b_validend fields from the valid bits + * of a page. If the consumer is not NFS, and the page is not + * valid for the entire range, clear the B_CACHE flag to force + * the consumer to re-read the page. + */ +static void +vfs_buf_set_valid(struct buf *bp, + vm_ooffset_t foff, vm_offset_t off, vm_offset_t size, + vm_page_t m) +{ + if (bp->b_vp->v_tag == VT_NFS) { + vm_offset_t svalid, evalid; + int validbits = m->valid; + + /* + * This only bothers with the first valid range in the + * page. + */ + svalid = off; + while (validbits && !(validbits & 1)) { + svalid += DEV_BSIZE; + validbits >>= 1; + } + evalid = svalid; + while (validbits & 1) { + evalid += DEV_BSIZE; + validbits >>= 1; + } + /* + * Make sure this range is contiguous with the range + * built up from previous pages. If not, then we will + * just use the range from the previous pages. + */ + if (svalid == bp->b_validend) { + bp->b_validoff = min(bp->b_validoff, svalid); + bp->b_validend = max(bp->b_validend, evalid); + } + } else if (!vm_page_is_valid(m, + (vm_offset_t) ((foff + off) & PAGE_MASK), + size)) { + bp->b_flags &= ~B_CACHE; + } +} + +/* + * Set the valid bits in a page, taking care of the b_validoff, + * b_validend fields which NFS uses to optimise small reads. Off is + * the offset of the page within the buf. + */ +static void +vfs_page_set_valid(struct buf *bp, vm_offset_t off, vm_page_t m) +{ + struct vnode *vp = bp->b_vp; + vm_offset_t soff, eoff; + + soff = off; + eoff = min(off + PAGE_SIZE, bp->b_bufsize); + if (vp->v_tag == VT_NFS) { + soff = max((bp->b_validoff + DEV_BSIZE - 1) & -DEV_BSIZE, soff); + eoff = min(bp->b_validend & -DEV_BSIZE, eoff); + } + vm_page_set_invalid(m, 0, PAGE_SIZE); + if (eoff > soff) + vm_page_set_validclean(m, soff, eoff - soff); +} + /* * This routine is called before a device strategy routine. * It is used to tell the VM system that paging I/O is in @@ -1775,36 +1852,25 @@ vfs_busy_pages(struct buf * bp, int clear_modify) if (bp->b_flags & B_VMIO) { vm_object_t obj = bp->b_vp->v_object; - vm_ooffset_t foff; - int iocount = bp->b_bufsize; + vm_offset_t off; - if (bp->b_vp->v_type == VBLK) - foff = (vm_ooffset_t) DEV_BSIZE * bp->b_lblkno; - else - foff = (vm_ooffset_t) bp->b_vp->v_mount->mnt_stat.f_iosize * bp->b_lblkno; vfs_setdirty(bp); - for (i = 0; i < bp->b_npages; i++) { + for (i = 0, off = 0; i < bp->b_npages; i++, off += PAGE_SIZE) { vm_page_t m = bp->b_pages[i]; - int resid = IDX_TO_OFF(m->pindex + 1) - foff; - if (resid > iocount) - resid = iocount; if ((bp->b_flags & B_CLUSTER) == 0) { obj->paging_in_progress++; m->busy++; } vm_page_protect(m, VM_PROT_NONE); - if (clear_modify) { - vm_page_set_validclean(m, - (vm_offset_t) (foff & PAGE_MASK), resid); - } else if (bp->b_bcount >= PAGE_SIZE) { + if (clear_modify) + vfs_page_set_valid(bp, off, m); + else if (bp->b_bcount >= PAGE_SIZE) { if (m->valid && (bp->b_flags & B_CACHE) == 0) { bp->b_pages[i] = bogus_page; pmap_qenter(trunc_page(bp->b_data), bp->b_pages, bp->b_npages); } } - foff += resid; - iocount -= resid; } } } @@ -1820,26 +1886,12 @@ vfs_clean_pages(struct buf * bp) int i; if (bp->b_flags & B_VMIO) { - vm_ooffset_t foff; - int iocount = bp->b_bufsize; + vm_offset_t off; - if (bp->b_vp->v_type == VBLK) - foff = (vm_ooffset_t) DEV_BSIZE * bp->b_lblkno; - else - foff = (vm_ooffset_t) bp->b_vp->v_mount->mnt_stat.f_iosize * bp->b_lblkno; - - for (i = 0; i < bp->b_npages; i++) { + for (i = 0, off = 0; i < bp->b_npages; i++, off += PAGE_SIZE) { vm_page_t m = bp->b_pages[i]; - int resid = IDX_TO_OFF(m->pindex + 1) - foff; - if (resid > iocount) - resid = iocount; - if (resid > 0) { - vm_page_set_validclean(m, - ((vm_offset_t) foff & PAGE_MASK), resid); - } - foff += resid; - iocount -= resid; + vfs_page_set_valid(bp, off, m); } } } diff --git a/sys/nfs/nfs.h b/sys/nfs/nfs.h index 406024ef0875..2dc19c176136 100644 --- a/sys/nfs/nfs.h +++ b/sys/nfs/nfs.h @@ -34,7 +34,7 @@ * SUCH DAMAGE. * * @(#)nfs.h 8.4 (Berkeley) 5/1/95 - * $Id: nfs.h,v 1.25 1997/05/10 16:12:02 dfr Exp $ + * $Id: nfs.h,v 1.26 1997/05/13 17:25:44 dfr Exp $ */ #ifndef _NFS_NFS_H_ @@ -583,7 +583,7 @@ int nfs_connect __P((struct nfsmount *,struct nfsreq *)); void nfs_disconnect __P((struct nfsmount *)); int nfs_getattrcache __P((struct vnode *,struct vattr *)); int nfsm_strtmbuf __P((struct mbuf **,char **,char *,long)); -int nfs_bioread __P((struct vnode *,struct uio *,int,struct ucred *)); +int nfs_bioread __P((struct vnode *,struct uio *,int,struct ucred *, int getpages)); int nfsm_uiotombuf __P((struct uio *,struct mbuf **,int,caddr_t *)); void nfsrv_init __P((int)); void nfs_clearcommit __P((struct mount *)); diff --git a/sys/nfs/nfs_bio.c b/sys/nfs/nfs_bio.c index bc550fc071fe..2a02371a7ac9 100644 --- a/sys/nfs/nfs_bio.c +++ b/sys/nfs/nfs_bio.c @@ -34,7 +34,7 @@ * SUCH DAMAGE. * * @(#)nfs_bio.c 8.9 (Berkeley) 3/30/95 - * $Id: nfs_bio.c,v 1.36 1997/04/19 14:28:36 dfr Exp $ + * $Id: nfs_bio.c,v 1.37 1997/05/13 19:41:32 dfr Exp $ */ @@ -52,6 +52,11 @@ #include #include #include +#include +#include +#include +#include +#include #include #include @@ -66,16 +71,71 @@ static struct buf *nfs_getcacheblk __P((struct vnode *vp, daddr_t bn, int size, extern int nfs_numasync; extern struct nfsstats nfsstats; +/* + * Vnode op for VM getpages. + */ +int +nfs_getpages(ap) + struct vop_getpages_args *ap; +{ + int i, bsize; + vm_object_t obj; + int pcount; + struct uio auio; + struct iovec aiov; + int error; + vm_page_t m; + + if (!(ap->a_vp->v_flag & VVMIO)) { + printf("nfs_getpages: called with non-VMIO vnode??\n"); + return EOPNOTSUPP; + } + + pcount = round_page(ap->a_count) / PAGE_SIZE; + + obj = ap->a_m[ap->a_reqpage]->object; + bsize = ap->a_vp->v_mount->mnt_stat.f_iosize; + + for (i = 0; i < pcount; i++) { + if (i != ap->a_reqpage) { + vnode_pager_freepage(ap->a_m[i]); + } + } + m = ap->a_m[ap->a_reqpage]; + + m->busy++; + m->flags &= ~PG_BUSY; + + auio.uio_iov = &aiov; + auio.uio_iovcnt = 1; + aiov.iov_base = 0; + aiov.iov_len = MAXBSIZE; + auio.uio_resid = MAXBSIZE; + auio.uio_offset = IDX_TO_OFF(m->pindex); + auio.uio_segflg = UIO_NOCOPY; + auio.uio_rw = UIO_READ; + auio.uio_procp = curproc; + error = nfs_bioread(ap->a_vp, &auio, IO_NODELOCKED, curproc->p_ucred, 1); + + m->flags |= PG_BUSY; + m->busy--; + + if (error && (auio.uio_resid == MAXBSIZE)) + return VM_PAGER_ERROR; + return 0; +} + /* * Vnode op for read using bio * Any similarity to readip() is purely coincidental */ int -nfs_bioread(vp, uio, ioflag, cred) +nfs_bioread(vp, uio, ioflag, cred, getpages) register struct vnode *vp; register struct uio *uio; int ioflag; struct ucred *cred; + int getpages; { register struct nfsnode *np = VTONFS(vp); register int biosize, diff, i; @@ -235,6 +295,27 @@ nfs_bioread(vp, uio, ioflag, cred) bp = nfs_getcacheblk(vp, lbn, bufsize, p); if (!bp) return (EINTR); + /* + * If we are being called from nfs_getpages, we must + * make sure the buffer is a vmio buffer. The vp will + * already be setup for vmio but there may be some old + * non-vmio buffers attached to it. + */ + if (getpages && !(bp->b_flags & B_VMIO)) { +#ifdef DIAGNOSTIC + printf("nfs_bioread: non vmio buf found, discarding\n"); +#endif + bp->b_flags |= B_NOCACHE; + bp->b_flags |= B_INVAFTERWRITE; + if (bp->b_dirtyend > 0) { + if ((bp->b_flags & B_DELWRI) == 0) + panic("nfsbioread"); + if (VOP_BWRITE(bp) == EINTR) + return (EINTR); + } else + brelse(bp); + goto again; + } if ((bp->b_flags & B_CACHE) == 0) { bp->b_flags |= B_READ; bp->b_flags &= ~(B_DONE | B_ERROR | B_INVAL); diff --git a/sys/nfs/nfs_vnops.c b/sys/nfs/nfs_vnops.c index d3ec002b6551..ff5ad943e67e 100644 --- a/sys/nfs/nfs_vnops.c +++ b/sys/nfs/nfs_vnops.c @@ -34,7 +34,7 @@ * SUCH DAMAGE. * * @(#)nfs_vnops.c 8.16 (Berkeley) 5/27/95 - * $Id: nfs_vnops.c,v 1.48 1997/05/09 13:18:42 dfr Exp $ + * $Id: nfs_vnops.c,v 1.49 1997/05/17 18:32:52 phk Exp $ */ @@ -184,6 +184,7 @@ static struct vnodeopv_entry_desc nfsv2_vnodeop_entries[] = { { &vop_truncate_desc, (vop_t *)nfs_truncate }, /* truncate */ { &vop_update_desc, (vop_t *)nfs_update }, /* update */ { &vop_bwrite_desc, (vop_t *)nfs_bwrite }, /* bwrite */ + { &vop_getpages_desc, (vop_t *)nfs_getpages }, /* getpages */ { NULL, NULL } }; static struct vnodeopv_desc nfsv2_vnodeop_opv_desc = @@ -1035,7 +1036,7 @@ nfs_read(ap) if (vp->v_type != VREG) return (EPERM); - return (nfs_bioread(vp, ap->a_uio, ap->a_ioflag, ap->a_cred)); + return (nfs_bioread(vp, ap->a_uio, ap->a_ioflag, ap->a_cred, 0)); } /* @@ -1053,7 +1054,7 @@ nfs_readlink(ap) if (vp->v_type != VLNK) return (EPERM); - return (nfs_bioread(vp, ap->a_uio, 0, ap->a_cred)); + return (nfs_bioread(vp, ap->a_uio, 0, ap->a_cred, 0)); } /* @@ -2055,7 +2056,7 @@ nfs_readdir(ap) * Call nfs_bioread() to do the real work. */ tresid = uio->uio_resid; - error = nfs_bioread(vp, uio, 0, ap->a_cred); + error = nfs_bioread(vp, uio, 0, ap->a_cred, 0); if (!error && uio->uio_resid == tresid) nfsstats.direofcache_misses++; diff --git a/sys/nfs/nfsnode.h b/sys/nfs/nfsnode.h index 540d80387863..12553ef0c555 100644 --- a/sys/nfs/nfsnode.h +++ b/sys/nfs/nfsnode.h @@ -34,7 +34,7 @@ * SUCH DAMAGE. * * @(#)nfsnode.h 8.9 (Berkeley) 5/14/95 - * $Id: nfsnode.h,v 1.19 1997/02/22 09:42:49 peter Exp $ + * $Id: nfsnode.h,v 1.20 1997/04/04 17:49:35 dfr Exp $ */ @@ -161,6 +161,7 @@ extern vop_t **spec_nfsv2nodeop_p; /* * Prototypes for NFS vnode operations */ +int nfs_getpages __P((struct vop_getpages_args *)); int nfs_write __P((struct vop_write_args *)); #define nfs_lease_check ((int (*) __P((struct vop_lease_args *)))nullop) int nqnfs_vop_lease_check __P((struct vop_lease_args *)); diff --git a/sys/nfsclient/nfs.h b/sys/nfsclient/nfs.h index 406024ef0875..2dc19c176136 100644 --- a/sys/nfsclient/nfs.h +++ b/sys/nfsclient/nfs.h @@ -34,7 +34,7 @@ * SUCH DAMAGE. * * @(#)nfs.h 8.4 (Berkeley) 5/1/95 - * $Id: nfs.h,v 1.25 1997/05/10 16:12:02 dfr Exp $ + * $Id: nfs.h,v 1.26 1997/05/13 17:25:44 dfr Exp $ */ #ifndef _NFS_NFS_H_ @@ -583,7 +583,7 @@ int nfs_connect __P((struct nfsmount *,struct nfsreq *)); void nfs_disconnect __P((struct nfsmount *)); int nfs_getattrcache __P((struct vnode *,struct vattr *)); int nfsm_strtmbuf __P((struct mbuf **,char **,char *,long)); -int nfs_bioread __P((struct vnode *,struct uio *,int,struct ucred *)); +int nfs_bioread __P((struct vnode *,struct uio *,int,struct ucred *, int getpages)); int nfsm_uiotombuf __P((struct uio *,struct mbuf **,int,caddr_t *)); void nfsrv_init __P((int)); void nfs_clearcommit __P((struct mount *)); diff --git a/sys/nfsclient/nfs_bio.c b/sys/nfsclient/nfs_bio.c index bc550fc071fe..2a02371a7ac9 100644 --- a/sys/nfsclient/nfs_bio.c +++ b/sys/nfsclient/nfs_bio.c @@ -34,7 +34,7 @@ * SUCH DAMAGE. * * @(#)nfs_bio.c 8.9 (Berkeley) 3/30/95 - * $Id: nfs_bio.c,v 1.36 1997/04/19 14:28:36 dfr Exp $ + * $Id: nfs_bio.c,v 1.37 1997/05/13 19:41:32 dfr Exp $ */ @@ -52,6 +52,11 @@ #include #include #include +#include +#include +#include +#include +#include #include #include @@ -66,16 +71,71 @@ static struct buf *nfs_getcacheblk __P((struct vnode *vp, daddr_t bn, int size, extern int nfs_numasync; extern struct nfsstats nfsstats; +/* + * Vnode op for VM getpages. + */ +int +nfs_getpages(ap) + struct vop_getpages_args *ap; +{ + int i, bsize; + vm_object_t obj; + int pcount; + struct uio auio; + struct iovec aiov; + int error; + vm_page_t m; + + if (!(ap->a_vp->v_flag & VVMIO)) { + printf("nfs_getpages: called with non-VMIO vnode??\n"); + return EOPNOTSUPP; + } + + pcount = round_page(ap->a_count) / PAGE_SIZE; + + obj = ap->a_m[ap->a_reqpage]->object; + bsize = ap->a_vp->v_mount->mnt_stat.f_iosize; + + for (i = 0; i < pcount; i++) { + if (i != ap->a_reqpage) { + vnode_pager_freepage(ap->a_m[i]); + } + } + m = ap->a_m[ap->a_reqpage]; + + m->busy++; + m->flags &= ~PG_BUSY; + + auio.uio_iov = &aiov; + auio.uio_iovcnt = 1; + aiov.iov_base = 0; + aiov.iov_len = MAXBSIZE; + auio.uio_resid = MAXBSIZE; + auio.uio_offset = IDX_TO_OFF(m->pindex); + auio.uio_segflg = UIO_NOCOPY; + auio.uio_rw = UIO_READ; + auio.uio_procp = curproc; + error = nfs_bioread(ap->a_vp, &auio, IO_NODELOCKED, curproc->p_ucred, 1); + + m->flags |= PG_BUSY; + m->busy--; + + if (error && (auio.uio_resid == MAXBSIZE)) + return VM_PAGER_ERROR; + return 0; +} + /* * Vnode op for read using bio * Any similarity to readip() is purely coincidental */ int -nfs_bioread(vp, uio, ioflag, cred) +nfs_bioread(vp, uio, ioflag, cred, getpages) register struct vnode *vp; register struct uio *uio; int ioflag; struct ucred *cred; + int getpages; { register struct nfsnode *np = VTONFS(vp); register int biosize, diff, i; @@ -235,6 +295,27 @@ nfs_bioread(vp, uio, ioflag, cred) bp = nfs_getcacheblk(vp, lbn, bufsize, p); if (!bp) return (EINTR); + /* + * If we are being called from nfs_getpages, we must + * make sure the buffer is a vmio buffer. The vp will + * already be setup for vmio but there may be some old + * non-vmio buffers attached to it. + */ + if (getpages && !(bp->b_flags & B_VMIO)) { +#ifdef DIAGNOSTIC + printf("nfs_bioread: non vmio buf found, discarding\n"); +#endif + bp->b_flags |= B_NOCACHE; + bp->b_flags |= B_INVAFTERWRITE; + if (bp->b_dirtyend > 0) { + if ((bp->b_flags & B_DELWRI) == 0) + panic("nfsbioread"); + if (VOP_BWRITE(bp) == EINTR) + return (EINTR); + } else + brelse(bp); + goto again; + } if ((bp->b_flags & B_CACHE) == 0) { bp->b_flags |= B_READ; bp->b_flags &= ~(B_DONE | B_ERROR | B_INVAL); diff --git a/sys/nfsclient/nfs_vnops.c b/sys/nfsclient/nfs_vnops.c index d3ec002b6551..ff5ad943e67e 100644 --- a/sys/nfsclient/nfs_vnops.c +++ b/sys/nfsclient/nfs_vnops.c @@ -34,7 +34,7 @@ * SUCH DAMAGE. * * @(#)nfs_vnops.c 8.16 (Berkeley) 5/27/95 - * $Id: nfs_vnops.c,v 1.48 1997/05/09 13:18:42 dfr Exp $ + * $Id: nfs_vnops.c,v 1.49 1997/05/17 18:32:52 phk Exp $ */ @@ -184,6 +184,7 @@ static struct vnodeopv_entry_desc nfsv2_vnodeop_entries[] = { { &vop_truncate_desc, (vop_t *)nfs_truncate }, /* truncate */ { &vop_update_desc, (vop_t *)nfs_update }, /* update */ { &vop_bwrite_desc, (vop_t *)nfs_bwrite }, /* bwrite */ + { &vop_getpages_desc, (vop_t *)nfs_getpages }, /* getpages */ { NULL, NULL } }; static struct vnodeopv_desc nfsv2_vnodeop_opv_desc = @@ -1035,7 +1036,7 @@ nfs_read(ap) if (vp->v_type != VREG) return (EPERM); - return (nfs_bioread(vp, ap->a_uio, ap->a_ioflag, ap->a_cred)); + return (nfs_bioread(vp, ap->a_uio, ap->a_ioflag, ap->a_cred, 0)); } /* @@ -1053,7 +1054,7 @@ nfs_readlink(ap) if (vp->v_type != VLNK) return (EPERM); - return (nfs_bioread(vp, ap->a_uio, 0, ap->a_cred)); + return (nfs_bioread(vp, ap->a_uio, 0, ap->a_cred, 0)); } /* @@ -2055,7 +2056,7 @@ nfs_readdir(ap) * Call nfs_bioread() to do the real work. */ tresid = uio->uio_resid; - error = nfs_bioread(vp, uio, 0, ap->a_cred); + error = nfs_bioread(vp, uio, 0, ap->a_cred, 0); if (!error && uio->uio_resid == tresid) nfsstats.direofcache_misses++; diff --git a/sys/nfsclient/nfsargs.h b/sys/nfsclient/nfsargs.h index 406024ef0875..2dc19c176136 100644 --- a/sys/nfsclient/nfsargs.h +++ b/sys/nfsclient/nfsargs.h @@ -34,7 +34,7 @@ * SUCH DAMAGE. * * @(#)nfs.h 8.4 (Berkeley) 5/1/95 - * $Id: nfs.h,v 1.25 1997/05/10 16:12:02 dfr Exp $ + * $Id: nfs.h,v 1.26 1997/05/13 17:25:44 dfr Exp $ */ #ifndef _NFS_NFS_H_ @@ -583,7 +583,7 @@ int nfs_connect __P((struct nfsmount *,struct nfsreq *)); void nfs_disconnect __P((struct nfsmount *)); int nfs_getattrcache __P((struct vnode *,struct vattr *)); int nfsm_strtmbuf __P((struct mbuf **,char **,char *,long)); -int nfs_bioread __P((struct vnode *,struct uio *,int,struct ucred *)); +int nfs_bioread __P((struct vnode *,struct uio *,int,struct ucred *, int getpages)); int nfsm_uiotombuf __P((struct uio *,struct mbuf **,int,caddr_t *)); void nfsrv_init __P((int)); void nfs_clearcommit __P((struct mount *)); diff --git a/sys/nfsclient/nfsnode.h b/sys/nfsclient/nfsnode.h index 540d80387863..12553ef0c555 100644 --- a/sys/nfsclient/nfsnode.h +++ b/sys/nfsclient/nfsnode.h @@ -34,7 +34,7 @@ * SUCH DAMAGE. * * @(#)nfsnode.h 8.9 (Berkeley) 5/14/95 - * $Id: nfsnode.h,v 1.19 1997/02/22 09:42:49 peter Exp $ + * $Id: nfsnode.h,v 1.20 1997/04/04 17:49:35 dfr Exp $ */ @@ -161,6 +161,7 @@ extern vop_t **spec_nfsv2nodeop_p; /* * Prototypes for NFS vnode operations */ +int nfs_getpages __P((struct vop_getpages_args *)); int nfs_write __P((struct vop_write_args *)); #define nfs_lease_check ((int (*) __P((struct vop_lease_args *)))nullop) int nqnfs_vop_lease_check __P((struct vop_lease_args *)); diff --git a/sys/nfsclient/nfsstats.h b/sys/nfsclient/nfsstats.h index 406024ef0875..2dc19c176136 100644 --- a/sys/nfsclient/nfsstats.h +++ b/sys/nfsclient/nfsstats.h @@ -34,7 +34,7 @@ * SUCH DAMAGE. * * @(#)nfs.h 8.4 (Berkeley) 5/1/95 - * $Id: nfs.h,v 1.25 1997/05/10 16:12:02 dfr Exp $ + * $Id: nfs.h,v 1.26 1997/05/13 17:25:44 dfr Exp $ */ #ifndef _NFS_NFS_H_ @@ -583,7 +583,7 @@ int nfs_connect __P((struct nfsmount *,struct nfsreq *)); void nfs_disconnect __P((struct nfsmount *)); int nfs_getattrcache __P((struct vnode *,struct vattr *)); int nfsm_strtmbuf __P((struct mbuf **,char **,char *,long)); -int nfs_bioread __P((struct vnode *,struct uio *,int,struct ucred *)); +int nfs_bioread __P((struct vnode *,struct uio *,int,struct ucred *, int getpages)); int nfsm_uiotombuf __P((struct uio *,struct mbuf **,int,caddr_t *)); void nfsrv_init __P((int)); void nfs_clearcommit __P((struct mount *)); diff --git a/sys/nfsserver/nfs.h b/sys/nfsserver/nfs.h index 406024ef0875..2dc19c176136 100644 --- a/sys/nfsserver/nfs.h +++ b/sys/nfsserver/nfs.h @@ -34,7 +34,7 @@ * SUCH DAMAGE. * * @(#)nfs.h 8.4 (Berkeley) 5/1/95 - * $Id: nfs.h,v 1.25 1997/05/10 16:12:02 dfr Exp $ + * $Id: nfs.h,v 1.26 1997/05/13 17:25:44 dfr Exp $ */ #ifndef _NFS_NFS_H_ @@ -583,7 +583,7 @@ int nfs_connect __P((struct nfsmount *,struct nfsreq *)); void nfs_disconnect __P((struct nfsmount *)); int nfs_getattrcache __P((struct vnode *,struct vattr *)); int nfsm_strtmbuf __P((struct mbuf **,char **,char *,long)); -int nfs_bioread __P((struct vnode *,struct uio *,int,struct ucred *)); +int nfs_bioread __P((struct vnode *,struct uio *,int,struct ucred *, int getpages)); int nfsm_uiotombuf __P((struct uio *,struct mbuf **,int,caddr_t *)); void nfsrv_init __P((int)); void nfs_clearcommit __P((struct mount *)); diff --git a/sys/nfsserver/nfsrvstats.h b/sys/nfsserver/nfsrvstats.h index 406024ef0875..2dc19c176136 100644 --- a/sys/nfsserver/nfsrvstats.h +++ b/sys/nfsserver/nfsrvstats.h @@ -34,7 +34,7 @@ * SUCH DAMAGE. * * @(#)nfs.h 8.4 (Berkeley) 5/1/95 - * $Id: nfs.h,v 1.25 1997/05/10 16:12:02 dfr Exp $ + * $Id: nfs.h,v 1.26 1997/05/13 17:25:44 dfr Exp $ */ #ifndef _NFS_NFS_H_ @@ -583,7 +583,7 @@ int nfs_connect __P((struct nfsmount *,struct nfsreq *)); void nfs_disconnect __P((struct nfsmount *)); int nfs_getattrcache __P((struct vnode *,struct vattr *)); int nfsm_strtmbuf __P((struct mbuf **,char **,char *,long)); -int nfs_bioread __P((struct vnode *,struct uio *,int,struct ucred *)); +int nfs_bioread __P((struct vnode *,struct uio *,int,struct ucred *, int getpages)); int nfsm_uiotombuf __P((struct uio *,struct mbuf **,int,caddr_t *)); void nfsrv_init __P((int)); void nfs_clearcommit __P((struct mount *)); diff --git a/sys/vm/vm_fault.c b/sys/vm/vm_fault.c index c96c42a4db85..c138ff271c80 100644 --- a/sys/vm/vm_fault.c +++ b/sys/vm/vm_fault.c @@ -66,7 +66,7 @@ * any improvements or extensions that they make and grant Carnegie the * rights to redistribute these changes. * - * $Id: vm_fault.c,v 1.67 1997/04/06 02:29:41 dyson Exp $ + * $Id: vm_fault.c,v 1.68 1997/04/06 16:16:11 peter Exp $ */ /* @@ -326,7 +326,7 @@ RetryFault:; m->flags |= PG_BUSY; - if (m->valid && + if (/*m->valid && */ ((m->valid & VM_PAGE_BITS_ALL) != VM_PAGE_BITS_ALL) && m->object != kernel_object && m->object != kmem_object) { goto readrest; diff --git a/sys/vm/vnode_pager.c b/sys/vm/vnode_pager.c index e4d7404888a0..d2583513144a 100644 --- a/sys/vm/vnode_pager.c +++ b/sys/vm/vnode_pager.c @@ -38,7 +38,7 @@ * SUCH DAMAGE. * * from: @(#)vnode_pager.c 7.5 (Berkeley) 4/20/91 - * $Id: vnode_pager.c,v 1.69 1997/02/22 09:48:42 peter Exp $ + * $Id: vnode_pager.c,v 1.70 1997/03/08 04:33:47 dyson Exp $ */ /* @@ -692,7 +692,12 @@ vnode_pager_leaf_getpages(object, m, count, reqpage) /* * if ANY DEV_BSIZE blocks are valid on a large filesystem block * then, the entire page is valid -- + * XXX no it isn't */ + + if (m[reqpage]->valid != VM_PAGE_BITS_ALL) + m[reqpage]->valid = 0; + if (m[reqpage]->valid) { m[reqpage]->valid = VM_PAGE_BITS_ALL; for (i = 0; i < count; i++) {