summaryrefslogtreecommitdiffstats
path: root/sys
diff options
context:
space:
mode:
authordg <dg@FreeBSD.org>1996-11-05 08:19:40 +0000
committerdg <dg@FreeBSD.org>1996-11-05 08:19:40 +0000
commit1252d9110c3883cb30b6473811777ee257ee1832 (patch)
tree33b0ac0feaa0ac319f1d257be1ac6671b26a84d6 /sys
parentff915b01647e6f5088f097917ca71db9b1654d13 (diff)
downloadFreeBSD-src-1252d9110c3883cb30b6473811777ee257ee1832.zip
FreeBSD-src-1252d9110c3883cb30b6473811777ee257ee1832.tar.gz
Eliminate an unnecessary synchronous write (and an 8K bcopy+bzero) when
truncating/deleting large files. Reviewed by: mckusick, dyson Submitted by: Kirk McKusick <mckusick@mckusick.com>, modified for FreeBSD by me.
Diffstat (limited to 'sys')
-rw-r--r--sys/ufs/ffs/ffs_inode.c39
1 files changed, 22 insertions, 17 deletions
diff --git a/sys/ufs/ffs/ffs_inode.c b/sys/ufs/ffs/ffs_inode.c
index b916e08..211df58 100644
--- a/sys/ufs/ffs/ffs_inode.c
+++ b/sys/ufs/ffs/ffs_inode.c
@@ -31,7 +31,7 @@
* SUCH DAMAGE.
*
* @(#)ffs_inode.c 8.5 (Berkeley) 12/30/93
- * $Id: ffs_inode.c,v 1.20 1996/01/19 03:59:12 dyson Exp $
+ * $Id: ffs_inode.c,v 1.21 1996/09/19 18:21:27 nate Exp $
*/
#include "opt_quota.h"
@@ -423,7 +423,7 @@ ffs_indirtrunc(ip, lbn, dbn, lastbn, level, countp)
register struct fs *fs = ip->i_fs;
register daddr_t *bap;
struct vnode *vp;
- daddr_t *copy, nb, nlbn, last;
+ daddr_t *copy = NULL, nb, nlbn, last;
long blkcount, factor;
int nblocks, blocksreleased = 0;
int error = 0, allerror = 0;
@@ -467,21 +467,20 @@ ffs_indirtrunc(ip, lbn, dbn, lastbn, level, countp)
}
bap = (daddr_t *)bp->b_data;
- MALLOC(copy, daddr_t *, fs->fs_bsize, M_TEMP, M_WAITOK);
- bcopy((caddr_t)bap, (caddr_t)copy, (u_int)fs->fs_bsize);
- bzero((caddr_t)&bap[last + 1],
- (u_int)(NINDIR(fs) - (last + 1)) * sizeof (daddr_t));
- if (last == -1)
- bp->b_flags |= B_INVAL;
- if ((vp->v_mount->mnt_flag & MNT_ASYNC) == 0) {
- error = bwrite(bp);
- } else {
- bawrite(bp);
- error = 0;
+ if (lastbn != -1) {
+ MALLOC(copy, daddr_t *, fs->fs_bsize, M_TEMP, M_WAITOK);
+ bcopy((caddr_t)bap, (caddr_t)copy, (u_int)fs->fs_bsize);
+ bzero((caddr_t)&bap[last + 1],
+ (u_int)(NINDIR(fs) - (last + 1)) * sizeof (daddr_t));
+ if ((vp->v_mount->mnt_flag & MNT_ASYNC) == 0) {
+ error = bwrite(bp);
+ if (error)
+ allerror = error;
+ } else {
+ bawrite(bp);
+ }
+ bap = copy;
}
- if (error)
- allerror = error;
- bap = copy;
/*
* Recursively free totally unused blocks.
@@ -516,7 +515,13 @@ ffs_indirtrunc(ip, lbn, dbn, lastbn, level, countp)
blocksreleased += blkcount;
}
}
- FREE(copy, M_TEMP);
+ if (copy != NULL) {
+ FREE(copy, M_TEMP);
+ } else {
+ bp->b_flags |= B_INVAL | B_NOCACHE;
+ brelse(bp);
+ }
+
*countp = blocksreleased;
return (allerror);
}
OpenPOWER on IntegriCloud