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