X-Git-Url: https://git.saurik.com/apple/xnu.git/blobdiff_plain/fa4905b191e0d16b0fffd53bd565eca71d01fae0..43866e378188c25dd1e2208016ab3cbeb086ae6c:/bsd/nfs/nfs_bio.c diff --git a/bsd/nfs/nfs_bio.c b/bsd/nfs/nfs_bio.c index 926de3419..7f41efe13 100644 --- a/bsd/nfs/nfs_bio.c +++ b/bsd/nfs/nfs_bio.c @@ -3,19 +3,22 @@ * * @APPLE_LICENSE_HEADER_START@ * - * The contents of this file constitute Original Code as defined in and - * are subject to the Apple Public Source License Version 1.1 (the - * "License"). You may not use this file except in compliance with the - * License. Please obtain a copy of the License at - * http://www.apple.com/publicsource and read it before using this file. + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. * - * This Original Code and all software distributed under the License are - * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the - * License for the specific language governing rights and limitations - * under the License. + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. * * @APPLE_LICENSE_HEADER_END@ */ @@ -100,6 +103,7 @@ static struct buf *nfs_getcacheblk __P((struct vnode *vp, daddr_t bn, int size, extern int nfs_numasync; extern struct nfsstats nfsstats; +extern int nbdwrite; /* * Vnode op for read using bio @@ -114,7 +118,8 @@ nfs_bioread(vp, uio, ioflag, cred, getpages) int getpages; { register struct nfsnode *np = VTONFS(vp); - register int biosize, diff, i; + register int biosize, i; + off_t diff; struct buf *bp = 0, *rabp; struct vattr vattr; struct proc *p; @@ -267,7 +272,7 @@ again: bufsize = biosize; if ((off_t)(lbn + 1) * biosize > np->n_size && (off_t)(lbn + 1) * biosize - np->n_size < biosize) { - bufsize = np->n_size - lbn * biosize; + bufsize = np->n_size - (off_t)lbn * biosize; bufsize = (bufsize + DEV_BSIZE - 1) & ~(DEV_BSIZE - 1); } bp = nfs_getcacheblk(vp, lbn, bufsize, p, operation); @@ -848,6 +853,22 @@ nfs_getcacheblk(vp, bn, size, p, operation) /*due to getblk/vm interractions, use vm page size or less values */ int biosize = min(vp->v_mount->mnt_stat.f_iosize, PAGE_SIZE); + if (nbdwrite > ((nbuf/4)*3) && operation == BLK_WRITE) { +#define __BUFFERS_RECLAIMED 2 + struct buf *tbp[__BUFFERS_RECLAIMED]; + int i; + + /* too many delayed writes, try to free up some buffers */ + for (i = 0; i < __BUFFERS_RECLAIMED; i++) + tbp[i] = geteblk(512); + + /* Yield to IO thread */ + (void)tsleep((caddr_t)&nbdwrite, PCATCH, "nbdwrite", 1); + + for (i = (__BUFFERS_RECLAIMED - 1); i >= 0; i--) + brelse(tbp[i]); + } + if (nmp->nm_flag & NFSMNT_INT) { bp = getblk(vp, bn, size, PCATCH, 0, operation); while (bp == (struct buf *)0) { @@ -859,7 +880,7 @@ nfs_getcacheblk(vp, bn, size, p, operation) bp = getblk(vp, bn, size, 0, 0, operation); if( vp->v_type == VREG) - bp->b_blkno = (bn * biosize) / DEV_BSIZE; + bp->b_blkno = ((off_t)bn * biosize) / DEV_BSIZE; return (bp); } @@ -1169,7 +1190,7 @@ nfs_doio(bp, cr, p) bp->b_validend = diff; } else bp->b_validend = bp->b_bcount; -#if 1 /* USV + JOE [ */ + if (bp->b_validend < bp->b_bufsize) { /* * we're about to release a partial buffer after a @@ -1185,7 +1206,6 @@ nfs_doio(bp, cr, p) FSDBG(258, bp->b_validend, bp->b_bufsize - bp->b_validend, 0, 2); } -#endif /* ] USV + JOE */ } if (p && (vp->v_flag & VTEXT) && (((nmp->nm_flag & NFSMNT_NQNFS) && @@ -1278,7 +1298,10 @@ nfs_doio(bp, cr, p) int s; CLR(bp->b_flags, B_INVAL | B_NOCACHE); - SET(bp->b_flags, B_DELWRI); + if (!ISSET(bp->b_flags, B_DELWRI)) { + SET(bp->b_flags, B_DELWRI); + nbdwrite++; + } FSDBG(261, bp->b_validoff, bp->b_validend, bp->b_bufsize, bp->b_bcount); /* @@ -1300,7 +1323,7 @@ nfs_doio(bp, cr, p) np->n_flag |= NWRITEERR; } bp->b_dirtyoff = bp->b_dirtyend = 0; -#if 1 /* JOE */ + /* * validoff and validend represent the real data present * in this buffer if validoff is non-zero, than we have @@ -1327,11 +1350,9 @@ nfs_doio(bp, cr, p) } else SET(bp->b_flags, B_INVAL); } -#endif } } else { -#if 1 /* JOE */ if (bp->b_validoff || (bp->b_validend < bp->b_bufsize && (off_t)bp->b_blkno * DEV_BSIZE + bp->b_validend != @@ -1342,7 +1363,6 @@ nfs_doio(bp, cr, p) FSDBG(260, bp->b_validoff, bp->b_validend, bp->b_bufsize, bp->b_bcount); } -#endif bp->b_resid = 0; biodone(bp); FSDBG_BOT(256, bp->b_validoff, bp->b_validend, bp->b_bufsize,