Source-Changes-HG archive

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

[src/trunk]: src/sys/ufs/ffs When unwinding a failed allocation, make sure to...



details:   https://anonhg.NetBSD.org/src/rev/8b2c340c5a3f
branches:  trunk
changeset: 486759:8b2c340c5a3f
user:      mycroft <mycroft%NetBSD.org@localhost>
date:      Sun May 28 08:15:40 2000 +0000

description:
When unwinding a failed allocation, make sure to nuke the unwound block from
the vnode's block list.  This fixes `itrunc3' panics (at least in some cases;
further testing is needed) and prevents further lossage later on.

diffstat:

 sys/ufs/ffs/ffs_balloc.c |  55 +++++++++++++++++++++++++++--------------------
 sys/ufs/ffs/ffs_inode.c  |   4 +-
 2 files changed, 33 insertions(+), 26 deletions(-)

diffs (138 lines):

diff -r 3a3814d5f304 -r 8b2c340c5a3f sys/ufs/ffs/ffs_balloc.c
--- a/sys/ufs/ffs/ffs_balloc.c  Sun May 28 07:53:30 2000 +0000
+++ b/sys/ufs/ffs/ffs_balloc.c  Sun May 28 08:15:40 2000 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: ffs_balloc.c,v 1.17 2000/02/25 19:58:25 fvdl Exp $     */
+/*     $NetBSD: ffs_balloc.c,v 1.18 2000/05/28 08:15:40 mycroft Exp $  */
 
 /*
  * Copyright (c) 1982, 1986, 1989, 1993
@@ -217,8 +217,8 @@
        allocblk = allociblk;
        if (nb == 0) {
                pref = ffs_blkpref(ip, lbn, 0, (ufs_daddr_t *)0);
-               error = ffs_alloc(ip, lbn, pref, (int)fs->fs_bsize,
-                       cred, &newb);
+               error = ffs_alloc(ip, lbn, pref, (int)fs->fs_bsize, cred,
+                   &newb);
                if (error)
                        return (error);
                nb = newb;
@@ -238,6 +238,7 @@
                        if ((error = bwrite(bp)) != 0)
                                goto fail;
                }
+               unwindidx = 0;
                allocib = &ip->i_ffs_ib[indirs[0].in_off];
                *allocib = ufs_rw32(nb, needswap);
                ip->i_flag |= IN_CHANGE | IN_UPDATE;
@@ -256,7 +257,7 @@
                nb = ufs_rw32(bap[indirs[i].in_off], needswap);
                if (i == num)
                        break;
-               i += 1;
+               i++;
                if (nb != 0) {
                        brelse(bp);
                        continue;
@@ -264,7 +265,7 @@
                if (pref == 0)
                        pref = ffs_blkpref(ip, lbn, 0, (ufs_daddr_t *)0);
                error = ffs_alloc(ip, lbn, pref, (int)fs->fs_bsize, cred,
-                                 &newb);
+                   &newb);
                if (error) {
                        brelse(bp);
                        goto fail;
@@ -288,6 +289,8 @@
                                goto fail;
                        }
                }
+               if (unwindidx < 0)
+                       unwindidx = i - 1;
                bap[indirs[i - 1].in_off] = ufs_rw32(nb, needswap);
                /*
                 * If required, write synchronously, otherwise use
@@ -305,7 +308,7 @@
        if (nb == 0) {
                pref = ffs_blkpref(ip, lbn, indirs[i].in_off, &bap[0]);
                error = ffs_alloc(ip, lbn, pref, (int)fs->fs_bsize, cred,
-                                 &newb);
+                   &newb);
                if (error) {
                        brelse(bp);
                        goto fail;
@@ -320,8 +323,6 @@
                        softdep_setup_allocindir_page(ip, lbn, bp,
                            indirs[i].in_off, nb, 0, nbp);
                bap[indirs[i].in_off] = ufs_rw32(nb, needswap);
-               if (allocib == NULL && unwindidx < 0)
-                       unwindidx = i - 1;
                /*
                 * If required, write synchronously, otherwise use
                 * delayed write.
@@ -364,24 +365,30 @@
                ffs_blkfree(ip, *blkp, fs->fs_bsize);
                deallocated += fs->fs_bsize;
        }
-       if (allocib != NULL) {
-               *allocib = 0;
-       } else if (unwindidx >= 0) {
-               int r;
-
-               r = bread(vp, indirs[unwindidx].in_lbn, 
-                   (int)fs->fs_bsize, NOCRED, &bp);
-               if (r) {
-                       panic("Could not unwind indirect block, error %d", r);
-                       brelse(bp);
+       if (unwindidx >= 0) {
+               if (unwindidx == 0) {
+                       *allocib = 0;
                } else {
-                       bap = (ufs_daddr_t *)bp->b_data;
-                       bap[indirs[unwindidx].in_off] = 0;
-                       if (flags & B_SYNC)
-                               bwrite(bp);
-                       else
-                               bdwrite(bp);
+                       int r;
+       
+                       r = bread(vp, indirs[unwindidx].in_lbn, 
+                           (int)fs->fs_bsize, NOCRED, &bp);
+                       if (r) {
+                               panic("Could not unwind indirect block, error %d", r);
+                               brelse(bp);
+                       } else {
+                               bap = (ufs_daddr_t *)bp->b_data;
+                               bap[indirs[unwindidx].in_off] = 0;
+                               if (flags & B_SYNC)
+                                       bwrite(bp);
+                               else
+                                       bdwrite(bp);
+                       }
                }
+               bp = getblk(vp, indirs[unwindidx + 1].in_lbn,
+                   (int)fs->fs_bsize, 0, 0);
+               bp->b_flags |= B_INVAL;
+               brelse(bp);
        }
        if (deallocated) {
 #ifdef QUOTA
diff -r 3a3814d5f304 -r 8b2c340c5a3f sys/ufs/ffs/ffs_inode.c
--- a/sys/ufs/ffs/ffs_inode.c   Sun May 28 07:53:30 2000 +0000
+++ b/sys/ufs/ffs/ffs_inode.c   Sun May 28 08:15:40 2000 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: ffs_inode.c,v 1.32 2000/05/28 04:13:58 mycroft Exp $   */
+/*     $NetBSD: ffs_inode.c,v 1.33 2000/05/28 08:15:42 mycroft Exp $   */
 
 /*
  * Copyright (c) 1982, 1986, 1989, 1993
@@ -507,7 +507,7 @@
        }
 
        bap = (ufs_daddr_t *)bp->b_data;
-       if (lastbn != -1) {
+       if (lastbn >= 0) {
                MALLOC(copy, ufs_daddr_t *, fs->fs_bsize, M_TEMP, M_WAITOK);
                memcpy((caddr_t)copy, (caddr_t)bap, (u_int)fs->fs_bsize);
                memset((caddr_t)&bap[last + 1], 0,



Home | Main Index | Thread Index | Old Index