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