xref: /original-bsd/sys/kern/vfs_subr.c (revision e59fb703)
1 /*
2  * Copyright (c) 1989 The Regents of the University of California.
3  * All rights reserved.
4  *
5  * %sccs.include.redist.c%
6  *
7  *	@(#)vfs_subr.c	7.64 (Berkeley) 12/19/91
8  */
9 
10 /*
11  * External virtual filesystem routines
12  */
13 
14 #include <sys/param.h>
15 #include <sys/proc.h>
16 #include <sys/mount.h>
17 #include <sys/time.h>
18 #include <sys/vnode.h>
19 #include <sys/specdev.h>
20 #include <sys/namei.h>
21 #include <sys/ucred.h>
22 #include <sys/buf.h>
23 #include <sys/errno.h>
24 #include <sys/malloc.h>
25 
26 /*
27  * Remove a mount point from the list of mounted filesystems.
28  * Unmount of the root is illegal.
29  */
30 void
31 vfs_remove(mp)
32 	register struct mount *mp;
33 {
34 
35 	if (mp == rootfs)
36 		panic("vfs_remove: unmounting root");
37 	mp->mnt_prev->mnt_next = mp->mnt_next;
38 	mp->mnt_next->mnt_prev = mp->mnt_prev;
39 	mp->mnt_vnodecovered->v_mountedhere = (struct mount *)0;
40 	vfs_unlock(mp);
41 }
42 
43 /*
44  * Lock a filesystem.
45  * Used to prevent access to it while mounting and unmounting.
46  */
47 vfs_lock(mp)
48 	register struct mount *mp;
49 {
50 
51 	while(mp->mnt_flag & MNT_MLOCK) {
52 		mp->mnt_flag |= MNT_MWAIT;
53 		sleep((caddr_t)mp, PVFS);
54 	}
55 	mp->mnt_flag |= MNT_MLOCK;
56 	return (0);
57 }
58 
59 /*
60  * Unlock a locked filesystem.
61  * Panic if filesystem is not locked.
62  */
63 void
64 vfs_unlock(mp)
65 	register struct mount *mp;
66 {
67 
68 	if ((mp->mnt_flag & MNT_MLOCK) == 0)
69 		panic("vfs_unlock: not locked");
70 	mp->mnt_flag &= ~MNT_MLOCK;
71 	if (mp->mnt_flag & MNT_MWAIT) {
72 		mp->mnt_flag &= ~MNT_MWAIT;
73 		wakeup((caddr_t)mp);
74 	}
75 }
76 
77 /*
78  * Mark a mount point as busy.
79  * Used to synchronize access and to delay unmounting.
80  */
81 vfs_busy(mp)
82 	register struct mount *mp;
83 {
84 
85 	while(mp->mnt_flag & MNT_MPBUSY) {
86 		mp->mnt_flag |= MNT_MPWANT;
87 		sleep((caddr_t)&mp->mnt_flag, PVFS);
88 	}
89 	if (mp->mnt_flag & MNT_UNMOUNT)
90 		return (1);
91 	mp->mnt_flag |= MNT_MPBUSY;
92 	return (0);
93 }
94 
95 /*
96  * Free a busy filesystem.
97  * Panic if filesystem is not busy.
98  */
99 vfs_unbusy(mp)
100 	register struct mount *mp;
101 {
102 
103 	if ((mp->mnt_flag & MNT_MPBUSY) == 0)
104 		panic("vfs_unbusy: not busy");
105 	mp->mnt_flag &= ~MNT_MPBUSY;
106 	if (mp->mnt_flag & MNT_MPWANT) {
107 		mp->mnt_flag &= ~MNT_MPWANT;
108 		wakeup((caddr_t)&mp->mnt_flag);
109 	}
110 }
111 
112 /*
113  * Lookup a mount point by filesystem identifier.
114  */
115 struct mount *
116 getvfs(fsid)
117 	fsid_t *fsid;
118 {
119 	register struct mount *mp;
120 
121 	mp = rootfs;
122 	do {
123 		if (mp->mnt_stat.f_fsid.val[0] == fsid->val[0] &&
124 		    mp->mnt_stat.f_fsid.val[1] == fsid->val[1]) {
125 			return (mp);
126 		}
127 		mp = mp->mnt_next;
128 	} while (mp != rootfs);
129 	return ((struct mount *)0);
130 }
131 
132 /*
133  * Set vnode attributes to VNOVAL
134  */
135 void vattr_null(vap)
136 	register struct vattr *vap;
137 {
138 
139 	vap->va_type = VNON;
140 	vap->va_size = vap->va_bytes = VNOVAL;
141 #ifdef _NOQUAD
142 	vap->va_size_rsv = vap->va_bytes_rsv = VNOVAL;
143 #endif
144 	vap->va_mode = vap->va_nlink = vap->va_uid = vap->va_gid =
145 		vap->va_fsid = vap->va_fileid =
146 		vap->va_blocksize = vap->va_rdev =
147 		vap->va_atime.tv_sec = vap->va_atime.tv_usec =
148 		vap->va_mtime.tv_sec = vap->va_mtime.tv_usec =
149 		vap->va_ctime.tv_sec = vap->va_ctime.tv_usec =
150 		vap->va_flags = vap->va_gen = VNOVAL;
151 }
152 
153 /*
154  * Routines having to do with the management of the vnode table.
155  */
156 struct vnode *vfreeh, **vfreet;
157 extern struct vnodeops dead_vnodeops, spec_vnodeops;
158 extern void vclean();
159 long numvnodes;
160 struct vattr va_null;
161 
162 /*
163  * Initialize the vnode structures and initialize each file system type.
164  */
165 vfsinit()
166 {
167 	struct vfsops **vfsp;
168 
169 	/*
170 	 * Initialize the vnode name cache
171 	 */
172 	nchinit();
173 	/*
174 	 * Initialize each file system type.
175 	 */
176 	vattr_null(&va_null);
177 	for (vfsp = &vfssw[0]; vfsp <= &vfssw[MOUNT_MAXTYPE]; vfsp++) {
178 		if (*vfsp == NULL)
179 			continue;
180 		(*(*vfsp)->vfs_init)();
181 	}
182 }
183 
184 /*
185  * Return the next vnode from the free list.
186  */
187 getnewvnode(tag, mp, vops, vpp)
188 	enum vtagtype tag;
189 	struct mount *mp;
190 	struct vnodeops *vops;
191 	struct vnode **vpp;
192 {
193 	register struct vnode *vp, *vq;
194 
195 	if (numvnodes < desiredvnodes) {
196 		vp = (struct vnode *)malloc((u_long)sizeof *vp,
197 		    M_VNODE, M_WAITOK);
198 		bzero((char *)vp, sizeof *vp);
199 		numvnodes++;
200 	} else {
201 		if ((vp = vfreeh) == NULL) {
202 			tablefull("vnode");
203 			*vpp = 0;
204 			return (ENFILE);
205 		}
206 		if (vp->v_usecount)
207 			panic("free vnode isn't");
208 		if (vq = vp->v_freef)
209 			vq->v_freeb = &vfreeh;
210 		else
211 			vfreet = &vfreeh;
212 		vfreeh = vq;
213 		vp->v_freef = NULL;
214 		vp->v_freeb = NULL;
215 		if (vp->v_type != VBAD)
216 			vgone(vp);
217 		if (vp->v_data)
218 			panic("cleaned vnode isn't");
219 		vp->v_flag = 0;
220 		vp->v_lastr = 0;
221 		vp->v_socket = 0;
222 	}
223 	vp->v_type = VNON;
224 	cache_purge(vp);
225 	vp->v_tag = tag;
226 	vp->v_op = vops;
227 	insmntque(vp, mp);
228 	VREF(vp);
229 	*vpp = vp;
230 	return (0);
231 }
232 
233 /*
234  * Move a vnode from one mount queue to another.
235  */
236 insmntque(vp, mp)
237 	register struct vnode *vp;
238 	register struct mount *mp;
239 {
240 	register struct vnode *vq;
241 
242 	/*
243 	 * Delete from old mount point vnode list, if on one.
244 	 */
245 	if (vp->v_mountb) {
246 		if (vq = vp->v_mountf)
247 			vq->v_mountb = vp->v_mountb;
248 		*vp->v_mountb = vq;
249 	}
250 	/*
251 	 * Insert into list of vnodes for the new mount point, if available.
252 	 */
253 	vp->v_mount = mp;
254 	if (mp == NULL) {
255 		vp->v_mountf = NULL;
256 		vp->v_mountb = NULL;
257 		return;
258 	}
259 	if (vq = mp->mnt_mounth)
260 		vq->v_mountb = &vp->v_mountf;
261 	vp->v_mountf = vq;
262 	vp->v_mountb = &mp->mnt_mounth;
263 	mp->mnt_mounth = vp;
264 }
265 
266 /*
267  * Make sure all write-behind blocks associated
268  * with mount point are flushed out (from sync).
269  */
270 mntflushbuf(mountp, flags)
271 	struct mount *mountp;
272 	int flags;
273 {
274 	register struct vnode *vp;
275 
276 	if ((mountp->mnt_flag & MNT_MPBUSY) == 0)
277 		panic("mntflushbuf: not busy");
278 loop:
279 	for (vp = mountp->mnt_mounth; vp; vp = vp->v_mountf) {
280 		if (VOP_ISLOCKED(vp))
281 			continue;
282 		if (vget(vp))
283 			goto loop;
284 		vflushbuf(vp, flags);
285 		vput(vp);
286 		if (vp->v_mount != mountp)
287 			goto loop;
288 	}
289 }
290 
291 /*
292  * Flush all dirty buffers associated with a vnode.
293  */
294 vflushbuf(vp, flags)
295 	register struct vnode *vp;
296 	int flags;
297 {
298 	register struct buf *bp;
299 	struct buf *nbp;
300 	int s;
301 
302 loop:
303 	s = splbio();
304 	for (bp = vp->v_dirtyblkhd; bp; bp = nbp) {
305 		nbp = bp->b_blockf;
306 		if ((bp->b_flags & B_BUSY))
307 			continue;
308 		if ((bp->b_flags & B_DELWRI) == 0)
309 			panic("vflushbuf: not dirty");
310 		bremfree(bp);
311 		bp->b_flags |= B_BUSY;
312 		splx(s);
313 		/*
314 		 * Wait for I/O associated with indirect blocks to complete,
315 		 * since there is no way to quickly wait for them below.
316 		 * NB: This is really specific to ufs, but is done here
317 		 * as it is easier and quicker.
318 		 */
319 		if (bp->b_vp == vp || (flags & B_SYNC) == 0)
320 			(void) bawrite(bp);
321 		else
322 			(void) bwrite(bp);
323 		goto loop;
324 	}
325 	splx(s);
326 	if ((flags & B_SYNC) == 0)
327 		return;
328 	s = splbio();
329 	while (vp->v_numoutput) {
330 		vp->v_flag |= VBWAIT;
331 		sleep((caddr_t)&vp->v_numoutput, PRIBIO + 1);
332 	}
333 	splx(s);
334 	if (vp->v_dirtyblkhd) {
335 		vprint("vflushbuf: dirty", vp);
336 		goto loop;
337 	}
338 }
339 
340 /*
341  * Update outstanding I/O count and do wakeup if requested.
342  */
343 vwakeup(bp)
344 	register struct buf *bp;
345 {
346 	register struct vnode *vp;
347 
348 	bp->b_dirtyoff = bp->b_dirtyend = 0;
349 	if (vp = bp->b_vp) {
350 		vp->v_numoutput--;
351 		if ((vp->v_flag & VBWAIT) && vp->v_numoutput <= 0) {
352 			if (vp->v_numoutput < 0)
353 				panic("vwakeup: neg numoutput");
354 			vp->v_flag &= ~VBWAIT;
355 			wakeup((caddr_t)&vp->v_numoutput);
356 		}
357 	}
358 }
359 
360 /*
361  * Invalidate in core blocks belonging to closed or umounted filesystem
362  *
363  * Go through the list of vnodes associated with the file system;
364  * for each vnode invalidate any buffers that it holds. Normally
365  * this routine is preceeded by a bflush call, so that on a quiescent
366  * filesystem there will be no dirty buffers when we are done. Binval
367  * returns the count of dirty buffers when it is finished.
368  */
369 mntinvalbuf(mountp)
370 	struct mount *mountp;
371 {
372 	register struct vnode *vp;
373 	int dirty = 0;
374 
375 	if ((mountp->mnt_flag & MNT_MPBUSY) == 0)
376 		panic("mntinvalbuf: not busy");
377 loop:
378 	for (vp = mountp->mnt_mounth; vp; vp = vp->v_mountf) {
379 		if (vget(vp))
380 			goto loop;
381 		dirty += vinvalbuf(vp, 1);
382 		vput(vp);
383 		if (vp->v_mount != mountp)
384 			goto loop;
385 	}
386 	return (dirty);
387 }
388 
389 /*
390  * Flush out and invalidate all buffers associated with a vnode.
391  * Called with the underlying object locked.
392  */
393 vinvalbuf(vp, save)
394 	register struct vnode *vp;
395 	int save;
396 {
397 	register struct buf *bp;
398 	struct buf *nbp, *blist;
399 	int s, dirty = 0;
400 
401 	for (;;) {
402 		if (blist = vp->v_dirtyblkhd)
403 			/* void */;
404 		else if (blist = vp->v_cleanblkhd)
405 			/* void */;
406 		else
407 			break;
408 		for (bp = blist; bp; bp = nbp) {
409 			nbp = bp->b_blockf;
410 			s = splbio();
411 			if (bp->b_flags & B_BUSY) {
412 				bp->b_flags |= B_WANTED;
413 				sleep((caddr_t)bp, PRIBIO + 1);
414 				splx(s);
415 				break;
416 			}
417 			bremfree(bp);
418 			bp->b_flags |= B_BUSY;
419 			splx(s);
420 			if (save && (bp->b_flags & B_DELWRI)) {
421 				dirty++;
422 				(void) VOP_BWRITE(bp);
423 				break;
424 			}
425 			if (bp->b_vp != vp)
426 				reassignbuf(bp, bp->b_vp);
427 			else
428 				bp->b_flags |= B_INVAL;
429 			brelse(bp);
430 		}
431 	}
432 	if (vp->v_dirtyblkhd || vp->v_cleanblkhd)
433 		panic("vinvalbuf: flush failed");
434 	return (dirty);
435 }
436 
437 /*
438  * Associate a buffer with a vnode.
439  */
440 bgetvp(vp, bp)
441 	register struct vnode *vp;
442 	register struct buf *bp;
443 {
444 	register struct vnode *vq;
445 	register struct buf *bq;
446 
447 	if (bp->b_vp)
448 		panic("bgetvp: not free");
449 	VHOLD(vp);
450 	bp->b_vp = vp;
451 	if (vp->v_type == VBLK || vp->v_type == VCHR)
452 		bp->b_dev = vp->v_rdev;
453 	else
454 		bp->b_dev = NODEV;
455 	/*
456 	 * Insert onto list for new vnode.
457 	 */
458 	if (bq = vp->v_cleanblkhd)
459 		bq->b_blockb = &bp->b_blockf;
460 	bp->b_blockf = bq;
461 	bp->b_blockb = &vp->v_cleanblkhd;
462 	vp->v_cleanblkhd = bp;
463 }
464 
465 /*
466  * Disassociate a buffer from a vnode.
467  */
468 brelvp(bp)
469 	register struct buf *bp;
470 {
471 	struct buf *bq;
472 	struct vnode *vp;
473 
474 	if (bp->b_vp == (struct vnode *) 0)
475 		panic("brelvp: NULL");
476 	/*
477 	 * Delete from old vnode list, if on one.
478 	 */
479 	if (bp->b_blockb) {
480 		if (bq = bp->b_blockf)
481 			bq->b_blockb = bp->b_blockb;
482 		*bp->b_blockb = bq;
483 		bp->b_blockf = NULL;
484 		bp->b_blockb = NULL;
485 	}
486 	vp = bp->b_vp;
487 	bp->b_vp = (struct vnode *) 0;
488 	HOLDRELE(vp);
489 }
490 
491 /*
492  * Reassign a buffer from one vnode to another.
493  * Used to assign file specific control information
494  * (indirect blocks) to the vnode to which they belong.
495  */
496 reassignbuf(bp, newvp)
497 	register struct buf *bp;
498 	register struct vnode *newvp;
499 {
500 	register struct buf *bq, **listheadp;
501 
502 	if (newvp == NULL)
503 		panic("reassignbuf: NULL");
504 	/*
505 	 * Delete from old vnode list, if on one.
506 	 */
507 	if (bp->b_blockb) {
508 		if (bq = bp->b_blockf)
509 			bq->b_blockb = bp->b_blockb;
510 		*bp->b_blockb = bq;
511 	}
512 	/*
513 	 * If dirty, put on list of dirty buffers;
514 	 * otherwise insert onto list of clean buffers.
515 	 */
516 	if (bp->b_flags & B_DELWRI)
517 		listheadp = &newvp->v_dirtyblkhd;
518 	else
519 		listheadp = &newvp->v_cleanblkhd;
520 	if (bq = *listheadp)
521 		bq->b_blockb = &bp->b_blockf;
522 	bp->b_blockf = bq;
523 	bp->b_blockb = listheadp;
524 	*listheadp = bp;
525 }
526 
527 /*
528  * Create a vnode for a block device.
529  * Used for root filesystem, argdev, and swap areas.
530  * Also used for memory file system special devices.
531  */
532 bdevvp(dev, vpp)
533 	dev_t dev;
534 	struct vnode **vpp;
535 {
536 	register struct vnode *vp;
537 	struct vnode *nvp;
538 	int error;
539 
540 	if (dev == NODEV)
541 		return (0);
542 	error = getnewvnode(VT_NON, (struct mount *)0, &spec_vnodeops, &nvp);
543 	if (error) {
544 		*vpp = 0;
545 		return (error);
546 	}
547 	vp = nvp;
548 	vp->v_type = VBLK;
549 	if (nvp = checkalias(vp, dev, (struct mount *)0)) {
550 		vput(vp);
551 		vp = nvp;
552 	}
553 	*vpp = vp;
554 	return (0);
555 }
556 
557 /*
558  * Check to see if the new vnode represents a special device
559  * for which we already have a vnode (either because of
560  * bdevvp() or because of a different vnode representing
561  * the same block device). If such an alias exists, deallocate
562  * the existing contents and return the aliased vnode. The
563  * caller is responsible for filling it with its new contents.
564  */
565 struct vnode *
566 checkalias(nvp, nvp_rdev, mp)
567 	register struct vnode *nvp;
568 	dev_t nvp_rdev;
569 	struct mount *mp;
570 {
571 	register struct vnode *vp;
572 	struct vnode **vpp;
573 
574 	if (nvp->v_type != VBLK && nvp->v_type != VCHR)
575 		return (NULLVP);
576 
577 	vpp = &speclisth[SPECHASH(nvp_rdev)];
578 loop:
579 	for (vp = *vpp; vp; vp = vp->v_specnext) {
580 		if (nvp_rdev != vp->v_rdev || nvp->v_type != vp->v_type)
581 			continue;
582 		/*
583 		 * Alias, but not in use, so flush it out.
584 		 */
585 		if (vp->v_usecount == 0) {
586 			vgone(vp);
587 			goto loop;
588 		}
589 		if (vget(vp))
590 			goto loop;
591 		break;
592 	}
593 	if (vp == NULL || vp->v_tag != VT_NON) {
594 		MALLOC(nvp->v_specinfo, struct specinfo *,
595 			sizeof(struct specinfo), M_VNODE, M_WAITOK);
596 		nvp->v_rdev = nvp_rdev;
597 		nvp->v_hashchain = vpp;
598 		nvp->v_specnext = *vpp;
599 		nvp->v_specflags = 0;
600 		*vpp = nvp;
601 		if (vp != NULL) {
602 			nvp->v_flag |= VALIASED;
603 			vp->v_flag |= VALIASED;
604 			vput(vp);
605 		}
606 		return (NULLVP);
607 	}
608 	VOP_UNLOCK(vp);
609 	vclean(vp, 0);
610 	vp->v_op = nvp->v_op;
611 	vp->v_tag = nvp->v_tag;
612 	nvp->v_type = VNON;
613 	insmntque(vp, mp);
614 	return (vp);
615 }
616 
617 /*
618  * Grab a particular vnode from the free list, increment its
619  * reference count and lock it. The vnode lock bit is set the
620  * vnode is being eliminated in vgone. The process is awakened
621  * when the transition is completed, and an error returned to
622  * indicate that the vnode is no longer usable (possibly having
623  * been changed to a new file system type).
624  */
625 vget(vp)
626 	register struct vnode *vp;
627 {
628 	register struct vnode *vq;
629 
630 	if (vp->v_flag & VXLOCK) {
631 		vp->v_flag |= VXWANT;
632 		sleep((caddr_t)vp, PINOD);
633 		return (1);
634 	}
635 	if (vp->v_usecount == 0) {
636 		if (vq = vp->v_freef)
637 			vq->v_freeb = vp->v_freeb;
638 		else
639 			vfreet = vp->v_freeb;
640 		*vp->v_freeb = vq;
641 		vp->v_freef = NULL;
642 		vp->v_freeb = NULL;
643 	}
644 	VREF(vp);
645 	VOP_LOCK(vp);
646 	return (0);
647 }
648 
649 /*
650  * Vnode reference, just increment the count
651  */
652 void vref(vp)
653 	struct vnode *vp;
654 {
655 
656 	vp->v_usecount++;
657 }
658 
659 /*
660  * vput(), just unlock and vrele()
661  */
662 void vput(vp)
663 	register struct vnode *vp;
664 {
665 	VOP_UNLOCK(vp);
666 	vrele(vp);
667 }
668 
669 /*
670  * Vnode release.
671  * If count drops to zero, call inactive routine and return to freelist.
672  */
673 void vrele(vp)
674 	register struct vnode *vp;
675 {
676 	struct proc *p = curproc;		/* XXX */
677 
678 #ifdef DIAGNOSTIC
679 	if (vp == NULL)
680 		panic("vrele: null vp");
681 #endif
682 	vp->v_usecount--;
683 	if (vp->v_usecount > 0)
684 		return;
685 #ifdef DIAGNOSTIC
686 	if (vp->v_usecount != 0 || vp->v_writecount != 0) {
687 		vprint("vrele: bad ref count", vp);
688 		panic("vrele: ref cnt");
689 	}
690 #endif
691 	if (vfreeh == NULLVP) {
692 		/*
693 		 * insert into empty list
694 		 */
695 		vfreeh = vp;
696 		vp->v_freeb = &vfreeh;
697 	} else {
698 		/*
699 		 * insert at tail of list
700 		 */
701 		*vfreet = vp;
702 		vp->v_freeb = vfreet;
703 	}
704 	vp->v_freef = NULL;
705 	vfreet = &vp->v_freef;
706 	VOP_INACTIVE(vp, p);
707 }
708 
709 /*
710  * Page or buffer structure gets a reference.
711  */
712 vhold(vp)
713 	register struct vnode *vp;
714 {
715 
716 	vp->v_holdcnt++;
717 }
718 
719 /*
720  * Page or buffer structure frees a reference.
721  */
722 holdrele(vp)
723 	register struct vnode *vp;
724 {
725 
726 	if (vp->v_holdcnt <= 0)
727 		panic("holdrele: holdcnt");
728 	vp->v_holdcnt--;
729 }
730 
731 /*
732  * Remove any vnodes in the vnode table belonging to mount point mp.
733  *
734  * If MNT_NOFORCE is specified, there should not be any active ones,
735  * return error if any are found (nb: this is a user error, not a
736  * system error). If MNT_FORCE is specified, detach any active vnodes
737  * that are found.
738  */
739 int busyprt = 0;	/* patch to print out busy vnodes */
740 
741 vflush(mp, skipvp, flags)
742 	struct mount *mp;
743 	struct vnode *skipvp;
744 	int flags;
745 {
746 	register struct vnode *vp, *nvp;
747 	int busy = 0;
748 
749 	if ((mp->mnt_flag & MNT_MPBUSY) == 0)
750 		panic("vflush: not busy");
751 loop:
752 	for (vp = mp->mnt_mounth; vp; vp = nvp) {
753 		if (vp->v_mount != mp)
754 			goto loop;
755 		nvp = vp->v_mountf;
756 		/*
757 		 * Skip over a selected vnode.
758 		 */
759 		if (vp == skipvp)
760 			continue;
761 		/*
762 		 * Skip over a vnodes marked VSYSTEM.
763 		 */
764 		if ((flags & SKIPSYSTEM) && (vp->v_flag & VSYSTEM))
765 			continue;
766 		/*
767 		 * With v_usecount == 0, all we need to do is clear
768 		 * out the vnode data structures and we are done.
769 		 */
770 		if (vp->v_usecount == 0) {
771 			vgone(vp);
772 			continue;
773 		}
774 		/*
775 		 * For block or character devices, revert to an
776 		 * anonymous device. For all other files, just kill them.
777 		 */
778 		if (flags & FORCECLOSE) {
779 			if (vp->v_type != VBLK && vp->v_type != VCHR) {
780 				vgone(vp);
781 			} else {
782 				vclean(vp, 0);
783 				vp->v_op = &spec_vnodeops;
784 				insmntque(vp, (struct mount *)0);
785 			}
786 			continue;
787 		}
788 		if (busyprt)
789 			vprint("vflush: busy vnode", vp);
790 		busy++;
791 	}
792 	if (busy)
793 		return (EBUSY);
794 	return (0);
795 }
796 
797 /*
798  * Disassociate the underlying file system from a vnode.
799  */
800 void vclean(vp, flags)
801 	register struct vnode *vp;
802 	int flags;
803 {
804 	struct vnodeops *origops;
805 	int active;
806 	struct proc *p = curproc;	/* XXX */
807 
808 	/*
809 	 * Check to see if the vnode is in use.
810 	 * If so we have to reference it before we clean it out
811 	 * so that its count cannot fall to zero and generate a
812 	 * race against ourselves to recycle it.
813 	 */
814 	if (active = vp->v_usecount)
815 		VREF(vp);
816 	/*
817 	 * Prevent the vnode from being recycled or
818 	 * brought into use while we clean it out.
819 	 */
820 	if (vp->v_flag & VXLOCK)
821 		panic("vclean: deadlock");
822 	vp->v_flag |= VXLOCK;
823 	/*
824 	 * Even if the count is zero, the VOP_INACTIVE routine may still
825 	 * have the object locked while it cleans it out. The VOP_LOCK
826 	 * ensures that the VOP_INACTIVE routine is done with its work.
827 	 * For active vnodes, it ensures that no other activity can
828 	 * occur while the buffer list is being cleaned out.
829 	 */
830 	VOP_LOCK(vp);
831 	if (flags & DOCLOSE)
832 		vinvalbuf(vp, 1);
833 	/*
834 	 * Prevent any further operations on the vnode from
835 	 * being passed through to the old file system.
836 	 */
837 	origops = vp->v_op;
838 	vp->v_op = &dead_vnodeops;
839 	vp->v_tag = VT_NON;
840 	/*
841 	 * If purging an active vnode, it must be unlocked, closed,
842 	 * and deactivated before being reclaimed.
843 	 */
844 	(*(origops->vop_unlock))(vp);
845 	if (active) {
846 		if (flags & DOCLOSE)
847 			(*(origops->vop_close))(vp, IO_NDELAY, NOCRED, p);
848 		(*(origops->vop_inactive))(vp, p);
849 	}
850 	/*
851 	 * Reclaim the vnode.
852 	 */
853 	if ((*(origops->vop_reclaim))(vp))
854 		panic("vclean: cannot reclaim");
855 	if (active)
856 		vrele(vp);
857 	/*
858 	 * Done with purge, notify sleepers in vget of the grim news.
859 	 */
860 	vp->v_flag &= ~VXLOCK;
861 	if (vp->v_flag & VXWANT) {
862 		vp->v_flag &= ~VXWANT;
863 		wakeup((caddr_t)vp);
864 	}
865 }
866 
867 /*
868  * Eliminate all activity associated with  the requested vnode
869  * and with all vnodes aliased to the requested vnode.
870  */
871 void vgoneall(vp)
872 	register struct vnode *vp;
873 {
874 	register struct vnode *vq;
875 
876 	if (vp->v_flag & VALIASED) {
877 		/*
878 		 * If a vgone (or vclean) is already in progress,
879 		 * wait until it is done and return.
880 		 */
881 		if (vp->v_flag & VXLOCK) {
882 			vp->v_flag |= VXWANT;
883 			sleep((caddr_t)vp, PINOD);
884 			return;
885 		}
886 		/*
887 		 * Ensure that vp will not be vgone'd while we
888 		 * are eliminating its aliases.
889 		 */
890 		vp->v_flag |= VXLOCK;
891 		while (vp->v_flag & VALIASED) {
892 			for (vq = *vp->v_hashchain; vq; vq = vq->v_specnext) {
893 				if (vq->v_rdev != vp->v_rdev ||
894 				    vq->v_type != vp->v_type || vp == vq)
895 					continue;
896 				vgone(vq);
897 				break;
898 			}
899 		}
900 		/*
901 		 * Remove the lock so that vgone below will
902 		 * really eliminate the vnode after which time
903 		 * vgone will awaken any sleepers.
904 		 */
905 		vp->v_flag &= ~VXLOCK;
906 	}
907 	vgone(vp);
908 }
909 
910 /*
911  * Eliminate all activity associated with a vnode
912  * in preparation for reuse.
913  */
914 void vgone(vp)
915 	register struct vnode *vp;
916 {
917 	register struct vnode *vq;
918 	struct vnode *vx;
919 	long count;
920 
921 	/*
922 	 * If a vgone (or vclean) is already in progress,
923 	 * wait until it is done and return.
924 	 */
925 	if (vp->v_flag & VXLOCK) {
926 		vp->v_flag |= VXWANT;
927 		sleep((caddr_t)vp, PINOD);
928 		return;
929 	}
930 	/*
931 	 * Clean out the filesystem specific data.
932 	 */
933 	vclean(vp, DOCLOSE);
934 	/*
935 	 * Delete from old mount point vnode list, if on one.
936 	 */
937 	if (vp->v_mountb) {
938 		if (vq = vp->v_mountf)
939 			vq->v_mountb = vp->v_mountb;
940 		*vp->v_mountb = vq;
941 		vp->v_mountf = NULL;
942 		vp->v_mountb = NULL;
943 	}
944 	/*
945 	 * If special device, remove it from special device alias list.
946 	 */
947 	if (vp->v_type == VBLK || vp->v_type == VCHR) {
948 		if (*vp->v_hashchain == vp) {
949 			*vp->v_hashchain = vp->v_specnext;
950 		} else {
951 			for (vq = *vp->v_hashchain; vq; vq = vq->v_specnext) {
952 				if (vq->v_specnext != vp)
953 					continue;
954 				vq->v_specnext = vp->v_specnext;
955 				break;
956 			}
957 			if (vq == NULL)
958 				panic("missing bdev");
959 		}
960 		if (vp->v_flag & VALIASED) {
961 			count = 0;
962 			for (vq = *vp->v_hashchain; vq; vq = vq->v_specnext) {
963 				if (vq->v_rdev != vp->v_rdev ||
964 				    vq->v_type != vp->v_type)
965 					continue;
966 				count++;
967 				vx = vq;
968 			}
969 			if (count == 0)
970 				panic("missing alias");
971 			if (count == 1)
972 				vx->v_flag &= ~VALIASED;
973 			vp->v_flag &= ~VALIASED;
974 		}
975 		FREE(vp->v_specinfo, M_VNODE);
976 		vp->v_specinfo = NULL;
977 	}
978 	/*
979 	 * If it is on the freelist, move it to the head of the list.
980 	 */
981 	if (vp->v_freeb) {
982 		if (vq = vp->v_freef)
983 			vq->v_freeb = vp->v_freeb;
984 		else
985 			vfreet = vp->v_freeb;
986 		*vp->v_freeb = vq;
987 		vp->v_freef = vfreeh;
988 		vp->v_freeb = &vfreeh;
989 		vfreeh->v_freeb = &vp->v_freef;
990 		vfreeh = vp;
991 	}
992 	vp->v_type = VBAD;
993 }
994 
995 /*
996  * Lookup a vnode by device number.
997  */
998 vfinddev(dev, type, vpp)
999 	dev_t dev;
1000 	enum vtype type;
1001 	struct vnode **vpp;
1002 {
1003 	register struct vnode *vp;
1004 
1005 	for (vp = speclisth[SPECHASH(dev)]; vp; vp = vp->v_specnext) {
1006 		if (dev != vp->v_rdev || type != vp->v_type)
1007 			continue;
1008 		*vpp = vp;
1009 		return (0);
1010 	}
1011 	return (1);
1012 }
1013 
1014 /*
1015  * Calculate the total number of references to a special device.
1016  */
1017 vcount(vp)
1018 	register struct vnode *vp;
1019 {
1020 	register struct vnode *vq;
1021 	int count;
1022 
1023 	if ((vp->v_flag & VALIASED) == 0)
1024 		return (vp->v_usecount);
1025 loop:
1026 	for (count = 0, vq = *vp->v_hashchain; vq; vq = vq->v_specnext) {
1027 		if (vq->v_rdev != vp->v_rdev || vq->v_type != vp->v_type)
1028 			continue;
1029 		/*
1030 		 * Alias, but not in use, so flush it out.
1031 		 */
1032 		if (vq->v_usecount == 0) {
1033 			vgone(vq);
1034 			goto loop;
1035 		}
1036 		count += vq->v_usecount;
1037 	}
1038 	return (count);
1039 }
1040 
1041 /*
1042  * Print out a description of a vnode.
1043  */
1044 static char *typename[] =
1045    { "VNON", "VREG", "VDIR", "VBLK", "VCHR", "VLNK", "VSOCK", "VFIFO", "VBAD" };
1046 
1047 vprint(label, vp)
1048 	char *label;
1049 	register struct vnode *vp;
1050 {
1051 	char buf[64];
1052 
1053 	if (label != NULL)
1054 		printf("%s: ", label);
1055 	printf("type %s, usecount %d, writecount %d, refcount %d,",
1056 		typename[vp->v_type], vp->v_usecount, vp->v_writecount,
1057 		vp->v_holdcnt);
1058 	buf[0] = '\0';
1059 	if (vp->v_flag & VROOT)
1060 		strcat(buf, "|VROOT");
1061 	if (vp->v_flag & VTEXT)
1062 		strcat(buf, "|VTEXT");
1063 	if (vp->v_flag & VSYSTEM)
1064 		strcat(buf, "|VSYSTEM");
1065 	if (vp->v_flag & VXLOCK)
1066 		strcat(buf, "|VXLOCK");
1067 	if (vp->v_flag & VXWANT)
1068 		strcat(buf, "|VXWANT");
1069 	if (vp->v_flag & VBWAIT)
1070 		strcat(buf, "|VBWAIT");
1071 	if (vp->v_flag & VALIASED)
1072 		strcat(buf, "|VALIASED");
1073 	if (buf[0] != '\0')
1074 		printf(" flags (%s)", &buf[1]);
1075 	printf("\n\t");
1076 	VOP_PRINT(vp);
1077 }
1078 
1079 #ifdef DEBUG
1080 /*
1081  * List all of the locked vnodes in the system.
1082  * Called when debugging the kernel.
1083  */
1084 printlockedvnodes()
1085 {
1086 	register struct mount *mp;
1087 	register struct vnode *vp;
1088 
1089 	printf("Locked vnodes\n");
1090 	mp = rootfs;
1091 	do {
1092 		for (vp = mp->mnt_mounth; vp; vp = vp->v_mountf)
1093 			if (VOP_ISLOCKED(vp))
1094 				vprint((char *)0, vp);
1095 		mp = mp->mnt_next;
1096 	} while (mp != rootfs);
1097 }
1098 #endif
1099 
1100 int kinfo_vdebug = 1;
1101 int kinfo_vgetfailed;
1102 #define KINFO_VNODESLOP	10
1103 /*
1104  * Dump vnode list (via kinfo).
1105  * Copyout address of vnode followed by vnode.
1106  */
1107 /* ARGSUSED */
1108 kinfo_vnode(op, where, acopysize, arg, aneeded)
1109 	int op;
1110 	char *where;
1111 	int *acopysize, arg, *aneeded;
1112 {
1113 	register struct mount *mp = rootfs;
1114 	struct mount *omp;
1115 	struct vnode *vp;
1116 	register char *bp = where, *savebp;
1117 	char *ewhere = where + *acopysize;
1118 	int error;
1119 
1120 #define VPTRSZ	sizeof (struct vnode *)
1121 #define VNODESZ	sizeof (struct vnode)
1122 	if (where == NULL) {
1123 		*aneeded = (numvnodes + KINFO_VNODESLOP) * (VPTRSZ + VNODESZ);
1124 		return (0);
1125 	}
1126 
1127 	do {
1128 		if (vfs_busy(mp)) {
1129 			mp = mp->mnt_next;
1130 			continue;
1131 		}
1132 		savebp = bp;
1133 again:
1134 		for (vp = mp->mnt_mounth; vp; vp = vp->v_mountf) {
1135 			/*
1136 			 * Check that the vp is still associated with
1137 			 * this filesystem.  RACE: could have been
1138 			 * recycled onto the same filesystem.
1139 			 */
1140 			if (vp->v_mount != mp) {
1141 				if (kinfo_vdebug)
1142 					printf("kinfo: vp changed\n");
1143 				bp = savebp;
1144 				goto again;
1145 			}
1146 			if ((bp + VPTRSZ + VNODESZ <= ewhere) &&
1147 			    ((error = copyout((caddr_t)&vp, bp, VPTRSZ)) ||
1148 			     (error = copyout((caddr_t)vp, bp + VPTRSZ,
1149 			      VNODESZ))))
1150 				return (error);
1151 			bp += VPTRSZ + VNODESZ;
1152 		}
1153 		omp = mp;
1154 		mp = mp->mnt_next;
1155 		vfs_unbusy(omp);
1156 	} while (mp != rootfs);
1157 
1158 	*aneeded = bp - where;
1159 	if (bp > ewhere)
1160 		*acopysize = ewhere - where;
1161 	else
1162 		*acopysize = bp - where;
1163 	return (0);
1164 }
1165