*
* @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@
*/
extern int nfs_numasync;
extern struct nfsstats nfsstats;
+extern int nbdwrite;
/*
* Vnode op for read using bio
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;
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);
/*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) {
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);
}
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
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) &&
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);
/*
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
} 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 !=
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,