diff options
author | dg <dg@FreeBSD.org> | 1996-11-05 08:19:40 +0000 |
---|---|---|
committer | dg <dg@FreeBSD.org> | 1996-11-05 08:19:40 +0000 |
commit | 1252d9110c3883cb30b6473811777ee257ee1832 (patch) | |
tree | 33b0ac0feaa0ac319f1d257be1ac6671b26a84d6 /sys/ufs/ffs/ffs_inode.c | |
parent | ff915b01647e6f5088f097917ca71db9b1654d13 (diff) | |
download | FreeBSD-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/ufs/ffs/ffs_inode.c')
-rw-r--r-- | sys/ufs/ffs/ffs_inode.c | 39 |
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); } |