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