xref: /csrg-svn/sys/ufs/lfs/lfs_inode.c (revision 8106)
1 /*	lfs_inode.c	4.24	82/09/06	*/
2 
3 #include "../h/param.h"
4 #include "../h/systm.h"
5 #include "../h/mount.h"
6 #include "../h/dir.h"
7 #include "../h/user.h"
8 #include "../h/inode.h"
9 #include "../h/fs.h"
10 #include "../h/conf.h"
11 #include "../h/buf.h"
12 #include "../h/inline.h"
13 #ifdef QUOTA
14 #include "../h/quota.h"
15 #endif
16 #include "../h/kernel.h"
17 
18 #define	INOHSZ	63
19 #if	((INOHSZ&(INOHSZ-1)) == 0)
20 #define	INOHASH(dev,ino)	(((dev)+(ino))&(INOHSZ-1))
21 #else
22 #define	INOHASH(dev,ino)	(((dev)+(ino))%INOHSZ)
23 #endif
24 
25 union ihead {				/* inode LRU cache, Chris Maltby */
26 	union  ihead *ih_head[2];
27 	struct inode *ih_chain[2];
28 } ihead[INOHSZ];
29 
30 struct inode *ifreeh, **ifreet;
31 
32 /*
33  * Initialize hash links for inodes
34  * and build inode free list.
35  */
36 ihinit()
37 {
38 	register int i;
39 	register struct inode *ip = inode;
40 	register union  ihead *ih = ihead;
41 
42 	for (i = INOHSZ; --i >= 0; ih++) {
43 		ih->ih_head[0] = ih;
44 		ih->ih_head[1] = ih;
45 	}
46 	ifreeh = ip;
47 	ifreet = &ip->i_freef;
48 	ip->i_freeb = &ifreeh;
49 	ip->i_forw = ip;
50 	ip->i_back = ip;
51 	for (i = ninode; --i > 0; ) {
52 		++ip;
53 		ip->i_forw = ip;
54 		ip->i_back = ip;
55 		*ifreet = ip;
56 		ip->i_freeb = ifreet;
57 		ifreet = &ip->i_freef;
58 	}
59 	ip->i_freef = NULL;
60 }
61 
62 #ifdef notdef
63 /*
64  * Find an inode if it is incore.
65  * This is the equivalent, for inodes,
66  * of ``incore'' in bio.c or ``pfind'' in subr.c.
67  */
68 struct inode *
69 ifind(dev, ino)
70 	dev_t dev;
71 	ino_t ino;
72 {
73 	register struct inode *ip;
74 	register union  ihead *ih;
75 
76 	ih = &ihead[INOHASH(dev, ino)];
77 	for (ip = ih->ih_chain[0]; ip != (struct inode *)ih; ip = ip->i_forw)
78 		if (ino==ip->i_number && dev==ip->i_dev)
79 			return (ip);
80 	return ((struct inode *)0);
81 }
82 #endif notdef
83 
84 /*
85  * Look up an inode by device,inumber.
86  * If it is in core (in the inode structure),
87  * honor the locking protocol.
88  * If it is not in core, read it in from the
89  * specified device.
90  * If the inode is mounted on, perform
91  * the indicated indirection.
92  * In all cases, a pointer to a locked
93  * inode structure is returned.
94  *
95  * panic: no imt -- if the mounted file
96  *	system is not in the mount table.
97  *	"cannot happen"
98  */
99 struct inode *
100 iget(dev, fs, ino)
101 	dev_t dev;
102 	register struct fs *fs;
103 	ino_t ino;
104 {
105 	register struct inode *ip;
106 	register union  ihead *ih;
107 	register struct mount *mp;
108 	register struct buf *bp;
109 	register struct dinode *dp;
110 	register struct inode *iq;
111 
112 loop:
113 	if (getfs(dev) != fs)
114 		panic("iget: bad fs");
115 	ih = &ihead[INOHASH(dev, ino)];
116 	for (ip = ih->ih_chain[0]; ip != (struct inode *)ih; ip = ip->i_forw)
117 		if (ino == ip->i_number && dev == ip->i_dev) {
118 			if ((ip->i_flag&ILOCK) != 0) {
119 				ip->i_flag |= IWANT;
120 				sleep((caddr_t)ip, PINOD);
121 				goto loop;
122 			}
123 			if ((ip->i_flag&IMOUNT) != 0) {
124 				for (mp = &mount[0]; mp < &mount[NMOUNT]; mp++)
125 					if(mp->m_inodp == ip) {
126 						dev = mp->m_dev;
127 						fs = mp->m_bufp->b_un.b_fs;
128 						ino = ROOTINO;
129 						goto loop;
130 					}
131 				panic("no imt");
132 			}
133 			if (ip->i_count == 0) {		/* ino on free list */
134 				if (iq = ip->i_freef)
135 					iq->i_freeb = ip->i_freeb;
136 				else
137 					ifreet = ip->i_freeb;
138 				*ip->i_freeb = iq;
139 				ip->i_freef = NULL;
140 				ip->i_freeb = NULL;
141 			}
142 			ip->i_count++;
143 			ip->i_flag |= ILOCK;
144 			return(ip);
145 		}
146 
147 	if ((ip = ifreeh) == NULL) {
148 		tablefull("inode");
149 		u.u_error = ENFILE;
150 		return(NULL);
151 	}
152 	if (iq = ip->i_freef)
153 		iq->i_freeb = &ifreeh;
154 	ifreeh = iq;
155 	ip->i_freef = NULL;
156 	ip->i_freeb = NULL;
157 	/*
158 	 * Now to take inode off the hash chain it was on
159 	 * (initially, or after an iflush, it is on a "hash chain"
160 	 * consisting entirely of itself, and pointed to by no-one,
161 	 * but that doesn't matter), and put it on the chain for
162 	 * its new (ino, dev) pair
163 	 */
164 	remque(ip);
165 	insque(ip, ih);
166 #ifdef QUOTA
167 	dqrele(ip->i_dquot);
168 #endif
169 	ip->i_dev = dev;
170 	ip->i_fs = fs;
171 	ip->i_number = ino;
172 	ip->i_flag = ILOCK;
173 	ip->i_count++;
174 	ip->i_lastr = 0;
175 	bp = bread(dev, fsbtodb(fs, itod(fs, ino)), fs->fs_bsize);
176 	/*
177 	 * Check I/O errors
178 	 */
179 	if ((bp->b_flags&B_ERROR) != 0) {
180 		brelse(bp);
181 		/*
182 		 * the inode doesn't contain anything useful, so it would
183 		 * be misleading to leave it on its hash chain.
184 		 * 'iput' will take care of putting it back on the free list.
185 		 */
186 		remque(ip);
187 		ip->i_forw = ip;
188 		ip->i_back = ip;
189 		/*
190 		 * we also loose its inumber, just in case (as iput
191 		 * doesn't do that any more) - but as it isn't on its
192 		 * hash chain, I doubt if this is really necessary .. kre
193 		 * (probably the two methods are interchangable)
194 		 */
195 		ip->i_number = 0;
196 #ifdef QUOTA
197 		ip->i_dquot = NODQUOT;
198 #endif
199 		iput(ip);
200 		return(NULL);
201 	}
202 	dp = bp->b_un.b_dino;
203 	dp += itoo(fs, ino);
204 	ip->i_ic = dp->di_ic;
205 	brelse(bp);
206 #ifdef QUOTA
207 	if (ip->i_mode == 0)
208 		ip->i_dquot = NODQUOT;
209 	else
210 		ip->i_dquot = inoquota(ip);
211 #endif
212 	return (ip);
213 }
214 
215 /*
216  * Decrement reference count of
217  * an inode structure.
218  * On the last reference,
219  * write the inode out and if necessary,
220  * truncate and deallocate the file.
221  */
222 iput(ip)
223 	register struct inode *ip;
224 {
225 
226 	if ((ip->i_flag & ILOCK) == 0)
227 		panic("iput");
228 	iunlock(ip);
229 	irele(ip);
230 }
231 
232 irele(ip)
233 	register struct inode *ip;
234 {
235 	register int i, x;
236 	register struct inode *jp;
237 	int mode;
238 
239 	if (ip->i_count == 1) {
240 		ip->i_flag |= ILOCK;
241 		if (ip->i_nlink <= 0) {
242 			itrunc(ip, 0);
243 			mode = ip->i_mode;
244 			ip->i_mode = 0;
245 			ip->i_rdev = 0;
246 			ip->i_flag |= IUPD|ICHG;
247 			ifree(ip, ip->i_number, mode);
248 #ifdef QUOTA
249 			chkiq(ip->i_dev, ip, ip->i_uid, 0);
250 			dqrele(ip->i_dquot);
251 			ip->i_dquot = NODQUOT;
252 #endif
253 		}
254 		IUPDAT(ip, &time.tv_sec, &time.tv_sec, 0);
255 		iunlock(ip);
256 		ip->i_flag = 0;
257 		/*
258 		 * Put the inode on the end of the free list.
259 		 * Possibly in some cases it would be better to
260 		 * put the inode at the head of the free list,
261 		 * (eg: where i_mode == 0 || i_number == 0)
262 		 * but I will think about that later .. kre
263 		 * (i_number is rarely 0 - only after an i/o error in iget,
264 		 * where i_mode == 0, the inode will probably be wanted
265 		 * again soon for an ialloc, so possibly we should keep it)
266 		 */
267 		if (ifreeh) {
268 			*ifreet = ip;
269 			ip->i_freeb = ifreet;
270 		} else {
271 			ifreeh = ip;
272 			ip->i_freeb = &ifreeh;
273 		}
274 		ip->i_freef = NULL;
275 		ifreet = &ip->i_freef;
276 	}
277 	ip->i_count--;
278 }
279 
280 /*
281  * Check accessed and update flags on
282  * an inode structure.
283  * If any is on, update the inode
284  * with the current time.
285  * If waitfor is given, then must insure
286  * i/o order so wait for write to complete.
287  */
288 iupdat(ip, ta, tm, waitfor)
289 	register struct inode *ip;
290 	time_t *ta, *tm;
291 	int waitfor;
292 {
293 	register struct buf *bp;
294 	struct dinode *dp;
295 	register struct fs *fp;
296 
297 	fp = ip->i_fs;
298 	if ((ip->i_flag & (IUPD|IACC|ICHG)) != 0) {
299 		if (fp->fs_ronly)
300 			return;
301 		bp = bread(ip->i_dev, fsbtodb(fp, itod(fp, ip->i_number)),
302 			fp->fs_bsize);
303 		if (bp->b_flags & B_ERROR) {
304 			brelse(bp);
305 			return;
306 		}
307 		if (ip->i_flag&IACC)
308 			ip->i_atime = *ta;
309 		if (ip->i_flag&IUPD)
310 			ip->i_mtime = *tm;
311 		if (ip->i_flag&ICHG)
312 			ip->i_ctime = time.tv_sec;
313 		ip->i_flag &= ~(IUPD|IACC|ICHG);
314 		dp = bp->b_un.b_dino + itoo(fp, ip->i_number);
315 		dp->di_ic = ip->i_ic;
316 		if (waitfor)
317 			bwrite(bp);
318 		else
319 			bdwrite(bp);
320 	}
321 }
322 
323 /*
324  * Truncate the inode ip to at most
325  * length size.  Free affected disk
326  * blocks -- the blocks of the file
327  * are removed in reverse order.
328  */
329 itrunc(ip, length)
330 	register struct inode *ip;
331 	register int length;
332 {
333 	register i;
334 	dev_t dev;
335 	daddr_t bn;
336 	struct inode itmp;
337 	register struct fs *fs;
338 #ifdef QUOTA
339 	register long cnt = 0;
340 	long tloop();
341 #endif
342 	/*
343 	 * Only plain files, directories and symbolic
344 	 * links contain blocks.
345 	 */
346 	i = ip->i_mode & IFMT;
347 	if (i != IFREG && i != IFDIR && i != IFLNK)
348 		return;
349 	if (ip->i_size <= length)
350 		return;
351 
352 	/*
353 	 * Clean inode on disk before freeing blocks
354 	 * to insure no duplicates if system crashes.
355 	 */
356 	itmp = *ip;
357 	itmp.i_size = length;
358 	for (i = 0; i < NDADDR; i++)
359 		itmp.i_db[i] = 0;
360 	for (i = 0; i < NIADDR; i++)
361 		itmp.i_ib[i] = 0;
362 	itmp.i_flag |= ICHG|IUPD;
363 	iupdat(&itmp, &time.tv_sec, &time.tv_sec, 1);
364 	ip->i_flag &= ~(IUPD|IACC|ICHG);
365 
366 	/*
367 	 * Now return blocks to free list... if machine
368 	 * crashes, they will be harmless MISSING blocks.
369 	 */
370 	dev = ip->i_dev;
371 	fs = ip->i_fs;
372 	/*
373 	 * release double indirect block first
374 	 */
375 	bn = ip->i_ib[NIADDR-1];
376 	if (bn != (daddr_t)0) {
377 		ip->i_ib[NIADDR - 1] = (daddr_t)0;
378 #ifdef QUOTA
379 		cnt +=
380 #endif
381 			tloop(ip, bn, 1);
382 	}
383 	/*
384 	 * release single indirect blocks second
385 	 */
386 	for (i = NIADDR - 2; i >= 0; i--) {
387 		bn = ip->i_ib[i];
388 		if (bn != (daddr_t)0) {
389 			ip->i_ib[i] = (daddr_t)0;
390 #ifdef QUOTA
391 			cnt +=
392 #endif
393 				tloop(ip, bn, 0);
394 		}
395 	}
396 	/*
397 	 * finally release direct blocks
398 	 */
399 	for (i = NDADDR - 1; i>=0; i--) {
400 		register size;
401 
402 		bn = ip->i_db[i];
403 		if (bn == (daddr_t)0)
404 			continue;
405 		ip->i_db[i] = (daddr_t)0;
406 		fre(ip, bn, size = (off_t)blksize(fs, ip, i));
407 #ifdef QUOTA
408 		cnt += size / DEV_BSIZE;
409 #endif
410 	}
411 	ip->i_size = 0;
412 	/*
413 	 * Inode was written and flags updated above.
414 	 * No need to modify flags here.
415 	 */
416 #ifdef QUOTA
417 	(void) chkdq(ip, -cnt, 0);
418 #endif
419 }
420 
421 #ifdef QUOTA
422 long
423 #endif
424 tloop(ip, bn, indflg)
425 	register struct inode *ip;
426 	daddr_t bn;
427 	int indflg;
428 {
429 	register i;
430 	register struct buf *bp;
431 	register daddr_t *bap;
432 	register struct fs *fs;
433 	daddr_t nb;
434 #ifdef QUOTA
435 	register long cnt = 0;
436 #endif
437 
438 	bp = NULL;
439 	fs = ip->i_fs;
440 	for (i = NINDIR(fs) - 1; i >= 0; i--) {
441 		if (bp == NULL) {
442 			bp = bread(ip->i_dev, fsbtodb(fs, bn), fs->fs_bsize);
443 			if (bp->b_flags & B_ERROR) {
444 				brelse(bp);
445 				return;
446 			}
447 			bap = bp->b_un.b_daddr;
448 		}
449 		nb = bap[i];
450 		if (nb == (daddr_t)0)
451 			continue;
452 		if (indflg) {
453 #ifdef QUOTA
454 			cnt +=
455 #endif
456 				tloop(ip, nb, 0);
457 		} else {
458 			fre(ip, nb, fs->fs_bsize);
459 #ifdef QUOTA
460 			cnt += fs->fs_bsize / DEV_BSIZE;
461 #endif
462 		}
463 	}
464 	if (bp != NULL)
465 		brelse(bp);
466 	fre(ip, bn, fs->fs_bsize);
467 #ifdef QUOTA
468 	cnt += fs->fs_bsize / DEV_BSIZE;
469 	return(cnt);
470 #endif
471 }
472 
473 /*
474  * remove any inodes in the inode cache belonging to dev
475  *
476  * There should not be any active ones, return error if any are found
477  * (nb: this is a user error, not a system err)
478  *
479  * Also, count the references to dev by block devices - this really
480  * has nothing to do with the object of the procedure, but as we have
481  * to scan the inode table here anyway, we might as well get the
482  * extra benefit.
483  *
484  * this is called from sumount()/sys3.c when dev is being unmounted
485  */
486 #ifdef QUOTA
487 iflush(dev, iq)
488 	dev_t dev;
489 	struct inode *iq;
490 #else
491 iflush(dev)
492 	dev_t dev;
493 #endif
494 {
495 	register struct inode *ip;
496 	register open = 0;
497 
498 	for (ip = inode; ip < inodeNINODE; ip++) {
499 #ifdef QUOTA
500 		if (ip != iq && ip->i_dev == dev)
501 #else
502 		if (ip->i_dev == dev)
503 #endif
504 			if (ip->i_count)
505 				return(-1);
506 			else {
507 				remque(ip);
508 				ip->i_forw = ip;
509 				ip->i_back = ip;
510 				/*
511 				 * as i_count == 0, the inode was on the free
512 				 * list already, just leave it there, it will
513 				 * fall off the bottom eventually. We could
514 				 * perhaps move it to the head of the free
515 				 * list, but as umounts are done so
516 				 * infrequently, we would gain very little,
517 				 * while making the code bigger.
518 				 */
519 #ifdef QUOTA
520 				dqrele(ip->i_dquot);
521 				ip->i_dquot = NODQUOT;
522 #endif
523 			}
524 		else if (ip->i_count && (ip->i_mode&IFMT)==IFBLK &&
525 		    ip->i_rdev == dev)
526 			open++;
527 	}
528 	return (open);
529 }
530 
531 #ifdef ilock
532 #undef ilock
533 #endif
534 #ifdef iunlock
535 #undef iunlock
536 #endif
537 /*
538  * Lock an inode. If its already locked, set the WANT bit and sleep.
539  */
540 ilock(ip)
541 	register struct inode *ip;
542 {
543 
544 	while (ip->i_flag&ILOCK) {
545 		ip->i_flag |= IWANT;
546 		sleep((caddr_t)ip, PINOD);
547 	}
548 	ip->i_flag |= ILOCK;
549 }
550 
551 /*
552  * Unlock an inode.  If WANT bit is on, wakeup.
553  */
554 iunlock(ip)
555 	register struct inode *ip;
556 {
557 
558 	ip->i_flag &= ~ILOCK;
559 	if (ip->i_flag&IWANT) {
560 		ip->i_flag &= ~IWANT;
561 		wakeup((caddr_t)ip);
562 	}
563 }
564