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