Print this page
7127 remove -Wno-missing-braces from Makefile.uts
Split |
Close |
Expand all |
Collapse all |
--- old/usr/src/uts/common/fs/bootfs/bootfs_vfsops.c
+++ new/usr/src/uts/common/fs/bootfs/bootfs_vfsops.c
1 1 /*
2 2 * This file and its contents are supplied under the terms of the
3 3 * Common Development and Distribution License ("CDDL"), version 1.0.
4 4 * You may only use this file in accordance with the terms of version
5 5 * 1.0 of the CDDL.
6 6 *
7 7 * A full copy of the text of the CDDL should have accompanied this
8 8 * source. A copy of the CDDL is also available via the Internet at
9 9 * http://www.illumos.org/license/CDDL.
10 10 */
11 11
12 12 /*
13 13 * Copyright (c) 2015 Joyent, Inc.
14 14 */
15 15
16 16 #include <sys/errno.h>
17 17 #include <sys/modctl.h>
18 18 #include <sys/types.h>
19 19 #include <sys/mkdev.h>
20 20 #include <sys/ddi.h>
21 21 #include <sys/sunddi.h>
22 22 #include <sys/vfs.h>
23 23 #include <sys/vfs_opreg.h>
24 24 #include <sys/systm.h>
25 25 #include <sys/id_space.h>
26 26 #include <sys/cmn_err.h>
27 27 #include <sys/ksynch.h>
28 28 #include <sys/policy.h>
29 29 #include <sys/mount.h>
30 30 #include <sys/sysmacros.h>
31 31
32 32 #include <sys/fs/bootfs_impl.h>
33 33
34 34 /*
35 35 * While booting, additional types of modules and files can be passed in to the
36 36 * loader. These include the familiar boot archive, as well as, a module hash
37 37 * and additional modules that are interpreted as files. As part of the handoff
38 38 * in early boot, information about these modules are saved as properties on the
39 39 * root of the devinfo tree, similar to other boot-time properties.
40 40 *
41 41 * This file system provides a read-only view of those additional files. Due to
42 42 * its limited scope, it has a slightly simpler construction than several other
43 43 * file systems. When mounted, it looks for the corresponding properties and
44 44 * creates bootfs_node_t's and vnodes for all of the corresponding files and
45 45 * directories that exist along the way. At this time, there are currently a
46 46 * rather small number of files passed in this way.
47 47 *
48 48 * This does lead to one behavior that folks used to other file systems might
49 49 * find peculiar. Because we are not always actively creating and destroying the
50 50 * required vnodes on demand, the count on the root vnode will not be going up
51 51 * accordingly with the existence of other vnodes. This means that a bootfs file
52 52 * system that is not in use will have all of its vnodes exist with a v_count of
53 53 * one.
54 54 */
55 55
56 56 major_t bootfs_major;
57 57 static int bootfs_fstype;
58 58 static id_space_t *bootfs_idspace;
59 59 static uint64_t bootfs_nactive;
60 60 static kmutex_t bootfs_lock;
61 61
62 62 static const char *bootfs_name = "bootfs";
63 63
64 64 static int
65 65 bootfs_mount(vfs_t *vfsp, vnode_t *mvp, struct mounta *uap, cred_t *cr)
66 66 {
67 67 int ret;
68 68 bootfs_t *bfs;
69 69 struct pathname dpn;
70 70 dev_t fsdev;
71 71
72 72 if ((ret = secpolicy_fs_mount(cr, mvp, vfsp)) != 0)
73 73 return (ret);
74 74
75 75 if (mvp->v_type != VDIR)
76 76 return (ENOTDIR);
77 77
78 78 if (uap->flags & MS_REMOUNT)
79 79 return (EBUSY);
80 80
81 81 mutex_enter(&mvp->v_lock);
82 82 if ((uap->flags & MS_OVERLAY) == 0 &&
83 83 (mvp->v_count != 1 || (mvp->v_flag & VROOT))) {
84 84 mutex_exit(&mvp->v_lock);
85 85 return (EBUSY);
86 86 }
87 87 mutex_exit(&mvp->v_lock);
88 88
89 89 /*
90 90 * We indicate that the backing store is bootfs. We don't want to use
91 91 * swap, because folks might think that this is putting all the data
92 92 * into memory ala tmpfs. Rather these modules are always in memory and
93 93 * there's nothing to be done about that.
94 94 */
95 95 vfs_setresource(vfsp, bootfs_name, 0);
96 96 bfs = kmem_zalloc(sizeof (bootfs_t), KM_NOSLEEP | KM_NORMALPRI);
97 97 if (bfs == NULL)
98 98 return (ENOMEM);
99 99
100 100 ret = pn_get(uap->dir,
101 101 (uap->flags & MS_SYSSPACE) ? UIO_SYSSPACE : UIO_USERSPACE, &dpn);
102 102 if (ret != 0) {
103 103 kmem_free(bfs, sizeof (bfs));
104 104 return (ret);
105 105 }
106 106
107 107 bfs->bfs_minor = id_alloc(bootfs_idspace);
108 108 bfs->bfs_kstat = kstat_create_zone("bootfs", bfs->bfs_minor, "bootfs",
109 109 "fs", KSTAT_TYPE_NAMED,
110 110 sizeof (bootfs_stat_t) / sizeof (kstat_named_t),
111 111 KSTAT_FLAG_VIRTUAL, GLOBAL_ZONEID);
112 112 if (bfs->bfs_kstat == NULL) {
113 113 id_free(bootfs_idspace, bfs->bfs_minor);
114 114 pn_free(&dpn);
115 115 kmem_free(bfs, sizeof (bfs));
116 116 return (ENOMEM);
117 117 }
118 118 bfs->bfs_kstat->ks_data = &bfs->bfs_stat;
119 119
120 120 fsdev = makedevice(bootfs_major, bfs->bfs_minor);
121 121 bfs->bfs_vfsp = vfsp;
122 122
123 123 vfsp->vfs_data = (caddr_t)bfs;
124 124 vfsp->vfs_fstype = bootfs_fstype;
125 125 vfsp->vfs_dev = fsdev;
126 126 vfsp->vfs_bsize = PAGESIZE;
127 127 vfsp->vfs_flag |= VFS_RDONLY | VFS_NOSETUID | VFS_NOTRUNC |
128 128 VFS_UNLINKABLE;
129 129 vfs_make_fsid(&vfsp->vfs_fsid, fsdev, bootfs_fstype);
130 130 bfs->bfs_mntpath = kmem_alloc(dpn.pn_pathlen + 1, KM_SLEEP);
131 131 bcopy(dpn.pn_path, bfs->bfs_mntpath, dpn.pn_pathlen);
132 132 bfs->bfs_mntpath[dpn.pn_pathlen] = '\0';
133 133 pn_free(&dpn);
134 134 list_create(&bfs->bfs_nodes, sizeof (bootfs_node_t),
135 135 offsetof(bootfs_node_t, bvn_alink));
136 136
137 137 kstat_named_init(&bfs->bfs_stat.bfss_nfiles, "nfiles",
138 138 KSTAT_DATA_UINT32);
139 139 kstat_named_init(&bfs->bfs_stat.bfss_ndirs, "ndirs",
140 140 KSTAT_DATA_UINT32);
141 141 kstat_named_init(&bfs->bfs_stat.bfss_nbytes, "nbytes",
142 142 KSTAT_DATA_UINT64);
143 143 kstat_named_init(&bfs->bfs_stat.bfss_ndups, "ndup",
144 144 KSTAT_DATA_UINT32);
145 145 kstat_named_init(&bfs->bfs_stat.bfss_ndiscards, "ndiscard",
146 146 KSTAT_DATA_UINT32);
147 147
148 148 bootfs_construct(bfs);
149 149
150 150 kstat_install(bfs->bfs_kstat);
151 151
152 152 return (0);
153 153 }
154 154
155 155 static int
156 156 bootfs_unmount(vfs_t *vfsp, int flag, cred_t *cr)
157 157 {
158 158 int ret;
159 159 bootfs_t *bfs = vfsp->vfs_data;
160 160 bootfs_node_t *bnp;
161 161
162 162 if ((ret = secpolicy_fs_unmount(cr, vfsp)) != 0)
163 163 return (ret);
164 164
165 165 if (flag & MS_FORCE)
166 166 return (ENOTSUP);
167 167
168 168 for (bnp = list_head(&bfs->bfs_nodes); bnp != NULL;
169 169 bnp = list_next(&bfs->bfs_nodes, bnp)) {
170 170 mutex_enter(&bnp->bvn_vnp->v_lock);
171 171 if (bnp->bvn_vnp->v_count > 1) {
172 172 mutex_exit(&bnp->bvn_vnp->v_lock);
173 173 return (EBUSY);
174 174 }
175 175 mutex_exit(&bnp->bvn_vnp->v_lock);
176 176 }
177 177
178 178 kstat_delete(bfs->bfs_kstat);
179 179 bootfs_destruct(bfs);
180 180 list_destroy(&bfs->bfs_nodes);
181 181 kmem_free(bfs->bfs_mntpath, strlen(bfs->bfs_mntpath) + 1);
182 182 id_free(bootfs_idspace, bfs->bfs_minor);
183 183 kmem_free(bfs, sizeof (bootfs_t));
184 184 return (0);
185 185 }
186 186
187 187 static int
188 188 bootfs_root(vfs_t *vfsp, vnode_t **vpp)
189 189 {
190 190 bootfs_t *bfs;
191 191
192 192 bfs = (bootfs_t *)vfsp->vfs_data;
193 193 *vpp = bfs->bfs_rootvn->bvn_vnp;
194 194 VN_HOLD(*vpp)
195 195
196 196 return (0);
197 197 }
198 198
199 199 static int
200 200 bootfs_statvfs(vfs_t *vfsp, struct statvfs64 *sbp)
201 201 {
202 202 const bootfs_t *bfs = (bootfs_t *)vfsp;
203 203 dev32_t d32;
204 204
205 205 sbp->f_bsize = PAGESIZE;
206 206 sbp->f_frsize = PAGESIZE;
207 207
208 208 sbp->f_blocks = bfs->bfs_stat.bfss_nbytes.value.ui64 >> PAGESHIFT;
209 209 sbp->f_bfree = 0;
210 210 sbp->f_bavail = 0;
211 211
212 212 sbp->f_files = bfs->bfs_stat.bfss_nfiles.value.ui32 +
213 213 bfs->bfs_stat.bfss_ndirs.value.ui32;
214 214 sbp->f_ffree = 0;
215 215 sbp->f_favail = 0;
↓ open down ↓ |
215 lines elided |
↑ open up ↑ |
216 216
217 217 (void) cmpldev(&d32, vfsp->vfs_dev);
218 218 sbp->f_fsid = d32;
219 219 (void) strlcpy(sbp->f_basetype, bootfs_name, FSTYPSZ);
220 220 bzero(sbp->f_fstr, sizeof (sbp->f_fstr));
221 221
222 222 return (0);
223 223 }
224 224
225 225 static const fs_operation_def_t bootfs_vfsops_tmpl[] = {
226 - VFSNAME_MOUNT, { .vfs_mount = bootfs_mount },
227 - VFSNAME_UNMOUNT, { .vfs_unmount = bootfs_unmount },
228 - VFSNAME_ROOT, { .vfs_root = bootfs_root },
229 - VFSNAME_STATVFS, { .vfs_statvfs = bootfs_statvfs },
230 - NULL, NULL
226 + { VFSNAME_MOUNT, { .vfs_mount = bootfs_mount } },
227 + { VFSNAME_UNMOUNT, { .vfs_unmount = bootfs_unmount } },
228 + { VFSNAME_ROOT, { .vfs_root = bootfs_root } },
229 + { VFSNAME_STATVFS, { .vfs_statvfs = bootfs_statvfs } },
230 + { NULL, { NULL } }
231 231 };
232 232
233 233 static int
234 234 bootfs_init(int fstype, char *name)
235 235 {
236 236 int ret;
237 237
238 238 bootfs_fstype = fstype;
239 239 ASSERT(bootfs_fstype != 0);
240 240
241 241 ret = vfs_setfsops(fstype, bootfs_vfsops_tmpl, NULL);
242 242 if (ret != 0)
243 243 return (ret);
244 244
245 245 ret = vn_make_ops(name, bootfs_vnodeops_template, &bootfs_vnodeops);
246 246 if (ret != 0) {
247 247 (void) vfs_freevfsops_by_type(bootfs_fstype);
248 248 return (ret);
249 249 }
250 250
251 251 bootfs_major = getudev();
252 252 if (bootfs_major == (major_t)-1) {
253 253 cmn_err(CE_WARN, "bootfs_init: Can't get unique device number");
254 254 bootfs_major = 0;
255 255 }
256 256
257 257 bootfs_nactive = 0;
258 258 return (0);
259 259 }
260 260
261 261 static mntopts_t bootfs_mntopts = {
262 262 0, NULL
263 263 };
264 264
265 265 static vfsdef_t bootfs_vfsdef = {
266 266 VFSDEF_VERSION,
267 267 "bootfs",
↓ open down ↓ |
27 lines elided |
↑ open up ↑ |
268 268 bootfs_init,
269 269 VSW_HASPROTO|VSW_STATS,
270 270 &bootfs_mntopts
271 271 };
272 272
273 273 static struct modlfs bootfs_modlfs = {
274 274 &mod_fsops, "boot-time modules file system", &bootfs_vfsdef
275 275 };
276 276
277 277 static struct modlinkage bootfs_modlinkage = {
278 - MODREV_1, &bootfs_modlfs, NULL
278 + MODREV_1, { &bootfs_modlfs, NULL }
279 279 };
280 280
281 281 int
282 282 _init(void)
283 283 {
284 284 bootfs_node_cache = kmem_cache_create("bootfs_node_cache",
285 285 sizeof (bootfs_node_t), 0, bootfs_node_constructor,
286 286 bootfs_node_destructor, NULL, NULL, NULL, 0);
287 287 bootfs_idspace = id_space_create("bootfs_minors", 1, INT32_MAX);
288 288 mutex_init(&bootfs_lock, NULL, MUTEX_DEFAULT, NULL);
289 289
290 290 return (mod_install(&bootfs_modlinkage));
291 291 }
292 292
293 293 int
294 294 _info(struct modinfo *modinfop)
295 295 {
296 296 return (mod_info(&bootfs_modlinkage, modinfop));
297 297 }
298 298
299 299 int
300 300 _fini(void)
301 301 {
302 302 int err;
303 303
304 304 mutex_enter(&bootfs_lock);
305 305 if (bootfs_nactive > 0) {
306 306 mutex_exit(&bootfs_lock);
307 307 return (EBUSY);
308 308 }
309 309 mutex_exit(&bootfs_lock);
310 310
311 311 err = mod_remove(&bootfs_modlinkage);
312 312 if (err != 0)
313 313 return (err);
314 314
315 315 (void) vfs_freevfsops_by_type(bootfs_fstype);
316 316 vn_freevnodeops(bootfs_vnodeops);
317 317 id_space_destroy(bootfs_idspace);
318 318 mutex_destroy(&bootfs_lock);
319 319 kmem_cache_destroy(bootfs_node_cache);
320 320 return (err);
321 321 }
↓ open down ↓ |
33 lines elided |
↑ open up ↑ |
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX