xref: /original-bsd/sys/kern/vfs_subr.c (revision de3f5c4e)
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.57 (Berkeley) 05/15/91
8  */
9 
10 /*
11  * External virtual filesystem routines
12  */
13 
14 #include "param.h"
15 #include "proc.h"
16 #include "mount.h"
17 #include "time.h"
18 #include "vnode.h"
19 #include "specdev.h"
20 #include "namei.h"
21 #include "ucred.h"
22 #include "buf.h"
23 #include "errno.h"
24 #include "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_mode = vap->va_nlink = vap->va_uid = vap->va_gid =
141 		vap->va_fsid = vap->va_fileid = vap->va_size =
142 		vap->va_size_rsv = vap->va_blocksize = vap->va_rdev =
143 		vap->va_bytes = vap->va_bytes_rsv =
144 		vap->va_atime.tv_sec = vap->va_atime.tv_usec =
145 		vap->va_mtime.tv_sec = vap->va_mtime.tv_usec =
146 		vap->va_ctime.tv_sec = vap->va_ctime.tv_usec =
147 		vap->va_flags = vap->va_gen = VNOVAL;
148 }
149 
150 /*
151  * Routines having to do with the management of the vnode table.
152  */
153 struct vnode *vfreeh, **vfreet;
154 extern struct vnodeops dead_vnodeops, spec_vnodeops;
155 extern void vclean();
156 long numvnodes;
157 struct vattr va_null;
158 
159 /*
160  * Initialize the vnode structures and initialize each file system type.
161  */
162 vfsinit()
163 {
164 	struct vfsops **vfsp;
165 
166 	/*
167 	 * Initialize the vnode name cache
168 	 */
169 	nchinit();
170 	/*
171 	 * Initialize each file system type.
172 	 */
173 	vattr_null(&va_null);
174 	for (vfsp = &vfssw[0]; vfsp <= &vfssw[MOUNT_MAXTYPE]; vfsp++) {
175 		if (*vfsp == NULL)
176 			continue;
177 		(*(*vfsp)->vfs_init)();
178 	}
179 }
180 
181 /*
182  * Return the next vnode from the free list.
183  */
184 getnewvnode(tag, mp, vops, vpp)
185 	enum vtagtype tag;
186 	struct mount *mp;
187 	struct vnodeops *vops;
188 	struct vnode **vpp;
189 {
190 	register struct vnode *vp, *vq;
191 
192 	if (numvnodes < desiredvnodes) {
193 		vp = (struct vnode *)malloc((u_long)sizeof *vp,
194 		    M_VNODE, M_WAITOK);
195 		bzero((char *)vp, sizeof *vp);
196 		numvnodes++;
197 	} else {
198 		if ((vp = vfreeh) == NULL) {
199 			tablefull("vnode");
200 			*vpp = 0;
201 			return (ENFILE);
202 		}
203 		if (vp->v_usecount)
204 			panic("free vnode isn't");
205 		if (vq = vp->v_freef)
206 			vq->v_freeb = &vfreeh;
207 		else
208 			vfreet = &vfreeh;
209 		vfreeh = vq;
210 		vp->v_freef = NULL;
211 		vp->v_freeb = NULL;
212 		if (vp->v_type != VBAD)
213 			vgone(vp);
214 		vp->v_flag = 0;
215 		vp->v_lastr = 0;
216 		vp->v_socket = 0;
217 	}
218 	vp->v_type = VNON;
219 	cache_purge(vp);
220 	vp->v_tag = tag;
221 	vp->v_op = vops;
222 	insmntque(vp, mp);
223 	VREF(vp);
224 	*vpp = vp;
225 	return (0);
226 }
227 
228 /*
229  * Move a vnode from one mount queue to another.
230  */
231 insmntque(vp, mp)
232 	register struct vnode *vp;
233 	register struct mount *mp;
234 {
235 	struct vnode *vq;
236 
237 	/*
238 	 * Delete from old mount point vnode list, if on one.
239 	 */
240 	if (vp->v_mountb) {
241 		if (vq = vp->v_mountf)
242 			vq->v_mountb = vp->v_mountb;
243 		*vp->v_mountb = vq;
244 	}
245 	/*
246 	 * Insert into list of vnodes for the new mount point, if available.
247 	 */
248 	vp->v_mount = mp;
249 	if (mp == NULL) {
250 		vp->v_mountf = NULL;
251 		vp->v_mountb = NULL;
252 		return;
253 	}
254 	if (mp->mnt_mounth) {
255 		vp->v_mountf = mp->mnt_mounth;
256 		vp->v_mountb = &mp->mnt_mounth;
257 		mp->mnt_mounth->v_mountb = &vp->v_mountf;
258 		mp->mnt_mounth = vp;
259 	} else {
260 		mp->mnt_mounth = vp;
261 		vp->v_mountb = &mp->mnt_mounth;
262 		vp->v_mountf = NULL;
263 	}
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) 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 
445 	if (bp->b_vp)
446 		panic("bgetvp: not free");
447 	VHOLD(vp);
448 	bp->b_vp = vp;
449 	if (vp->v_type == VBLK || vp->v_type == VCHR)
450 		bp->b_dev = vp->v_rdev;
451 	else
452 		bp->b_dev = NODEV;
453 	/*
454 	 * Insert onto list for new vnode.
455 	 */
456 	if (vp->v_cleanblkhd) {
457 		bp->b_blockf = vp->v_cleanblkhd;
458 		bp->b_blockb = &vp->v_cleanblkhd;
459 		vp->v_cleanblkhd->b_blockb = &bp->b_blockf;
460 		vp->v_cleanblkhd = bp;
461 	} else {
462 		vp->v_cleanblkhd = bp;
463 		bp->b_blockb = &vp->v_cleanblkhd;
464 		bp->b_blockf = NULL;
465 	}
466 }
467 
468 /*
469  * Disassociate a buffer from a vnode.
470  */
471 brelvp(bp)
472 	register struct buf *bp;
473 {
474 	struct buf *bq;
475 	struct vnode *vp;
476 
477 	if (bp->b_vp == (struct vnode *) 0)
478 		panic("brelvp: NULL");
479 	/*
480 	 * Delete from old vnode list, if on one.
481 	 */
482 	if (bp->b_blockb) {
483 		if (bq = bp->b_blockf)
484 			bq->b_blockb = bp->b_blockb;
485 		*bp->b_blockb = bq;
486 		bp->b_blockf = NULL;
487 		bp->b_blockb = NULL;
488 	}
489 	vp = bp->b_vp;
490 	bp->b_vp = (struct vnode *) 0;
491 	HOLDRELE(vp);
492 }
493 
494 /*
495  * Reassign a buffer from one vnode to another.
496  * Used to assign file specific control information
497  * (indirect blocks) to the vnode to which they belong.
498  */
499 reassignbuf(bp, newvp)
500 	register struct buf *bp;
501 	register struct vnode *newvp;
502 {
503 	register struct buf *bq, **listheadp;
504 
505 	if (newvp == NULL)
506 		panic("reassignbuf: NULL");
507 	/*
508 	 * Delete from old vnode list, if on one.
509 	 */
510 	if (bp->b_blockb) {
511 		if (bq = bp->b_blockf)
512 			bq->b_blockb = bp->b_blockb;
513 		*bp->b_blockb = bq;
514 	}
515 	/*
516 	 * If dirty, put on list of dirty buffers;
517 	 * otherwise insert onto list of clean buffers.
518 	 */
519 	if (bp->b_flags & B_DELWRI)
520 		listheadp = &newvp->v_dirtyblkhd;
521 	else
522 		listheadp = &newvp->v_cleanblkhd;
523 	if (*listheadp) {
524 		bp->b_blockf = *listheadp;
525 		bp->b_blockb = listheadp;
526 		bp->b_blockf->b_blockb = &bp->b_blockf;
527 		*listheadp = bp;
528 	} else {
529 		*listheadp = bp;
530 		bp->b_blockb = listheadp;
531 		bp->b_blockf = NULL;
532 	}
533 }
534 
535 /*
536  * Create a vnode for a block device.
537  * Used for root filesystem, argdev, and swap areas.
538  * Also used for memory file system special devices.
539  */
540 bdevvp(dev, vpp)
541 	dev_t dev;
542 	struct vnode **vpp;
543 {
544 	register struct vnode *vp;
545 	struct vnode *nvp;
546 	int error;
547 
548 	if (dev == NODEV)
549 		return (0);
550 	error = getnewvnode(VT_NON, (struct mount *)0, &spec_vnodeops, &nvp);
551 	if (error) {
552 		*vpp = 0;
553 		return (error);
554 	}
555 	vp = nvp;
556 	vp->v_type = VBLK;
557 	if (nvp = checkalias(vp, dev, (struct mount *)0)) {
558 		vput(vp);
559 		vp = nvp;
560 	}
561 	*vpp = vp;
562 	return (0);
563 }
564 
565 /*
566  * Check to see if the new vnode represents a special device
567  * for which we already have a vnode (either because of
568  * bdevvp() or because of a different vnode representing
569  * the same block device). If such an alias exists, deallocate
570  * the existing contents and return the aliased vnode. The
571  * caller is responsible for filling it with its new contents.
572  */
573 struct vnode *
574 checkalias(nvp, nvp_rdev, mp)
575 	register struct vnode *nvp;
576 	dev_t nvp_rdev;
577 	struct mount *mp;
578 {
579 	register struct vnode *vp;
580 	struct vnode **vpp;
581 
582 	if (nvp->v_type != VBLK && nvp->v_type != VCHR)
583 		return (NULLVP);
584 
585 	vpp = &speclisth[SPECHASH(nvp_rdev)];
586 loop:
587 	for (vp = *vpp; vp; vp = vp->v_specnext) {
588 		if (nvp_rdev != vp->v_rdev || nvp->v_type != vp->v_type)
589 			continue;
590 		/*
591 		 * Alias, but not in use, so flush it out.
592 		 */
593 		if (vp->v_usecount == 0) {
594 			vgone(vp);
595 			goto loop;
596 		}
597 		if (vget(vp))
598 			goto loop;
599 		break;
600 	}
601 	if (vp == NULL || vp->v_tag != VT_NON) {
602 		MALLOC(nvp->v_specinfo, struct specinfo *,
603 			sizeof(struct specinfo), M_VNODE, M_WAITOK);
604 		nvp->v_rdev = nvp_rdev;
605 		nvp->v_hashchain = vpp;
606 		nvp->v_specnext = *vpp;
607 		nvp->v_specflags = 0;
608 		*vpp = nvp;
609 		if (vp != NULL) {
610 			nvp->v_flag |= VALIASED;
611 			vp->v_flag |= VALIASED;
612 			vput(vp);
613 		}
614 		return (NULLVP);
615 	}
616 	VOP_UNLOCK(vp);
617 	vclean(vp, 0);
618 	vp->v_op = nvp->v_op;
619 	vp->v_tag = nvp->v_tag;
620 	nvp->v_type = VNON;
621 	insmntque(vp, mp);
622 	return (vp);
623 }
624 
625 /*
626  * Grab a particular vnode from the free list, increment its
627  * reference count and lock it. The vnode lock bit is set the
628  * vnode is being eliminated in vgone. The process is awakened
629  * when the transition is completed, and an error returned to
630  * indicate that the vnode is no longer usable (possibly having
631  * been changed to a new file system type).
632  */
633 vget(vp)
634 	register struct vnode *vp;
635 {
636 	register struct vnode *vq;
637 
638 	if (vp->v_flag & VXLOCK) {
639 		vp->v_flag |= VXWANT;
640 		sleep((caddr_t)vp, PINOD);
641 		return (1);
642 	}
643 	if (vp->v_usecount == 0) {
644 		if (vq = vp->v_freef)
645 			vq->v_freeb = vp->v_freeb;
646 		else
647 			vfreet = vp->v_freeb;
648 		*vp->v_freeb = vq;
649 		vp->v_freef = NULL;
650 		vp->v_freeb = NULL;
651 	}
652 	VREF(vp);
653 	VOP_LOCK(vp);
654 	return (0);
655 }
656 
657 /*
658  * Vnode reference, just increment the count
659  */
660 void vref(vp)
661 	struct vnode *vp;
662 {
663 
664 	vp->v_usecount++;
665 }
666 
667 /*
668  * vput(), just unlock and vrele()
669  */
670 void vput(vp)
671 	register struct vnode *vp;
672 {
673 	VOP_UNLOCK(vp);
674 	vrele(vp);
675 }
676 
677 /*
678  * Vnode release.
679  * If count drops to zero, call inactive routine and return to freelist.
680  */
681 void vrele(vp)
682 	register struct vnode *vp;
683 {
684 	struct proc *p = curproc;		/* XXX */
685 
686 	if (vp == NULL)
687 		panic("vrele: null vp");
688 	vp->v_usecount--;
689 	if (vp->v_usecount < 0)
690 		vprint("vrele: bad ref count", vp);
691 	if (vp->v_usecount > 0)
692 		return;
693 	if (vfreeh == NULLVP) {
694 		/*
695 		 * insert into empty list
696 		 */
697 		vfreeh = vp;
698 		vp->v_freeb = &vfreeh;
699 	} else {
700 		/*
701 		 * insert at tail of list
702 		 */
703 		*vfreet = vp;
704 		vp->v_freeb = vfreet;
705 	}
706 	vp->v_freef = NULL;
707 	vfreet = &vp->v_freef;
708 	VOP_INACTIVE(vp, p);
709 }
710 
711 /*
712  * Page or buffer structure gets a reference.
713  */
714 vhold(vp)
715 	register struct vnode *vp;
716 {
717 
718 	vp->v_holdcnt++;
719 }
720 
721 /*
722  * Page or buffer structure frees a reference.
723  */
724 holdrele(vp)
725 	register struct vnode *vp;
726 {
727 
728 	if (vp->v_holdcnt <= 0)
729 		panic("holdrele: holdcnt");
730 	vp->v_holdcnt--;
731 }
732 
733 /*
734  * Remove any vnodes in the vnode table belonging to mount point mp.
735  *
736  * If MNT_NOFORCE is specified, there should not be any active ones,
737  * return error if any are found (nb: this is a user error, not a
738  * system error). If MNT_FORCE is specified, detach any active vnodes
739  * that are found.
740  */
741 int busyprt = 0;	/* patch to print out busy vnodes */
742 
743 vflush(mp, skipvp, flags)
744 	struct mount *mp;
745 	struct vnode *skipvp;
746 	int flags;
747 {
748 	register struct vnode *vp, *nvp;
749 	int busy = 0;
750 
751 	if ((mp->mnt_flag & MNT_MPBUSY) == 0)
752 		panic("vflush: not busy");
753 loop:
754 	for (vp = mp->mnt_mounth; vp; vp = nvp) {
755 		if (vp->v_mount != mp)
756 			goto loop;
757 		nvp = vp->v_mountf;
758 		/*
759 		 * Skip over a selected vnode.
760 		 */
761 		if (vp == skipvp)
762 			continue;
763 		/*
764 		 * Skip over a vnodes marked VSYSTEM.
765 		 */
766 		if ((flags & SKIPSYSTEM) && (vp->v_flag & VSYSTEM))
767 			continue;
768 		/*
769 		 * With v_usecount == 0, all we need to do is clear
770 		 * out the vnode data structures and we are done.
771 		 */
772 		if (vp->v_usecount == 0) {
773 			vgone(vp);
774 			continue;
775 		}
776 		/*
777 		 * For block or character devices, revert to an
778 		 * anonymous device. For all other files, just kill them.
779 		 */
780 		if (flags & FORCECLOSE) {
781 			if (vp->v_type != VBLK && vp->v_type != VCHR) {
782 				vgone(vp);
783 			} else {
784 				vclean(vp, 0);
785 				vp->v_op = &spec_vnodeops;
786 				insmntque(vp, (struct mount *)0);
787 			}
788 			continue;
789 		}
790 		if (busyprt)
791 			vprint("vflush: busy vnode", vp);
792 		busy++;
793 	}
794 	if (busy)
795 		return (EBUSY);
796 	return (0);
797 }
798 
799 /*
800  * Disassociate the underlying file system from a vnode.
801  */
802 void vclean(vp, flags)
803 	register struct vnode *vp;
804 	int flags;
805 {
806 	struct vnodeops *origops;
807 	int active;
808 	struct proc *p = curproc;	/* XXX */
809 
810 	/*
811 	 * Check to see if the vnode is in use.
812 	 * If so we have to reference it before we clean it out
813 	 * so that its count cannot fall to zero and generate a
814 	 * race against ourselves to recycle it.
815 	 */
816 	if (active = vp->v_usecount)
817 		VREF(vp);
818 	/*
819 	 * Prevent the vnode from being recycled or
820 	 * brought into use while we clean it out.
821 	 */
822 	if (vp->v_flag & VXLOCK)
823 		panic("vclean: deadlock");
824 	vp->v_flag |= VXLOCK;
825 	/*
826 	 * Even if the count is zero, the VOP_INACTIVE routine may still
827 	 * have the object locked while it cleans it out. The VOP_LOCK
828 	 * ensures that the VOP_INACTIVE routine is done with its work.
829 	 * For active vnodes, it ensures that no other activity can
830 	 * occur while the buffer list is being cleaned out.
831 	 */
832 	VOP_LOCK(vp);
833 	if (flags & DOCLOSE)
834 		vinvalbuf(vp, 1);
835 	/*
836 	 * Prevent any further operations on the vnode from
837 	 * being passed through to the old file system.
838 	 */
839 	origops = vp->v_op;
840 	vp->v_op = &dead_vnodeops;
841 	vp->v_tag = VT_NON;
842 	/*
843 	 * If purging an active vnode, it must be unlocked, closed,
844 	 * and deactivated before being reclaimed.
845 	 */
846 	(*(origops->vn_unlock))(vp);
847 	if (active) {
848 		if (flags & DOCLOSE)
849 			(*(origops->vn_close))(vp, IO_NDELAY, NOCRED, p);
850 		(*(origops->vn_inactive))(vp, p);
851 	}
852 	/*
853 	 * Reclaim the vnode.
854 	 */
855 	if ((*(origops->vn_reclaim))(vp))
856 		panic("vclean: cannot reclaim");
857 	if (active)
858 		vrele(vp);
859 	/*
860 	 * Done with purge, notify sleepers in vget of the grim news.
861 	 */
862 	vp->v_flag &= ~VXLOCK;
863 	if (vp->v_flag & VXWANT) {
864 		vp->v_flag &= ~VXWANT;
865 		wakeup((caddr_t)vp);
866 	}
867 }
868 
869 /*
870  * Eliminate all activity associated with  the requested vnode
871  * and with all vnodes aliased to the requested vnode.
872  */
873 void vgoneall(vp)
874 	register struct vnode *vp;
875 {
876 	register struct vnode *vq;
877 
878 	if (vp->v_flag & VALIASED) {
879 		/*
880 		 * If a vgone (or vclean) is already in progress,
881 		 * wait until it is done and return.
882 		 */
883 		if (vp->v_flag & VXLOCK) {
884 			vp->v_flag |= VXWANT;
885 			sleep((caddr_t)vp, PINOD);
886 			return;
887 		}
888 		/*
889 		 * Ensure that vp will not be vgone'd while we
890 		 * are eliminating its aliases.
891 		 */
892 		vp->v_flag |= VXLOCK;
893 		while (vp->v_flag & VALIASED) {
894 			for (vq = *vp->v_hashchain; vq; vq = vq->v_specnext) {
895 				if (vq->v_rdev != vp->v_rdev ||
896 				    vq->v_type != vp->v_type || vp == vq)
897 					continue;
898 				vgone(vq);
899 				break;
900 			}
901 		}
902 		/*
903 		 * Remove the lock so that vgone below will
904 		 * really eliminate the vnode after which time
905 		 * vgone will awaken any sleepers.
906 		 */
907 		vp->v_flag &= ~VXLOCK;
908 	}
909 	vgone(vp);
910 }
911 
912 /*
913  * Eliminate all activity associated with a vnode
914  * in preparation for reuse.
915  */
916 void vgone(vp)
917 	register struct vnode *vp;
918 {
919 	register struct vnode *vq;
920 	struct vnode *vx;
921 	long count;
922 
923 	/*
924 	 * If a vgone (or vclean) is already in progress,
925 	 * wait until it is done and return.
926 	 */
927 	if (vp->v_flag & VXLOCK) {
928 		vp->v_flag |= VXWANT;
929 		sleep((caddr_t)vp, PINOD);
930 		return;
931 	}
932 	/*
933 	 * Clean out the filesystem specific data.
934 	 */
935 	vclean(vp, DOCLOSE);
936 	/*
937 	 * Delete from old mount point vnode list, if on one.
938 	 */
939 	if (vp->v_mountb) {
940 		if (vq = vp->v_mountf)
941 			vq->v_mountb = vp->v_mountb;
942 		*vp->v_mountb = vq;
943 		vp->v_mountf = NULL;
944 		vp->v_mountb = NULL;
945 	}
946 	/*
947 	 * If special device, remove it from special device alias list.
948 	 */
949 	if (vp->v_type == VBLK || vp->v_type == VCHR) {
950 		if (*vp->v_hashchain == vp) {
951 			*vp->v_hashchain = vp->v_specnext;
952 		} else {
953 			for (vq = *vp->v_hashchain; vq; vq = vq->v_specnext) {
954 				if (vq->v_specnext != vp)
955 					continue;
956 				vq->v_specnext = vp->v_specnext;
957 				break;
958 			}
959 			if (vq == NULL)
960 				panic("missing bdev");
961 		}
962 		if (vp->v_flag & VALIASED) {
963 			count = 0;
964 			for (vq = *vp->v_hashchain; vq; vq = vq->v_specnext) {
965 				if (vq->v_rdev != vp->v_rdev ||
966 				    vq->v_type != vp->v_type)
967 					continue;
968 				count++;
969 				vx = vq;
970 			}
971 			if (count == 0)
972 				panic("missing alias");
973 			if (count == 1)
974 				vx->v_flag &= ~VALIASED;
975 			vp->v_flag &= ~VALIASED;
976 		}
977 		FREE(vp->v_specinfo, M_VNODE);
978 		vp->v_specinfo = NULL;
979 	}
980 	/*
981 	 * If it is on the freelist, move it to the head of the list.
982 	 */
983 	if (vp->v_freeb) {
984 		if (vq = vp->v_freef)
985 			vq->v_freeb = vp->v_freeb;
986 		else
987 			vfreet = vp->v_freeb;
988 		*vp->v_freeb = vq;
989 		vp->v_freef = vfreeh;
990 		vp->v_freeb = &vfreeh;
991 		vfreeh->v_freeb = &vp->v_freef;
992 		vfreeh = vp;
993 	}
994 	vp->v_type = VBAD;
995 }
996 
997 /*
998  * Lookup a vnode by device number.
999  */
1000 vfinddev(dev, type, vpp)
1001 	dev_t dev;
1002 	enum vtype type;
1003 	struct vnode **vpp;
1004 {
1005 	register struct vnode *vp;
1006 
1007 	for (vp = speclisth[SPECHASH(dev)]; vp; vp = vp->v_specnext) {
1008 		if (dev != vp->v_rdev || type != vp->v_type)
1009 			continue;
1010 		*vpp = vp;
1011 		return (0);
1012 	}
1013 	return (1);
1014 }
1015 
1016 /*
1017  * Calculate the total number of references to a special device.
1018  */
1019 vcount(vp)
1020 	register struct vnode *vp;
1021 {
1022 	register struct vnode *vq;
1023 	int count;
1024 
1025 	if ((vp->v_flag & VALIASED) == 0)
1026 		return (vp->v_usecount);
1027 loop:
1028 	for (count = 0, vq = *vp->v_hashchain; vq; vq = vq->v_specnext) {
1029 		if (vq->v_rdev != vp->v_rdev || vq->v_type != vp->v_type)
1030 			continue;
1031 		/*
1032 		 * Alias, but not in use, so flush it out.
1033 		 */
1034 		if (vq->v_usecount == 0) {
1035 			vgone(vq);
1036 			goto loop;
1037 		}
1038 		count += vq->v_usecount;
1039 	}
1040 	return (count);
1041 }
1042 
1043 /*
1044  * Print out a description of a vnode.
1045  */
1046 static char *typename[] =
1047    { "VNON", "VREG", "VDIR", "VBLK", "VCHR", "VLNK", "VSOCK", "VFIFO", "VBAD" };
1048 
1049 vprint(label, vp)
1050 	char *label;
1051 	register struct vnode *vp;
1052 {
1053 	char buf[64];
1054 
1055 	if (label != NULL)
1056 		printf("%s: ", label);
1057 	printf("type %s, usecount %d, refcount %d,", typename[vp->v_type],
1058 		vp->v_usecount, vp->v_holdcnt);
1059 	buf[0] = '\0';
1060 	if (vp->v_flag & VROOT)
1061 		strcat(buf, "|VROOT");
1062 	if (vp->v_flag & VTEXT)
1063 		strcat(buf, "|VTEXT");
1064 	if (vp->v_flag & VSYSTEM)
1065 		strcat(buf, "|VSYSTEM");
1066 	if (vp->v_flag & VXLOCK)
1067 		strcat(buf, "|VXLOCK");
1068 	if (vp->v_flag & VXWANT)
1069 		strcat(buf, "|VXWANT");
1070 	if (vp->v_flag & VBWAIT)
1071 		strcat(buf, "|VBWAIT");
1072 	if (vp->v_flag & VALIASED)
1073 		strcat(buf, "|VALIASED");
1074 	if (buf[0] != '\0')
1075 		printf(" flags (%s)", &buf[1]);
1076 	printf("\n\t");
1077 	VOP_PRINT(vp);
1078 }
1079 
1080 #ifdef DEBUG
1081 /*
1082  * List all of the locked vnodes in the system.
1083  * Called when debugging the kernel.
1084  */
1085 printlockedvnodes()
1086 {
1087 	register struct mount *mp;
1088 	register struct vnode *vp;
1089 
1090 	printf("Locked vnodes\n");
1091 	mp = rootfs;
1092 	do {
1093 		for (vp = mp->mnt_mounth; vp; vp = vp->v_mountf)
1094 			if (VOP_ISLOCKED(vp))
1095 				vprint((char *)0, vp);
1096 		mp = mp->mnt_next;
1097 	} while (mp != rootfs);
1098 }
1099 #endif
1100 
1101 int kinfo_vdebug = 1;
1102 int kinfo_vgetfailed;
1103 #define KINFO_VNODESLOP	10
1104 /*
1105  * Dump vnode list (via kinfo).
1106  * Copyout address of vnode followed by vnode.
1107  */
1108 /* ARGSUSED */
1109 kinfo_vnode(op, where, acopysize, arg, aneeded)
1110 	int op;
1111 	char *where;
1112 	int *acopysize, arg, *aneeded;
1113 {
1114 	register struct mount *mp = rootfs;
1115 	struct mount *omp;
1116 	struct vnode *vp;
1117 	register char *bp = where, *savebp;
1118 	char *ewhere = where + *acopysize;
1119 	int error;
1120 
1121 #define VPTRSZ	sizeof (struct vnode *)
1122 #define VNODESZ	sizeof (struct vnode)
1123 	if (where == NULL) {
1124 		*aneeded = (numvnodes + KINFO_VNODESLOP) * (VPTRSZ + VNODESZ);
1125 		return (0);
1126 	}
1127 
1128 	do {
1129 		if (vfs_busy(mp)) {
1130 			mp = mp->mnt_next;
1131 			continue;
1132 		}
1133 		savebp = bp;
1134 again:
1135 		for (vp = mp->mnt_mounth; vp; vp = vp->v_mountf) {
1136 			/*
1137 			 * Check that the vp is still associated with
1138 			 * this filesystem.  RACE: could have been
1139 			 * recycled onto the same filesystem.
1140 			 */
1141 			if (vp->v_mount != mp) {
1142 				if (kinfo_vdebug)
1143 					printf("kinfo: vp changed\n");
1144 				bp = savebp;
1145 				goto again;
1146 			}
1147 			if ((bp + VPTRSZ + VNODESZ <= ewhere) &&
1148 			    ((error = copyout((caddr_t)&vp, bp, VPTRSZ)) ||
1149 			     (error = copyout((caddr_t)vp, bp + VPTRSZ,
1150 			      VNODESZ))))
1151 				return (error);
1152 			bp += VPTRSZ + VNODESZ;
1153 		}
1154 		omp = mp;
1155 		mp = mp->mnt_next;
1156 		vfs_unbusy(omp);
1157 	} while (mp != rootfs);
1158 
1159 	*aneeded = bp - where;
1160 	if (bp > ewhere)
1161 		*acopysize = ewhere - where;
1162 	else
1163 		*acopysize = bp - where;
1164 	return (0);
1165 }
1166