xref: /csrg-svn/sys/ufs/lfs/lfs_inode.c (revision 38776)
1 /*
2  * Copyright (c) 1982, 1986, 1989 Regents of the University of California.
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms are permitted
6  * provided that the above copyright notice and this paragraph are
7  * duplicated in all such forms and that any documentation,
8  * advertising materials, and other materials related to such
9  * distribution and use acknowledge that the software was developed
10  * by the University of California, Berkeley.  The name of the
11  * University may not be used to endorse or promote products derived
12  * from this software without specific prior written permission.
13  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
14  * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
15  * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
16  *
17  *	@(#)lfs_inode.c	7.12 (Berkeley) 08/26/89
18  */
19 
20 #include "param.h"
21 #include "systm.h"
22 #include "mount.h"
23 #include "user.h"
24 #include "file.h"
25 #include "buf.h"
26 #include "cmap.h"
27 #include "vnode.h"
28 #include "../ufs/inode.h"
29 #include "../ufs/fs.h"
30 #include "../ufs/ufsmount.h"
31 #ifdef QUOTA
32 #include "../ufs/quota.h"
33 #endif
34 #include "kernel.h"
35 #include "malloc.h"
36 
37 #define	INOHSZ	512
38 #if	((INOHSZ&(INOHSZ-1)) == 0)
39 #define	INOHASH(dev,ino)	(((dev)+(ino))&(INOHSZ-1))
40 #else
41 #define	INOHASH(dev,ino)	(((unsigned)((dev)+(ino)))%INOHSZ)
42 #endif
43 
44 #define INSFREE(ip) {\
45 	if (ifreeh) { \
46 		*ifreet = (ip); \
47 		(ip)->i_freeb = ifreet; \
48 	} else { \
49 		ifreeh = (ip); \
50 		(ip)->i_freeb = &ifreeh; \
51 	} \
52 	(ip)->i_freef = NULL; \
53 	ifreet = &(ip)->i_freef; \
54 }
55 
56 union ihead {				/* inode LRU cache, Chris Maltby */
57 	union  ihead *ih_head[2];
58 	struct inode *ih_chain[2];
59 } ihead[INOHSZ];
60 
61 struct inode *ifreeh, **ifreet, *bdevlisth;
62 
63 /*
64  * Initialize hash links for inodes
65  * and build inode free list.
66  */
67 ihinit()
68 {
69 	register int i;
70 	register struct inode *ip = inode;
71 	register union  ihead *ih = ihead;
72 
73 	for (i = INOHSZ; --i >= 0; ih++) {
74 		ih->ih_head[0] = ih;
75 		ih->ih_head[1] = ih;
76 	}
77 	ifreeh = ip;
78 	ifreet = &ip->i_freef;
79 	ip->i_freeb = &ifreeh;
80 	ip->i_forw = ip;
81 	ip->i_back = ip;
82 	ITOV(ip)->v_data = (qaddr_t)ip;
83 	for (i = ninode; --i > 0; ) {
84 		++ip;
85 		ip->i_forw = ip;
86 		ip->i_back = ip;
87 		ITOV(ip)->v_data = (qaddr_t)ip;
88 		*ifreet = ip;
89 		ip->i_freeb = ifreet;
90 		ifreet = &ip->i_freef;
91 	}
92 	ip->i_freef = NULL;
93 }
94 
95 /*
96  * Look up an vnode/inode by device,inumber.
97  * If it is in core (in the inode structure),
98  * honor the locking protocol.
99  * If it is not in core, read it in from the
100  * specified device.
101  * Callers must check for mount points!!
102  * In all cases, a pointer to a locked
103  * inode structure is returned.
104  */
105 iget(xp, ino, ipp)
106 	struct inode *xp;
107 	ino_t ino;
108 	struct inode **ipp;
109 {
110 	dev_t dev = xp->i_dev;
111 	struct mount *mntp = ITOV(xp)->v_mount;
112 	register struct fs *fs = VFSTOUFS(mntp)->um_fs;
113 	register struct inode *ip, *iq;
114 	register struct vnode *vp;
115 	struct inode *nip;
116 	struct buf *bp;
117 	struct dinode tdip, *dp;
118 	union  ihead *ih;
119 	int error;
120 
121 loop:
122 	ih = &ihead[INOHASH(dev, ino)];
123 	for (ip = ih->ih_chain[0]; ip != (struct inode *)ih; ip = ip->i_forw)
124 		if (ino == ip->i_number && dev == ip->i_dev) {
125 			/*
126 			 * Following is essentially an inline expanded
127 			 * copy of igrab(), expanded inline for speed,
128 			 * and so that the test for a mounted on inode
129 			 * can be deferred until after we are sure that
130 			 * the inode isn't busy.
131 			 */
132 			if ((ip->i_flag&ILOCKED) != 0) {
133 				ip->i_flag |= IWANT;
134 				sleep((caddr_t)ip, PINOD);
135 				goto loop;
136 			}
137 			vp = ITOV(ip);
138 			if (vp->v_count == 0) {		/* ino on free list */
139 				if (iq = ip->i_freef)
140 					iq->i_freeb = ip->i_freeb;
141 				else
142 					ifreet = ip->i_freeb;
143 				*ip->i_freeb = iq;
144 				ip->i_freef = NULL;
145 				ip->i_freeb = NULL;
146 			}
147 			ILOCK(ip);
148 			VREF(vp);
149 			*ipp = ip;
150 			return(0);
151 		}
152 	if (error = getnewino(dev, ino, &nip)) {
153 		*ipp = 0;
154 		return (error);
155 	}
156 	ip = nip;
157 	/*
158 	 * Read in the disk contents for the inode.
159 	 */
160 	if (error = bread(VFSTOUFS(mntp)->um_devvp, fsbtodb(fs, itod(fs, ino)),
161 	    (int)fs->fs_bsize, NOCRED, &bp)) {
162 		/*
163 		 * The inode doesn't contain anything useful, so it would
164 		 * be misleading to leave it on its hash chain. Iput() will
165 		 * take care of putting it back on the free list. We also
166 		 * lose its inumber, just in case.
167 		 */
168 		remque(ip);
169 		ip->i_forw = ip;
170 		ip->i_back = ip;
171 		ip->i_number = 0;
172 		ITOV(ip)->v_type = VNON;
173 		INSFREE(ip);
174 		iunlock(ip);
175 		ip->i_flag = 0;
176 		brelse(bp);
177 		*ipp = 0;
178 		return(error);
179 	}
180 	/*
181 	 * Check to see if the new inode represents a block device
182 	 * for which we already have an inode (either because of
183 	 * bdevvp() or because of a different inode representing
184 	 * the same block device). If such an alias exists, put the
185 	 * just allocated inode back on the free list, and replace
186 	 * the contents of the existing inode with the contents of
187 	 * the new inode.
188 	 */
189 	dp = bp->b_un.b_dino;
190 	dp += itoo(fs, ino);
191 	if ((dp->di_mode & IFMT) != IFBLK) {
192 		ip->i_ic = dp->di_ic;
193 		brelse(bp);
194 	} else {
195 again:
196 		for (iq = bdevlisth; iq; iq = iq->i_devlst) {
197 			vp = ITOV(iq);
198 			if (dp->di_rdev != vp->v_rdev)
199 				continue;
200 			igrab(iq);
201 			if (dp->di_rdev != vp->v_rdev) {
202 				iput(iq);
203 				goto again;
204 			}
205 			/*
206 			 * Discard unneeded inode.
207 			 */
208 			remque(ip);
209 			ip->i_forw = ip;
210 			ip->i_back = ip;
211 			ip->i_number = 0;
212 			ITOV(ip)->v_type = VNON;
213 			INSFREE(ip);
214 			iunlock(ip);
215 			ip->i_flag = 0;
216 			/*
217 			 * Reinitialize aliased inode.
218 			 * We must release the buffer that we just read
219 			 * before doing the iupdat() to avoid a possible
220 			 * deadlock with updating an inode in the same
221 			 * disk block.
222 			 */
223 			ip = iq;
224 			tdip.di_ic = dp->di_ic;
225 			brelse(bp);
226 			error = iupdat(ip, &time, &time, 1);
227 			ip->i_ic = tdip.di_ic;
228 			remque(ip);
229 			insque(ip, ih);
230 			ip->i_dev = dev;
231 			ip->i_number = ino;
232 			if (ip->i_devvp) {
233 				vrele(ip->i_devvp);
234 				ip->i_devvp = 0;
235 			}
236 			cache_purge(vp);
237 			break;
238 		}
239 		if (iq == 0) {
240 			ip->i_ic = dp->di_ic;
241 			brelse(bp);
242 			ip->i_devlst = bdevlisth;
243 			bdevlisth = ip;
244 		}
245 	}
246 	/*
247 	 * Finish inode initialization.
248 	 */
249 	ip->i_fs = fs;
250 	ip->i_devvp = VFSTOUFS(mntp)->um_devvp;
251 	VREF(ip->i_devvp);
252 	/*
253 	 * Initialize the associated vnode
254 	 */
255 	vp = ITOV(ip);
256 	vinit(vp, mntp, IFTOVT(ip->i_mode), &ufs_vnodeops);
257 	if (vp->v_type == VCHR || vp->v_type == VBLK) {
258 		vp->v_rdev = ip->i_rdev;
259 		vp->v_op = &blk_vnodeops;
260 	}
261 	if (ino == ROOTINO)
262 		vp->v_flag |= VROOT;
263 #ifdef QUOTA
264 	if (ip->i_mode != 0)
265 		ip->i_dquot = inoquota(ip);
266 #endif
267 	/*
268 	 * Set up a generation number for this inode if it does not
269 	 * already have one. This should only happen on old filesystems.
270 	 */
271 	if (ip->i_gen == 0) {
272 		if (++nextgennumber < (u_long)time.tv_sec)
273 			nextgennumber = time.tv_sec;
274 		ip->i_gen = nextgennumber;
275 		if ((vp->v_mount->m_flag & M_RDONLY) == 0)
276 			ip->i_flag |= IMOD;
277 	}
278 	*ipp = ip;
279 	return (0);
280 }
281 
282 /*
283  * Allocate a new inode.
284  *
285  * Put it onto its hash chain and lock it so that other requests for
286  * this inode will block if they arrive while we are sleeping waiting
287  * for old data structures to be purged or for the contents of the disk
288  * portion of this inode to be read.
289  */
290 getnewino(dev, ino, ipp)
291 	dev_t dev;
292 	ino_t ino;
293 	struct inode **ipp;
294 {
295 	union ihead *ih;
296 	register struct inode *ip, *iq;
297 	register struct vnode *vp;
298 
299 	/*
300 	 * Remove the next inode from the free list.
301 	 */
302 	if ((ip = ifreeh) == NULL) {
303 		tablefull("inode");
304 		*ipp = 0;
305 		return(ENFILE);
306 	}
307 	vp = ITOV(ip);
308 	if (vp->v_count)
309 		panic("free inode isn't");
310 	if (iq = ip->i_freef)
311 		iq->i_freeb = &ifreeh;
312 	ifreeh = iq;
313 	ip->i_freef = NULL;
314 	ip->i_freeb = NULL;
315 	/*
316 	 * Now to take inode off the hash chain it was on
317 	 * (initially, or after an iflush, it is on a "hash chain"
318 	 * consisting entirely of itself, and pointed to by no-one)
319 	 * and put it on the chain for its new (ino, dev) pair.
320 	 */
321 	remque(ip);
322 	ip->i_dev = dev;
323 	ip->i_number = ino;
324 	if (dev != NODEV) {
325 		ih = &ihead[INOHASH(dev, ino)];
326 		insque(ip, ih);
327 	}
328 	ip->i_flag = 0;
329 	ILOCK(ip);
330 	ip->i_lastr = 0;
331 	/*
332 	 * Purge old data structures associated with the inode.
333 	 */
334 	cache_purge(vp);
335 	if (ip->i_devvp) {
336 		vrele(ip->i_devvp);
337 		ip->i_devvp = 0;
338 	}
339 #ifdef QUOTA
340 	dqrele(ip->i_dquot);
341 	ip->i_dquot = NODQUOT;
342 #endif
343 	if (vp->v_type == VBLK) {
344 		if (bdevlisth == ip) {
345 			bdevlisth = ip->i_devlst;
346 		} else {
347 			for (iq = bdevlisth; iq; iq = iq->i_devlst) {
348 				if (iq->i_devlst != ip)
349 					continue;
350 				iq->i_devlst = ip->i_devlst;
351 				break;
352 			}
353 			if (iq == NULL)
354 				panic("missing bdev");
355 		}
356 	}
357 	*ipp = ip;
358 	return (0);
359 }
360 
361 /*
362  * Convert a pointer to an inode into a reference to an inode.
363  *
364  * This is basically the internal piece of iget (after the
365  * inode pointer is located) but without the test for mounted
366  * filesystems.  It is caller's responsibility to check that
367  * the inode pointer is valid.
368  */
369 igrab(ip)
370 	register struct inode *ip;
371 {
372 	register struct vnode *vp = ITOV(ip);
373 
374 	while ((ip->i_flag&ILOCKED) != 0) {
375 		ip->i_flag |= IWANT;
376 		sleep((caddr_t)ip, PINOD);
377 	}
378 	if (vp->v_count == 0) {		/* ino on free list */
379 		register struct inode *iq;
380 
381 		if (iq = ip->i_freef)
382 			iq->i_freeb = ip->i_freeb;
383 		else
384 			ifreet = ip->i_freeb;
385 		*ip->i_freeb = iq;
386 		ip->i_freef = NULL;
387 		ip->i_freeb = NULL;
388 	}
389 	VREF(vp);
390 	ILOCK(ip);
391 }
392 
393 /*
394  * Create a vnode for a block device.
395  * Used for root filesystem, argdev, and swap areas.
396  */
397 bdevvp(dev, vpp)
398 	dev_t dev;
399 	struct vnode **vpp;
400 {
401 	register struct inode *ip;
402 	register struct vnode *vp;
403 	struct inode *nip;
404 	int error;
405 
406 	/*
407 	 * Check for the existence of an existing vnode.
408 	 */
409 again:
410 	for (ip = bdevlisth; ip; ip = ip->i_devlst) {
411 		vp = ITOV(ip);
412 		if (dev != vp->v_rdev)
413 			continue;
414 		igrab(ip);
415 		if (dev != vp->v_rdev) {
416 			iput(ip);
417 			goto again;
418 		}
419 		IUNLOCK(ip);
420 		*vpp = vp;
421 		return (0);
422 	}
423 	if (error = getnewino(NODEV, (ino_t)0, &nip)) {
424 		*vpp = 0;
425 		return (error);
426 	}
427 	ip = nip;
428 	ip->i_fs = 0;
429 	ip->i_devlst = bdevlisth;
430 	bdevlisth = ip;
431 	vp = ITOV(ip);
432 	vinit(vp, 0, VBLK, &blk_vnodeops);
433 	vp->v_rdev = dev;
434 	IUNLOCK(ip);
435 	*vpp = vp;
436 	return (0);
437 }
438 
439 /*
440  * Decrement reference count of
441  * an inode structure.
442  * On the last reference,
443  * write the inode out and if necessary,
444  * truncate and deallocate the file.
445  */
446 iput(ip)
447 	register struct inode *ip;
448 {
449 
450 	if ((ip->i_flag & ILOCKED) == 0)
451 		panic("iput");
452 	IUNLOCK(ip);
453 	vrele(ITOV(ip));
454 }
455 
456 
457 ufs_inactive(vp)
458 	struct vnode *vp;
459 {
460 	register struct inode *ip = VTOI(vp);
461 	int mode, error;
462 
463 	if (ITOV(ip)->v_count != 0)
464 		panic("ufs_inactive: not inactive");
465 	/*
466 	 * Get rid of inodes related to stale file handles.
467 	 */
468 	if (ip->i_mode == 0)
469 		goto freeit;
470 	ILOCK(ip);
471 	if (ip->i_nlink <= 0 && (ITOV(ip)->v_mount->m_flag&M_RDONLY) == 0) {
472 		error = itrunc(ip, (u_long)0);
473 		mode = ip->i_mode;
474 		ip->i_mode = 0;
475 		ip->i_rdev = 0;
476 		ip->i_flag |= IUPD|ICHG;
477 		ifree(ip, ip->i_number, mode);
478 #ifdef QUOTA
479 		(void) chkiq(ip->i_dev, ip, ip->i_uid, 0);
480 		dqrele(ip->i_dquot);
481 		ip->i_dquot = NODQUOT;
482 #endif
483 	}
484 	IUPDAT(ip, &time, &time, 0);
485 	IUNLOCK(ip);
486 freeit:
487 	ip->i_flag = 0;
488 	/*
489 	 * Put the inode on the end of the free list.
490 	 * Possibly in some cases it would be better to
491 	 * put the inode at the head of the free list,
492 	 * (eg: where i_mode == 0 || i_number == 0).
493 	 */
494 	INSFREE(ip);
495 	return (error);
496 }
497 
498 /*
499  * Check accessed and update flags on
500  * an inode structure.
501  * If any is on, update the inode
502  * with the current time.
503  * If waitfor is given, then must insure
504  * i/o order so wait for write to complete.
505  */
506 iupdat(ip, ta, tm, waitfor)
507 	register struct inode *ip;
508 	struct timeval *ta, *tm;
509 	int waitfor;
510 {
511 	struct buf *bp;
512 	struct vnode *vp = ITOV(ip);
513 	struct dinode *dp;
514 	register struct fs *fs;
515 	int error;
516 
517 	fs = ip->i_fs;
518 	if ((ip->i_flag & (IUPD|IACC|ICHG|IMOD)) == 0)
519 		return (0);
520 	if (vp->v_mount->m_flag & M_RDONLY)
521 		return (0);
522 	error = bread(ip->i_devvp, fsbtodb(fs, itod(fs, ip->i_number)),
523 		(int)fs->fs_bsize, NOCRED, &bp);
524 	if (error) {
525 		brelse(bp);
526 		return (error);
527 	}
528 	if (ip->i_flag&IACC)
529 		ip->i_atime = ta->tv_sec;
530 	if (ip->i_flag&IUPD)
531 		ip->i_mtime = tm->tv_sec;
532 	if (ip->i_flag&ICHG)
533 		ip->i_ctime = time.tv_sec;
534 	ip->i_flag &= ~(IUPD|IACC|ICHG|IMOD);
535 	dp = bp->b_un.b_dino + itoo(fs, ip->i_number);
536 	dp->di_ic = ip->i_ic;
537 	if (waitfor) {
538 		return (bwrite(bp));
539 	} else {
540 		bdwrite(bp);
541 		return (0);
542 	}
543 }
544 
545 #define	SINGLE	0	/* index of single indirect block */
546 #define	DOUBLE	1	/* index of double indirect block */
547 #define	TRIPLE	2	/* index of triple indirect block */
548 /*
549  * Truncate the inode ip to at most
550  * length size.  Free affected disk
551  * blocks -- the blocks of the file
552  * are removed in reverse order.
553  *
554  * NB: triple indirect blocks are untested.
555  */
556 itrunc(oip, length)
557 	register struct inode *oip;
558 	u_long length;
559 {
560 	register daddr_t lastblock;
561 	daddr_t bn, lbn, lastiblock[NIADDR];
562 	register struct fs *fs;
563 	register struct inode *ip;
564 	struct buf *bp;
565 	int offset, osize, size, level;
566 	long count, nblocks, blocksreleased = 0;
567 	register int i;
568 	int error, allerror = 0;
569 	struct inode tip;
570 
571 	if (oip->i_size <= length) {
572 		oip->i_flag |= ICHG|IUPD;
573 		error = iupdat(oip, &time, &time, 1);
574 		return (error);
575 	}
576 	/*
577 	 * Calculate index into inode's block list of
578 	 * last direct and indirect blocks (if any)
579 	 * which we want to keep.  Lastblock is -1 when
580 	 * the file is truncated to 0.
581 	 */
582 	fs = oip->i_fs;
583 	lastblock = lblkno(fs, length + fs->fs_bsize - 1) - 1;
584 	lastiblock[SINGLE] = lastblock - NDADDR;
585 	lastiblock[DOUBLE] = lastiblock[SINGLE] - NINDIR(fs);
586 	lastiblock[TRIPLE] = lastiblock[DOUBLE] - NINDIR(fs) * NINDIR(fs);
587 	nblocks = btodb(fs->fs_bsize);
588 	/*
589 	 * Update the size of the file. If the file is not being
590 	 * truncated to a block boundry, the contents of the
591 	 * partial block following the end of the file must be
592 	 * zero'ed in case it ever become accessable again because
593 	 * of subsequent file growth.
594 	 */
595 	osize = oip->i_size;
596 	offset = blkoff(fs, length);
597 	if (offset == 0) {
598 		oip->i_size = length;
599 	} else {
600 		lbn = lblkno(fs, length);
601 		error = balloc(oip, lbn, offset, &bn, B_CLRBUF);
602 		if (error)
603 			return (error);
604 		if ((long)bn < 0)
605 			panic("itrunc: hole");
606 		oip->i_size = length;
607 		size = blksize(fs, oip, lbn);
608 		count = howmany(size, CLBYTES);
609 		for (i = 0; i < count; i++)
610 			munhash(oip->i_devvp, bn + i * CLBYTES / DEV_BSIZE);
611 		error = bread(oip->i_devvp, bn, size, NOCRED, &bp);
612 		if (error) {
613 			oip->i_size = osize;
614 			brelse(bp);
615 			return (error);
616 		}
617 		bzero(bp->b_un.b_addr + offset, (unsigned)(size - offset));
618 		bdwrite(bp);
619 	}
620 	/*
621 	 * Update file and block pointers
622 	 * on disk before we start freeing blocks.
623 	 * If we crash before free'ing blocks below,
624 	 * the blocks will be returned to the free list.
625 	 * lastiblock values are also normalized to -1
626 	 * for calls to indirtrunc below.
627 	 */
628 	tip = *oip;
629 	tip.i_size = osize;
630 	for (level = TRIPLE; level >= SINGLE; level--)
631 		if (lastiblock[level] < 0) {
632 			oip->i_ib[level] = 0;
633 			lastiblock[level] = -1;
634 		}
635 	for (i = NDADDR - 1; i > lastblock; i--)
636 		oip->i_db[i] = 0;
637 	oip->i_flag |= ICHG|IUPD;
638 	allerror = syncip(oip);
639 
640 	/*
641 	 * Indirect blocks first.
642 	 */
643 	ip = &tip;
644 	for (level = TRIPLE; level >= SINGLE; level--) {
645 		bn = ip->i_ib[level];
646 		if (bn != 0) {
647 			error = indirtrunc(ip, bn, lastiblock[level], level,
648 				&count);
649 			if (error)
650 				allerror = error;
651 			blocksreleased += count;
652 			if (lastiblock[level] < 0) {
653 				ip->i_ib[level] = 0;
654 				blkfree(ip, bn, (off_t)fs->fs_bsize);
655 				blocksreleased += nblocks;
656 			}
657 		}
658 		if (lastiblock[level] >= 0)
659 			goto done;
660 	}
661 
662 	/*
663 	 * All whole direct blocks or frags.
664 	 */
665 	for (i = NDADDR - 1; i > lastblock; i--) {
666 		register off_t bsize;
667 
668 		bn = ip->i_db[i];
669 		if (bn == 0)
670 			continue;
671 		ip->i_db[i] = 0;
672 		bsize = (off_t)blksize(fs, ip, i);
673 		blkfree(ip, bn, bsize);
674 		blocksreleased += btodb(bsize);
675 	}
676 	if (lastblock < 0)
677 		goto done;
678 
679 	/*
680 	 * Finally, look for a change in size of the
681 	 * last direct block; release any frags.
682 	 */
683 	bn = ip->i_db[lastblock];
684 	if (bn != 0) {
685 		off_t oldspace, newspace;
686 
687 		/*
688 		 * Calculate amount of space we're giving
689 		 * back as old block size minus new block size.
690 		 */
691 		oldspace = blksize(fs, ip, lastblock);
692 		ip->i_size = length;
693 		newspace = blksize(fs, ip, lastblock);
694 		if (newspace == 0)
695 			panic("itrunc: newspace");
696 		if (oldspace - newspace > 0) {
697 			/*
698 			 * Block number of space to be free'd is
699 			 * the old block # plus the number of frags
700 			 * required for the storage we're keeping.
701 			 */
702 			bn += numfrags(fs, newspace);
703 			blkfree(ip, bn, oldspace - newspace);
704 			blocksreleased += btodb(oldspace - newspace);
705 		}
706 	}
707 done:
708 /* BEGIN PARANOIA */
709 	for (level = SINGLE; level <= TRIPLE; level++)
710 		if (ip->i_ib[level] != oip->i_ib[level])
711 			panic("itrunc1");
712 	for (i = 0; i < NDADDR; i++)
713 		if (ip->i_db[i] != oip->i_db[i])
714 			panic("itrunc2");
715 /* END PARANOIA */
716 	oip->i_blocks -= blocksreleased;
717 	if (oip->i_blocks < 0)			/* sanity */
718 		oip->i_blocks = 0;
719 	oip->i_flag |= ICHG;
720 #ifdef QUOTA
721 	(void) chkdq(oip, -blocksreleased, 0);
722 #endif
723 	return (allerror);
724 }
725 
726 /*
727  * Release blocks associated with the inode ip and
728  * stored in the indirect block bn.  Blocks are free'd
729  * in LIFO order up to (but not including) lastbn.  If
730  * level is greater than SINGLE, the block is an indirect
731  * block and recursive calls to indirtrunc must be used to
732  * cleanse other indirect blocks.
733  *
734  * NB: triple indirect blocks are untested.
735  */
736 indirtrunc(ip, bn, lastbn, level, countp)
737 	register struct inode *ip;
738 	daddr_t bn, lastbn;
739 	int level;
740 	long *countp;
741 {
742 	register int i;
743 	struct buf *bp;
744 	register struct fs *fs = ip->i_fs;
745 	register daddr_t *bap;
746 	daddr_t *copy, nb, last;
747 	long blkcount, factor;
748 	int nblocks, blocksreleased = 0;
749 	int error, allerror = 0;
750 
751 	/*
752 	 * Calculate index in current block of last
753 	 * block to be kept.  -1 indicates the entire
754 	 * block so we need not calculate the index.
755 	 */
756 	factor = 1;
757 	for (i = SINGLE; i < level; i++)
758 		factor *= NINDIR(fs);
759 	last = lastbn;
760 	if (lastbn > 0)
761 		last /= factor;
762 	nblocks = btodb(fs->fs_bsize);
763 	/*
764 	 * Get buffer of block pointers, zero those
765 	 * entries corresponding to blocks to be free'd,
766 	 * and update on disk copy first.
767 	 */
768 	error = bread(ip->i_devvp, fsbtodb(fs, bn), (int)fs->fs_bsize,
769 		NOCRED, &bp);
770 	if (error) {
771 		brelse(bp);
772 		*countp = 0;
773 		return (error);
774 	}
775 	bap = bp->b_un.b_daddr;
776 	MALLOC(copy, daddr_t *, fs->fs_bsize, M_TEMP, M_WAITOK);
777 	bcopy((caddr_t)bap, (caddr_t)copy, (u_int)fs->fs_bsize);
778 	bzero((caddr_t)&bap[last + 1],
779 	  (u_int)(NINDIR(fs) - (last + 1)) * sizeof (daddr_t));
780 	error = bwrite(bp);
781 	if (error)
782 		allerror = error;
783 	bap = copy;
784 
785 	/*
786 	 * Recursively free totally unused blocks.
787 	 */
788 	for (i = NINDIR(fs) - 1; i > last; i--) {
789 		nb = bap[i];
790 		if (nb == 0)
791 			continue;
792 		if (level > SINGLE) {
793 			error = indirtrunc(ip, nb, (daddr_t)-1, level - 1,
794 				&blkcount);
795 			if (error)
796 				allerror = error;
797 			blocksreleased += blkcount;
798 		}
799 		blkfree(ip, nb, (off_t)fs->fs_bsize);
800 		blocksreleased += nblocks;
801 	}
802 
803 	/*
804 	 * Recursively free last partial block.
805 	 */
806 	if (level > SINGLE && lastbn >= 0) {
807 		last = lastbn % factor;
808 		nb = bap[i];
809 		if (nb != 0) {
810 			error = indirtrunc(ip, nb, last, level - 1, &blkcount);
811 			if (error)
812 				allerror = error;
813 			blocksreleased += blkcount;
814 		}
815 	}
816 	FREE(copy, M_TEMP);
817 	*countp = blocksreleased;
818 	return (allerror);
819 }
820 
821 /*
822  * Remove any inodes in the inode cache belonging to dev.
823  *
824  * There should not be any active ones, return error if any are found
825  * (nb: this is a user error, not a system err).
826  */
827 #ifdef QUOTA
828 iflush(dev, iq)
829 	dev_t dev;
830 	struct inode *iq;
831 #else
832 iflush(dev)
833 	dev_t dev;
834 #endif
835 {
836 	register struct inode *ip;
837 
838 	for (ip = inode; ip < inodeNINODE; ip++) {
839 #ifdef QUOTA
840 		if (ip != iq && ip->i_dev == dev)
841 #else
842 		if (ip->i_dev == dev)
843 #endif
844 			if (ITOV(ip)->v_count)
845 				return (EBUSY);
846 			else {
847 				remque(ip);
848 				ip->i_forw = ip;
849 				ip->i_back = ip;
850 				/*
851 				 * as v_count == 0, the inode was on the free
852 				 * list already, just leave it there, it will
853 				 * fall off the bottom eventually. We could
854 				 * perhaps move it to the head of the free
855 				 * list, but as umounts are done so
856 				 * infrequently, we would gain very little,
857 				 * while making the code bigger.
858 				 */
859 #ifdef QUOTA
860 				dqrele(ip->i_dquot);
861 				ip->i_dquot = NODQUOT;
862 #endif
863 				if (ip->i_devvp) {
864 					vrele(ip->i_devvp);
865 					ip->i_devvp = 0;
866 				}
867 			}
868 	}
869 	return (0);
870 }
871 
872 /*
873  * Lock an inode. If its already locked, set the WANT bit and sleep.
874  */
875 ilock(ip)
876 	register struct inode *ip;
877 {
878 
879 	while (ip->i_flag & ILOCKED) {
880 		ip->i_flag |= IWANT;
881 		(void) sleep((caddr_t)ip, PINOD);
882 	}
883 	ip->i_flag |= ILOCKED;
884 }
885 
886 /*
887  * Unlock an inode.  If WANT bit is on, wakeup.
888  */
889 iunlock(ip)
890 	register struct inode *ip;
891 {
892 
893 	if ((ip->i_flag & ILOCKED) == 0)
894 		printf("unlocking unlocked inode %d on dev 0x%x\n",
895 			ip->i_number, ip->i_dev);
896 	ip->i_flag &= ~ILOCKED;
897 	if (ip->i_flag&IWANT) {
898 		ip->i_flag &= ~IWANT;
899 		wakeup((caddr_t)ip);
900 	}
901 }
902 
903 /*
904  * Check mode permission on inode pointer. Mode is READ, WRITE or EXEC.
905  * The mode is shifted to select the owner/group/other fields. The
906  * super user is granted all permissions.
907  *
908  * NB: Called from vnode op table. It seems this could all be done
909  * using vattr's but...
910  */
911 iaccess(ip, mode, cred)
912 	register struct inode *ip;
913 	register int mode;
914 	struct ucred *cred;
915 {
916 	register gid_t *gp;
917 	register struct vnode *vp = ITOV(ip);
918 	int i;
919 
920 	/*
921 	 * If you're the super-user,
922 	 * you always get access.
923 	 */
924 	if (cred->cr_uid == 0)
925 		return (0);
926 	/*
927 	 * Access check is based on only one of owner, group, public.
928 	 * If not owner, then check group. If not a member of the
929 	 * group, then check public access.
930 	 */
931 	if (cred->cr_uid != ip->i_uid) {
932 		mode >>= 3;
933 		gp = cred->cr_groups;
934 		for (i = 0; i < cred->cr_ngroups; i++, gp++)
935 			if (ip->i_gid == *gp)
936 				goto found;
937 		mode >>= 3;
938 found:
939 		;
940 	}
941 	if ((ip->i_mode & mode) != 0)
942 		return (0);
943 	return (EACCES);
944 }
945