]> git.saurik.com Git - apple/xnu.git/blobdiff - bsd/nfs/nfs_bio.c
xnu-344.21.73.tar.gz
[apple/xnu.git] / bsd / nfs / nfs_bio.c
index 926de3419bb343ac2fdf92bfd078f9f7d32777d6..7f41efe13fb85952defd9b67213fca4b1fa07a98 100644 (file)
@@ -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,