1*bbb1b6f9SApple OSS Distributions /*
2*bbb1b6f9SApple OSS Distributions * Copyright (c) 2019 Apple Inc. All rights reserved.
3*bbb1b6f9SApple OSS Distributions *
4*bbb1b6f9SApple OSS Distributions * @APPLE_LICENSE_HEADER_START@
5*bbb1b6f9SApple OSS Distributions *
6*bbb1b6f9SApple OSS Distributions * This file contains Original Code and/or Modifications of Original Code
7*bbb1b6f9SApple OSS Distributions * as defined in and that are subject to the Apple Public Source License
8*bbb1b6f9SApple OSS Distributions * Version 2.0 (the 'License'). You may not use this file except in
9*bbb1b6f9SApple OSS Distributions * compliance with the License. Please obtain a copy of the License at
10*bbb1b6f9SApple OSS Distributions * http://www.opensource.apple.com/apsl/ and read it before using this
11*bbb1b6f9SApple OSS Distributions * file.
12*bbb1b6f9SApple OSS Distributions *
13*bbb1b6f9SApple OSS Distributions * The Original Code and all software distributed under the License are
14*bbb1b6f9SApple OSS Distributions * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
15*bbb1b6f9SApple OSS Distributions * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
16*bbb1b6f9SApple OSS Distributions * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
17*bbb1b6f9SApple OSS Distributions * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
18*bbb1b6f9SApple OSS Distributions * Please see the License for the specific language governing rights and
19*bbb1b6f9SApple OSS Distributions * limitations under the License.
20*bbb1b6f9SApple OSS Distributions *
21*bbb1b6f9SApple OSS Distributions * @APPLE_LICENSE_HEADER_END@
22*bbb1b6f9SApple OSS Distributions */
23*bbb1b6f9SApple OSS Distributions
24*bbb1b6f9SApple OSS Distributions /*-
25*bbb1b6f9SApple OSS Distributions * Portions Copyright (c) 1992, 1993, 1995
26*bbb1b6f9SApple OSS Distributions * The Regents of the University of California. All rights reserved.
27*bbb1b6f9SApple OSS Distributions *
28*bbb1b6f9SApple OSS Distributions * This code is derived from software donated to Berkeley by
29*bbb1b6f9SApple OSS Distributions * Jan-Simon Pendry.
30*bbb1b6f9SApple OSS Distributions *
31*bbb1b6f9SApple OSS Distributions * Redistribution and use in source and binary forms, with or without
32*bbb1b6f9SApple OSS Distributions * modification, are permitted provided that the following conditions
33*bbb1b6f9SApple OSS Distributions * are met:
34*bbb1b6f9SApple OSS Distributions * 1. Redistributions of source code must retain the above copyright
35*bbb1b6f9SApple OSS Distributions * notice, this list of conditions and the following disclaimer.
36*bbb1b6f9SApple OSS Distributions * 2. Redistributions in binary form must reproduce the above copyright
37*bbb1b6f9SApple OSS Distributions * notice, this list of conditions and the following disclaimer in the
38*bbb1b6f9SApple OSS Distributions * documentation and/or other materials provided with the distribution.
39*bbb1b6f9SApple OSS Distributions * 4. Neither the name of the University nor the names of its contributors
40*bbb1b6f9SApple OSS Distributions * may be used to endorse or promote products derived from this software
41*bbb1b6f9SApple OSS Distributions * without specific prior written permission.
42*bbb1b6f9SApple OSS Distributions *
43*bbb1b6f9SApple OSS Distributions * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
44*bbb1b6f9SApple OSS Distributions * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
45*bbb1b6f9SApple OSS Distributions * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
46*bbb1b6f9SApple OSS Distributions * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
47*bbb1b6f9SApple OSS Distributions * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
48*bbb1b6f9SApple OSS Distributions * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
49*bbb1b6f9SApple OSS Distributions * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
50*bbb1b6f9SApple OSS Distributions * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
51*bbb1b6f9SApple OSS Distributions * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
52*bbb1b6f9SApple OSS Distributions * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
53*bbb1b6f9SApple OSS Distributions * SUCH DAMAGE.
54*bbb1b6f9SApple OSS Distributions *
55*bbb1b6f9SApple OSS Distributions * @(#)null_vfsops.c 8.2 (Berkeley) 1/21/94
56*bbb1b6f9SApple OSS Distributions *
57*bbb1b6f9SApple OSS Distributions * @(#)lofs_vfsops.c 1.2 (Berkeley) 6/18/92
58*bbb1b6f9SApple OSS Distributions * $FreeBSD$
59*bbb1b6f9SApple OSS Distributions */
60*bbb1b6f9SApple OSS Distributions
61*bbb1b6f9SApple OSS Distributions #include <sys/param.h>
62*bbb1b6f9SApple OSS Distributions #include <sys/systm.h>
63*bbb1b6f9SApple OSS Distributions #include <sys/fcntl.h>
64*bbb1b6f9SApple OSS Distributions #include <sys/kernel.h>
65*bbb1b6f9SApple OSS Distributions #include <sys/lock.h>
66*bbb1b6f9SApple OSS Distributions #include <sys/malloc.h>
67*bbb1b6f9SApple OSS Distributions #include <sys/mount.h>
68*bbb1b6f9SApple OSS Distributions #include <sys/namei.h>
69*bbb1b6f9SApple OSS Distributions #include <sys/proc.h>
70*bbb1b6f9SApple OSS Distributions #include <sys/vnode.h>
71*bbb1b6f9SApple OSS Distributions #include <sys/vnode_internal.h>
72*bbb1b6f9SApple OSS Distributions #include <security/mac_internal.h>
73*bbb1b6f9SApple OSS Distributions #include <sys/kauth.h>
74*bbb1b6f9SApple OSS Distributions
75*bbb1b6f9SApple OSS Distributions #include <sys/param.h>
76*bbb1b6f9SApple OSS Distributions
77*bbb1b6f9SApple OSS Distributions #include <IOKit/IOBSD.h>
78*bbb1b6f9SApple OSS Distributions
79*bbb1b6f9SApple OSS Distributions #include "nullfs.h"
80*bbb1b6f9SApple OSS Distributions
81*bbb1b6f9SApple OSS Distributions #define NULLFS_ENTITLEMENT "com.apple.private.nullfs_allow"
82*bbb1b6f9SApple OSS Distributions
83*bbb1b6f9SApple OSS Distributions static int
nullfs_vfs_getlowerattr(mount_t mp,struct vfs_attr * vfap,vfs_context_t ctx)84*bbb1b6f9SApple OSS Distributions nullfs_vfs_getlowerattr(mount_t mp, struct vfs_attr * vfap, vfs_context_t ctx)
85*bbb1b6f9SApple OSS Distributions {
86*bbb1b6f9SApple OSS Distributions memset(vfap, 0, sizeof(*vfap));
87*bbb1b6f9SApple OSS Distributions VFSATTR_INIT(vfap);
88*bbb1b6f9SApple OSS Distributions VFSATTR_WANTED(vfap, f_bsize);
89*bbb1b6f9SApple OSS Distributions VFSATTR_WANTED(vfap, f_iosize);
90*bbb1b6f9SApple OSS Distributions VFSATTR_WANTED(vfap, f_blocks);
91*bbb1b6f9SApple OSS Distributions VFSATTR_WANTED(vfap, f_bfree);
92*bbb1b6f9SApple OSS Distributions VFSATTR_WANTED(vfap, f_bavail);
93*bbb1b6f9SApple OSS Distributions VFSATTR_WANTED(vfap, f_bused);
94*bbb1b6f9SApple OSS Distributions VFSATTR_WANTED(vfap, f_files);
95*bbb1b6f9SApple OSS Distributions VFSATTR_WANTED(vfap, f_ffree);
96*bbb1b6f9SApple OSS Distributions VFSATTR_WANTED(vfap, f_capabilities);
97*bbb1b6f9SApple OSS Distributions
98*bbb1b6f9SApple OSS Distributions return vfs_getattr(mp, vfap, ctx);
99*bbb1b6f9SApple OSS Distributions }
100*bbb1b6f9SApple OSS Distributions
101*bbb1b6f9SApple OSS Distributions /*
102*bbb1b6f9SApple OSS Distributions * Mount null layer
103*bbb1b6f9SApple OSS Distributions */
104*bbb1b6f9SApple OSS Distributions static int
nullfs_mount(struct mount * mp,__unused vnode_t devvp,user_addr_t user_data,vfs_context_t ctx)105*bbb1b6f9SApple OSS Distributions nullfs_mount(struct mount * mp, __unused vnode_t devvp, user_addr_t user_data, vfs_context_t ctx)
106*bbb1b6f9SApple OSS Distributions {
107*bbb1b6f9SApple OSS Distributions int error = 0;
108*bbb1b6f9SApple OSS Distributions struct vnode *lowerrootvp = NULL, *vp = NULL;
109*bbb1b6f9SApple OSS Distributions struct vfsstatfs * sp = NULL;
110*bbb1b6f9SApple OSS Distributions struct null_mount * xmp = NULL;
111*bbb1b6f9SApple OSS Distributions struct null_mount_conf conf = {0};
112*bbb1b6f9SApple OSS Distributions char path[MAXPATHLEN];
113*bbb1b6f9SApple OSS Distributions
114*bbb1b6f9SApple OSS Distributions size_t count;
115*bbb1b6f9SApple OSS Distributions struct vfs_attr vfa;
116*bbb1b6f9SApple OSS Distributions /* set defaults (arbitrary since this file system is readonly) */
117*bbb1b6f9SApple OSS Distributions uint32_t bsize = BLKDEV_IOSIZE;
118*bbb1b6f9SApple OSS Distributions size_t iosize = BLKDEV_IOSIZE;
119*bbb1b6f9SApple OSS Distributions uint64_t blocks = 4711 * 4711;
120*bbb1b6f9SApple OSS Distributions uint64_t bfree = 0;
121*bbb1b6f9SApple OSS Distributions uint64_t bavail = 0;
122*bbb1b6f9SApple OSS Distributions uint64_t bused = 4711;
123*bbb1b6f9SApple OSS Distributions uint64_t files = 4711;
124*bbb1b6f9SApple OSS Distributions uint64_t ffree = 0;
125*bbb1b6f9SApple OSS Distributions
126*bbb1b6f9SApple OSS Distributions kauth_cred_t cred = vfs_context_ucred(ctx);
127*bbb1b6f9SApple OSS Distributions
128*bbb1b6f9SApple OSS Distributions NULLFSDEBUG("nullfs_mount(mp = %p) %llx\n", (void *)mp, vfs_flags(mp));
129*bbb1b6f9SApple OSS Distributions
130*bbb1b6f9SApple OSS Distributions if (vfs_flags(mp) & MNT_ROOTFS) {
131*bbb1b6f9SApple OSS Distributions return EOPNOTSUPP;
132*bbb1b6f9SApple OSS Distributions }
133*bbb1b6f9SApple OSS Distributions
134*bbb1b6f9SApple OSS Distributions /*
135*bbb1b6f9SApple OSS Distributions * Update is a no-op
136*bbb1b6f9SApple OSS Distributions */
137*bbb1b6f9SApple OSS Distributions if (vfs_isupdate(mp)) {
138*bbb1b6f9SApple OSS Distributions return ENOTSUP;
139*bbb1b6f9SApple OSS Distributions }
140*bbb1b6f9SApple OSS Distributions
141*bbb1b6f9SApple OSS Distributions /* check entitlement */
142*bbb1b6f9SApple OSS Distributions if (!IOCurrentTaskHasEntitlement(NULLFS_ENTITLEMENT)) {
143*bbb1b6f9SApple OSS Distributions return EPERM;
144*bbb1b6f9SApple OSS Distributions }
145*bbb1b6f9SApple OSS Distributions
146*bbb1b6f9SApple OSS Distributions /*
147*bbb1b6f9SApple OSS Distributions * Get configuration
148*bbb1b6f9SApple OSS Distributions */
149*bbb1b6f9SApple OSS Distributions error = copyin(user_data, &conf, sizeof(conf));
150*bbb1b6f9SApple OSS Distributions if (error) {
151*bbb1b6f9SApple OSS Distributions NULLFSDEBUG("nullfs: error copying configuration form user %d\n", error);
152*bbb1b6f9SApple OSS Distributions goto error;
153*bbb1b6f9SApple OSS Distributions }
154*bbb1b6f9SApple OSS Distributions
155*bbb1b6f9SApple OSS Distributions /*
156*bbb1b6f9SApple OSS Distributions * Get argument
157*bbb1b6f9SApple OSS Distributions */
158*bbb1b6f9SApple OSS Distributions error = copyinstr(user_data + sizeof(conf), path, MAXPATHLEN - 1, &count);
159*bbb1b6f9SApple OSS Distributions if (error) {
160*bbb1b6f9SApple OSS Distributions NULLFSDEBUG("nullfs: error copying data form user %d\n", error);
161*bbb1b6f9SApple OSS Distributions goto error;
162*bbb1b6f9SApple OSS Distributions }
163*bbb1b6f9SApple OSS Distributions
164*bbb1b6f9SApple OSS Distributions /* This could happen if the system is configured for 32 bit inodes instead of
165*bbb1b6f9SApple OSS Distributions * 64 bit */
166*bbb1b6f9SApple OSS Distributions if (count > sizeof(vfs_statfs(mp)->f_mntfromname)) {
167*bbb1b6f9SApple OSS Distributions error = EINVAL;
168*bbb1b6f9SApple OSS Distributions NULLFSDEBUG("nullfs: path to translocate too large for this system %ld vs %ld\n", count, sizeof(vfs_statfs(mp)->f_mntfromname));
169*bbb1b6f9SApple OSS Distributions goto error;
170*bbb1b6f9SApple OSS Distributions }
171*bbb1b6f9SApple OSS Distributions
172*bbb1b6f9SApple OSS Distributions error = vnode_lookup(path, 0, &lowerrootvp, ctx);
173*bbb1b6f9SApple OSS Distributions if (error) {
174*bbb1b6f9SApple OSS Distributions NULLFSDEBUG("lookup %s -> %d\n", path, error);
175*bbb1b6f9SApple OSS Distributions goto error;
176*bbb1b6f9SApple OSS Distributions }
177*bbb1b6f9SApple OSS Distributions
178*bbb1b6f9SApple OSS Distributions /* lowervrootvp has an iocount after vnode_lookup, drop that for a usecount.
179*bbb1b6f9SApple OSS Distributions * Keep this to signal what we want to keep around the thing we are mirroring.
180*bbb1b6f9SApple OSS Distributions * Drop it in unmount.*/
181*bbb1b6f9SApple OSS Distributions error = vnode_ref(lowerrootvp);
182*bbb1b6f9SApple OSS Distributions vnode_put(lowerrootvp);
183*bbb1b6f9SApple OSS Distributions if (error) {
184*bbb1b6f9SApple OSS Distributions // If vnode_ref failed, then null it out so it can't be used anymore in cleanup.
185*bbb1b6f9SApple OSS Distributions lowerrootvp = NULL;
186*bbb1b6f9SApple OSS Distributions goto error;
187*bbb1b6f9SApple OSS Distributions }
188*bbb1b6f9SApple OSS Distributions
189*bbb1b6f9SApple OSS Distributions NULLFSDEBUG("mount %s\n", path);
190*bbb1b6f9SApple OSS Distributions
191*bbb1b6f9SApple OSS Distributions xmp = kalloc_type(struct null_mount, Z_WAITOK | Z_ZERO | Z_NOFAIL);
192*bbb1b6f9SApple OSS Distributions
193*bbb1b6f9SApple OSS Distributions /*
194*bbb1b6f9SApple OSS Distributions * Grab the uid/gid of the caller, which may be used for unveil later
195*bbb1b6f9SApple OSS Distributions */
196*bbb1b6f9SApple OSS Distributions xmp->uid = kauth_cred_getuid(cred);
197*bbb1b6f9SApple OSS Distributions xmp->gid = kauth_cred_getgid(cred);
198*bbb1b6f9SApple OSS Distributions
199*bbb1b6f9SApple OSS Distributions /*
200*bbb1b6f9SApple OSS Distributions * Save reference to underlying FS
201*bbb1b6f9SApple OSS Distributions */
202*bbb1b6f9SApple OSS Distributions xmp->nullm_lowerrootvp = lowerrootvp;
203*bbb1b6f9SApple OSS Distributions xmp->nullm_lowerrootvid = vnode_vid(lowerrootvp);
204*bbb1b6f9SApple OSS Distributions
205*bbb1b6f9SApple OSS Distributions error = null_getnewvnode(mp, NULL, NULL, &vp, NULL, 1);
206*bbb1b6f9SApple OSS Distributions if (error) {
207*bbb1b6f9SApple OSS Distributions goto error;
208*bbb1b6f9SApple OSS Distributions }
209*bbb1b6f9SApple OSS Distributions
210*bbb1b6f9SApple OSS Distributions /* vp has an iocount on it from vnode_create. drop that for a usecount. This
211*bbb1b6f9SApple OSS Distributions * is our root vnode so we drop the ref in unmount
212*bbb1b6f9SApple OSS Distributions *
213*bbb1b6f9SApple OSS Distributions * Assuming for now that because we created this vnode and we aren't finished mounting we can get a ref*/
214*bbb1b6f9SApple OSS Distributions vnode_ref(vp);
215*bbb1b6f9SApple OSS Distributions vnode_put(vp);
216*bbb1b6f9SApple OSS Distributions
217*bbb1b6f9SApple OSS Distributions nullfs_init_lck(&xmp->nullm_lock);
218*bbb1b6f9SApple OSS Distributions
219*bbb1b6f9SApple OSS Distributions xmp->nullm_rootvp = vp;
220*bbb1b6f9SApple OSS Distributions
221*bbb1b6f9SApple OSS Distributions /* read the flags the user set, but then ignore some of them, we will only
222*bbb1b6f9SApple OSS Distributions * allow them if they are set on the lower file system */
223*bbb1b6f9SApple OSS Distributions uint64_t flags = vfs_flags(mp) & (~(MNT_IGNORE_OWNERSHIP | MNT_LOCAL));
224*bbb1b6f9SApple OSS Distributions uint64_t lowerflags = vfs_flags(vnode_mount(lowerrootvp)) & (MNT_LOCAL | MNT_QUARANTINE | MNT_IGNORE_OWNERSHIP | MNT_NOEXEC);
225*bbb1b6f9SApple OSS Distributions
226*bbb1b6f9SApple OSS Distributions if (lowerflags) {
227*bbb1b6f9SApple OSS Distributions flags |= lowerflags;
228*bbb1b6f9SApple OSS Distributions }
229*bbb1b6f9SApple OSS Distributions
230*bbb1b6f9SApple OSS Distributions /* force these flags */
231*bbb1b6f9SApple OSS Distributions flags |= (MNT_DONTBROWSE | MNT_MULTILABEL | MNT_NOSUID | MNT_RDONLY);
232*bbb1b6f9SApple OSS Distributions vfs_setflags(mp, flags);
233*bbb1b6f9SApple OSS Distributions
234*bbb1b6f9SApple OSS Distributions vfs_setfsprivate(mp, xmp);
235*bbb1b6f9SApple OSS Distributions vfs_getnewfsid(mp);
236*bbb1b6f9SApple OSS Distributions vfs_setlocklocal(mp);
237*bbb1b6f9SApple OSS Distributions
238*bbb1b6f9SApple OSS Distributions /* fill in the stat block */
239*bbb1b6f9SApple OSS Distributions sp = vfs_statfs(mp);
240*bbb1b6f9SApple OSS Distributions strlcpy(sp->f_mntfromname, path, sizeof(sp->f_mntfromname));
241*bbb1b6f9SApple OSS Distributions
242*bbb1b6f9SApple OSS Distributions sp->f_flags = flags;
243*bbb1b6f9SApple OSS Distributions
244*bbb1b6f9SApple OSS Distributions xmp->nullm_flags = NULLM_CASEINSENSITIVE; /* default to case insensitive */
245*bbb1b6f9SApple OSS Distributions
246*bbb1b6f9SApple OSS Distributions // Set the flags that are requested
247*bbb1b6f9SApple OSS Distributions xmp->nullm_flags |= conf.flags & NULLM_UNVEIL;
248*bbb1b6f9SApple OSS Distributions
249*bbb1b6f9SApple OSS Distributions error = nullfs_vfs_getlowerattr(vnode_mount(lowerrootvp), &vfa, ctx);
250*bbb1b6f9SApple OSS Distributions if (error == 0) {
251*bbb1b6f9SApple OSS Distributions if (VFSATTR_IS_SUPPORTED(&vfa, f_bsize)) {
252*bbb1b6f9SApple OSS Distributions bsize = vfa.f_bsize;
253*bbb1b6f9SApple OSS Distributions }
254*bbb1b6f9SApple OSS Distributions if (VFSATTR_IS_SUPPORTED(&vfa, f_iosize)) {
255*bbb1b6f9SApple OSS Distributions iosize = vfa.f_iosize;
256*bbb1b6f9SApple OSS Distributions }
257*bbb1b6f9SApple OSS Distributions if (VFSATTR_IS_SUPPORTED(&vfa, f_blocks)) {
258*bbb1b6f9SApple OSS Distributions blocks = vfa.f_blocks;
259*bbb1b6f9SApple OSS Distributions }
260*bbb1b6f9SApple OSS Distributions if (VFSATTR_IS_SUPPORTED(&vfa, f_bfree)) {
261*bbb1b6f9SApple OSS Distributions bfree = vfa.f_bfree;
262*bbb1b6f9SApple OSS Distributions }
263*bbb1b6f9SApple OSS Distributions if (VFSATTR_IS_SUPPORTED(&vfa, f_bavail)) {
264*bbb1b6f9SApple OSS Distributions bavail = vfa.f_bavail;
265*bbb1b6f9SApple OSS Distributions }
266*bbb1b6f9SApple OSS Distributions if (VFSATTR_IS_SUPPORTED(&vfa, f_bused)) {
267*bbb1b6f9SApple OSS Distributions bused = vfa.f_bused;
268*bbb1b6f9SApple OSS Distributions }
269*bbb1b6f9SApple OSS Distributions if (VFSATTR_IS_SUPPORTED(&vfa, f_files)) {
270*bbb1b6f9SApple OSS Distributions files = vfa.f_files;
271*bbb1b6f9SApple OSS Distributions }
272*bbb1b6f9SApple OSS Distributions if (VFSATTR_IS_SUPPORTED(&vfa, f_ffree)) {
273*bbb1b6f9SApple OSS Distributions ffree = vfa.f_ffree;
274*bbb1b6f9SApple OSS Distributions }
275*bbb1b6f9SApple OSS Distributions if (VFSATTR_IS_SUPPORTED(&vfa, f_capabilities)) {
276*bbb1b6f9SApple OSS Distributions if ((vfa.f_capabilities.capabilities[VOL_CAPABILITIES_FORMAT] & (VOL_CAP_FMT_CASE_SENSITIVE)) &&
277*bbb1b6f9SApple OSS Distributions (vfa.f_capabilities.valid[VOL_CAPABILITIES_FORMAT] & (VOL_CAP_FMT_CASE_SENSITIVE))) {
278*bbb1b6f9SApple OSS Distributions xmp->nullm_flags &= ~NULLM_CASEINSENSITIVE;
279*bbb1b6f9SApple OSS Distributions }
280*bbb1b6f9SApple OSS Distributions }
281*bbb1b6f9SApple OSS Distributions } else {
282*bbb1b6f9SApple OSS Distributions goto error;
283*bbb1b6f9SApple OSS Distributions }
284*bbb1b6f9SApple OSS Distributions
285*bbb1b6f9SApple OSS Distributions sp->f_bsize = bsize;
286*bbb1b6f9SApple OSS Distributions sp->f_iosize = iosize;
287*bbb1b6f9SApple OSS Distributions sp->f_blocks = blocks;
288*bbb1b6f9SApple OSS Distributions sp->f_bfree = bfree;
289*bbb1b6f9SApple OSS Distributions sp->f_bavail = bavail;
290*bbb1b6f9SApple OSS Distributions sp->f_bused = bused;
291*bbb1b6f9SApple OSS Distributions sp->f_files = files;
292*bbb1b6f9SApple OSS Distributions sp->f_ffree = ffree;
293*bbb1b6f9SApple OSS Distributions
294*bbb1b6f9SApple OSS Distributions /* Associate the mac label information from the mirrored filesystem with the
295*bbb1b6f9SApple OSS Distributions * mirror */
296*bbb1b6f9SApple OSS Distributions MAC_PERFORM(mount_label_associate, cred, vnode_mount(lowerrootvp), vfs_mntlabel(mp));
297*bbb1b6f9SApple OSS Distributions
298*bbb1b6f9SApple OSS Distributions NULLFSDEBUG("nullfs_mount: lower %s, alias at %s\n", sp->f_mntfromname, sp->f_mntonname);
299*bbb1b6f9SApple OSS Distributions return 0;
300*bbb1b6f9SApple OSS Distributions
301*bbb1b6f9SApple OSS Distributions error:
302*bbb1b6f9SApple OSS Distributions if (xmp) {
303*bbb1b6f9SApple OSS Distributions kfree_type(struct null_mount, xmp);
304*bbb1b6f9SApple OSS Distributions }
305*bbb1b6f9SApple OSS Distributions if (lowerrootvp) {
306*bbb1b6f9SApple OSS Distributions vnode_getwithref(lowerrootvp);
307*bbb1b6f9SApple OSS Distributions vnode_rele(lowerrootvp);
308*bbb1b6f9SApple OSS Distributions vnode_put(lowerrootvp);
309*bbb1b6f9SApple OSS Distributions }
310*bbb1b6f9SApple OSS Distributions if (vp) {
311*bbb1b6f9SApple OSS Distributions /* we made the root vnode but the mount is failed, so clean it up */
312*bbb1b6f9SApple OSS Distributions vnode_getwithref(vp);
313*bbb1b6f9SApple OSS Distributions vnode_rele(vp);
314*bbb1b6f9SApple OSS Distributions /* give vp back */
315*bbb1b6f9SApple OSS Distributions vnode_recycle(vp);
316*bbb1b6f9SApple OSS Distributions vnode_put(vp);
317*bbb1b6f9SApple OSS Distributions }
318*bbb1b6f9SApple OSS Distributions return error;
319*bbb1b6f9SApple OSS Distributions }
320*bbb1b6f9SApple OSS Distributions
321*bbb1b6f9SApple OSS Distributions /*
322*bbb1b6f9SApple OSS Distributions * Free reference to null layer
323*bbb1b6f9SApple OSS Distributions */
324*bbb1b6f9SApple OSS Distributions static int
nullfs_unmount(struct mount * mp,int mntflags,__unused vfs_context_t ctx)325*bbb1b6f9SApple OSS Distributions nullfs_unmount(struct mount * mp, int mntflags, __unused vfs_context_t ctx)
326*bbb1b6f9SApple OSS Distributions {
327*bbb1b6f9SApple OSS Distributions struct null_mount * mntdata;
328*bbb1b6f9SApple OSS Distributions struct vnode * vp;
329*bbb1b6f9SApple OSS Distributions int error, flags;
330*bbb1b6f9SApple OSS Distributions
331*bbb1b6f9SApple OSS Distributions NULLFSDEBUG("nullfs_unmount: mp = %p\n", (void *)mp);
332*bbb1b6f9SApple OSS Distributions
333*bbb1b6f9SApple OSS Distributions /* check entitlement or superuser*/
334*bbb1b6f9SApple OSS Distributions if (!IOCurrentTaskHasEntitlement(NULLFS_ENTITLEMENT) &&
335*bbb1b6f9SApple OSS Distributions vfs_context_suser(ctx) != 0) {
336*bbb1b6f9SApple OSS Distributions return EPERM;
337*bbb1b6f9SApple OSS Distributions }
338*bbb1b6f9SApple OSS Distributions
339*bbb1b6f9SApple OSS Distributions if (mntflags & MNT_FORCE) {
340*bbb1b6f9SApple OSS Distributions flags = FORCECLOSE;
341*bbb1b6f9SApple OSS Distributions } else {
342*bbb1b6f9SApple OSS Distributions flags = 0;
343*bbb1b6f9SApple OSS Distributions }
344*bbb1b6f9SApple OSS Distributions
345*bbb1b6f9SApple OSS Distributions mntdata = MOUNTTONULLMOUNT(mp);
346*bbb1b6f9SApple OSS Distributions vp = mntdata->nullm_rootvp;
347*bbb1b6f9SApple OSS Distributions
348*bbb1b6f9SApple OSS Distributions // release our reference on the root before flushing.
349*bbb1b6f9SApple OSS Distributions // it will get pulled out of the mount structure by reclaim
350*bbb1b6f9SApple OSS Distributions vnode_getalways(vp);
351*bbb1b6f9SApple OSS Distributions
352*bbb1b6f9SApple OSS Distributions error = vflush(mp, vp, flags);
353*bbb1b6f9SApple OSS Distributions if (error) {
354*bbb1b6f9SApple OSS Distributions vnode_put(vp);
355*bbb1b6f9SApple OSS Distributions return error;
356*bbb1b6f9SApple OSS Distributions }
357*bbb1b6f9SApple OSS Distributions
358*bbb1b6f9SApple OSS Distributions if (vnode_isinuse(vp, 1) && flags == 0) {
359*bbb1b6f9SApple OSS Distributions vnode_put(vp);
360*bbb1b6f9SApple OSS Distributions return EBUSY;
361*bbb1b6f9SApple OSS Distributions }
362*bbb1b6f9SApple OSS Distributions
363*bbb1b6f9SApple OSS Distributions vnode_rele(vp); // Drop reference taken by nullfs_mount
364*bbb1b6f9SApple OSS Distributions vnode_put(vp); // Drop ref taken above
365*bbb1b6f9SApple OSS Distributions
366*bbb1b6f9SApple OSS Distributions //Force close to get rid of the last vnode
367*bbb1b6f9SApple OSS Distributions (void)vflush(mp, NULL, FORCECLOSE);
368*bbb1b6f9SApple OSS Distributions
369*bbb1b6f9SApple OSS Distributions /* no more vnodes, so tear down the mountpoint */
370*bbb1b6f9SApple OSS Distributions
371*bbb1b6f9SApple OSS Distributions lck_mtx_lock(&mntdata->nullm_lock);
372*bbb1b6f9SApple OSS Distributions
373*bbb1b6f9SApple OSS Distributions vfs_setfsprivate(mp, NULL);
374*bbb1b6f9SApple OSS Distributions
375*bbb1b6f9SApple OSS Distributions vnode_getalways(mntdata->nullm_lowerrootvp);
376*bbb1b6f9SApple OSS Distributions vnode_rele(mntdata->nullm_lowerrootvp);
377*bbb1b6f9SApple OSS Distributions vnode_put(mntdata->nullm_lowerrootvp);
378*bbb1b6f9SApple OSS Distributions
379*bbb1b6f9SApple OSS Distributions lck_mtx_unlock(&mntdata->nullm_lock);
380*bbb1b6f9SApple OSS Distributions
381*bbb1b6f9SApple OSS Distributions nullfs_destroy_lck(&mntdata->nullm_lock);
382*bbb1b6f9SApple OSS Distributions
383*bbb1b6f9SApple OSS Distributions kfree_type(struct null_mount, mntdata);
384*bbb1b6f9SApple OSS Distributions
385*bbb1b6f9SApple OSS Distributions uint64_t vflags = vfs_flags(mp);
386*bbb1b6f9SApple OSS Distributions vfs_setflags(mp, vflags & ~MNT_LOCAL);
387*bbb1b6f9SApple OSS Distributions
388*bbb1b6f9SApple OSS Distributions return 0;
389*bbb1b6f9SApple OSS Distributions }
390*bbb1b6f9SApple OSS Distributions
391*bbb1b6f9SApple OSS Distributions static int
nullfs_root(struct mount * mp,struct vnode ** vpp,__unused vfs_context_t ctx)392*bbb1b6f9SApple OSS Distributions nullfs_root(struct mount * mp, struct vnode ** vpp, __unused vfs_context_t ctx)
393*bbb1b6f9SApple OSS Distributions {
394*bbb1b6f9SApple OSS Distributions struct vnode * vp;
395*bbb1b6f9SApple OSS Distributions int error;
396*bbb1b6f9SApple OSS Distributions
397*bbb1b6f9SApple OSS Distributions NULLFSDEBUG("nullfs_root(mp = %p, vp = %p)\n", (void *)mp, (void *)MOUNTTONULLMOUNT(mp)->nullm_rootvp);
398*bbb1b6f9SApple OSS Distributions
399*bbb1b6f9SApple OSS Distributions /*
400*bbb1b6f9SApple OSS Distributions * Return locked reference to root.
401*bbb1b6f9SApple OSS Distributions */
402*bbb1b6f9SApple OSS Distributions vp = MOUNTTONULLMOUNT(mp)->nullm_rootvp;
403*bbb1b6f9SApple OSS Distributions
404*bbb1b6f9SApple OSS Distributions error = vnode_get(vp);
405*bbb1b6f9SApple OSS Distributions if (error) {
406*bbb1b6f9SApple OSS Distributions return error;
407*bbb1b6f9SApple OSS Distributions }
408*bbb1b6f9SApple OSS Distributions
409*bbb1b6f9SApple OSS Distributions *vpp = vp;
410*bbb1b6f9SApple OSS Distributions return 0;
411*bbb1b6f9SApple OSS Distributions }
412*bbb1b6f9SApple OSS Distributions
413*bbb1b6f9SApple OSS Distributions static int
nullfs_vfs_getattr(struct mount * mp,struct vfs_attr * vfap,vfs_context_t ctx)414*bbb1b6f9SApple OSS Distributions nullfs_vfs_getattr(struct mount * mp, struct vfs_attr * vfap, vfs_context_t ctx)
415*bbb1b6f9SApple OSS Distributions {
416*bbb1b6f9SApple OSS Distributions struct vnode * coveredvp = NULL;
417*bbb1b6f9SApple OSS Distributions struct vfs_attr vfa;
418*bbb1b6f9SApple OSS Distributions struct null_mount * null_mp = MOUNTTONULLMOUNT(mp);
419*bbb1b6f9SApple OSS Distributions vol_capabilities_attr_t capabilities;
420*bbb1b6f9SApple OSS Distributions struct vfsstatfs * sp = vfs_statfs(mp);
421*bbb1b6f9SApple OSS Distributions vfs_context_t ectx = nullfs_get_patched_context(null_mp, ctx);
422*bbb1b6f9SApple OSS Distributions
423*bbb1b6f9SApple OSS Distributions struct timespec tzero = {.tv_sec = 0, .tv_nsec = 0};
424*bbb1b6f9SApple OSS Distributions
425*bbb1b6f9SApple OSS Distributions NULLFSDEBUG("%s\n", __FUNCTION__);
426*bbb1b6f9SApple OSS Distributions
427*bbb1b6f9SApple OSS Distributions /* Set default capabilities in case the lower file system is gone */
428*bbb1b6f9SApple OSS Distributions memset(&capabilities, 0, sizeof(capabilities));
429*bbb1b6f9SApple OSS Distributions capabilities.capabilities[VOL_CAPABILITIES_FORMAT] = VOL_CAP_FMT_FAST_STATFS | VOL_CAP_FMT_HIDDEN_FILES;
430*bbb1b6f9SApple OSS Distributions capabilities.valid[VOL_CAPABILITIES_FORMAT] = VOL_CAP_FMT_FAST_STATFS | VOL_CAP_FMT_HIDDEN_FILES;
431*bbb1b6f9SApple OSS Distributions
432*bbb1b6f9SApple OSS Distributions if (nullfs_vfs_getlowerattr(vnode_mount(null_mp->nullm_lowerrootvp), &vfa, ectx) == 0) {
433*bbb1b6f9SApple OSS Distributions if (VFSATTR_IS_SUPPORTED(&vfa, f_capabilities)) {
434*bbb1b6f9SApple OSS Distributions memcpy(&capabilities, &vfa.f_capabilities, sizeof(capabilities));
435*bbb1b6f9SApple OSS Distributions /* don't support vget */
436*bbb1b6f9SApple OSS Distributions capabilities.capabilities[VOL_CAPABILITIES_FORMAT] &= ~(VOL_CAP_FMT_PERSISTENTOBJECTIDS | VOL_CAP_FMT_PATH_FROM_ID);
437*bbb1b6f9SApple OSS Distributions
438*bbb1b6f9SApple OSS Distributions capabilities.capabilities[VOL_CAPABILITIES_FORMAT] |= VOL_CAP_FMT_HIDDEN_FILES; /* Always support UF_HIDDEN */
439*bbb1b6f9SApple OSS Distributions
440*bbb1b6f9SApple OSS Distributions capabilities.valid[VOL_CAPABILITIES_FORMAT] &= ~(VOL_CAP_FMT_PERSISTENTOBJECTIDS | VOL_CAP_FMT_PATH_FROM_ID);
441*bbb1b6f9SApple OSS Distributions
442*bbb1b6f9SApple OSS Distributions capabilities.valid[VOL_CAPABILITIES_FORMAT] |= VOL_CAP_FMT_HIDDEN_FILES; /* Always support UF_HIDDEN */
443*bbb1b6f9SApple OSS Distributions
444*bbb1b6f9SApple OSS Distributions /* dont' support interfaces that only make sense on a writable file system
445*bbb1b6f9SApple OSS Distributions * or one with specific vnops implemented */
446*bbb1b6f9SApple OSS Distributions capabilities.capabilities[VOL_CAPABILITIES_INTERFACES] = 0;
447*bbb1b6f9SApple OSS Distributions
448*bbb1b6f9SApple OSS Distributions capabilities.valid[VOL_CAPABILITIES_INTERFACES] &=
449*bbb1b6f9SApple OSS Distributions ~(VOL_CAP_INT_SEARCHFS | VOL_CAP_INT_ATTRLIST | VOL_CAP_INT_READDIRATTR | VOL_CAP_INT_EXCHANGEDATA |
450*bbb1b6f9SApple OSS Distributions VOL_CAP_INT_COPYFILE | VOL_CAP_INT_ALLOCATE | VOL_CAP_INT_VOL_RENAME | VOL_CAP_INT_ADVLOCK | VOL_CAP_INT_FLOCK);
451*bbb1b6f9SApple OSS Distributions }
452*bbb1b6f9SApple OSS Distributions }
453*bbb1b6f9SApple OSS Distributions
454*bbb1b6f9SApple OSS Distributions if (VFSATTR_IS_ACTIVE(vfap, f_create_time)) {
455*bbb1b6f9SApple OSS Distributions VFSATTR_RETURN(vfap, f_create_time, tzero);
456*bbb1b6f9SApple OSS Distributions }
457*bbb1b6f9SApple OSS Distributions
458*bbb1b6f9SApple OSS Distributions if (VFSATTR_IS_ACTIVE(vfap, f_modify_time)) {
459*bbb1b6f9SApple OSS Distributions VFSATTR_RETURN(vfap, f_modify_time, tzero);
460*bbb1b6f9SApple OSS Distributions }
461*bbb1b6f9SApple OSS Distributions
462*bbb1b6f9SApple OSS Distributions if (VFSATTR_IS_ACTIVE(vfap, f_access_time)) {
463*bbb1b6f9SApple OSS Distributions VFSATTR_RETURN(vfap, f_access_time, tzero);
464*bbb1b6f9SApple OSS Distributions }
465*bbb1b6f9SApple OSS Distributions
466*bbb1b6f9SApple OSS Distributions if (VFSATTR_IS_ACTIVE(vfap, f_bsize)) {
467*bbb1b6f9SApple OSS Distributions VFSATTR_RETURN(vfap, f_bsize, sp->f_bsize);
468*bbb1b6f9SApple OSS Distributions }
469*bbb1b6f9SApple OSS Distributions
470*bbb1b6f9SApple OSS Distributions if (VFSATTR_IS_ACTIVE(vfap, f_iosize)) {
471*bbb1b6f9SApple OSS Distributions VFSATTR_RETURN(vfap, f_iosize, sp->f_iosize);
472*bbb1b6f9SApple OSS Distributions }
473*bbb1b6f9SApple OSS Distributions
474*bbb1b6f9SApple OSS Distributions if (VFSATTR_IS_ACTIVE(vfap, f_owner)) {
475*bbb1b6f9SApple OSS Distributions VFSATTR_RETURN(vfap, f_owner, 0);
476*bbb1b6f9SApple OSS Distributions }
477*bbb1b6f9SApple OSS Distributions
478*bbb1b6f9SApple OSS Distributions if (VFSATTR_IS_ACTIVE(vfap, f_blocks)) {
479*bbb1b6f9SApple OSS Distributions VFSATTR_RETURN(vfap, f_blocks, sp->f_blocks);
480*bbb1b6f9SApple OSS Distributions }
481*bbb1b6f9SApple OSS Distributions
482*bbb1b6f9SApple OSS Distributions if (VFSATTR_IS_ACTIVE(vfap, f_bfree)) {
483*bbb1b6f9SApple OSS Distributions VFSATTR_RETURN(vfap, f_bfree, sp->f_bfree);
484*bbb1b6f9SApple OSS Distributions }
485*bbb1b6f9SApple OSS Distributions
486*bbb1b6f9SApple OSS Distributions if (VFSATTR_IS_ACTIVE(vfap, f_bavail)) {
487*bbb1b6f9SApple OSS Distributions VFSATTR_RETURN(vfap, f_bavail, sp->f_bavail);
488*bbb1b6f9SApple OSS Distributions }
489*bbb1b6f9SApple OSS Distributions
490*bbb1b6f9SApple OSS Distributions if (VFSATTR_IS_ACTIVE(vfap, f_bused)) {
491*bbb1b6f9SApple OSS Distributions VFSATTR_RETURN(vfap, f_bused, sp->f_bused);
492*bbb1b6f9SApple OSS Distributions }
493*bbb1b6f9SApple OSS Distributions
494*bbb1b6f9SApple OSS Distributions if (VFSATTR_IS_ACTIVE(vfap, f_files)) {
495*bbb1b6f9SApple OSS Distributions VFSATTR_RETURN(vfap, f_files, sp->f_files);
496*bbb1b6f9SApple OSS Distributions }
497*bbb1b6f9SApple OSS Distributions
498*bbb1b6f9SApple OSS Distributions if (VFSATTR_IS_ACTIVE(vfap, f_ffree)) {
499*bbb1b6f9SApple OSS Distributions VFSATTR_RETURN(vfap, f_ffree, sp->f_ffree);
500*bbb1b6f9SApple OSS Distributions }
501*bbb1b6f9SApple OSS Distributions
502*bbb1b6f9SApple OSS Distributions if (VFSATTR_IS_ACTIVE(vfap, f_fssubtype)) {
503*bbb1b6f9SApple OSS Distributions VFSATTR_RETURN(vfap, f_fssubtype, 0);
504*bbb1b6f9SApple OSS Distributions }
505*bbb1b6f9SApple OSS Distributions
506*bbb1b6f9SApple OSS Distributions if (VFSATTR_IS_ACTIVE(vfap, f_capabilities)) {
507*bbb1b6f9SApple OSS Distributions memcpy(&vfap->f_capabilities, &capabilities, sizeof(vol_capabilities_attr_t));
508*bbb1b6f9SApple OSS Distributions
509*bbb1b6f9SApple OSS Distributions VFSATTR_SET_SUPPORTED(vfap, f_capabilities);
510*bbb1b6f9SApple OSS Distributions }
511*bbb1b6f9SApple OSS Distributions
512*bbb1b6f9SApple OSS Distributions if (VFSATTR_IS_ACTIVE(vfap, f_attributes)) {
513*bbb1b6f9SApple OSS Distributions vol_attributes_attr_t * volattr = &vfap->f_attributes;
514*bbb1b6f9SApple OSS Distributions
515*bbb1b6f9SApple OSS Distributions volattr->validattr.commonattr = 0;
516*bbb1b6f9SApple OSS Distributions volattr->validattr.volattr = ATTR_VOL_NAME | ATTR_VOL_CAPABILITIES | ATTR_VOL_ATTRIBUTES;
517*bbb1b6f9SApple OSS Distributions volattr->validattr.dirattr = 0;
518*bbb1b6f9SApple OSS Distributions volattr->validattr.fileattr = 0;
519*bbb1b6f9SApple OSS Distributions volattr->validattr.forkattr = 0;
520*bbb1b6f9SApple OSS Distributions
521*bbb1b6f9SApple OSS Distributions volattr->nativeattr.commonattr = 0;
522*bbb1b6f9SApple OSS Distributions volattr->nativeattr.volattr = ATTR_VOL_NAME | ATTR_VOL_CAPABILITIES | ATTR_VOL_ATTRIBUTES;
523*bbb1b6f9SApple OSS Distributions volattr->nativeattr.dirattr = 0;
524*bbb1b6f9SApple OSS Distributions volattr->nativeattr.fileattr = 0;
525*bbb1b6f9SApple OSS Distributions volattr->nativeattr.forkattr = 0;
526*bbb1b6f9SApple OSS Distributions
527*bbb1b6f9SApple OSS Distributions VFSATTR_SET_SUPPORTED(vfap, f_attributes);
528*bbb1b6f9SApple OSS Distributions }
529*bbb1b6f9SApple OSS Distributions
530*bbb1b6f9SApple OSS Distributions if (VFSATTR_IS_ACTIVE(vfap, f_vol_name)) {
531*bbb1b6f9SApple OSS Distributions /* The name of the volume is the same as the directory we mounted on */
532*bbb1b6f9SApple OSS Distributions coveredvp = vfs_vnodecovered(mp);
533*bbb1b6f9SApple OSS Distributions if (coveredvp) {
534*bbb1b6f9SApple OSS Distributions const char * name = vnode_getname_printable(coveredvp);
535*bbb1b6f9SApple OSS Distributions strlcpy(vfap->f_vol_name, name, MAXPATHLEN);
536*bbb1b6f9SApple OSS Distributions vnode_putname_printable(name);
537*bbb1b6f9SApple OSS Distributions
538*bbb1b6f9SApple OSS Distributions VFSATTR_SET_SUPPORTED(vfap, f_vol_name);
539*bbb1b6f9SApple OSS Distributions vnode_put(coveredvp);
540*bbb1b6f9SApple OSS Distributions }
541*bbb1b6f9SApple OSS Distributions }
542*bbb1b6f9SApple OSS Distributions
543*bbb1b6f9SApple OSS Distributions nullfs_cleanup_patched_context(null_mp, ectx);
544*bbb1b6f9SApple OSS Distributions
545*bbb1b6f9SApple OSS Distributions return 0;
546*bbb1b6f9SApple OSS Distributions }
547*bbb1b6f9SApple OSS Distributions
548*bbb1b6f9SApple OSS Distributions static int
nullfs_sync(__unused struct mount * mp,__unused int waitfor,__unused vfs_context_t ctx)549*bbb1b6f9SApple OSS Distributions nullfs_sync(__unused struct mount * mp, __unused int waitfor, __unused vfs_context_t ctx)
550*bbb1b6f9SApple OSS Distributions {
551*bbb1b6f9SApple OSS Distributions /*
552*bbb1b6f9SApple OSS Distributions * XXX - Assumes no data cached at null layer.
553*bbb1b6f9SApple OSS Distributions */
554*bbb1b6f9SApple OSS Distributions return 0;
555*bbb1b6f9SApple OSS Distributions }
556*bbb1b6f9SApple OSS Distributions
557*bbb1b6f9SApple OSS Distributions
558*bbb1b6f9SApple OSS Distributions
559*bbb1b6f9SApple OSS Distributions static int
nullfs_vfs_start(__unused struct mount * mp,__unused int flags,__unused vfs_context_t ctx)560*bbb1b6f9SApple OSS Distributions nullfs_vfs_start(__unused struct mount * mp, __unused int flags, __unused vfs_context_t ctx)
561*bbb1b6f9SApple OSS Distributions {
562*bbb1b6f9SApple OSS Distributions NULLFSDEBUG("%s\n", __FUNCTION__);
563*bbb1b6f9SApple OSS Distributions return 0;
564*bbb1b6f9SApple OSS Distributions }
565*bbb1b6f9SApple OSS Distributions
566*bbb1b6f9SApple OSS Distributions extern const struct vnodeopv_desc nullfs_vnodeop_opv_desc;
567*bbb1b6f9SApple OSS Distributions
568*bbb1b6f9SApple OSS Distributions const struct vnodeopv_desc * nullfs_vnodeopv_descs[] = {
569*bbb1b6f9SApple OSS Distributions &nullfs_vnodeop_opv_desc,
570*bbb1b6f9SApple OSS Distributions };
571*bbb1b6f9SApple OSS Distributions
572*bbb1b6f9SApple OSS Distributions struct vfsops nullfs_vfsops = {
573*bbb1b6f9SApple OSS Distributions .vfs_mount = nullfs_mount,
574*bbb1b6f9SApple OSS Distributions .vfs_unmount = nullfs_unmount,
575*bbb1b6f9SApple OSS Distributions .vfs_start = nullfs_vfs_start,
576*bbb1b6f9SApple OSS Distributions .vfs_root = nullfs_root,
577*bbb1b6f9SApple OSS Distributions .vfs_getattr = nullfs_vfs_getattr,
578*bbb1b6f9SApple OSS Distributions .vfs_sync = nullfs_sync,
579*bbb1b6f9SApple OSS Distributions .vfs_init = nullfs_init,
580*bbb1b6f9SApple OSS Distributions .vfs_sysctl = NULL,
581*bbb1b6f9SApple OSS Distributions .vfs_setattr = NULL,
582*bbb1b6f9SApple OSS Distributions };
583