xref: /csrg-svn/sys/ufs/lfs/lfs_inode.c (revision 51484)
123399Smckusick /*
237736Smckusick  * Copyright (c) 1982, 1986, 1989 Regents of the University of California.
337736Smckusick  * All rights reserved.
423399Smckusick  *
544537Sbostic  * %sccs.include.redist.c%
637736Smckusick  *
7*51484Sbostic  *	@(#)lfs_inode.c	7.45 (Berkeley) 11/01/91
823399Smckusick  */
924Sbill 
10*51484Sbostic #include <sys/param.h>
11*51484Sbostic #include <sys/systm.h>
12*51484Sbostic #include <sys/mount.h>
13*51484Sbostic #include <sys/proc.h>
14*51484Sbostic #include <sys/file.h>
15*51484Sbostic #include <sys/buf.h>
16*51484Sbostic #include <sys/vnode.h>
17*51484Sbostic #include <sys/kernel.h>
18*51484Sbostic #include <sys/malloc.h>
1924Sbill 
20*51484Sbostic #include <ufs/quota.h>
21*51484Sbostic #include <ufs/inode.h>
22*51484Sbostic #include <ufs/ufsmount.h>
23*51484Sbostic #include <ufs/ufs_extern.h>
2447571Skarels 
25*51484Sbostic #include <lfs/lfs.h>
26*51484Sbostic #include <lfs/lfs_extern.h>
2724Sbill 
2851155Sbostic extern int prtactive;	/* 1 => print out reclaim of active vnodes */
2939574Smckusick 
3051346Sbostic int
3151155Sbostic lfs_init()
3224Sbill {
33*51484Sbostic 	return (ufs_init());
3424Sbill }
3524Sbill 
3624Sbill /*
37*51484Sbostic  * Look up an LFS dinode number to find its incore vnode.  If not already
38*51484Sbostic  * in core, read it in from the specified device.  Return the inode locked.
39*51484Sbostic  * Detection and handling of mount points must be done by the calling routine.
4024Sbill  */
4151346Sbostic int
42*51484Sbostic lfs_iget(pip, ino, ipp)
43*51484Sbostic 	struct inode *pip;
444818Swnj 	ino_t ino;
4537736Smckusick 	struct inode **ipp;
4624Sbill {
47*51484Sbostic 	register LFS *fs;
48*51484Sbostic 	register struct inode *ip;
4937736Smckusick 	register struct vnode *vp;
50*51484Sbostic 	struct buf *bp;
51*51484Sbostic 	struct inode *nip;
52*51484Sbostic 	struct mount *mntp;
5339440Smckusick 	struct vnode *nvp;
54*51484Sbostic 	dev_t dev;
5551346Sbostic 	int error;
5624Sbill 
5751155Sbostic printf("lfs_iget ino %d\n", ino);
5851155Sbostic 
59*51484Sbostic 	if (ino < ROOTINO)
60*51484Sbostic 		return (EINVAL);
61*51484Sbostic 
62*51484Sbostic 	dev = pip->i_dev;
63*51484Sbostic 	if ((*ipp = ufs_ihashget(dev, ino)) != NULL)
64*51484Sbostic 		return (0);
65*51484Sbostic 
6651155Sbostic 	/* Allocate new vnode/inode. */
67*51484Sbostic 	mntp = ITOV(pip)->v_mount;
6851155Sbostic 	error = lfs_vcreate(mntp, ino, &nvp);
6951155Sbostic 	if (error) {
70*51484Sbostic 		*ipp = NULL;
7137736Smckusick 		return (error);
7237736Smckusick 	}
7339440Smckusick 	ip = VTOI(nvp);
7451155Sbostic 
7537736Smckusick 	/*
7639440Smckusick 	 * Put it onto its hash chain and lock it so that other requests for
7739440Smckusick 	 * this inode will block if they arrive while we are sleeping waiting
7839440Smckusick 	 * for old data structures to be purged or for the contents of the
7939440Smckusick 	 * disk portion of this inode to be read.
8039440Smckusick 	 */
81*51484Sbostic 	ufs_ihashins(ip);
8251155Sbostic 
83*51484Sbostic 	/* Read in the disk contents for the inode, copy into the inode. */
84*51484Sbostic 	fs = VFSTOUFS(mntp)->um_lfs;
85*51484Sbostic 	if (error = bread(VFSTOUFS(mntp)->um_devvp, lfs_itod(fs, ino),
86*51484Sbostic 	    (int)fs->lfs_bsize, NOCRED, &bp)) {
8737736Smckusick 		/*
8841334Smckusick 		 * The inode does not contain anything useful, so it would
89*51484Sbostic 		 * be misleading to leave it on its hash chain.  Iput() will
90*51484Sbostic 		 * take care of putting it back on the free list.
9141334Smckusick 		 */
9241334Smckusick 		remque(ip);
9341334Smckusick 		ip->i_forw = ip;
9441334Smckusick 		ip->i_back = ip;
95*51484Sbostic 
96*51484Sbostic 		/* Unlock and discard unneeded inode. */
97*51484Sbostic 		ufs_iput(ip);
9837736Smckusick 		brelse(bp);
99*51484Sbostic 		*ipp = NULL;
10039440Smckusick 		return (error);
10137736Smckusick 	}
10251155Sbostic 	ip->i_din = *lfs_ifind(fs, ino, bp->b_un.b_dino);
10339440Smckusick 	brelse(bp);
10451155Sbostic 
105*51484Sbostic 	/* Initialize the vnode from the inode, check for aliases. */
106*51484Sbostic 	if (error = ufs_vinit(mntp, ip, &nip)) {
107*51484Sbostic 		ufs_iput(ip);
108*51484Sbostic 		*ipp = NULL;
109*51484Sbostic 		return (error);
11040289Smckusick 	}
111*51484Sbostic 	*ipp = nip;
11237736Smckusick 	return (0);
11337736Smckusick }
1147334Skre 
11551346Sbostic int
116*51484Sbostic lfs_iupdat(ip, ta, tm, waitfor)
117*51484Sbostic 	register struct inode *ip;
118*51484Sbostic 	struct timeval *ta, *tm;
119*51484Sbostic         int waitfor;
1207118Smckusick {
12138452Smckusick 	/*
122*51484Sbostic 	 * XXX
123*51484Sbostic 	 * This isn't right, but ufs_iupdat() isn't either.
12438452Smckusick 	 */
125*51484Sbostic 	ITIMES(ip, ta, tm);
126*51484Sbostic 	return (0);
12724Sbill }
12824Sbill 
12924Sbill /*
130*51484Sbostic  * Truncate the inode ip to at most length size.
13110736Ssam  *
13210736Ssam  * NB: triple indirect blocks are untested.
13324Sbill  */
134*51484Sbostic /* ARGSUSED */
135*51484Sbostic int
13651155Sbostic lfs_itrunc(oip, length, flags)
13717942Smckusick 	register struct inode *oip;
1389165Ssam 	u_long length;
13939676Smckusick 	int flags;
14024Sbill {
141*51484Sbostic 	register LFS *fs;
14217942Smckusick 	struct buf *bp;
143*51484Sbostic 	daddr_t lbn;
144*51484Sbostic 	int error, offset, size;
1459165Ssam 
14645721Smckusick 	vnode_pager_setsize(ITOV(oip), length);
147*51484Sbostic 
148*51484Sbostic 	/* If length is larger than the file, just update the times. */
14913000Ssam 	if (oip->i_size <= length) {
15013000Ssam 		oip->i_flag |= ICHG|IUPD;
15151183Sbostic 		ITIMES(oip, &time, &time);
15251183Sbostic 		return (0);
15313000Ssam 	}
154*51484Sbostic 
1551203Sbill 	/*
156*51484Sbostic 	 * Update the size of the file. If the file is not being truncated to
157*51484Sbostic 	 * a block boundry, the contents of the partial block following the end
158*51484Sbostic 	 * of the file must be zero'ed in case it ever become accessable again
159*51484Sbostic 	 * because of subsequent file growth.
1601203Sbill 	 */
161*51484Sbostic 	fs = oip->i_lfs;
16217942Smckusick 	offset = blkoff(fs, length);
163*51484Sbostic 	if (offset == 0)
16417942Smckusick 		oip->i_size = length;
165*51484Sbostic 	else {
16617942Smckusick 		lbn = lblkno(fs, length);
16741313Smckusick #ifdef QUOTA
16841313Smckusick 		if (error = getinoquota(oip))
16941313Smckusick 			return (error);
17051183Sbostic #endif
17151183Sbostic 		if (error = bread(ITOV(oip), lbn, fs->lfs_bsize, NOCRED, &bp))
17237736Smckusick 			return (error);
17317942Smckusick 		oip->i_size = length;
17451155Sbostic 		size = blksize(fs);				/* LFS */
17545721Smckusick 		(void) vnode_pager_uncache(ITOV(oip));
17626272Skarels 		bzero(bp->b_un.b_addr + offset, (unsigned)(size - offset));
17745112Smckusick 		allocbuf(bp, size);
17851183Sbostic 		lfs_bwrite(bp);
17917942Smckusick 	}
180*51484Sbostic 	/* BZERO INODE BLOCK POINTERS HERE, FOR CONSISTENCY XXX */
18124Sbill }
182