Print this page
    
11083 support NFS server in zone
Portions contributed by: Dan Kruchinin <dan.kruchinin@nexenta.com>
Portions contributed by: Stepan Zastupov <stepan.zastupov@gmail.com>
Portions contributed by: Joyce McIntosh <joyce.mcintosh@nexenta.com>
Portions contributed by: Mike Zeller <mike@mikezeller.net>
Portions contributed by: Dan McDonald <danmcd@joyent.com>
Portions contributed by: Gordon Ross <gordon.w.ross@gmail.com>
Portions contributed by: Vitaliy Gusev <gusev.vitaliy@gmail.com>
Reviewed by: Rick McNeal <rick.mcneal@nexenta.com>
Reviewed by: Rob Gittins <rob.gittins@nexenta.com>
Reviewed by: Sanjay Nadkarni <sanjay.nadkarni@nexenta.com>
Reviewed by: Jason King <jbk@joyent.com>
Reviewed by: C Fraire <cfraire@me.com>
Change-Id: I22f289d357503f9b48a0bc2482cc4328a6d43d16
    
      
        | Split | 
	Close | 
      
      | Expand all | 
      | Collapse all | 
    
    
          --- old/usr/src/uts/common/fs/sharefs/sharefs_vfsops.c
          +++ new/usr/src/uts/common/fs/sharefs/sharefs_vfsops.c
   1    1  /*
   2    2   * CDDL HEADER START
   3    3   *
   4    4   * The contents of this file are subject to the terms of the
   5    5   * Common Development and Distribution License (the "License").
   6    6   * You may not use this file except in compliance with the License.
   7    7   *
   8    8   * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
   9    9   * or http://www.opensolaris.org/os/licensing.
  10   10   * See the License for the specific language governing permissions
  11   11   * and limitations under the License.
  12   12   *
  13   13   * When distributing Covered Code, include this CDDL HEADER in each
  14   14   * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  15   15   * If applicable, add the following below this CDDL HEADER, with the
  
    | 
      ↓ open down ↓ | 
    15 lines elided | 
    
      ↑ open up ↑ | 
  
  16   16   * fields enclosed by brackets "[]" replaced with your own identifying
  17   17   * information: Portions Copyright [yyyy] [name of copyright owner]
  18   18   *
  19   19   * CDDL HEADER END
  20   20   */
  21   21  
  22   22  /*
  23   23   * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
  24   24   */
  25   25  
       26 +/*
       27 + * Copyright 2018 Nexenta Systems, Inc.
       28 + */
       29 +
  26   30  #include <sys/atomic.h>
  27   31  #include <sys/cmn_err.h>
  28   32  #include <sys/errno.h>
  29   33  #include <sys/mount.h>
  30   34  #include <sharefs/sharefs.h>
  31   35  #include <sys/vfs_opreg.h>
  32   36  #include <sys/policy.h>
  33   37  #include <sys/sunddi.h>
  34   38  #include <sys/sysmacros.h>
  35   39  #include <sys/systm.h>
  36   40  
  37   41  #include <sys/mntent.h>
  38   42  #include <sys/vfs.h>
  39   43  
  40   44  /*
  41   45   * Kernel sharetab filesystem.
  42   46   *
  43   47   * This is a pseudo filesystem which exports information about shares currently
  44   48   * in kernel memory. The only element of the pseudo filesystem is a file.
  45   49   *
  46   50   * This file contains functions that interact with the VFS layer.
  47   51   *
  48   52   *      sharetab        sharefs_datanode_t      sharefs.c
  49   53   *
  50   54   */
  51   55  
  52   56  vnodeops_t                      *sharefs_ops_data;
  53   57  
  54   58  static const fs_operation_def_t sharefs_vfstops[];
  55   59  static gfs_opsvec_t              sharefs_opsvec[];
  56   60  
  57   61  static int sharefs_init(int, char *);
  58   62  
  59   63  /*
  60   64   * The sharefs system call.
  61   65   */
  62   66  static struct sysent sharefs_sysent = {
  63   67          3,
  64   68          SE_32RVAL1 | SE_ARGC | SE_NOUNLOAD,
  65   69          sharefs
  66   70  };
  67   71  
  68   72  static struct modlsys modlsys = {
  69   73          &mod_syscallops,
  70   74          "sharefs syscall",
  71   75          &sharefs_sysent
  72   76  };
  73   77  
  74   78  #ifdef  _SYSCALL32_IMPL
  75   79  static struct modlsys modlsys32 = {
  76   80          &mod_syscallops32,
  77   81          "sharefs syscall (32-bit)",
  78   82          &sharefs_sysent
  79   83  };
  80   84  #endif /* _SYSCALL32_IMPL */
  81   85  
  82   86  /*
  83   87   * Module linkage
  84   88   */
  85   89  static mntopts_t sharefs_mntopts = {
  86   90          0,
  87   91          NULL
  88   92  };
  89   93  
  90   94  static vfsdef_t vfw = {
  91   95          VFSDEF_VERSION,
  92   96          "sharefs",
  93   97          sharefs_init,
  94   98          VSW_HASPROTO | VSW_ZMOUNT,
  95   99          &sharefs_mntopts,
  96  100  };
  97  101  
  98  102  extern struct mod_ops   mod_fsops;
  99  103  
 100  104  static struct modlfs modlfs = {
 101  105          &mod_fsops,
 102  106          "sharetab filesystem",
 103  107          &vfw
 104  108  };
 105  109  
 106  110  static struct modlinkage modlinkage = {
 107  111          MODREV_1,
 108  112          &modlfs,
 109  113          &modlsys,
 110  114  #ifdef  _SYSCALL32_IMPL
 111  115          &modlsys32,
 112  116  #endif
 113  117          NULL
 114  118  };
 115  119  
 116  120  int
 117  121  _init(void)
 118  122  {
 119  123          return (mod_install(&modlinkage));
 120  124  }
 121  125  
 122  126  int
 123  127  _info(struct modinfo *modinfop)
 124  128  {
 125  129          return (mod_info(&modlinkage, modinfop));
 126  130  }
 127  131  
 128  132  int
 129  133  _fini(void)
 130  134  {
 131  135          /*
 132  136           * The sharetab filesystem cannot be unloaded.
 133  137           */
 134  138          return (EBUSY);
 135  139  }
 136  140  
 137  141  /*
 138  142   * Filesystem initialization.
 139  143   */
 140  144  
 141  145  static int sharefs_fstype;
 142  146  static major_t sharefs_major;
 143  147  static minor_t sharefs_minor;
 144  148  
 145  149  static gfs_opsvec_t sharefs_opsvec[] = {
 146  150          { "sharefs sharetab file", sharefs_tops_data, &sharefs_ops_data },
 147  151          { NULL }
 148  152  };
 149  153  
 150  154  /* ARGSUSED */
 151  155  static int
 152  156  sharefs_init(int fstype, char *name)
 153  157  {
 154  158          vfsops_t        *vfsops;
 155  159          int             error;
 156  160  
 157  161          sharefs_fstype = fstype;
 158  162          if (error = vfs_setfsops(fstype, sharefs_vfstops, &vfsops)) {
 159  163                  cmn_err(CE_WARN, "sharefs_init: bad vfs ops template");
 160  164                  return (error);
 161  165          }
 162  166  
 163  167          if (error = gfs_make_opsvec(sharefs_opsvec)) {
 164  168                  (void) vfs_freevfsops(vfsops);
 165  169                  return (error);
 166  170          }
 167  171  
 168  172          if ((sharefs_major = getudev()) == (major_t)-1) {
 169  173                  cmn_err(CE_WARN,
 170  174                      "sharefs_init: can't get unique device number");
 171  175                  sharefs_major = 0;
 172  176          }
 173  177  
 174  178          sharefs_sharetab_init();
 175  179  
 176  180          return (0);
 177  181  }
 178  182  
 179  183  /*
 180  184   * VFS entry points
 181  185   */
 182  186  static int
 183  187  sharefs_mount(vfs_t *vfsp, vnode_t *mvp, struct mounta *uap, cred_t *cr)
 184  188  {
 185  189          sharefs_vfs_t   *data;
 186  190          dev_t           dev;
 187  191  
 188  192          if (secpolicy_fs_mount(cr, mvp, vfsp) != 0)
 189  193                  return (EPERM);
 190  194  
 191  195          if ((uap->flags & MS_OVERLAY) == 0 &&
 192  196              (mvp->v_count > 1 || (mvp->v_flag & VROOT)))
 193  197                  return (EBUSY);
 194  198  
 195  199          data = kmem_alloc(sizeof (sharefs_vfs_t), KM_SLEEP);
 196  200  
 197  201          /*
 198  202           * Initialize vfs fields
 199  203           */
 200  204          vfsp->vfs_bsize = DEV_BSIZE;
 201  205          vfsp->vfs_fstype = sharefs_fstype;
 202  206          do {
 203  207                  dev = makedevice(sharefs_major,
 204  208                      atomic_inc_32_nv(&sharefs_minor) & L_MAXMIN32);
 205  209          } while (vfs_devismounted(dev));
 206  210          vfs_make_fsid(&vfsp->vfs_fsid, dev, sharefs_fstype);
 207  211          vfsp->vfs_data = data;
 208  212          vfsp->vfs_dev = dev;
 209  213  
 210  214          /*
 211  215           * Create root
 212  216           */
 213  217          data->sharefs_vfs_root = sharefs_create_root_file(vfsp);
 214  218  
 215  219          return (0);
 216  220  }
 217  221  
 218  222  static int
 219  223  sharefs_unmount(vfs_t *vfsp, int flag, struct cred *cr)
 220  224  {
 221  225          sharefs_vfs_t   *data;
 222  226  
 223  227          if (secpolicy_fs_unmount(cr, vfsp) != 0)
 224  228                  return (EPERM);
 225  229  
 226  230          /*
 227  231           * We do not currently support forced unmounts
 228  232           */
 229  233          if (flag & MS_FORCE)
 230  234                  return (ENOTSUP);
 231  235  
 232  236          /*
 233  237           * We should never have a reference count of less than 2: one for the
 234  238           * caller, one for the root vnode.
 235  239           */
  
    | 
      ↓ open down ↓ | 
    200 lines elided | 
    
      ↑ open up ↑ | 
  
 236  240          ASSERT(vfsp->vfs_count >= 2);
 237  241  
 238  242          /*
 239  243           * Any active vnodes will result in a hold on the root vnode
 240  244           */
 241  245          data = vfsp->vfs_data;
 242  246          if (data->sharefs_vfs_root->v_count > 1)
 243  247                  return (EBUSY);
 244  248  
 245  249          /*
 246      -         * Only allow an unmount iff there are no entries in memory.
 247      -         */
 248      -        rw_enter(&sharetab_lock, RW_READER);
 249      -        if (sharetab_size != 0) {
 250      -                rw_exit(&sharetab_lock);
 251      -                return (EBUSY);
 252      -        }
 253      -        rw_exit(&sharetab_lock);
 254      -
 255      -        /*
 256  250           * Release the last hold on the root vnode
 257  251           */
 258  252          VN_RELE(data->sharefs_vfs_root);
 259  253  
 260  254          kmem_free(data, sizeof (sharefs_vfs_t));
 261  255  
 262  256          return (0);
 263  257  }
 264  258  
 265  259  static int
 266  260  sharefs_root(vfs_t *vfsp, vnode_t **vpp)
 267  261  {
 268  262          sharefs_vfs_t   *data = vfsp->vfs_data;
 269  263  
 270  264          *vpp = data->sharefs_vfs_root;
 271  265          VN_HOLD(*vpp);
 272  266  
 273  267          return (0);
 274  268  }
 275  269  
 276  270  static int
 277  271  sharefs_statvfs(vfs_t *vfsp, statvfs64_t *sp)
 278  272  {
 279  273          dev32_t d32;
 280  274          int     total = 1;
 281  275  
 282  276          bzero(sp, sizeof (*sp));
 283  277          sp->f_bsize = DEV_BSIZE;
 284  278          sp->f_frsize = DEV_BSIZE;
 285  279          sp->f_files = total;
 286  280          sp->f_ffree = sp->f_favail = INT_MAX - total;
 287  281          (void) cmpldev(&d32, vfsp->vfs_dev);
 288  282          sp->f_fsid = d32;
 289  283          (void) strlcpy(sp->f_basetype, vfssw[vfsp->vfs_fstype].vsw_name,
 290  284              sizeof (sp->f_basetype));
 291  285          sp->f_flag = vf_to_stf(vfsp->vfs_flag);
 292  286          sp->f_namemax = SHAREFS_NAME_MAX;
 293  287          (void) strlcpy(sp->f_fstr, "sharefs", sizeof (sp->f_fstr));
 294  288  
 295  289          return (0);
 296  290  }
 297  291  
 298  292  static const fs_operation_def_t sharefs_vfstops[] = {
 299  293          { VFSNAME_MOUNT,        { .vfs_mount = sharefs_mount } },
 300  294          { VFSNAME_UNMOUNT,      { .vfs_unmount = sharefs_unmount } },
 301  295          { VFSNAME_ROOT,         { .vfs_root = sharefs_root } },
 302  296          { VFSNAME_STATVFS,      { .vfs_statvfs = sharefs_statvfs } },
 303  297          { NULL }
 304  298  };
  
    | 
      ↓ open down ↓ | 
    39 lines elided | 
    
      ↑ open up ↑ | 
  
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX