Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/sys/ufs/ffs ffs_indirtrunc(): for !wapbl, restore rev 1.117 ...
details: https://anonhg.NetBSD.org/src/rev/bb0f5c4c63ff
branches: trunk
changeset: 348832:bb0f5c4c63ff
user: jdolecek <jdolecek%NetBSD.org@localhost>
date: Thu Nov 10 19:10:05 2016 +0000
description:
ffs_indirtrunc(): for !wapbl, restore rev 1.117 behavior of writing the zeroed
(indirect) block before freeing the referenced blocks; it's necessary for
fsck to recover the filesystem, if system goes down during truncate
patch courtesy of hannken@ with only sligh tweaks
diffstat:
sys/ufs/ffs/ffs_inode.c | 61 +++++++++++++++++++++++++++++++++++++-----------
1 files changed, 47 insertions(+), 14 deletions(-)
diffs (119 lines):
diff -r ad86af02831f -r bb0f5c4c63ff sys/ufs/ffs/ffs_inode.c
--- a/sys/ufs/ffs/ffs_inode.c Thu Nov 10 18:35:17 2016 +0000
+++ b/sys/ufs/ffs/ffs_inode.c Thu Nov 10 19:10:05 2016 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: ffs_inode.c,v 1.120 2016/11/07 21:14:23 jdolecek Exp $ */
+/* $NetBSD: ffs_inode.c,v 1.121 2016/11/10 19:10:05 jdolecek Exp $ */
/*-
* Copyright (c) 2008 The NetBSD Foundation, Inc.
@@ -61,7 +61,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: ffs_inode.c,v 1.120 2016/11/07 21:14:23 jdolecek Exp $");
+__KERNEL_RCSID(0, "$NetBSD: ffs_inode.c,v 1.121 2016/11/10 19:10:05 jdolecek Exp $");
#if defined(_KERNEL_OPT)
#include "opt_ffs.h"
@@ -533,6 +533,8 @@
* blocks were deallocated creating a hole, but that is okay.
*/
if (error == EAGAIN) {
+ if (!allerror)
+ allerror = error;
length = osize;
uvm_vnp_setsize(ovp, length);
}
@@ -573,10 +575,12 @@
int64_t *bap2 = NULL;
struct vnode *vp;
daddr_t nb, nlbn, last;
+ char *copy = NULL;
int64_t factor;
int64_t nblocks;
- int error = 0;
+ int error = 0, allerror = 0;
const int needswap = UFS_FSNEEDSWAP(fs);
+ const int wapbl = (ip->i_ump->um_mountp->mnt_wapbl != NULL);
#define RBAP(ip, i) (((ip)->i_ump->um_fstype == UFS1) ? \
ufs_rw32(bap1[i], needswap) : ufs_rw64(bap2[i], needswap))
@@ -602,7 +606,7 @@
nblocks = btodb(fs->fs_bsize);
/*
* Get buffer of block pointers, zero those entries corresponding
- * to blocks to be free'd, and update on disk copy. Since
+ * to blocks to be free'd, and update on disk copy first. Since
* double(triple) indirect before single(double) indirect, calls
* to bmap on these blocks will fail. However, we already have
* the on disk address, so we have to set the b_blkno field
@@ -635,13 +639,35 @@
return error;
}
- if (ip->i_ump->um_fstype == UFS1)
- bap1 = (int32_t *)bp->b_data;
- else
- bap2 = (int64_t *)bp->b_data;
+ /*
+ * Clear reference to blocks to be removed on disk, before actually
+ * reclaiming them, so that fsck is more likely to be able to recover
+ * the filesystem if system goes down during the truncate process.
+ * This assumes the truncate process would not fail, contrary
+ * to the wapbl case.
+ */
+ if (lastbn >= 0 && !wapbl) {
+ copy = kmem_alloc(fs->fs_bsize, KM_SLEEP);
+ memcpy((void *)copy, bp->b_data, (u_int)fs->fs_bsize);
+ for (i = last + 1; i < FFS_NINDIR(fs); i++)
+ BAP_ASSIGN(ip, i, 0);
+ error = bwrite(bp);
+ if (error)
+ allerror = error;
+
+ if (ip->i_ump->um_fstype == UFS1)
+ bap1 = (int32_t *)copy;
+ else
+ bap2 = (int64_t *)copy;
+ } else {
+ if (ip->i_ump->um_fstype == UFS1)
+ bap1 = (int32_t *)bp->b_data;
+ else
+ bap2 = (int64_t *)bp->b_data;
+ }
/*
- * Recursively free totally unused blocks, starting from first.
+ * Recursively free totally unused blocks.
*/
for (i = FFS_NINDIR(fs) - 1, nlbn = lbn + 1 - i * factor; i > last;
i--, nlbn += factor) {
@@ -686,15 +712,22 @@
}
out:
- if (lastbn < 0 && error == 0) {
+ if (error && !allerror)
+ allerror = error;
+
+ if (copy != NULL) {
+ kmem_free(copy, fs->fs_bsize);
+ } else if (lastbn < 0 && error == 0) {
/* all freed, release without writing back */
brelse(bp, BC_INVAL);
- } else {
- /* only partially freed, write the updated block */
- (void) bwrite(bp);
+ } else if (wapbl) {
+ /* only partially freed, write the updated block */
+ error = bwrite(bp);
+ if (!allerror)
+ allerror = error;
}
- return (error);
+ return (allerror);
}
void
Home |
Main Index |
Thread Index |
Old Index