diff options
author | bde <bde@FreeBSD.org> | 1997-03-22 09:33:55 +0000 |
---|---|---|
committer | bde <bde@FreeBSD.org> | 1997-03-22 09:33:55 +0000 |
commit | 90027d0150af2b72f6ae09f8db21175330453548 (patch) | |
tree | 973a404b9c78ed1947989290047a49a753b11a22 /sys/ufs/lfs/lfs_inode.c | |
parent | 60e14681284303aa19c383bd113f78d75db543e8 (diff) | |
download | FreeBSD-src-90027d0150af2b72f6ae09f8db21175330453548.zip FreeBSD-src-90027d0150af2b72f6ae09f8db21175330453548.tar.gz |
Merged enough of lfs from Lite2 for mkdep of LINT to work again.
Diffstat (limited to 'sys/ufs/lfs/lfs_inode.c')
-rw-r--r-- | sys/ufs/lfs/lfs_inode.c | 109 |
1 files changed, 59 insertions, 50 deletions
diff --git a/sys/ufs/lfs/lfs_inode.c b/sys/ufs/lfs/lfs_inode.c index 8948a5e..48297dc 100644 --- a/sys/ufs/lfs/lfs_inode.c +++ b/sys/ufs/lfs/lfs_inode.c @@ -30,8 +30,8 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * @(#)lfs_inode.c 8.5 (Berkeley) 12/30/93 - * $Id: lfs_inode.c,v 1.15 1997/02/22 09:47:21 peter Exp $ + * @(#)lfs_inode.c 8.9 (Berkeley) 5/8/95 + * $Id: lfs_inode.c,v 1.16 1997/03/22 06:53:37 bde Exp $ */ #include "opt_quota.h" @@ -58,12 +58,6 @@ #include <ufs/lfs/lfs.h> #include <ufs/lfs/lfs_extern.h> -int -lfs_init() -{ - return (ufs_init()); -} - /* Search a block for a specific dinode. */ struct dinode * lfs_ifind(fs, ino, dip) @@ -114,13 +108,13 @@ lfs_update(ap) return(0); if (ip->i_flag & IN_ACCESS) - ip->i_atime.tv_sec = ap->a_access->tv_sec; + ip->i_atime = ap->a_access->tv_sec; if (ip->i_flag & IN_UPDATE) { - ip->i_mtime.tv_sec = ap->a_modify->tv_sec; + ip->i_mtime = ap->a_modify->tv_sec; (ip)->i_modrev++; } if (ip->i_flag & IN_CHANGE) - ip->i_ctime.tv_sec = time.tv_sec; + ip->i_ctime = time.tv_sec; ip->i_flag &= ~(IN_ACCESS | IN_CHANGE | IN_UPDATE); if (!(ip->i_flag & IN_MODIFIED)) @@ -139,22 +133,22 @@ lfs_update(ap) #define UPDATE_SEGUSE \ if (lastseg != -1) { \ LFS_SEGENTRY(sup, fs, lastseg, sup_bp); \ - if ((num << fs->lfs_bshift) > sup->su_nbytes) \ + if (num > sup->su_nbytes) \ panic("lfs_truncate: negative bytes in segment %d", \ lastseg); \ - sup->su_nbytes -= num << fs->lfs_bshift; \ + sup->su_nbytes -= num; \ e1 = VOP_BWRITE(sup_bp); \ - blocksreleased += num; \ + fragsreleased += numfrags(fs, num); \ } -#define SEGDEC { \ +#define SEGDEC(S) { \ if (daddr != 0) { \ if (lastseg != (seg = datosn(fs, daddr))) { \ UPDATE_SEGUSE; \ - num = 1; \ + num = (S); \ lastseg = seg; \ } else \ - ++num; \ + num += (S); \ } \ } @@ -175,7 +169,7 @@ lfs_truncate(ap) { register struct indir *inp; register int i; - register daddr_t *daddrp; + register ufs_daddr_t *daddrp; register struct vnode *vp = ap->a_vp; off_t length = ap->a_length; struct buf *bp, *sup_bp; @@ -185,9 +179,10 @@ lfs_truncate(ap) struct lfs *fs; struct indir a[NIADDR + 2], a_end[NIADDR + 2]; SEGUSE *sup; - daddr_t daddr, lastblock, lbn, olastblock; - long off, a_released, blocksreleased, i_released; - int e1, e2, depth, lastseg, num, offset, seg, size; + ufs_daddr_t daddr, lastblock, lbn, olastblock; + ufs_daddr_t oldsize_lastblock, oldsize_newlast, newsize; + long off, a_released, fragsreleased, i_released; + int e1, e2, depth, lastseg, num, offset, seg, freesize; ip = VTOI(vp); gettime(&tv); @@ -223,23 +218,28 @@ lfs_truncate(ap) * Update the size of the file. If the file is not being truncated to * a block boundry, the contents of the partial block following the end * of the file must be zero'ed in case it ever become accessable again - * because of subsequent file growth. + * because of subsequent file growth. For this part of the code, + * oldsize_newlast refers to the old size of the new last block in the file. */ offset = blkoff(fs, length); + lbn = lblkno(fs, length); + oldsize_newlast = blksize(fs, ip, lbn); + + /* Now set oldsize to the current size of the current last block */ + oldsize_lastblock = blksize(fs, ip, olastblock); if (offset == 0) ip->i_size = length; else { - lbn = lblkno(fs, length); #ifdef QUOTA if (e1 = getinoquota(ip)) return (e1); #endif - if (e1 = bread(vp, lbn, fs->lfs_bsize, NOCRED, &bp)) + if (e1 = bread(vp, lbn, oldsize_newlast, NOCRED, &bp)) return (e1); ip->i_size = length; - size = blksize(fs); - bzero((char *)bp->b_data + offset, (u_int)(size - offset)); - allocbuf(bp, size); + newsize = blksize(fs, ip, lbn); + bzero((char *)bp->b_data + offset, (u_int)(newsize - offset)); + allocbuf(bp, newsize); if (e1 = VOP_BWRITE(bp)) return (e1); } @@ -247,20 +247,24 @@ lfs_truncate(ap) * Modify sup->su_nbyte counters for each deleted block; keep track * of number of blocks removed for ip->i_blocks. */ - blocksreleased = 0; + fragsreleased = 0; num = 0; lastseg = -1; for (lbn = olastblock; lbn >= lastblock;) { /* XXX use run length from bmap array to make this faster */ ufs_bmaparray(vp, lbn, &daddr, a, &depth, NULL, NULL); - if (lbn == olastblock) + if (lbn == olastblock) { for (i = NIADDR + 2; i--;) a_end[i] = a[i]; + freesize = oldsize_lastblock; + } else + freesize = fs->lfs_bsize; + switch (depth) { case 0: /* Direct block. */ daddr = ip->i_db[lbn]; - SEGDEC; + SEGDEC(freesize); ip->i_db[lbn] = 0; --lbn; break; @@ -282,19 +286,20 @@ lfs_truncate(ap) inp->in_lbn, fs->lfs_bsize, NOCRED, &bp)) panic("lfs_truncate: bread bno %d", inp->in_lbn); - daddrp = (daddr_t *)bp->b_data + inp->in_off; + daddrp = (ufs_daddr_t *)bp->b_data + + inp->in_off; for (i = inp->in_off; i++ <= a_end[depth].in_off;) { daddr = *daddrp++; - SEGDEC; + SEGDEC(freesize); } a_end[depth].in_off = NINDIR(fs) - 1; if (inp->in_off == 0) brelse (bp); else { - bzero((daddr_t *)bp->b_data + + bzero((ufs_daddr_t *)bp->b_data + inp->in_off, fs->lfs_bsize - - inp->in_off * sizeof(daddr_t)); + inp->in_off * sizeof(ufs_daddr_t)); if (e1 = VOP_BWRITE(bp)) return (e1); } @@ -302,7 +307,7 @@ lfs_truncate(ap) if (depth == 0 && a[1].in_off == 0) { off = a[0].in_off; daddr = ip->i_ib[off]; - SEGDEC; + SEGDEC(freesize); ip->i_ib[off] = 0; } if (lbn == lastblock || lbn <= NDADDR) @@ -324,13 +329,14 @@ lfs_truncate(ap) } #ifdef DIAGNOSTIC - if (ip->i_blocks < fsbtodb(fs, blocksreleased)) { - printf("lfs_truncate: block count < 0\n"); - blocksreleased = ip->i_blocks; + if (ip->i_blocks < fragstodb(fs, fragsreleased)) { + printf("lfs_truncate: frag count < 0\n"); + fragsreleased = dbtofrags(fs, ip->i_blocks); + panic("lfs_truncate: frag count < 0\n"); } #endif - ip->i_blocks -= fsbtodb(fs, blocksreleased); - fs->lfs_bfree += fsbtodb(fs, blocksreleased); + ip->i_blocks -= fragstodb(fs, fragsreleased); + fs->lfs_bfree += fragstodb(fs, fragsreleased); ip->i_flag |= IN_CHANGE | IN_UPDATE; /* * Traverse dirty block list counting number of dirty buffers @@ -341,7 +347,7 @@ lfs_truncate(ap) i_released = 0; for (bp = vp->v_dirtyblkhd.lh_first; bp; bp = bp->b_vnbufs.le_next) if (bp->b_flags & B_LOCKED) { - ++a_released; + a_released += numfrags(fs, bp->b_bcount); /* * XXX * When buffers are created in the cache, their block @@ -354,25 +360,28 @@ lfs_truncate(ap) * here. */ if (bp->b_blkno == bp->b_lblkno) - ++i_released; + i_released += numfrags(fs, bp->b_bcount); } - blocksreleased = fsbtodb(fs, i_released); + fragsreleased = i_released; #ifdef DIAGNOSTIC - if (blocksreleased > ip->i_blocks) { + if (fragsreleased > dbtofrags(fs, ip->i_blocks)) { printf("lfs_inode: Warning! %s\n", - "more blocks released from inode than are in inode"); - blocksreleased = ip->i_blocks; + "more frags released from inode than are in inode"); + fragsreleased = dbtofrags(fs, ip->i_blocks); + panic("lfs_inode: Warning. More frags released\n"); } #endif - fs->lfs_bfree += blocksreleased; - ip->i_blocks -= blocksreleased; + fs->lfs_bfree += fragstodb(fs, fragsreleased); + ip->i_blocks -= fragstodb(fs, fragsreleased); #ifdef DIAGNOSTIC - if (length == 0 && ip->i_blocks != 0) + if (length == 0 && ip->i_blocks != 0) { printf("lfs_inode: Warning! %s%ld%s\n", "Truncation to zero, but ", ip->i_blocks, " blocks left on inode"); + panic("lfs_inode"); + } #endif - fs->lfs_avail += fsbtodb(fs, a_released); + fs->lfs_avail += fragstodb(fs, a_released); e1 = vinvalbuf(vp, (length > 0) ? V_SAVE : 0, ap->a_cred, ap->a_p, 0, 0); e2 = VOP_UPDATE(vp, &tv, &tv, 0); |