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