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