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