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