xref: /original-bsd/sys/ufs/lfs/lfs_inode.c (revision 82ad9df5)
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.8 (Berkeley) 06/07/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 			vp->v_count++;
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 	ip->i_devvp->v_count++;
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 	vp->v_count++;
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 	ILOCK(ip);
464 	if (ip->i_nlink <= 0 && (ITOV(ip)->v_mount->m_flag&M_RDONLY) == 0) {
465 		error = itrunc(ip, (u_long)0);
466 		mode = ip->i_mode;
467 		ip->i_mode = 0;
468 		ip->i_rdev = 0;
469 		ip->i_flag |= IUPD|ICHG;
470 		ifree(ip, ip->i_number, mode);
471 #ifdef QUOTA
472 		(void) chkiq(ip->i_dev, ip, ip->i_uid, 0);
473 		dqrele(ip->i_dquot);
474 		ip->i_dquot = NODQUOT;
475 #endif
476 	}
477 	IUPDAT(ip, &time, &time, 0);
478 	IUNLOCK(ip);
479 	ip->i_flag = 0;
480 	/*
481 	 * Put the inode on the end of the free list.
482 	 * Possibly in some cases it would be better to
483 	 * put the inode at the head of the free list,
484 	 * (eg: where i_mode == 0 || i_number == 0).
485 	 */
486 	INSFREE(ip);
487 	return (error);
488 }
489 
490 /*
491  * Check accessed and update flags on
492  * an inode structure.
493  * If any is on, update the inode
494  * with the current time.
495  * If waitfor is given, then must insure
496  * i/o order so wait for write to complete.
497  */
498 iupdat(ip, ta, tm, waitfor)
499 	register struct inode *ip;
500 	struct timeval *ta, *tm;
501 	int waitfor;
502 {
503 	struct buf *bp;
504 	struct vnode *vp = ITOV(ip);
505 	struct dinode *dp;
506 	register struct fs *fs;
507 	int error;
508 
509 	fs = ip->i_fs;
510 	if ((ip->i_flag & (IUPD|IACC|ICHG|IMOD)) == 0)
511 		return (0);
512 	if (vp->v_mount->m_flag & M_RDONLY)
513 		return (0);
514 	error = bread(ip->i_devvp, fsbtodb(fs, itod(fs, ip->i_number)),
515 		(int)fs->fs_bsize, &bp);
516 	if (error) {
517 		brelse(bp);
518 		return (error);
519 	}
520 	if (ip->i_flag&IACC)
521 		ip->i_atime = ta->tv_sec;
522 	if (ip->i_flag&IUPD)
523 		ip->i_mtime = tm->tv_sec;
524 	if (ip->i_flag&ICHG)
525 		ip->i_ctime = time.tv_sec;
526 	ip->i_flag &= ~(IUPD|IACC|ICHG|IMOD);
527 	dp = bp->b_un.b_dino + itoo(fs, ip->i_number);
528 	dp->di_ic = ip->i_ic;
529 	if (waitfor) {
530 		return (bwrite(bp));
531 	} else {
532 		bdwrite(bp);
533 		return (0);
534 	}
535 }
536 
537 #define	SINGLE	0	/* index of single indirect block */
538 #define	DOUBLE	1	/* index of double indirect block */
539 #define	TRIPLE	2	/* index of triple indirect block */
540 /*
541  * Truncate the inode ip to at most
542  * length size.  Free affected disk
543  * blocks -- the blocks of the file
544  * are removed in reverse order.
545  *
546  * NB: triple indirect blocks are untested.
547  */
548 itrunc(oip, length)
549 	register struct inode *oip;
550 	u_long length;
551 {
552 	register daddr_t lastblock;
553 	daddr_t bn, lbn, lastiblock[NIADDR];
554 	register struct fs *fs;
555 	register struct inode *ip;
556 	struct buf *bp;
557 	int offset, osize, size, level;
558 	long count, nblocks, blocksreleased = 0;
559 	register int i;
560 	int error, allerror = 0;
561 	struct inode tip;
562 
563 	if (oip->i_size <= length) {
564 		oip->i_flag |= ICHG|IUPD;
565 		error = iupdat(oip, &time, &time, 1);
566 		return (error);
567 	}
568 	/*
569 	 * Calculate index into inode's block list of
570 	 * last direct and indirect blocks (if any)
571 	 * which we want to keep.  Lastblock is -1 when
572 	 * the file is truncated to 0.
573 	 */
574 	fs = oip->i_fs;
575 	lastblock = lblkno(fs, length + fs->fs_bsize - 1) - 1;
576 	lastiblock[SINGLE] = lastblock - NDADDR;
577 	lastiblock[DOUBLE] = lastiblock[SINGLE] - NINDIR(fs);
578 	lastiblock[TRIPLE] = lastiblock[DOUBLE] - NINDIR(fs) * NINDIR(fs);
579 	nblocks = btodb(fs->fs_bsize);
580 	/*
581 	 * Update the size of the file. If the file is not being
582 	 * truncated to a block boundry, the contents of the
583 	 * partial block following the end of the file must be
584 	 * zero'ed in case it ever become accessable again because
585 	 * of subsequent file growth.
586 	 */
587 	osize = oip->i_size;
588 	offset = blkoff(fs, length);
589 	if (offset == 0) {
590 		oip->i_size = length;
591 	} else {
592 		lbn = lblkno(fs, length);
593 		error = balloc(oip, lbn, offset, &bn, B_CLRBUF);
594 		if (error)
595 			return (error);
596 		if ((long)bn < 0)
597 			panic("itrunc: hole");
598 		oip->i_size = length;
599 		size = blksize(fs, oip, lbn);
600 		count = howmany(size, CLBYTES);
601 		for (i = 0; i < count; i++)
602 			munhash(oip->i_devvp, bn + i * CLBYTES / DEV_BSIZE);
603 		error = bread(oip->i_devvp, bn, size, &bp);
604 		if (error) {
605 			oip->i_size = osize;
606 			brelse(bp);
607 			return (error);
608 		}
609 		bzero(bp->b_un.b_addr + offset, (unsigned)(size - offset));
610 		bdwrite(bp);
611 	}
612 	/*
613 	 * Update file and block pointers
614 	 * on disk before we start freeing blocks.
615 	 * If we crash before free'ing blocks below,
616 	 * the blocks will be returned to the free list.
617 	 * lastiblock values are also normalized to -1
618 	 * for calls to indirtrunc below.
619 	 */
620 	tip = *oip;
621 	tip.i_size = osize;
622 	for (level = TRIPLE; level >= SINGLE; level--)
623 		if (lastiblock[level] < 0) {
624 			oip->i_ib[level] = 0;
625 			lastiblock[level] = -1;
626 		}
627 	for (i = NDADDR - 1; i > lastblock; i--)
628 		oip->i_db[i] = 0;
629 	oip->i_flag |= ICHG|IUPD;
630 	allerror = syncip(oip);
631 
632 	/*
633 	 * Indirect blocks first.
634 	 */
635 	ip = &tip;
636 	for (level = TRIPLE; level >= SINGLE; level--) {
637 		bn = ip->i_ib[level];
638 		if (bn != 0) {
639 			error = indirtrunc(ip, bn, lastiblock[level], level,
640 				&count);
641 			if (error)
642 				allerror = error;
643 			blocksreleased += count;
644 			if (lastiblock[level] < 0) {
645 				ip->i_ib[level] = 0;
646 				blkfree(ip, bn, (off_t)fs->fs_bsize);
647 				blocksreleased += nblocks;
648 			}
649 		}
650 		if (lastiblock[level] >= 0)
651 			goto done;
652 	}
653 
654 	/*
655 	 * All whole direct blocks or frags.
656 	 */
657 	for (i = NDADDR - 1; i > lastblock; i--) {
658 		register off_t bsize;
659 
660 		bn = ip->i_db[i];
661 		if (bn == 0)
662 			continue;
663 		ip->i_db[i] = 0;
664 		bsize = (off_t)blksize(fs, ip, i);
665 		blkfree(ip, bn, bsize);
666 		blocksreleased += btodb(bsize);
667 	}
668 	if (lastblock < 0)
669 		goto done;
670 
671 	/*
672 	 * Finally, look for a change in size of the
673 	 * last direct block; release any frags.
674 	 */
675 	bn = ip->i_db[lastblock];
676 	if (bn != 0) {
677 		off_t oldspace, newspace;
678 
679 		/*
680 		 * Calculate amount of space we're giving
681 		 * back as old block size minus new block size.
682 		 */
683 		oldspace = blksize(fs, ip, lastblock);
684 		ip->i_size = length;
685 		newspace = blksize(fs, ip, lastblock);
686 		if (newspace == 0)
687 			panic("itrunc: newspace");
688 		if (oldspace - newspace > 0) {
689 			/*
690 			 * Block number of space to be free'd is
691 			 * the old block # plus the number of frags
692 			 * required for the storage we're keeping.
693 			 */
694 			bn += numfrags(fs, newspace);
695 			blkfree(ip, bn, oldspace - newspace);
696 			blocksreleased += btodb(oldspace - newspace);
697 		}
698 	}
699 done:
700 /* BEGIN PARANOIA */
701 	for (level = SINGLE; level <= TRIPLE; level++)
702 		if (ip->i_ib[level] != oip->i_ib[level])
703 			panic("itrunc1");
704 	for (i = 0; i < NDADDR; i++)
705 		if (ip->i_db[i] != oip->i_db[i])
706 			panic("itrunc2");
707 /* END PARANOIA */
708 	oip->i_blocks -= blocksreleased;
709 	if (oip->i_blocks < 0)			/* sanity */
710 		oip->i_blocks = 0;
711 	oip->i_flag |= ICHG;
712 #ifdef QUOTA
713 	(void) chkdq(oip, -blocksreleased, 0);
714 #endif
715 	return (allerror);
716 }
717 
718 /*
719  * Release blocks associated with the inode ip and
720  * stored in the indirect block bn.  Blocks are free'd
721  * in LIFO order up to (but not including) lastbn.  If
722  * level is greater than SINGLE, the block is an indirect
723  * block and recursive calls to indirtrunc must be used to
724  * cleanse other indirect blocks.
725  *
726  * NB: triple indirect blocks are untested.
727  */
728 indirtrunc(ip, bn, lastbn, level, countp)
729 	register struct inode *ip;
730 	daddr_t bn, lastbn;
731 	int level;
732 	long *countp;
733 {
734 	register int i;
735 	struct buf *bp;
736 	register struct fs *fs = ip->i_fs;
737 	register daddr_t *bap;
738 	daddr_t *copy, nb, last;
739 	long blkcount, factor;
740 	int nblocks, blocksreleased = 0;
741 	int error, allerror = 0;
742 
743 	/*
744 	 * Calculate index in current block of last
745 	 * block to be kept.  -1 indicates the entire
746 	 * block so we need not calculate the index.
747 	 */
748 	factor = 1;
749 	for (i = SINGLE; i < level; i++)
750 		factor *= NINDIR(fs);
751 	last = lastbn;
752 	if (lastbn > 0)
753 		last /= factor;
754 	nblocks = btodb(fs->fs_bsize);
755 	/*
756 	 * Get buffer of block pointers, zero those
757 	 * entries corresponding to blocks to be free'd,
758 	 * and update on disk copy first.
759 	 */
760 	error = bread(ip->i_devvp, fsbtodb(fs, bn), (int)fs->fs_bsize, &bp);
761 	if (error) {
762 		brelse(bp);
763 		*countp = 0;
764 		return (error);
765 	}
766 	bap = bp->b_un.b_daddr;
767 	MALLOC(copy, daddr_t *, fs->fs_bsize, M_TEMP, M_WAITOK);
768 	bcopy((caddr_t)bap, (caddr_t)copy, (u_int)fs->fs_bsize);
769 	bzero((caddr_t)&bap[last + 1],
770 	  (u_int)(NINDIR(fs) - (last + 1)) * sizeof (daddr_t));
771 	error = bwrite(bp);
772 	if (error)
773 		allerror = error;
774 	bap = copy;
775 
776 	/*
777 	 * Recursively free totally unused blocks.
778 	 */
779 	for (i = NINDIR(fs) - 1; i > last; i--) {
780 		nb = bap[i];
781 		if (nb == 0)
782 			continue;
783 		if (level > SINGLE) {
784 			error = indirtrunc(ip, nb, (daddr_t)-1, level - 1,
785 				&blkcount);
786 			if (error)
787 				allerror = error;
788 			blocksreleased += blkcount;
789 		}
790 		blkfree(ip, nb, (off_t)fs->fs_bsize);
791 		blocksreleased += nblocks;
792 	}
793 
794 	/*
795 	 * Recursively free last partial block.
796 	 */
797 	if (level > SINGLE && lastbn >= 0) {
798 		last = lastbn % factor;
799 		nb = bap[i];
800 		if (nb != 0) {
801 			error = indirtrunc(ip, nb, last, level - 1, &blkcount);
802 			if (error)
803 				allerror = error;
804 			blocksreleased += blkcount;
805 		}
806 	}
807 	FREE(copy, M_TEMP);
808 	*countp = blocksreleased;
809 	return (allerror);
810 }
811 
812 /*
813  * Remove any inodes in the inode cache belonging to dev.
814  *
815  * There should not be any active ones, return error if any are found
816  * (nb: this is a user error, not a system err).
817  */
818 #ifdef QUOTA
819 iflush(dev, iq)
820 	dev_t dev;
821 	struct inode *iq;
822 #else
823 iflush(dev)
824 	dev_t dev;
825 #endif
826 {
827 	register struct inode *ip;
828 
829 	for (ip = inode; ip < inodeNINODE; ip++) {
830 #ifdef QUOTA
831 		if (ip != iq && ip->i_dev == dev)
832 #else
833 		if (ip->i_dev == dev)
834 #endif
835 			if (ITOV(ip)->v_count)
836 				return (EBUSY);
837 			else {
838 				remque(ip);
839 				ip->i_forw = ip;
840 				ip->i_back = ip;
841 				/*
842 				 * as v_count == 0, the inode was on the free
843 				 * list already, just leave it there, it will
844 				 * fall off the bottom eventually. We could
845 				 * perhaps move it to the head of the free
846 				 * list, but as umounts are done so
847 				 * infrequently, we would gain very little,
848 				 * while making the code bigger.
849 				 */
850 #ifdef QUOTA
851 				dqrele(ip->i_dquot);
852 				ip->i_dquot = NODQUOT;
853 #endif
854 				if (ip->i_devvp) {
855 					vrele(ip->i_devvp);
856 					ip->i_devvp = 0;
857 				}
858 			}
859 	}
860 	return (0);
861 }
862 
863 /*
864  * Lock an inode. If its already locked, set the WANT bit and sleep.
865  */
866 ilock(ip)
867 	register struct inode *ip;
868 {
869 
870 	while (ip->i_flag & ILOCKED) {
871 		ip->i_flag |= IWANT;
872 		(void) sleep((caddr_t)ip, PINOD);
873 	}
874 	ip->i_flag |= ILOCKED;
875 }
876 
877 /*
878  * Unlock an inode.  If WANT bit is on, wakeup.
879  */
880 iunlock(ip)
881 	register struct inode *ip;
882 {
883 
884 	if ((ip->i_flag & ILOCKED) == 0)
885 		printf("unlocking unlocked inode %d on dev 0x%x\n",
886 			ip->i_number, ip->i_dev);
887 	ip->i_flag &= ~ILOCKED;
888 	if (ip->i_flag&IWANT) {
889 		ip->i_flag &= ~IWANT;
890 		wakeup((caddr_t)ip);
891 	}
892 }
893 
894 /*
895  * Check mode permission on inode pointer. Mode is READ, WRITE or EXEC.
896  * The mode is shifted to select the owner/group/other fields. The
897  * super user is granted all permissions.
898  *
899  * NB: Called from vnode op table. It seems this could all be done
900  * using vattr's but...
901  */
902 iaccess(ip, mode, cred)
903 	register struct inode *ip;
904 	register int mode;
905 	struct ucred *cred;
906 {
907 	register gid_t *gp;
908 	register struct vnode *vp = ITOV(ip);
909 	int i;
910 
911 	/*
912 	 * If you're the super-user,
913 	 * you always get access.
914 	 */
915 	if (cred->cr_uid == 0)
916 		return (0);
917 	/*
918 	 * Access check is based on only one of owner, group, public.
919 	 * If not owner, then check group. If not a member of the
920 	 * group, then check public access.
921 	 */
922 	if (cred->cr_uid != ip->i_uid) {
923 		mode >>= 3;
924 		gp = cred->cr_groups;
925 		for (i = 0; i < cred->cr_ngroups; i++, gp++)
926 			if (ip->i_gid == *gp)
927 				goto found;
928 		mode >>= 3;
929 found:
930 		;
931 	}
932 	if ((ip->i_mode & mode) != 0)
933 		return (0);
934 	return (EACCES);
935 }
936