Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/sys/ufs/lfs Fix buffer handling problems in lfs_vinvalbuf



details:   https://anonhg.NetBSD.org/src/rev/630ba5dea718
branches:  trunk
changeset: 468017:630ba5dea718
user:      perseant <perseant%NetBSD.org@localhost>
date:      Thu Apr 01 23:28:09 1999 +0000

description:
Fix buffer handling problems in lfs_vinvalbuf

diffstat:

 sys/ufs/lfs/lfs_inode.c |  55 ++++++++++++++++++++++++++++++++----------------
 1 files changed, 36 insertions(+), 19 deletions(-)

diffs (106 lines):

diff -r 909c1c9189f3 -r 630ba5dea718 sys/ufs/lfs/lfs_inode.c
--- a/sys/ufs/lfs/lfs_inode.c   Thu Apr 01 23:12:30 1999 +0000
+++ b/sys/ufs/lfs/lfs_inode.c   Thu Apr 01 23:28:09 1999 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: lfs_inode.c,v 1.21 1999/03/29 21:51:38 perseant Exp $  */
+/*     $NetBSD: lfs_inode.c,v 1.22 1999/04/01 23:28:09 perseant Exp $  */
 
 /*-
  * Copyright (c) 1999 The NetBSD Foundation, Inc.
@@ -262,6 +262,7 @@
        /*
         * Update the size of the file. If the file is not being truncated to
         * a block boundry, the contents of the partial block following the end
+        * must be zero'd in case it ever becomes accessible again
         * because of subsequent file growth.  For this part of the code,
         * oldsize_newlast refers to the old size of the new last block in the
         * file.
@@ -442,7 +443,7 @@
 #endif
        fs->lfs_avail += fragstodb(fs, a_released);
        if(length>0)
-               e1 = lfs_vinvalbuf(vp, ap->a_cred, ap->a_p, lastblock);
+               e1 = lfs_vinvalbuf(vp, ap->a_cred, ap->a_p, lastblock-1);
        else
                e1 = vinvalbuf(vp, 0, ap->a_cred, ap->a_p, 0, 0); 
        e2 = VOP_UPDATE(vp, NULL, NULL, 0);
@@ -467,8 +468,10 @@
 {
        register struct buf *bp;
        struct buf *nbp, *blist;
-       int i, s, error;
+       int i, s, error, dirty;
 
+      top:
+       dirty=0;
        for (i=0;i<2;i++) {
                if(i==0)
                        blist = vp->v_cleanblkhd.lh_first;
@@ -477,7 +480,15 @@
 
                for (bp = blist; bp; bp = nbp) {
                        nbp = bp->b_vnbufs.le_next;
+
                        s = splbio();
+                       if (bp->b_flags & B_GATHERED) {
+                               error = tsleep(vp, PRIBIO+1, "lfs_vin2", 0);
+                               splx(s);
+                               if(error)
+                                       return error;
+                               goto top;
+                       }
                        if (bp->b_flags & B_BUSY) {
                                bp->b_flags |= B_WANTED;
                                error = tsleep((caddr_t)bp,
@@ -485,29 +496,35 @@
                                splx(s);
                                if (error)
                                        return (error);
-                               break;
+                               goto top;
                        }
-                       /*
-                        * Don't touch gathered buffers; and certainly don't
-                        * mark cleaner buffers B_INVAL, since that would
-                        * change them to "fake buffers".
-                        *
-                        * But get rid of anything else that's past the new
-                        * last block.
-                        */
+
                        bp->b_flags |= B_BUSY;
                        splx(s);
                        if((bp->b_lblkno >= 0 && bp->b_lblkno > maxblk)
-                          || (bp->b_lblkno < 0 && bp->b_lblkno < -maxblk-NIADDR))
+                          || (bp->b_lblkno < 0 && bp->b_lblkno < -maxblk-(NIADDR-1)))
                        {
-                               if(!(bp->b_flags & (B_GATHERED|B_CALL)))
-                                       bp->b_flags |= B_INVAL;
+                               bp->b_flags |= B_INVAL | B_VFLUSH;
+                               if(bp->b_flags & B_CALL) {
+                                       lfs_freebuf(bp);
+                               } else {
+                                       brelse(bp);
+                               }
+                               ++dirty;
+                       } else {
+                               /*
+                                * This buffer is still on its free list.
+                                * So don't brelse, but wake up any sleepers.
+                                */
+                               bp->b_flags &= ~B_BUSY;
+                               if(bp->b_flags & B_WANTED) {
+                                       bp->b_flags &= ~(B_WANTED|B_AGE);
+                                       wakeup(bp);
+                               }
                        }
-                       if(bp->b_flags & B_CALL)
-                               bp->b_flags &= ~B_BUSY;
-                       else
-                               brelse(bp);
                }
        }
+       if(dirty)
+               goto top;
        return (0);
 }



Home | Main Index | Thread Index | Old Index