xref: /csrg-svn/sys/ufs/lfs/lfs_inode.c (revision 51484)
1 /*
2  * Copyright (c) 1982, 1986, 1989 Regents of the University of California.
3  * All rights reserved.
4  *
5  * %sccs.include.redist.c%
6  *
7  *	@(#)lfs_inode.c	7.45 (Berkeley) 11/01/91
8  */
9 
10 #include <sys/param.h>
11 #include <sys/systm.h>
12 #include <sys/mount.h>
13 #include <sys/proc.h>
14 #include <sys/file.h>
15 #include <sys/buf.h>
16 #include <sys/vnode.h>
17 #include <sys/kernel.h>
18 #include <sys/malloc.h>
19 
20 #include <ufs/quota.h>
21 #include <ufs/inode.h>
22 #include <ufs/ufsmount.h>
23 #include <ufs/ufs_extern.h>
24 
25 #include <lfs/lfs.h>
26 #include <lfs/lfs_extern.h>
27 
28 extern int prtactive;	/* 1 => print out reclaim of active vnodes */
29 
30 int
31 lfs_init()
32 {
33 	return (ufs_init());
34 }
35 
36 /*
37  * Look up an LFS dinode number to find its incore vnode.  If not already
38  * in core, read it in from the specified device.  Return the inode locked.
39  * Detection and handling of mount points must be done by the calling routine.
40  */
41 int
42 lfs_iget(pip, ino, ipp)
43 	struct inode *pip;
44 	ino_t ino;
45 	struct inode **ipp;
46 {
47 	register LFS *fs;
48 	register struct inode *ip;
49 	register struct vnode *vp;
50 	struct buf *bp;
51 	struct inode *nip;
52 	struct mount *mntp;
53 	struct vnode *nvp;
54 	dev_t dev;
55 	int error;
56 
57 printf("lfs_iget ino %d\n", ino);
58 
59 	if (ino < ROOTINO)
60 		return (EINVAL);
61 
62 	dev = pip->i_dev;
63 	if ((*ipp = ufs_ihashget(dev, ino)) != NULL)
64 		return (0);
65 
66 	/* Allocate new vnode/inode. */
67 	mntp = ITOV(pip)->v_mount;
68 	error = lfs_vcreate(mntp, ino, &nvp);
69 	if (error) {
70 		*ipp = NULL;
71 		return (error);
72 	}
73 	ip = VTOI(nvp);
74 
75 	/*
76 	 * Put it onto its hash chain and lock it so that other requests for
77 	 * this inode will block if they arrive while we are sleeping waiting
78 	 * for old data structures to be purged or for the contents of the
79 	 * disk portion of this inode to be read.
80 	 */
81 	ufs_ihashins(ip);
82 
83 	/* Read in the disk contents for the inode, copy into the inode. */
84 	fs = VFSTOUFS(mntp)->um_lfs;
85 	if (error = bread(VFSTOUFS(mntp)->um_devvp, lfs_itod(fs, ino),
86 	    (int)fs->lfs_bsize, NOCRED, &bp)) {
87 		/*
88 		 * The inode does not contain anything useful, so it would
89 		 * be misleading to leave it on its hash chain.  Iput() will
90 		 * take care of putting it back on the free list.
91 		 */
92 		remque(ip);
93 		ip->i_forw = ip;
94 		ip->i_back = ip;
95 
96 		/* Unlock and discard unneeded inode. */
97 		ufs_iput(ip);
98 		brelse(bp);
99 		*ipp = NULL;
100 		return (error);
101 	}
102 	ip->i_din = *lfs_ifind(fs, ino, bp->b_un.b_dino);
103 	brelse(bp);
104 
105 	/* Initialize the vnode from the inode, check for aliases. */
106 	if (error = ufs_vinit(mntp, ip, &nip)) {
107 		ufs_iput(ip);
108 		*ipp = NULL;
109 		return (error);
110 	}
111 	*ipp = nip;
112 	return (0);
113 }
114 
115 int
116 lfs_iupdat(ip, ta, tm, waitfor)
117 	register struct inode *ip;
118 	struct timeval *ta, *tm;
119         int waitfor;
120 {
121 	/*
122 	 * XXX
123 	 * This isn't right, but ufs_iupdat() isn't either.
124 	 */
125 	ITIMES(ip, ta, tm);
126 	return (0);
127 }
128 
129 /*
130  * Truncate the inode ip to at most length size.
131  *
132  * NB: triple indirect blocks are untested.
133  */
134 /* ARGSUSED */
135 int
136 lfs_itrunc(oip, length, flags)
137 	register struct inode *oip;
138 	u_long length;
139 	int flags;
140 {
141 	register LFS *fs;
142 	struct buf *bp;
143 	daddr_t lbn;
144 	int error, offset, size;
145 
146 	vnode_pager_setsize(ITOV(oip), length);
147 
148 	/* If length is larger than the file, just update the times. */
149 	if (oip->i_size <= length) {
150 		oip->i_flag |= ICHG|IUPD;
151 		ITIMES(oip, &time, &time);
152 		return (0);
153 	}
154 
155 	/*
156 	 * Update the size of the file. If the file is not being truncated to
157 	 * a block boundry, the contents of the partial block following the end
158 	 * of the file must be zero'ed in case it ever become accessable again
159 	 * because of subsequent file growth.
160 	 */
161 	fs = oip->i_lfs;
162 	offset = blkoff(fs, length);
163 	if (offset == 0)
164 		oip->i_size = length;
165 	else {
166 		lbn = lblkno(fs, length);
167 #ifdef QUOTA
168 		if (error = getinoquota(oip))
169 			return (error);
170 #endif
171 		if (error = bread(ITOV(oip), lbn, fs->lfs_bsize, NOCRED, &bp))
172 			return (error);
173 		oip->i_size = length;
174 		size = blksize(fs);				/* LFS */
175 		(void) vnode_pager_uncache(ITOV(oip));
176 		bzero(bp->b_un.b_addr + offset, (unsigned)(size - offset));
177 		allocbuf(bp, size);
178 		lfs_bwrite(bp);
179 	}
180 	/* BZERO INODE BLOCK POINTERS HERE, FOR CONSISTENCY XXX */
181 }
182