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 }