diff -u ext2fs.orig/ext2_alloc.c ext2fs/ext2_alloc.c --- ext2fs.orig/ext2_alloc.c 2009-08-18 20:32:13.000000000 -0500 +++ ext2fs/ext2_alloc.c 2009-08-28 09:44:04.000000000 -0500 @@ -1,4 +1,4 @@ -/*- +w/*- * modified for Lites 1.1 * * Aug 1995, Godmar Back (gback@cs.utah.edu) @@ -441,7 +441,7 @@ /* if the next block is actually what we thought it is, then set the goal to what we thought it should be */ - if(ip->i_next_alloc_block == lbn) + if(ip->i_next_alloc_block == lbn && ip->i_next_alloc_goal != 0) return ip->i_next_alloc_goal; /* now check whether we were provided with an array that basically diff -u ext2fs.orig/ext2_inode.c ext2fs/ext2_inode.c --- ext2fs.orig/ext2_inode.c 2009-08-18 20:32:13.000000000 -0500 +++ ext2fs/ext2_inode.c 2009-09-01 13:29:55.000000000 -0500 @@ -126,16 +126,11 @@ long count, nblocks, blocksreleased = 0; int aflags, error, i, allerror; off_t osize; -/* -printf("ext2_truncate called %d to %d\n", VTOI(ovp)->i_number, length); -*/ /* - * negative file sizes will totally break the code below and - * are not meaningful anyways. - */ + + oip = VTOI(ovp); if (length < 0) - return EFBIG; + return (EINVAL); - oip = VTOI(ovp); if (ovp->v_type == VLNK && oip->i_size < ovp->v_mount->mnt_maxsymlinklen) { #ifdef DIAGNOSTIC @@ -157,23 +152,29 @@ /* * Lengthen the size of the file. We must ensure that the * last byte of the file is allocated. Since the smallest - * value of oszie is 0, length will be at least 1. + * value of osize is 0, length will be at least 1. */ if (osize < length) { if (length > oip->i_e2fs->fs_maxfilesize) return (EFBIG); + vnode_pager_setsize(ovp, length); offset = blkoff(fs, length - 1); lbn = lblkno(fs, length - 1); aflags = B_CLRBUF; if (flags & IO_SYNC) aflags |= B_SYNC; - vnode_pager_setsize(ovp, length); - if ((error = ext2_balloc(oip, lbn, offset + 1, cred, &bp, - aflags)) != 0) + error = ext2_balloc(oip, lbn, offset + 1, cred, &bp, aflags) + if (error) { + vnode_pager_setsize(vp, osize); return (error); + } oip->i_size = length; - if (aflags & IO_SYNC) + if (bp->b_bufsize == fs->fs_bsize) + bp->b_flags |= B_CLUSTEROK; + if (aflags & B_SYNC) bwrite(bp); + else if (ovp->v_mount->mnt_flag & MNT_ASYNC) + bdwrite(bp); else bawrite(bp); oip->i_flag |= IN_CHANGE | IN_UPDATE; @@ -195,15 +196,19 @@ aflags = B_CLRBUF; if (flags & IO_SYNC) aflags |= B_SYNC; - if ((error = ext2_balloc(oip, lbn, offset, cred, &bp, - aflags)) != 0) + error = ext2_balloc(oip, lbn, offset, cred, &bp, aflags) + if (error) return (error); oip->i_size = length; size = blksize(fs, oip, lbn); bzero((char *)bp->b_data + offset, (u_int)(size - offset)); allocbuf(bp, size); - if (aflags & IO_SYNC) + if (bp->b_bufsize == fs->fs_bsize) + bp->b_flags |= B_CLUSTEROK; + if (aflags & B_SYNC) bwrite(bp); + else if (ovp->v_mount->mnt_flag & MNT_ASYNC) + bdwrite(bp); else bawrite(bp); } @@ -247,6 +252,7 @@ error = vtruncbuf(ovp, cred, td, length, (int)fs->s_blocksize); if (error && (allerror == 0)) allerror = error; + vnode_pager_setsize(ovp, length); /* * Indirect blocks first. diff -u ext2fs.orig/ext2_vfsops.c ext2fs/ext2_vfsops.c --- ext2fs.orig/ext2_vfsops.c 2009-08-18 20:32:13.000000000 -0500 +++ ext2fs/ext2_vfsops.c 2009-08-27 21:44:12.000000000 -0500 @@ -171,8 +171,6 @@ flags = WRITECLOSE; if (mp->mnt_flag & MNT_FORCE) flags |= FORCECLOSE; - if (vfs_busy(mp, LK_NOWAIT, 0, td)) - return (EBUSY); error = ext2_flushfiles(mp, flags, td); vfs_unbusy(mp, td); if (!error && fs->s_wasvalid) { @@ -500,6 +498,7 @@ * 4) invalidate all inactive vnodes. * 5) invalidate all cached file data. * 6) re-read inode data for all active vnodes. + * XXX we are missing some steps, in particular # 3 */ static int ext2_reload(struct mount *mp, struct thread *td) @@ -1007,8 +1006,8 @@ * still zero, it will be unlinked and returned to the free * list by vput(). */ - vput(vp); brelse(bp); + vput(vp); *vpp = NULL; return (error); } @@ -1032,7 +1031,7 @@ /* ext2_print_inode(ip); */ - brelse(bp); + bqrelse(bp); /* * Initialize the vnode from the inode, check for aliases.