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 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 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