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