xref: /csrg-svn/sys/kern/vfs_subr.c (revision 37488)
1*37488Smckusick /*
2*37488Smckusick  * Copyright (c) 1989 The Regents of the University of California.
3*37488Smckusick  * All rights reserved.
4*37488Smckusick  *
5*37488Smckusick  * Redistribution and use in source and binary forms are permitted
6*37488Smckusick  * provided that the above copyright notice and this paragraph are
7*37488Smckusick  * duplicated in all such forms and that any documentation,
8*37488Smckusick  * advertising materials, and other materials related to such
9*37488Smckusick  * distribution and use acknowledge that the software was developed
10*37488Smckusick  * by the University of California, Berkeley.  The name of the
11*37488Smckusick  * University may not be used to endorse or promote products derived
12*37488Smckusick  * from this software without specific prior written permission.
13*37488Smckusick  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
14*37488Smckusick  * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
15*37488Smckusick  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
16*37488Smckusick  *
17*37488Smckusick  *	@(#)vfs_subr.c	7.1 (Berkeley) 04/24/89
18*37488Smckusick  */
19*37488Smckusick 
20*37488Smckusick /*
21*37488Smckusick  * External virtual filesystem routines
22*37488Smckusick  */
23*37488Smckusick 
24*37488Smckusick #include "param.h"
25*37488Smckusick #include "mount.h"
26*37488Smckusick #include "time.h"
27*37488Smckusick #include "vnode.h"
28*37488Smckusick #include "errno.h"
29*37488Smckusick 
30*37488Smckusick /*
31*37488Smckusick  * Add a new mount point to the list of mounted filesystems.
32*37488Smckusick  * Lock the filesystem so that namei will not cross into the
33*37488Smckusick  * the tree below the covered vnode.
34*37488Smckusick  */
35*37488Smckusick vfs_add(mountedvp, mp, flags)
36*37488Smckusick 	register struct vnode *mountedvp;
37*37488Smckusick 	register struct mount *mp;
38*37488Smckusick 	int flags;
39*37488Smckusick {
40*37488Smckusick 	register int error;
41*37488Smckusick 
42*37488Smckusick 	error = vfs_lock(mp);
43*37488Smckusick 	if (error)
44*37488Smckusick 		return (error);
45*37488Smckusick 	if (mountedvp == (struct vnode *)0) {
46*37488Smckusick 		/*
47*37488Smckusick 		 * We are mounting the root filesystem.
48*37488Smckusick 		 */
49*37488Smckusick 		rootfs = mp;
50*37488Smckusick 		mp->m_next = mp;
51*37488Smckusick 		mp->m_prev = mp;
52*37488Smckusick 	} else {
53*37488Smckusick 		if (mountedvp->v_mountedhere != (struct mount *)0) {
54*37488Smckusick 			vfs_unlock(mp);
55*37488Smckusick 			return(EBUSY);
56*37488Smckusick 		}
57*37488Smckusick 		/*
58*37488Smckusick 		 * Put the new filesystem on the mount list after root.
59*37488Smckusick 		 */
60*37488Smckusick 		mp->m_next = rootfs->m_next;
61*37488Smckusick 		mp->m_prev = rootfs;
62*37488Smckusick 		rootfs->m_next = mp;
63*37488Smckusick 		mp->m_next->m_prev = mp;
64*37488Smckusick 		mountedvp->v_mountedhere = mp;
65*37488Smckusick 	}
66*37488Smckusick 	mp->m_vnodecovered = mountedvp;
67*37488Smckusick 	if (flags & M_RDONLY) {
68*37488Smckusick 		mp->m_flag |= M_RDONLY;
69*37488Smckusick 	} else {
70*37488Smckusick 		mp->m_flag &= ~M_RDONLY;
71*37488Smckusick 	}
72*37488Smckusick 	if (flags & M_NOSUID) {
73*37488Smckusick 		mp->m_flag |= M_NOSUID;
74*37488Smckusick 	} else {
75*37488Smckusick 		mp->m_flag &= ~M_NOSUID;
76*37488Smckusick 	}
77*37488Smckusick 	return (0);
78*37488Smckusick }
79*37488Smckusick 
80*37488Smckusick /*
81*37488Smckusick  * Remove a mount point from the list of mounted filesystems.
82*37488Smckusick  * Unmount of the root is illegal.
83*37488Smckusick  */
84*37488Smckusick void
85*37488Smckusick vfs_remove(mp)
86*37488Smckusick 	register struct mount *mp;
87*37488Smckusick {
88*37488Smckusick 
89*37488Smckusick 	if (mp == rootfs)
90*37488Smckusick 		panic("vfs_remove: unmounting root");
91*37488Smckusick 	mp->m_prev->m_next = mp->m_next;
92*37488Smckusick 	mp->m_next->m_prev = mp->m_prev;
93*37488Smckusick 	mp->m_vnodecovered->v_mountedhere = (struct mount *)0;
94*37488Smckusick 	vfs_unlock(mp);
95*37488Smckusick }
96*37488Smckusick 
97*37488Smckusick /*
98*37488Smckusick  * Lock a filesystem.
99*37488Smckusick  * Used to prevent access to it while mounting and unmounting.
100*37488Smckusick  */
101*37488Smckusick vfs_lock(mp)
102*37488Smckusick 	register struct mount *mp;
103*37488Smckusick {
104*37488Smckusick 
105*37488Smckusick 	if (mp->m_flag & M_MLOCK)
106*37488Smckusick 		return (EBUSY);
107*37488Smckusick 	mp->m_flag |= M_MLOCK;
108*37488Smckusick 	return (0);
109*37488Smckusick }
110*37488Smckusick 
111*37488Smckusick /*
112*37488Smckusick  * Unlock a locked filesystem.
113*37488Smckusick  * Panic if filesystem is not locked.
114*37488Smckusick  */
115*37488Smckusick void
116*37488Smckusick vfs_unlock(mp)
117*37488Smckusick 	register struct mount *mp;
118*37488Smckusick {
119*37488Smckusick 
120*37488Smckusick 	if ((mp->m_flag & M_MLOCK) == 0)
121*37488Smckusick 		panic("vfs_unlock: locked fs");
122*37488Smckusick 	mp->m_flag &= ~M_MLOCK;
123*37488Smckusick 	if (mp->m_flag & M_MWAIT) {
124*37488Smckusick 		mp->m_flag &= ~M_MWAIT;
125*37488Smckusick 		wakeup((caddr_t)mp);
126*37488Smckusick 	}
127*37488Smckusick }
128*37488Smckusick 
129*37488Smckusick /*
130*37488Smckusick  * Lookup a mount point by filesystem identifier.
131*37488Smckusick  */
132*37488Smckusick struct mount *
133*37488Smckusick getvfs(fsid)
134*37488Smckusick 	fsid_t *fsid;
135*37488Smckusick {
136*37488Smckusick 	register struct mount *mp;
137*37488Smckusick 
138*37488Smckusick 	for (mp = rootfs; mp; mp = mp->m_next) {
139*37488Smckusick 		if (mp->m_fsid.val[0] == fsid->val[0] &&
140*37488Smckusick 		    mp->m_fsid.val[1] == fsid->val[1]) {
141*37488Smckusick 			break;
142*37488Smckusick 		}
143*37488Smckusick 	}
144*37488Smckusick 	return (mp);
145*37488Smckusick }
146*37488Smckusick 
147*37488Smckusick /*
148*37488Smckusick  * Set vnode attributes to VNOVAL
149*37488Smckusick  */
150*37488Smckusick void vattr_null(vap)
151*37488Smckusick 	register struct vattr *vap;
152*37488Smckusick {
153*37488Smckusick 
154*37488Smckusick 	vap->va_type = VNON;
155*37488Smckusick 	vap->va_mode = vap->va_nlink = vap->va_uid = vap->va_gid =
156*37488Smckusick 		vap->va_fsid = vap->va_fileid = vap->va_size =
157*37488Smckusick 		vap->va_size1 = vap->va_blocksize = vap->va_rdev =
158*37488Smckusick 		vap->va_bytes = vap->va_bytes1 =
159*37488Smckusick 		vap->va_atime.tv_sec = vap->va_atime.tv_usec =
160*37488Smckusick 		vap->va_mtime.tv_sec = vap->va_mtime.tv_usec =
161*37488Smckusick 		vap->va_ctime.tv_sec = vap->va_ctime.tv_usec = VNOVAL;
162*37488Smckusick }
163