vfs_export.c revision 8692
1/*
2 * Copyright (c) 1989, 1993
3 *	The Regents of the University of California.  All rights reserved.
4 * (c) UNIX System Laboratories, Inc.
5 * All or some portions of this file are derived from material licensed
6 * to the University of California by American Telephone and Telegraph
7 * Co. or Unix System Laboratories, Inc. and are reproduced herein with
8 * the permission of UNIX System Laboratories, Inc.
9 *
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
12 * are met:
13 * 1. Redistributions of source code must retain the above copyright
14 *    notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright
16 *    notice, this list of conditions and the following disclaimer in the
17 *    documentation and/or other materials provided with the distribution.
18 * 3. All advertising materials mentioning features or use of this software
19 *    must display the following acknowledgement:
20 *	This product includes software developed by the University of
21 *	California, Berkeley and its contributors.
22 * 4. Neither the name of the University nor the names of its contributors
23 *    may be used to endorse or promote products derived from this software
24 *    without specific prior written permission.
25 *
26 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
27 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
28 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
29 * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
30 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
31 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
32 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
33 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
34 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
35 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
36 * SUCH DAMAGE.
37 *
38 *	@(#)vfs_subr.c	8.13 (Berkeley) 4/18/94
39 * $Id: vfs_subr.c,v 1.29 1995/05/12 04:24:53 davidg Exp $
40 */
41
42/*
43 * External virtual filesystem routines
44 */
45
46#include <sys/param.h>
47#include <sys/systm.h>
48#include <sys/proc.h>
49#include <sys/mount.h>
50#include <sys/time.h>
51#include <sys/vnode.h>
52#include <sys/stat.h>
53#include <sys/namei.h>
54#include <sys/ucred.h>
55#include <sys/buf.h>
56#include <sys/errno.h>
57#include <sys/malloc.h>
58#include <sys/domain.h>
59#include <sys/mbuf.h>
60
61#include <vm/vm.h>
62#include <sys/sysctl.h>
63
64#include <miscfs/specfs/specdev.h>
65
66void insmntque __P((struct vnode *, struct mount *));
67
68enum vtype iftovt_tab[16] = {
69	VNON, VFIFO, VCHR, VNON, VDIR, VNON, VBLK, VNON,
70	VREG, VNON, VLNK, VNON, VSOCK, VNON, VNON, VBAD,
71};
72int vttoif_tab[9] = {
73	0, S_IFREG, S_IFDIR, S_IFBLK, S_IFCHR, S_IFLNK,
74	S_IFSOCK, S_IFIFO, S_IFMT,
75};
76
77/*
78 * Insq/Remq for the vnode usage lists.
79 */
80#define	bufinsvn(bp, dp)	LIST_INSERT_HEAD(dp, bp, b_vnbufs)
81#define	bufremvn(bp) {  \
82	LIST_REMOVE(bp, b_vnbufs); \
83	(bp)->b_vnbufs.le_next = NOLIST; \
84}
85
86TAILQ_HEAD(freelst, vnode) vnode_free_list;	/* vnode free list */
87u_long freevnodes	= 0;
88
89struct mntlist mountlist;	/* mounted filesystem list */
90
91int desiredvnodes;
92
93/*
94 * Initialize the vnode management data structures.
95 */
96void
97vntblinit()
98{
99	desiredvnodes = maxproc + vm_object_cache_max;
100
101	TAILQ_INIT(&vnode_free_list);
102	TAILQ_INIT(&mountlist);
103}
104
105/*
106 * Lock a filesystem.
107 * Used to prevent access to it while mounting and unmounting.
108 */
109int
110vfs_lock(mp)
111	register struct mount *mp;
112{
113
114	while (mp->mnt_flag & MNT_MLOCK) {
115		mp->mnt_flag |= MNT_MWAIT;
116		(void) tsleep((caddr_t) mp, PVFS, "vfslck", 0);
117	}
118	mp->mnt_flag |= MNT_MLOCK;
119	return (0);
120}
121
122/*
123 * Unlock a locked filesystem.
124 * Panic if filesystem is not locked.
125 */
126void
127vfs_unlock(mp)
128	register struct mount *mp;
129{
130
131	if ((mp->mnt_flag & MNT_MLOCK) == 0)
132		panic("vfs_unlock: not locked");
133	mp->mnt_flag &= ~MNT_MLOCK;
134	if (mp->mnt_flag & MNT_MWAIT) {
135		mp->mnt_flag &= ~MNT_MWAIT;
136		wakeup((caddr_t) mp);
137	}
138}
139
140/*
141 * Mark a mount point as busy.
142 * Used to synchronize access and to delay unmounting.
143 */
144int
145vfs_busy(mp)
146	register struct mount *mp;
147{
148
149	while (mp->mnt_flag & MNT_MPBUSY) {
150		mp->mnt_flag |= MNT_MPWANT;
151		(void) tsleep((caddr_t) &mp->mnt_flag, PVFS, "vfsbsy", 0);
152	}
153	if (mp->mnt_flag & MNT_UNMOUNT)
154		return (1);
155	mp->mnt_flag |= MNT_MPBUSY;
156	return (0);
157}
158
159/*
160 * Free a busy filesystem.
161 * Panic if filesystem is not busy.
162 */
163void
164vfs_unbusy(mp)
165	register struct mount *mp;
166{
167
168	if ((mp->mnt_flag & MNT_MPBUSY) == 0)
169		panic("vfs_unbusy: not busy");
170	mp->mnt_flag &= ~MNT_MPBUSY;
171	if (mp->mnt_flag & MNT_MPWANT) {
172		mp->mnt_flag &= ~MNT_MPWANT;
173		wakeup((caddr_t) &mp->mnt_flag);
174	}
175}
176
177void
178vfs_unmountroot(rootfs)
179	struct mount *rootfs;
180{
181	struct mount *mp = rootfs;
182	int error;
183
184	if (vfs_busy(mp)) {
185		printf("failed to unmount root\n");
186		return;
187	}
188	mp->mnt_flag |= MNT_UNMOUNT;
189	if ((error = vfs_lock(mp))) {
190		printf("lock of root filesystem failed (%d)\n", error);
191		return;
192	}
193	vnode_pager_umount(mp);	/* release cached vnodes */
194	cache_purgevfs(mp);	/* remove cache entries for this file sys */
195
196	if ((error = VFS_SYNC(mp, MNT_WAIT, initproc->p_ucred, initproc)))
197		printf("sync of root filesystem failed (%d)\n", error);
198
199	if ((error = VFS_UNMOUNT(mp, MNT_FORCE, initproc))) {
200		printf("unmount of root filesystem failed (");
201		if (error == EBUSY)
202			printf("BUSY)\n");
203		else
204			printf("%d)\n", error);
205	}
206	mp->mnt_flag &= ~MNT_UNMOUNT;
207	vfs_unbusy(mp);
208}
209
210/*
211 * Unmount all filesystems.  Should only be called by halt().
212 */
213void
214vfs_unmountall()
215{
216	struct mount *mp, *mp_next, *rootfs = NULL;
217	int error;
218
219	/* unmount all but rootfs */
220	for (mp = mountlist.tqh_first; mp != NULL; mp = mp_next) {
221		mp_next = mp->mnt_list.tqe_next;
222
223		if (mp->mnt_flag & MNT_ROOTFS) {
224			rootfs = mp;
225			continue;
226		}
227		error = dounmount(mp, MNT_FORCE, initproc);
228		if (error) {
229			printf("unmount of %s failed (", mp->mnt_stat.f_mntonname);
230			if (error == EBUSY)
231				printf("BUSY)\n");
232			else
233				printf("%d)\n", error);
234		}
235	}
236
237	/* and finally... */
238	if (rootfs) {
239		vfs_unmountroot(rootfs);
240	} else {
241		printf("no root filesystem\n");
242	}
243}
244
245/*
246 * Lookup a mount point by filesystem identifier.
247 */
248struct mount *
249getvfs(fsid)
250	fsid_t *fsid;
251{
252	register struct mount *mp;
253
254	for (mp = mountlist.tqh_first; mp != NULL; mp = mp->mnt_list.tqe_next) {
255		if (mp->mnt_stat.f_fsid.val[0] == fsid->val[0] &&
256		    mp->mnt_stat.f_fsid.val[1] == fsid->val[1])
257			return (mp);
258	}
259	return ((struct mount *) 0);
260}
261
262/*
263 * Get a new unique fsid
264 */
265void
266getnewfsid(mp, mtype)
267	struct mount *mp;
268	int mtype;
269{
270	static u_short xxxfs_mntid;
271
272	fsid_t tfsid;
273
274	mp->mnt_stat.f_fsid.val[0] = makedev(nblkdev + mtype, 0);
275	mp->mnt_stat.f_fsid.val[1] = mtype;
276	if (xxxfs_mntid == 0)
277		++xxxfs_mntid;
278	tfsid.val[0] = makedev(nblkdev + mtype, xxxfs_mntid);
279	tfsid.val[1] = mtype;
280	if (mountlist.tqh_first != NULL) {
281		while (getvfs(&tfsid)) {
282			tfsid.val[0]++;
283			xxxfs_mntid++;
284		}
285	}
286	mp->mnt_stat.f_fsid.val[0] = tfsid.val[0];
287}
288
289/*
290 * Set vnode attributes to VNOVAL
291 */
292void
293vattr_null(vap)
294	register struct vattr *vap;
295{
296
297	vap->va_type = VNON;
298	vap->va_size = VNOVAL;
299	vap->va_bytes = VNOVAL;
300	vap->va_mode = vap->va_nlink = vap->va_uid = vap->va_gid =
301	    vap->va_fsid = vap->va_fileid =
302	    vap->va_blocksize = vap->va_rdev =
303	    vap->va_atime.ts_sec = vap->va_atime.ts_nsec =
304	    vap->va_mtime.ts_sec = vap->va_mtime.ts_nsec =
305	    vap->va_ctime.ts_sec = vap->va_ctime.ts_nsec =
306	    vap->va_flags = vap->va_gen = VNOVAL;
307	vap->va_vaflags = 0;
308}
309
310/*
311 * Routines having to do with the management of the vnode table.
312 */
313extern int (**dead_vnodeop_p) ();
314extern void vclean();
315
316/*
317 * Return the next vnode from the free list.
318 */
319int
320getnewvnode(tag, mp, vops, vpp)
321	enum vtagtype tag;
322	struct mount *mp;
323	int (**vops) ();
324	struct vnode **vpp;
325{
326	register struct vnode *vp;
327
328	vp = vnode_free_list.tqh_first;
329	/*
330	 * we allocate a new vnode if
331	 * 	1. we don't have any free
332	 *		Pretty obvious, we actually used to panic, but that
333	 *		is a silly thing to do.
334	 *	2. we havn't filled our pool yet
335	 *		We don't want to trash the incore (VM-)vnodecache.
336	 *	3. if less that 1/4th of our vnodes are free.
337	 *		We don't want to trash the namei cache either.
338	 */
339	if (freevnodes < (numvnodes >> 2) ||
340	    numvnodes < desiredvnodes ||
341	    vp == NULL) {
342		vp = (struct vnode *) malloc((u_long) sizeof *vp,
343		    M_VNODE, M_WAITOK);
344		bzero((char *) vp, sizeof *vp);
345		numvnodes++;
346	} else {
347		TAILQ_REMOVE(&vnode_free_list, vp, v_freelist);
348		freevnodes--;
349
350		if (vp->v_usecount)
351			panic("free vnode isn't");
352
353		/* see comment on why 0xdeadb is set at end of vgone (below) */
354		vp->v_freelist.tqe_prev = (struct vnode **) 0xdeadb;
355		vp->v_lease = NULL;
356		if (vp->v_type != VBAD)
357			vgone(vp);
358#ifdef DIAGNOSTIC
359		{
360			int s;
361
362			if (vp->v_data)
363				panic("cleaned vnode isn't");
364			s = splbio();
365			if (vp->v_numoutput)
366				panic("Clean vnode has pending I/O's");
367			splx(s);
368		}
369#endif
370		vp->v_flag = 0;
371		vp->v_lastr = 0;
372		vp->v_ralen = 0;
373		vp->v_maxra = 0;
374		vp->v_lastw = 0;
375		vp->v_lasta = 0;
376		vp->v_cstart = 0;
377		vp->v_clen = 0;
378		vp->v_socket = 0;
379		vp->v_writecount = 0;	/* XXX */
380	}
381	vp->v_type = VNON;
382	cache_purge(vp);
383	vp->v_tag = tag;
384	vp->v_op = vops;
385	insmntque(vp, mp);
386	*vpp = vp;
387	vp->v_usecount = 1;
388	vp->v_data = 0;
389	return (0);
390}
391
392/*
393 * Move a vnode from one mount queue to another.
394 */
395void
396insmntque(vp, mp)
397	register struct vnode *vp;
398	register struct mount *mp;
399{
400
401	/*
402	 * Delete from old mount point vnode list, if on one.
403	 */
404	if (vp->v_mount != NULL)
405		LIST_REMOVE(vp, v_mntvnodes);
406	/*
407	 * Insert into list of vnodes for the new mount point, if available.
408	 */
409	if ((vp->v_mount = mp) == NULL)
410		return;
411	LIST_INSERT_HEAD(&mp->mnt_vnodelist, vp, v_mntvnodes);
412}
413
414/*
415 * Update outstanding I/O count and do wakeup if requested.
416 */
417void
418vwakeup(bp)
419	register struct buf *bp;
420{
421	register struct vnode *vp;
422
423	bp->b_flags &= ~B_WRITEINPROG;
424	if ((vp = bp->b_vp)) {
425		vp->v_numoutput--;
426		if (vp->v_numoutput < 0)
427			panic("vwakeup: neg numoutput");
428		if ((vp->v_numoutput == 0) && (vp->v_flag & VBWAIT)) {
429			vp->v_flag &= ~VBWAIT;
430			wakeup((caddr_t) &vp->v_numoutput);
431		}
432	}
433}
434
435/*
436 * Flush out and invalidate all buffers associated with a vnode.
437 * Called with the underlying object locked.
438 */
439int
440vinvalbuf(vp, flags, cred, p, slpflag, slptimeo)
441	register struct vnode *vp;
442	int flags;
443	struct ucred *cred;
444	struct proc *p;
445	int slpflag, slptimeo;
446{
447	register struct buf *bp;
448	struct buf *nbp, *blist;
449	int s, error;
450	vm_pager_t pager;
451	vm_object_t object;
452
453	if (flags & V_SAVE) {
454		if ((error = VOP_FSYNC(vp, cred, MNT_WAIT, p)))
455			return (error);
456		if (vp->v_dirtyblkhd.lh_first != NULL)
457			panic("vinvalbuf: dirty bufs");
458	}
459	for (;;) {
460		if ((blist = vp->v_cleanblkhd.lh_first) && (flags & V_SAVEMETA))
461			while (blist && blist->b_lblkno < 0)
462				blist = blist->b_vnbufs.le_next;
463		if (!blist && (blist = vp->v_dirtyblkhd.lh_first) &&
464		    (flags & V_SAVEMETA))
465			while (blist && blist->b_lblkno < 0)
466				blist = blist->b_vnbufs.le_next;
467		if (!blist)
468			break;
469
470		for (bp = blist; bp; bp = nbp) {
471			nbp = bp->b_vnbufs.le_next;
472			if ((flags & V_SAVEMETA) && bp->b_lblkno < 0)
473				continue;
474			s = splbio();
475			if (bp->b_flags & B_BUSY) {
476				bp->b_flags |= B_WANTED;
477				error = tsleep((caddr_t) bp,
478				    slpflag | (PRIBIO + 1), "vinvalbuf",
479				    slptimeo);
480				splx(s);
481				if (error)
482					return (error);
483				break;
484			}
485			bremfree(bp);
486			bp->b_flags |= B_BUSY;
487			splx(s);
488			/*
489			 * XXX Since there are no node locks for NFS, I
490			 * believe there is a slight chance that a delayed
491			 * write will occur while sleeping just above, so
492			 * check for it.
493			 */
494			if ((bp->b_flags & B_DELWRI) && (flags & V_SAVE)) {
495				(void) VOP_BWRITE(bp);
496				break;
497			}
498			bp->b_flags |= (B_INVAL|B_NOCACHE|B_RELBUF);
499			brelse(bp);
500		}
501	}
502
503	s = splbio();
504	while (vp->v_numoutput > 0) {
505		vp->v_flag |= VBWAIT;
506		tsleep(&vp->v_numoutput, PVM, "vnvlbv", 0);
507	}
508	splx(s);
509
510	/*
511	 * Destroy the copy in the VM cache, too.
512	 */
513	object = (vm_object_t) vp->v_vmdata;
514	if (object != NULL) {
515		vm_object_lock(object);
516		vm_object_page_remove(object, 0, object->size,
517		    (flags & V_SAVE) ? TRUE : FALSE);
518		vm_object_unlock(object);
519	}
520	if (!(flags & V_SAVEMETA) &&
521	    (vp->v_dirtyblkhd.lh_first || vp->v_cleanblkhd.lh_first))
522		panic("vinvalbuf: flush failed");
523	return (0);
524}
525
526/*
527 * Associate a buffer with a vnode.
528 */
529void
530bgetvp(vp, bp)
531	register struct vnode *vp;
532	register struct buf *bp;
533{
534	int s;
535
536	if (bp->b_vp)
537		panic("bgetvp: not free");
538	VHOLD(vp);
539	bp->b_vp = vp;
540	if (vp->v_type == VBLK || vp->v_type == VCHR)
541		bp->b_dev = vp->v_rdev;
542	else
543		bp->b_dev = NODEV;
544	/*
545	 * Insert onto list for new vnode.
546	 */
547	s = splbio();
548	bufinsvn(bp, &vp->v_cleanblkhd);
549	splx(s);
550}
551
552/*
553 * Disassociate a buffer from a vnode.
554 */
555void
556brelvp(bp)
557	register struct buf *bp;
558{
559	struct vnode *vp;
560	int s;
561
562	if (bp->b_vp == (struct vnode *) 0)
563		panic("brelvp: NULL");
564	/*
565	 * Delete from old vnode list, if on one.
566	 */
567	s = splbio();
568	if (bp->b_vnbufs.le_next != NOLIST)
569		bufremvn(bp);
570	splx(s);
571
572	vp = bp->b_vp;
573	bp->b_vp = (struct vnode *) 0;
574	HOLDRELE(vp);
575}
576
577/*
578 * Associate a p-buffer with a vnode.
579 */
580void
581pbgetvp(vp, bp)
582	register struct vnode *vp;
583	register struct buf *bp;
584{
585	if (bp->b_vp)
586		panic("pbgetvp: not free");
587	VHOLD(vp);
588	bp->b_vp = vp;
589	if (vp->v_type == VBLK || vp->v_type == VCHR)
590		bp->b_dev = vp->v_rdev;
591	else
592		bp->b_dev = NODEV;
593}
594
595/*
596 * Disassociate a p-buffer from a vnode.
597 */
598void
599pbrelvp(bp)
600	register struct buf *bp;
601{
602	struct vnode *vp;
603
604	if (bp->b_vp == (struct vnode *) 0)
605		panic("brelvp: NULL");
606
607	vp = bp->b_vp;
608	bp->b_vp = (struct vnode *) 0;
609	HOLDRELE(vp);
610}
611
612/*
613 * Reassign a buffer from one vnode to another.
614 * Used to assign file specific control information
615 * (indirect blocks) to the vnode to which they belong.
616 */
617void
618reassignbuf(bp, newvp)
619	register struct buf *bp;
620	register struct vnode *newvp;
621{
622	register struct buflists *listheadp;
623
624	if (newvp == NULL) {
625		printf("reassignbuf: NULL");
626		return;
627	}
628	/*
629	 * Delete from old vnode list, if on one.
630	 */
631	if (bp->b_vnbufs.le_next != NOLIST)
632		bufremvn(bp);
633	/*
634	 * If dirty, put on list of dirty buffers; otherwise insert onto list
635	 * of clean buffers.
636	 */
637	if (bp->b_flags & B_DELWRI) {
638		struct buf *tbp;
639
640		tbp = newvp->v_dirtyblkhd.lh_first;
641		if (!tbp || (tbp->b_lblkno > bp->b_lblkno)) {
642			bufinsvn(bp, &newvp->v_dirtyblkhd);
643		} else {
644			while (tbp->b_vnbufs.le_next && (tbp->b_vnbufs.le_next->b_lblkno < bp->b_lblkno)) {
645				tbp = tbp->b_vnbufs.le_next;
646			}
647			LIST_INSERT_AFTER(tbp, bp, b_vnbufs);
648		}
649	} else {
650		listheadp = &newvp->v_cleanblkhd;
651		bufinsvn(bp, listheadp);
652	}
653}
654
655/*
656 * Create a vnode for a block device.
657 * Used for root filesystem, argdev, and swap areas.
658 * Also used for memory file system special devices.
659 */
660int
661bdevvp(dev, vpp)
662	dev_t dev;
663	struct vnode **vpp;
664{
665	register struct vnode *vp;
666	struct vnode *nvp;
667	int error;
668
669	if (dev == NODEV)
670		return (0);
671	error = getnewvnode(VT_NON, (struct mount *) 0, spec_vnodeop_p, &nvp);
672	if (error) {
673		*vpp = 0;
674		return (error);
675	}
676	vp = nvp;
677	vp->v_type = VBLK;
678	if ((nvp = checkalias(vp, dev, (struct mount *) 0))) {
679		vput(vp);
680		vp = nvp;
681	}
682	*vpp = vp;
683	return (0);
684}
685
686/*
687 * Check to see if the new vnode represents a special device
688 * for which we already have a vnode (either because of
689 * bdevvp() or because of a different vnode representing
690 * the same block device). If such an alias exists, deallocate
691 * the existing contents and return the aliased vnode. The
692 * caller is responsible for filling it with its new contents.
693 */
694struct vnode *
695checkalias(nvp, nvp_rdev, mp)
696	register struct vnode *nvp;
697	dev_t nvp_rdev;
698	struct mount *mp;
699{
700	register struct vnode *vp;
701	struct vnode **vpp;
702
703	if (nvp->v_type != VBLK && nvp->v_type != VCHR)
704		return (NULLVP);
705
706	vpp = &speclisth[SPECHASH(nvp_rdev)];
707loop:
708	for (vp = *vpp; vp; vp = vp->v_specnext) {
709		if (nvp_rdev != vp->v_rdev || nvp->v_type != vp->v_type)
710			continue;
711		/*
712		 * Alias, but not in use, so flush it out.
713		 */
714		if (vp->v_usecount == 0) {
715			vgone(vp);
716			goto loop;
717		}
718		if (vget(vp, 1))
719			goto loop;
720		break;
721	}
722	if (vp == NULL || vp->v_tag != VT_NON) {
723		MALLOC(nvp->v_specinfo, struct specinfo *,
724		    sizeof(struct specinfo), M_VNODE, M_WAITOK);
725		nvp->v_rdev = nvp_rdev;
726		nvp->v_hashchain = vpp;
727		nvp->v_specnext = *vpp;
728		nvp->v_specflags = 0;
729		*vpp = nvp;
730		if (vp != NULL) {
731			nvp->v_flag |= VALIASED;
732			vp->v_flag |= VALIASED;
733			vput(vp);
734		}
735		return (NULLVP);
736	}
737	VOP_UNLOCK(vp);
738	vclean(vp, 0);
739	vp->v_op = nvp->v_op;
740	vp->v_tag = nvp->v_tag;
741	nvp->v_type = VNON;
742	insmntque(vp, mp);
743	return (vp);
744}
745
746/*
747 * Grab a particular vnode from the free list, increment its
748 * reference count and lock it. The vnode lock bit is set the
749 * vnode is being eliminated in vgone. The process is awakened
750 * when the transition is completed, and an error returned to
751 * indicate that the vnode is no longer usable (possibly having
752 * been changed to a new file system type).
753 */
754int
755vget(vp, lockflag)
756	register struct vnode *vp;
757	int lockflag;
758{
759
760	/*
761	 * If the vnode is in the process of being cleaned out for another
762	 * use, we wait for the cleaning to finish and then return failure.
763	 * Cleaning is determined either by checking that the VXLOCK flag is
764	 * set, or that the use count is zero with the back pointer set to
765	 * show that it has been removed from the free list by getnewvnode.
766	 * The VXLOCK flag may not have been set yet because vclean is blocked
767	 * in the VOP_LOCK call waiting for the VOP_INACTIVE to complete.
768	 */
769	if ((vp->v_flag & VXLOCK) ||
770	    (vp->v_usecount == 0 &&
771		vp->v_freelist.tqe_prev == (struct vnode **) 0xdeadb)) {
772		vp->v_flag |= VXWANT;
773		(void) tsleep((caddr_t) vp, PINOD, "vget", 0);
774		return (1);
775	}
776	if (vp->v_usecount == 0) {
777		TAILQ_REMOVE(&vnode_free_list, vp, v_freelist);
778		freevnodes--;
779	}
780	vp->v_usecount++;
781	if (lockflag)
782		VOP_LOCK(vp);
783	return (0);
784}
785
786/*
787 * Vnode reference, just increment the count
788 */
789void
790vref(vp)
791	struct vnode *vp;
792{
793
794	if (vp->v_usecount <= 0)
795		panic("vref used where vget required");
796	vp->v_usecount++;
797}
798
799/*
800 * vput(), just unlock and vrele()
801 */
802void
803vput(vp)
804	register struct vnode *vp;
805{
806
807	VOP_UNLOCK(vp);
808	vrele(vp);
809}
810
811/*
812 * Vnode release.
813 * If count drops to zero, call inactive routine and return to freelist.
814 */
815void
816vrele(vp)
817	register struct vnode *vp;
818{
819
820#ifdef DIAGNOSTIC
821	if (vp == NULL)
822		panic("vrele: null vp");
823#endif
824	vp->v_usecount--;
825	if (vp->v_usecount > 0)
826		return;
827#ifdef DIAGNOSTIC
828	if (vp->v_usecount != 0 /* || vp->v_writecount != 0 */ ) {
829		vprint("vrele: bad ref count", vp);
830		panic("vrele: ref cnt");
831	}
832#endif
833	if (vp->v_flag & VAGE) {
834		TAILQ_INSERT_HEAD(&vnode_free_list, vp, v_freelist);
835		vp->v_flag &= ~VAGE;
836	} else {
837		TAILQ_INSERT_TAIL(&vnode_free_list, vp, v_freelist);
838	}
839	freevnodes++;
840
841	VOP_INACTIVE(vp);
842}
843
844/*
845 * Page or buffer structure gets a reference.
846 */
847void
848vhold(vp)
849	register struct vnode *vp;
850{
851
852	vp->v_holdcnt++;
853}
854
855/*
856 * Page or buffer structure frees a reference.
857 */
858void
859holdrele(vp)
860	register struct vnode *vp;
861{
862
863	if (vp->v_holdcnt <= 0)
864		panic("holdrele: holdcnt");
865	vp->v_holdcnt--;
866}
867
868/*
869 * Remove any vnodes in the vnode table belonging to mount point mp.
870 *
871 * If MNT_NOFORCE is specified, there should not be any active ones,
872 * return error if any are found (nb: this is a user error, not a
873 * system error). If MNT_FORCE is specified, detach any active vnodes
874 * that are found.
875 */
876#ifdef DIAGNOSTIC
877int busyprt = 0;		/* print out busy vnodes */
878struct ctldebug debug1 = {"busyprt", &busyprt};
879
880#endif
881
882int
883vflush(mp, skipvp, flags)
884	struct mount *mp;
885	struct vnode *skipvp;
886	int flags;
887{
888	register struct vnode *vp, *nvp;
889	int busy = 0;
890
891	if ((mp->mnt_flag & MNT_MPBUSY) == 0)
892		panic("vflush: not busy");
893loop:
894	for (vp = mp->mnt_vnodelist.lh_first; vp; vp = nvp) {
895		/*
896		 * Make sure this vnode wasn't reclaimed in getnewvnode().
897		 * Start over if it has (it won't be on the list anymore).
898		 */
899		if (vp->v_mount != mp)
900			goto loop;
901		nvp = vp->v_mntvnodes.le_next;
902		/*
903		 * Skip over a selected vnode.
904		 */
905		if (vp == skipvp)
906			continue;
907		/*
908		 * Skip over a vnodes marked VSYSTEM.
909		 */
910		if ((flags & SKIPSYSTEM) && (vp->v_flag & VSYSTEM))
911			continue;
912		/*
913		 * If WRITECLOSE is set, only flush out regular file vnodes
914		 * open for writing.
915		 */
916		if ((flags & WRITECLOSE) &&
917		    (vp->v_writecount == 0 || vp->v_type != VREG))
918			continue;
919		/*
920		 * With v_usecount == 0, all we need to do is clear out the
921		 * vnode data structures and we are done.
922		 */
923		if (vp->v_usecount == 0) {
924			vgone(vp);
925			continue;
926		}
927		/*
928		 * If FORCECLOSE is set, forcibly close the vnode. For block
929		 * or character devices, revert to an anonymous device. For
930		 * all other files, just kill them.
931		 */
932		if (flags & FORCECLOSE) {
933			if (vp->v_type != VBLK && vp->v_type != VCHR) {
934				vgone(vp);
935			} else {
936				vclean(vp, 0);
937				vp->v_op = spec_vnodeop_p;
938				insmntque(vp, (struct mount *) 0);
939			}
940			continue;
941		}
942#ifdef DIAGNOSTIC
943		if (busyprt)
944			vprint("vflush: busy vnode", vp);
945#endif
946		busy++;
947	}
948	if (busy)
949		return (EBUSY);
950	return (0);
951}
952
953/*
954 * Disassociate the underlying file system from a vnode.
955 */
956void
957vclean(vp, flags)
958	register struct vnode *vp;
959	int flags;
960{
961	int active;
962
963	/*
964	 * Check to see if the vnode is in use. If so we have to reference it
965	 * before we clean it out so that its count cannot fall to zero and
966	 * generate a race against ourselves to recycle it.
967	 */
968	if ((active = vp->v_usecount))
969		VREF(vp);
970	/*
971	 * Even if the count is zero, the VOP_INACTIVE routine may still have
972	 * the object locked while it cleans it out. The VOP_LOCK ensures that
973	 * the VOP_INACTIVE routine is done with its work. For active vnodes,
974	 * it ensures that no other activity can occur while the underlying
975	 * object is being cleaned out.
976	 */
977	VOP_LOCK(vp);
978	/*
979	 * Prevent the vnode from being recycled or brought into use while we
980	 * clean it out.
981	 */
982	if (vp->v_flag & VXLOCK)
983		panic("vclean: deadlock");
984	vp->v_flag |= VXLOCK;
985	/*
986	 * Clean out any buffers associated with the vnode.
987	 */
988	if (flags & DOCLOSE)
989		vinvalbuf(vp, V_SAVE, NOCRED, NULL, 0, 0);
990	/*
991	 * Any other processes trying to obtain this lock must first wait for
992	 * VXLOCK to clear, then call the new lock operation.
993	 */
994	VOP_UNLOCK(vp);
995	/*
996	 * If purging an active vnode, it must be closed and deactivated
997	 * before being reclaimed.
998	 */
999	if (active) {
1000		if (flags & DOCLOSE)
1001			VOP_CLOSE(vp, IO_NDELAY, NOCRED, NULL);
1002		VOP_INACTIVE(vp);
1003	}
1004	/*
1005	 * Reclaim the vnode.
1006	 */
1007	if (VOP_RECLAIM(vp))
1008		panic("vclean: cannot reclaim");
1009	if (active)
1010		vrele(vp);
1011
1012	/*
1013	 * Done with purge, notify sleepers of the grim news.
1014	 */
1015	vp->v_op = dead_vnodeop_p;
1016	vp->v_tag = VT_NON;
1017	vp->v_flag &= ~VXLOCK;
1018	if (vp->v_flag & VXWANT) {
1019		vp->v_flag &= ~VXWANT;
1020		wakeup((caddr_t) vp);
1021	}
1022}
1023
1024/*
1025 * Eliminate all activity associated with  the requested vnode
1026 * and with all vnodes aliased to the requested vnode.
1027 */
1028void
1029vgoneall(vp)
1030	register struct vnode *vp;
1031{
1032	register struct vnode *vq;
1033
1034	if (vp->v_flag & VALIASED) {
1035		/*
1036		 * If a vgone (or vclean) is already in progress, wait until
1037		 * it is done and return.
1038		 */
1039		if (vp->v_flag & VXLOCK) {
1040			vp->v_flag |= VXWANT;
1041			(void) tsleep((caddr_t) vp, PINOD, "vgall", 0);
1042			return;
1043		}
1044		/*
1045		 * Ensure that vp will not be vgone'd while we are eliminating
1046		 * its aliases.
1047		 */
1048		vp->v_flag |= VXLOCK;
1049		while (vp->v_flag & VALIASED) {
1050			for (vq = *vp->v_hashchain; vq; vq = vq->v_specnext) {
1051				if (vq->v_rdev != vp->v_rdev ||
1052				    vq->v_type != vp->v_type || vp == vq)
1053					continue;
1054				vgone(vq);
1055				break;
1056			}
1057		}
1058		/*
1059		 * Remove the lock so that vgone below will really eliminate
1060		 * the vnode after which time vgone will awaken any sleepers.
1061		 */
1062		vp->v_flag &= ~VXLOCK;
1063	}
1064	vgone(vp);
1065}
1066
1067/*
1068 * Eliminate all activity associated with a vnode
1069 * in preparation for reuse.
1070 */
1071void
1072vgone(vp)
1073	register struct vnode *vp;
1074{
1075	register struct vnode *vq;
1076	struct vnode *vx;
1077
1078	/*
1079	 * If a vgone (or vclean) is already in progress, wait until it is
1080	 * done and return.
1081	 */
1082	if (vp->v_flag & VXLOCK) {
1083		vp->v_flag |= VXWANT;
1084		(void) tsleep((caddr_t) vp, PINOD, "vgone", 0);
1085		return;
1086	}
1087	/*
1088	 * Clean out the filesystem specific data.
1089	 */
1090	vclean(vp, DOCLOSE);
1091	/*
1092	 * Delete from old mount point vnode list, if on one.
1093	 */
1094	if (vp->v_mount != NULL) {
1095		LIST_REMOVE(vp, v_mntvnodes);
1096		vp->v_mount = NULL;
1097	}
1098	/*
1099	 * If special device, remove it from special device alias list.
1100	 */
1101	if (vp->v_type == VBLK || vp->v_type == VCHR) {
1102		if (*vp->v_hashchain == vp) {
1103			*vp->v_hashchain = vp->v_specnext;
1104		} else {
1105			for (vq = *vp->v_hashchain; vq; vq = vq->v_specnext) {
1106				if (vq->v_specnext != vp)
1107					continue;
1108				vq->v_specnext = vp->v_specnext;
1109				break;
1110			}
1111			if (vq == NULL)
1112				panic("missing bdev");
1113		}
1114		if (vp->v_flag & VALIASED) {
1115			vx = NULL;
1116			for (vq = *vp->v_hashchain; vq; vq = vq->v_specnext) {
1117				if (vq->v_rdev != vp->v_rdev ||
1118				    vq->v_type != vp->v_type)
1119					continue;
1120				if (vx)
1121					break;
1122				vx = vq;
1123			}
1124			if (vx == NULL)
1125				panic("missing alias");
1126			if (vq == NULL)
1127				vx->v_flag &= ~VALIASED;
1128			vp->v_flag &= ~VALIASED;
1129		}
1130		FREE(vp->v_specinfo, M_VNODE);
1131		vp->v_specinfo = NULL;
1132	}
1133	/*
1134	 * If it is on the freelist and not already at the head, move it to
1135	 * the head of the list. The test of the back pointer and the
1136	 * reference count of zero is because it will be removed from the free
1137	 * list by getnewvnode, but will not have its reference count
1138	 * incremented until after calling vgone. If the reference count were
1139	 * incremented first, vgone would (incorrectly) try to close the
1140	 * previous instance of the underlying object. So, the back pointer is
1141	 * explicitly set to `0xdeadb' in getnewvnode after removing it from
1142	 * the freelist to ensure that we do not try to move it here.
1143	 */
1144	if (vp->v_usecount == 0 &&
1145	    vp->v_freelist.tqe_prev != (struct vnode **) 0xdeadb &&
1146	    vnode_free_list.tqh_first != vp) {
1147		TAILQ_REMOVE(&vnode_free_list, vp, v_freelist);
1148		TAILQ_INSERT_HEAD(&vnode_free_list, vp, v_freelist);
1149	}
1150	vp->v_type = VBAD;
1151}
1152
1153/*
1154 * Lookup a vnode by device number.
1155 */
1156int
1157vfinddev(dev, type, vpp)
1158	dev_t dev;
1159	enum vtype type;
1160	struct vnode **vpp;
1161{
1162	register struct vnode *vp;
1163
1164	for (vp = speclisth[SPECHASH(dev)]; vp; vp = vp->v_specnext) {
1165		if (dev != vp->v_rdev || type != vp->v_type)
1166			continue;
1167		*vpp = vp;
1168		return (1);
1169	}
1170	return (0);
1171}
1172
1173/*
1174 * Calculate the total number of references to a special device.
1175 */
1176int
1177vcount(vp)
1178	register struct vnode *vp;
1179{
1180	register struct vnode *vq, *vnext;
1181	int count;
1182
1183loop:
1184	if ((vp->v_flag & VALIASED) == 0)
1185		return (vp->v_usecount);
1186	for (count = 0, vq = *vp->v_hashchain; vq; vq = vnext) {
1187		vnext = vq->v_specnext;
1188		if (vq->v_rdev != vp->v_rdev || vq->v_type != vp->v_type)
1189			continue;
1190		/*
1191		 * Alias, but not in use, so flush it out.
1192		 */
1193		if (vq->v_usecount == 0 && vq != vp) {
1194			vgone(vq);
1195			goto loop;
1196		}
1197		count += vq->v_usecount;
1198	}
1199	return (count);
1200}
1201
1202/*
1203 * Print out a description of a vnode.
1204 */
1205static char *typename[] =
1206{"VNON", "VREG", "VDIR", "VBLK", "VCHR", "VLNK", "VSOCK", "VFIFO", "VBAD"};
1207
1208void
1209vprint(label, vp)
1210	char *label;
1211	register struct vnode *vp;
1212{
1213	char buf[64];
1214
1215	if (label != NULL)
1216		printf("%s: ", label);
1217	printf("type %s, usecount %d, writecount %d, refcount %ld,",
1218	    typename[vp->v_type], vp->v_usecount, vp->v_writecount,
1219	    vp->v_holdcnt);
1220	buf[0] = '\0';
1221	if (vp->v_flag & VROOT)
1222		strcat(buf, "|VROOT");
1223	if (vp->v_flag & VTEXT)
1224		strcat(buf, "|VTEXT");
1225	if (vp->v_flag & VSYSTEM)
1226		strcat(buf, "|VSYSTEM");
1227	if (vp->v_flag & VXLOCK)
1228		strcat(buf, "|VXLOCK");
1229	if (vp->v_flag & VXWANT)
1230		strcat(buf, "|VXWANT");
1231	if (vp->v_flag & VBWAIT)
1232		strcat(buf, "|VBWAIT");
1233	if (vp->v_flag & VALIASED)
1234		strcat(buf, "|VALIASED");
1235	if (buf[0] != '\0')
1236		printf(" flags (%s)", &buf[1]);
1237	if (vp->v_data == NULL) {
1238		printf("\n");
1239	} else {
1240		printf("\n\t");
1241		VOP_PRINT(vp);
1242	}
1243}
1244
1245#ifdef DDB
1246/*
1247 * List all of the locked vnodes in the system.
1248 * Called when debugging the kernel.
1249 */
1250void
1251printlockedvnodes()
1252{
1253	register struct mount *mp;
1254	register struct vnode *vp;
1255
1256	printf("Locked vnodes\n");
1257	for (mp = mountlist.tqh_first; mp != NULL; mp = mp->mnt_list.tqe_next) {
1258		for (vp = mp->mnt_vnodelist.lh_first;
1259		    vp != NULL;
1260		    vp = vp->v_mntvnodes.le_next)
1261			if (VOP_ISLOCKED(vp))
1262				vprint((char *) 0, vp);
1263	}
1264}
1265#endif
1266
1267int kinfo_vdebug = 1;
1268int kinfo_vgetfailed;
1269
1270#define KINFO_VNODESLOP	10
1271/*
1272 * Dump vnode list (via sysctl).
1273 * Copyout address of vnode followed by vnode.
1274 */
1275/* ARGSUSED */
1276int
1277sysctl_vnode(where, sizep)
1278	char *where;
1279	size_t *sizep;
1280{
1281	register struct mount *mp, *nmp;
1282	struct vnode *vp;
1283	register char *bp = where, *savebp;
1284	char *ewhere;
1285	int error;
1286
1287#define VPTRSZ	sizeof (struct vnode *)
1288#define VNODESZ	sizeof (struct vnode)
1289	if (where == NULL) {
1290		*sizep = (numvnodes + KINFO_VNODESLOP) * (VPTRSZ + VNODESZ);
1291		return (0);
1292	}
1293	ewhere = where + *sizep;
1294
1295	for (mp = mountlist.tqh_first; mp != NULL; mp = nmp) {
1296		nmp = mp->mnt_list.tqe_next;
1297		if (vfs_busy(mp))
1298			continue;
1299		savebp = bp;
1300again:
1301		for (vp = mp->mnt_vnodelist.lh_first;
1302		    vp != NULL;
1303		    vp = vp->v_mntvnodes.le_next) {
1304			/*
1305			 * Check that the vp is still associated with this
1306			 * filesystem.  RACE: could have been recycled onto
1307			 * the same filesystem.
1308			 */
1309			if (vp->v_mount != mp) {
1310				if (kinfo_vdebug)
1311					printf("kinfo: vp changed\n");
1312				bp = savebp;
1313				goto again;
1314			}
1315			if (bp + VPTRSZ + VNODESZ > ewhere) {
1316				*sizep = bp - where;
1317				return (ENOMEM);
1318			}
1319			if ((error = copyout((caddr_t) &vp, bp, VPTRSZ)) ||
1320			    (error = copyout((caddr_t) vp, bp + VPTRSZ, VNODESZ)))
1321				return (error);
1322			bp += VPTRSZ + VNODESZ;
1323		}
1324		vfs_unbusy(mp);
1325	}
1326
1327	*sizep = bp - where;
1328	return (0);
1329}
1330
1331/*
1332 * Check to see if a filesystem is mounted on a block device.
1333 */
1334int
1335vfs_mountedon(vp)
1336	register struct vnode *vp;
1337{
1338	register struct vnode *vq;
1339
1340	if (vp->v_specflags & SI_MOUNTEDON)
1341		return (EBUSY);
1342	if (vp->v_flag & VALIASED) {
1343		for (vq = *vp->v_hashchain; vq; vq = vq->v_specnext) {
1344			if (vq->v_rdev != vp->v_rdev ||
1345			    vq->v_type != vp->v_type)
1346				continue;
1347			if (vq->v_specflags & SI_MOUNTEDON)
1348				return (EBUSY);
1349		}
1350	}
1351	return (0);
1352}
1353
1354/*
1355 * Build hash lists of net addresses and hang them off the mount point.
1356 * Called by ufs_mount() to set up the lists of export addresses.
1357 */
1358static int
1359vfs_hang_addrlist(mp, nep, argp)
1360	struct mount *mp;
1361	struct netexport *nep;
1362	struct export_args *argp;
1363{
1364	register struct netcred *np;
1365	register struct radix_node_head *rnh;
1366	register int i;
1367	struct radix_node *rn;
1368	struct sockaddr *saddr, *smask = 0;
1369	struct domain *dom;
1370	int error;
1371
1372	if (argp->ex_addrlen == 0) {
1373		if (mp->mnt_flag & MNT_DEFEXPORTED)
1374			return (EPERM);
1375		np = &nep->ne_defexported;
1376		np->netc_exflags = argp->ex_flags;
1377		np->netc_anon = argp->ex_anon;
1378		np->netc_anon.cr_ref = 1;
1379		mp->mnt_flag |= MNT_DEFEXPORTED;
1380		return (0);
1381	}
1382	i = sizeof(struct netcred) + argp->ex_addrlen + argp->ex_masklen;
1383	np = (struct netcred *) malloc(i, M_NETADDR, M_WAITOK);
1384	bzero((caddr_t) np, i);
1385	saddr = (struct sockaddr *) (np + 1);
1386	if ((error = copyin(argp->ex_addr, (caddr_t) saddr, argp->ex_addrlen)))
1387		goto out;
1388	if (saddr->sa_len > argp->ex_addrlen)
1389		saddr->sa_len = argp->ex_addrlen;
1390	if (argp->ex_masklen) {
1391		smask = (struct sockaddr *) ((caddr_t) saddr + argp->ex_addrlen);
1392		error = copyin(argp->ex_addr, (caddr_t) smask, argp->ex_masklen);
1393		if (error)
1394			goto out;
1395		if (smask->sa_len > argp->ex_masklen)
1396			smask->sa_len = argp->ex_masklen;
1397	}
1398	i = saddr->sa_family;
1399	if ((rnh = nep->ne_rtable[i]) == 0) {
1400		/*
1401		 * Seems silly to initialize every AF when most are not used,
1402		 * do so on demand here
1403		 */
1404		for (dom = domains; dom; dom = dom->dom_next)
1405			if (dom->dom_family == i && dom->dom_rtattach) {
1406				dom->dom_rtattach((void **) &nep->ne_rtable[i],
1407				    dom->dom_rtoffset);
1408				break;
1409			}
1410		if ((rnh = nep->ne_rtable[i]) == 0) {
1411			error = ENOBUFS;
1412			goto out;
1413		}
1414	}
1415	rn = (*rnh->rnh_addaddr) ((caddr_t) saddr, (caddr_t) smask, rnh,
1416	    np->netc_rnodes);
1417	if (rn == 0 || np != (struct netcred *) rn) {	/* already exists */
1418		error = EPERM;
1419		goto out;
1420	}
1421	np->netc_exflags = argp->ex_flags;
1422	np->netc_anon = argp->ex_anon;
1423	np->netc_anon.cr_ref = 1;
1424	return (0);
1425out:
1426	free(np, M_NETADDR);
1427	return (error);
1428}
1429
1430/* ARGSUSED */
1431static int
1432vfs_free_netcred(rn, w)
1433	struct radix_node *rn;
1434	caddr_t w;
1435{
1436	register struct radix_node_head *rnh = (struct radix_node_head *) w;
1437
1438	(*rnh->rnh_deladdr) (rn->rn_key, rn->rn_mask, rnh);
1439	free((caddr_t) rn, M_NETADDR);
1440	return (0);
1441}
1442
1443/*
1444 * Free the net address hash lists that are hanging off the mount points.
1445 */
1446static void
1447vfs_free_addrlist(nep)
1448	struct netexport *nep;
1449{
1450	register int i;
1451	register struct radix_node_head *rnh;
1452
1453	for (i = 0; i <= AF_MAX; i++)
1454		if ((rnh = nep->ne_rtable[i])) {
1455			(*rnh->rnh_walktree) (rnh, vfs_free_netcred,
1456			    (caddr_t) rnh);
1457			free((caddr_t) rnh, M_RTABLE);
1458			nep->ne_rtable[i] = 0;
1459		}
1460}
1461
1462int
1463vfs_export(mp, nep, argp)
1464	struct mount *mp;
1465	struct netexport *nep;
1466	struct export_args *argp;
1467{
1468	int error;
1469
1470	if (argp->ex_flags & MNT_DELEXPORT) {
1471		vfs_free_addrlist(nep);
1472		mp->mnt_flag &= ~(MNT_EXPORTED | MNT_DEFEXPORTED);
1473	}
1474	if (argp->ex_flags & MNT_EXPORTED) {
1475		if ((error = vfs_hang_addrlist(mp, nep, argp)))
1476			return (error);
1477		mp->mnt_flag |= MNT_EXPORTED;
1478	}
1479	return (0);
1480}
1481
1482struct netcred *
1483vfs_export_lookup(mp, nep, nam)
1484	register struct mount *mp;
1485	struct netexport *nep;
1486	struct mbuf *nam;
1487{
1488	register struct netcred *np;
1489	register struct radix_node_head *rnh;
1490	struct sockaddr *saddr;
1491
1492	np = NULL;
1493	if (mp->mnt_flag & MNT_EXPORTED) {
1494		/*
1495		 * Lookup in the export list first.
1496		 */
1497		if (nam != NULL) {
1498			saddr = mtod(nam, struct sockaddr *);
1499			rnh = nep->ne_rtable[saddr->sa_family];
1500			if (rnh != NULL) {
1501				np = (struct netcred *)
1502				    (*rnh->rnh_matchaddr) ((caddr_t) saddr,
1503				    rnh);
1504				if (np && np->netc_rnodes->rn_flags & RNF_ROOT)
1505					np = NULL;
1506			}
1507		}
1508		/*
1509		 * If no address match, use the default if it exists.
1510		 */
1511		if (np == NULL && mp->mnt_flag & MNT_DEFEXPORTED)
1512			np = &nep->ne_defexported;
1513	}
1514	return (np);
1515}
1516
1517
1518/*
1519 * perform msync on all vnodes under a mount point
1520 * the mount point must be locked.
1521 */
1522void
1523vfs_msync(struct mount *mp, int flags) {
1524	struct vnode *vp;
1525loop:
1526	for (vp = mp->mnt_vnodelist.lh_first;
1527	     vp != NULL;
1528	     vp = vp->v_mntvnodes.le_next) {
1529
1530		if (vp->v_mount != mp)
1531			goto loop;
1532		if (VOP_ISLOCKED(vp) && (flags != MNT_WAIT))
1533			continue;
1534		if (vp->v_vmdata &&
1535		   (((vm_object_t) vp->v_vmdata)->flags & OBJ_WRITEABLE)) {
1536			if (vget(vp, 1))
1537				goto loop;
1538			_vm_object_page_clean( (vm_object_t) vp->v_vmdata,
1539					0, 0, TRUE);
1540			vput(vp);
1541		}
1542	}
1543}
1544