1*8329232eSGordon Ross /*
2*8329232eSGordon Ross  * CDDL HEADER START
3*8329232eSGordon Ross  *
4*8329232eSGordon Ross  * The contents of this file are subject to the terms of the
5*8329232eSGordon Ross  * Common Development and Distribution License (the "License").
6*8329232eSGordon Ross  * You may not use this file except in compliance with the License.
7*8329232eSGordon Ross  *
8*8329232eSGordon Ross  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9*8329232eSGordon Ross  * or http://www.opensolaris.org/os/licensing.
10*8329232eSGordon Ross  * See the License for the specific language governing permissions
11*8329232eSGordon Ross  * and limitations under the License.
12*8329232eSGordon Ross  *
13*8329232eSGordon Ross  * When distributing Covered Code, include this CDDL HEADER in each
14*8329232eSGordon Ross  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15*8329232eSGordon Ross  * If applicable, add the following below this CDDL HEADER, with the
16*8329232eSGordon Ross  * fields enclosed by brackets "[]" replaced with your own identifying
17*8329232eSGordon Ross  * information: Portions Copyright [yyyy] [name of copyright owner]
18*8329232eSGordon Ross  *
19*8329232eSGordon Ross  * CDDL HEADER END
20*8329232eSGordon Ross  */
21*8329232eSGordon Ross /*
22*8329232eSGordon Ross  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
23*8329232eSGordon Ross  * Use is subject to license terms.
24*8329232eSGordon Ross  */
25*8329232eSGordon Ross /*
26*8329232eSGordon Ross  * Copyright 2017 Nexenta Systems, Inc.  All rights reserved.
27*8329232eSGordon Ross  */
28*8329232eSGordon Ross 
29*8329232eSGordon Ross #include <sys/types.h>
30*8329232eSGordon Ross #include <sys/systm.h>
31*8329232eSGordon Ross #include <sys/errno.h>
32*8329232eSGordon Ross #include <sys/vfs.h>
33*8329232eSGordon Ross #include <sys/vnode.h>
34*8329232eSGordon Ross #include <sys/mount.h>
35*8329232eSGordon Ross #include <sys/cmn_err.h>
36*8329232eSGordon Ross #include <sys/debug.h>
37*8329232eSGordon Ross 
38*8329232eSGordon Ross #if 0 // XXX
39*8329232eSGordon Ross 
40*8329232eSGordon Ross #include <sys/user.h>
41*8329232eSGordon Ross #include <sys/vm.h>
42*8329232eSGordon Ross #include <sys/conf.h>
43*8329232eSGordon Ross #include <sys/class.h>
44*8329232eSGordon Ross #include <sys/systm.h>
45*8329232eSGordon Ross #include <sys/modctl.h>
46*8329232eSGordon Ross #include <sys/exec.h>
47*8329232eSGordon Ross #include <sys/exechdr.h>
48*8329232eSGordon Ross #include <sys/devops.h>
49*8329232eSGordon Ross #include <sys/ddi.h>
50*8329232eSGordon Ross #include <sys/sunddi.h>
51*8329232eSGordon Ross #include <sys/hwconf.h>
52*8329232eSGordon Ross #include <sys/ddi_impldefs.h>
53*8329232eSGordon Ross #include <sys/autoconf.h>
54*8329232eSGordon Ross #include <sys/disp.h>
55*8329232eSGordon Ross #include <sys/kmem.h>
56*8329232eSGordon Ross #include <sys/instance.h>
57*8329232eSGordon Ross #include <sys/modhash.h>
58*8329232eSGordon Ross #include <sys/dacf.h>
59*8329232eSGordon Ross #include <ipp/ipp.h>
60*8329232eSGordon Ross #include <sys/strsubr.h>
61*8329232eSGordon Ross #include <sys/kcpc.h>
62*8329232eSGordon Ross #include <sys/brand.h>
63*8329232eSGordon Ross #include <sys/cpc_pcbe.h>
64*8329232eSGordon Ross #include <sys/kstat.h>
65*8329232eSGordon Ross #include <sys/socketvar.h>
66*8329232eSGordon Ross #include <sys/kiconv.h>
67*8329232eSGordon Ross 
68*8329232eSGordon Ross #endif // XXX
69*8329232eSGordon Ross 
70*8329232eSGordon Ross #include <libfksmbfs.h>
71*8329232eSGordon Ross 
72*8329232eSGordon Ross /*
73*8329232eSGordon Ross  * Install a filesystem.
74*8329232eSGordon Ross  */
75*8329232eSGordon Ross /*ARGSUSED1*/
76*8329232eSGordon Ross int
fake_installfs(vfsdef_t * def)77*8329232eSGordon Ross fake_installfs(vfsdef_t *def)
78*8329232eSGordon Ross {
79*8329232eSGordon Ross 	struct vfssw *vswp;
80*8329232eSGordon Ross 	char *fsname = def->name;
81*8329232eSGordon Ross 	int fstype;	/* index into vfssw[] and vsanchor_fstype[] */
82*8329232eSGordon Ross 	int allocated;
83*8329232eSGordon Ross 	int err;
84*8329232eSGordon Ross 
85*8329232eSGordon Ross 	if (def->def_version != VFSDEF_VERSION) {
86*8329232eSGordon Ross 		cmn_err(CE_WARN, "file system '%s' version mismatch", fsname);
87*8329232eSGordon Ross 		return (ENXIO);
88*8329232eSGordon Ross 	}
89*8329232eSGordon Ross 
90*8329232eSGordon Ross 	allocated = 0;
91*8329232eSGordon Ross 
92*8329232eSGordon Ross 	WLOCK_VFSSW();
93*8329232eSGordon Ross 	if ((vswp = vfs_getvfsswbyname(fsname)) == NULL) {
94*8329232eSGordon Ross 		if ((vswp = allocate_vfssw(fsname)) == NULL) {
95*8329232eSGordon Ross 			WUNLOCK_VFSSW();
96*8329232eSGordon Ross 			/*
97*8329232eSGordon Ross 			 * See 1095689.  If this message appears, then
98*8329232eSGordon Ross 			 * we either need to make the vfssw table bigger
99*8329232eSGordon Ross 			 * statically, or make it grow dynamically.
100*8329232eSGordon Ross 			 */
101*8329232eSGordon Ross 			cmn_err(CE_WARN, "no room for '%s' in vfssw!", fsname);
102*8329232eSGordon Ross 			return (ENXIO);
103*8329232eSGordon Ross 		}
104*8329232eSGordon Ross 		allocated = 1;
105*8329232eSGordon Ross 	}
106*8329232eSGordon Ross 	ASSERT(vswp != NULL);
107*8329232eSGordon Ross 
108*8329232eSGordon Ross 	fstype = vswp - vfssw;	/* Pointer arithmetic to get the fstype */
109*8329232eSGordon Ross 
110*8329232eSGordon Ross 	/* Turn on everything by default *except* VSW_STATS */
111*8329232eSGordon Ross 	vswp->vsw_flag = def->flags & ~(VSW_STATS);
112*8329232eSGordon Ross 
113*8329232eSGordon Ross 	if (def->flags & VSW_HASPROTO) {
114*8329232eSGordon Ross 		vfs_mergeopttbl(&vfs_mntopts, def->optproto,
115*8329232eSGordon Ross 		    &vswp->vsw_optproto);
116*8329232eSGordon Ross 	} else {
117*8329232eSGordon Ross 		vfs_copyopttbl(&vfs_mntopts, &vswp->vsw_optproto);
118*8329232eSGordon Ross 	}
119*8329232eSGordon Ross 
120*8329232eSGordon Ross 	if (def->flags & VSW_CANRWRO) {
121*8329232eSGordon Ross 		/*
122*8329232eSGordon Ross 		 * This obviously implies VSW_CANREMOUNT.
123*8329232eSGordon Ross 		 */
124*8329232eSGordon Ross 		vswp->vsw_flag |= VSW_CANREMOUNT;
125*8329232eSGordon Ross 	}
126*8329232eSGordon Ross 
127*8329232eSGordon Ross 	/* vopstats ... */
128*8329232eSGordon Ross 
129*8329232eSGordon Ross 	if (def->init == NULL)
130*8329232eSGordon Ross 		err = EFAULT;
131*8329232eSGordon Ross 	else
132*8329232eSGordon Ross 		err = (*(def->init))(fstype, fsname);
133*8329232eSGordon Ross 
134*8329232eSGordon Ross 	if (err != 0) {
135*8329232eSGordon Ross 		if (allocated) {
136*8329232eSGordon Ross 			kmem_free(vswp->vsw_name, strlen(vswp->vsw_name)+1);
137*8329232eSGordon Ross 			vswp->vsw_name = "";
138*8329232eSGordon Ross 		}
139*8329232eSGordon Ross 		vswp->vsw_flag = 0;
140*8329232eSGordon Ross 		vswp->vsw_init = NULL;
141*8329232eSGordon Ross 	}
142*8329232eSGordon Ross 
143*8329232eSGordon Ross 	vfs_unrefvfssw(vswp);
144*8329232eSGordon Ross 	WUNLOCK_VFSSW();
145*8329232eSGordon Ross 
146*8329232eSGordon Ross 	/* ... vopstats */
147*8329232eSGordon Ross 
148*8329232eSGordon Ross 	return (err);
149*8329232eSGordon Ross }
150*8329232eSGordon Ross 
151*8329232eSGordon Ross int fake_removefs_allowed = 1;
152*8329232eSGordon Ross 
153*8329232eSGordon Ross /*
154*8329232eSGordon Ross  * Remove a filesystem
155*8329232eSGordon Ross  */
156*8329232eSGordon Ross int
fake_removefs(vfsdef_t * def)157*8329232eSGordon Ross fake_removefs(vfsdef_t *def)
158*8329232eSGordon Ross {
159*8329232eSGordon Ross 	struct vfssw *vswp;
160*8329232eSGordon Ross 
161*8329232eSGordon Ross 	if (fake_removefs_allowed == 0)
162*8329232eSGordon Ross 		return (EBUSY);
163*8329232eSGordon Ross 
164*8329232eSGordon Ross 	WLOCK_VFSSW();
165*8329232eSGordon Ross 	if ((vswp = vfs_getvfsswbyname(def->name)) == NULL) {
166*8329232eSGordon Ross 		WUNLOCK_VFSSW();
167*8329232eSGordon Ross 		cmn_err(CE_WARN, "fake_removefs: %s not in vfssw",
168*8329232eSGordon Ross 			def->name);
169*8329232eSGordon Ross 		return (EINVAL);
170*8329232eSGordon Ross 	}
171*8329232eSGordon Ross 	if (vswp->vsw_count != 1) {
172*8329232eSGordon Ross 		vfs_unrefvfssw(vswp);
173*8329232eSGordon Ross 		WUNLOCK_VFSSW();
174*8329232eSGordon Ross 		return (EBUSY);
175*8329232eSGordon Ross 	}
176*8329232eSGordon Ross 
177*8329232eSGordon Ross 	/*
178*8329232eSGordon Ross 	 * A mounted filesystem could still have vsw_count = 0
179*8329232eSGordon Ross 	 * so we must check whether anyone is actually using our ops
180*8329232eSGordon Ross 	 */
181*8329232eSGordon Ross 	if (vfs_opsinuse(&vswp->vsw_vfsops)) {
182*8329232eSGordon Ross 		vfs_unrefvfssw(vswp);
183*8329232eSGordon Ross 		WUNLOCK_VFSSW();
184*8329232eSGordon Ross 		return (EBUSY);
185*8329232eSGordon Ross 	}
186*8329232eSGordon Ross 
187*8329232eSGordon Ross 	vfs_freeopttbl(&vswp->vsw_optproto);
188*8329232eSGordon Ross 	vswp->vsw_optproto.mo_count = 0;
189*8329232eSGordon Ross 
190*8329232eSGordon Ross 	vswp->vsw_flag = 0;
191*8329232eSGordon Ross 	vswp->vsw_init = NULL;
192*8329232eSGordon Ross 	vfs_unrefvfssw(vswp);
193*8329232eSGordon Ross 	WUNLOCK_VFSSW();
194*8329232eSGordon Ross 	return (0);
195*8329232eSGordon Ross }