xref: /csrg-svn/sys/ufs/lfs/lfs_inode.c (revision 51498)
123399Smckusick /*
2*51498Sbostic  * Copyright (c) 1986, 1989, 1991 Regents of the University of California.
337736Smckusick  * All rights reserved.
423399Smckusick  *
544537Sbostic  * %sccs.include.redist.c%
637736Smckusick  *
7*51498Sbostic  *	@(#)lfs_inode.c	7.46 (Berkeley) 11/01/91
823399Smckusick  */
924Sbill 
1051484Sbostic #include <sys/param.h>
1151484Sbostic #include <sys/systm.h>
1251484Sbostic #include <sys/mount.h>
1351484Sbostic #include <sys/proc.h>
1451484Sbostic #include <sys/file.h>
1551484Sbostic #include <sys/buf.h>
1651484Sbostic #include <sys/vnode.h>
1751484Sbostic #include <sys/kernel.h>
1851484Sbostic #include <sys/malloc.h>
1924Sbill 
20*51498Sbostic #include <ufs/ufs/quota.h>
21*51498Sbostic #include <ufs/ufs/inode.h>
22*51498Sbostic #include <ufs/ufs/ufsmount.h>
23*51498Sbostic #include <ufs/ufs/ufs_extern.h>
2447571Skarels 
25*51498Sbostic #include <ufs/lfs/lfs.h>
26*51498Sbostic #include <ufs/lfs/lfs_extern.h>
2724Sbill 
2851346Sbostic int
2951155Sbostic lfs_init()
3024Sbill {
3151484Sbostic 	return (ufs_init());
3224Sbill }
3324Sbill 
3424Sbill /*
3551484Sbostic  * Look up an LFS dinode number to find its incore vnode.  If not already
3651484Sbostic  * in core, read it in from the specified device.  Return the inode locked.
3751484Sbostic  * Detection and handling of mount points must be done by the calling routine.
3824Sbill  */
3951346Sbostic int
4051484Sbostic lfs_iget(pip, ino, ipp)
4151484Sbostic 	struct inode *pip;
424818Swnj 	ino_t ino;
4337736Smckusick 	struct inode **ipp;
4424Sbill {
45*51498Sbostic 	register struct lfs *fs;
4651484Sbostic 	register struct inode *ip;
4751484Sbostic 	struct buf *bp;
4851484Sbostic 	struct mount *mntp;
49*51498Sbostic 	struct vnode *vp;
5051484Sbostic 	dev_t dev;
5151346Sbostic 	int error;
5224Sbill 
53*51498Sbostic 	mntp = ITOV(pip)->v_mount;
54*51498Sbostic 	fs = VFSTOUFS(mntp)->um_lfs;
5551484Sbostic 	if (ino < ROOTINO)
5651484Sbostic 		return (EINVAL);
5751484Sbostic 
5851484Sbostic 	dev = pip->i_dev;
5951484Sbostic 	if ((*ipp = ufs_ihashget(dev, ino)) != NULL)
6051484Sbostic 		return (0);
6151484Sbostic 
6251155Sbostic 	/* Allocate new vnode/inode. */
63*51498Sbostic 	if (error = lfs_vcreate(mntp, ino, &vp)) {
6451484Sbostic 		*ipp = NULL;
6537736Smckusick 		return (error);
6637736Smckusick 	}
67*51498Sbostic 	ip = VTOI(vp);
6851155Sbostic 
6937736Smckusick 	/*
7039440Smckusick 	 * Put it onto its hash chain and lock it so that other requests for
7139440Smckusick 	 * this inode will block if they arrive while we are sleeping waiting
7239440Smckusick 	 * for old data structures to be purged or for the contents of the
7339440Smckusick 	 * disk portion of this inode to be read.
7439440Smckusick 	 */
7551484Sbostic 	ufs_ihashins(ip);
7651155Sbostic 
7751484Sbostic 	/* Read in the disk contents for the inode, copy into the inode. */
7851484Sbostic 	if (error = bread(VFSTOUFS(mntp)->um_devvp, lfs_itod(fs, ino),
7951484Sbostic 	    (int)fs->lfs_bsize, NOCRED, &bp)) {
8037736Smckusick 		/*
8141334Smckusick 		 * The inode does not contain anything useful, so it would
8251484Sbostic 		 * be misleading to leave it on its hash chain.  Iput() will
83*51498Sbostic 		 * return it to the free list.
8441334Smckusick 		 */
8541334Smckusick 		remque(ip);
8641334Smckusick 		ip->i_forw = ip;
8741334Smckusick 		ip->i_back = ip;
8851484Sbostic 
8951484Sbostic 		/* Unlock and discard unneeded inode. */
9051484Sbostic 		ufs_iput(ip);
9137736Smckusick 		brelse(bp);
9251484Sbostic 		*ipp = NULL;
9339440Smckusick 		return (error);
9437736Smckusick 	}
9551155Sbostic 	ip->i_din = *lfs_ifind(fs, ino, bp->b_un.b_dino);
9639440Smckusick 	brelse(bp);
9751155Sbostic 
98*51498Sbostic 	/*
99*51498Sbostic 	 * Initialize the vnode from the inode, check for aliases.  In all
100*51498Sbostic 	 * cases re-init ip, the underlying vnode/inode may have changed.
101*51498Sbostic 	 */
102*51498Sbostic 	if (error = ufs_vinit(mntp, &vp)) {
10351484Sbostic 		ufs_iput(ip);
10451484Sbostic 		*ipp = NULL;
10551484Sbostic 		return (error);
10640289Smckusick 	}
107*51498Sbostic 	*ipp = VTOI(vp);
10837736Smckusick 	return (0);
10937736Smckusick }
1107334Skre 
11151346Sbostic int
11251484Sbostic lfs_iupdat(ip, ta, tm, waitfor)
11351484Sbostic 	register struct inode *ip;
11451484Sbostic 	struct timeval *ta, *tm;
11551484Sbostic         int waitfor;
1167118Smckusick {
11738452Smckusick 	/*
11851484Sbostic 	 * XXX
11951484Sbostic 	 * This isn't right, but ufs_iupdat() isn't either.
12038452Smckusick 	 */
12151484Sbostic 	ITIMES(ip, ta, tm);
12251484Sbostic 	return (0);
12324Sbill }
12424Sbill 
12524Sbill /*
12651484Sbostic  * Truncate the inode ip to at most length size.
12710736Ssam  *
12810736Ssam  * NB: triple indirect blocks are untested.
12924Sbill  */
13051484Sbostic /* ARGSUSED */
13151484Sbostic int
13251155Sbostic lfs_itrunc(oip, length, flags)
13317942Smckusick 	register struct inode *oip;
1349165Ssam 	u_long length;
13539676Smckusick 	int flags;
13624Sbill {
137*51498Sbostic 	register struct lfs *fs;
13817942Smckusick 	struct buf *bp;
13951484Sbostic 	daddr_t lbn;
14051484Sbostic 	int error, offset, size;
1419165Ssam 
14245721Smckusick 	vnode_pager_setsize(ITOV(oip), length);
14351484Sbostic 
14451484Sbostic 	/* If length is larger than the file, just update the times. */
14513000Ssam 	if (oip->i_size <= length) {
14613000Ssam 		oip->i_flag |= ICHG|IUPD;
14751183Sbostic 		ITIMES(oip, &time, &time);
14851183Sbostic 		return (0);
14913000Ssam 	}
15051484Sbostic 
1511203Sbill 	/*
15251484Sbostic 	 * Update the size of the file. If the file is not being truncated to
15351484Sbostic 	 * a block boundry, the contents of the partial block following the end
15451484Sbostic 	 * of the file must be zero'ed in case it ever become accessable again
15551484Sbostic 	 * because of subsequent file growth.
1561203Sbill 	 */
15751484Sbostic 	fs = oip->i_lfs;
15817942Smckusick 	offset = blkoff(fs, length);
15951484Sbostic 	if (offset == 0)
16017942Smckusick 		oip->i_size = length;
16151484Sbostic 	else {
16217942Smckusick 		lbn = lblkno(fs, length);
16341313Smckusick #ifdef QUOTA
16441313Smckusick 		if (error = getinoquota(oip))
16541313Smckusick 			return (error);
16651183Sbostic #endif
16751183Sbostic 		if (error = bread(ITOV(oip), lbn, fs->lfs_bsize, NOCRED, &bp))
16837736Smckusick 			return (error);
16917942Smckusick 		oip->i_size = length;
17051155Sbostic 		size = blksize(fs);				/* LFS */
17145721Smckusick 		(void) vnode_pager_uncache(ITOV(oip));
17226272Skarels 		bzero(bp->b_un.b_addr + offset, (unsigned)(size - offset));
17345112Smckusick 		allocbuf(bp, size);
17451183Sbostic 		lfs_bwrite(bp);
17517942Smckusick 	}
17651484Sbostic 	/* BZERO INODE BLOCK POINTERS HERE, FOR CONSISTENCY XXX */
17724Sbill }
178