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
        
*** 16,31 ****
   * fields enclosed by brackets "[]" replaced with your own identifying
   * information: Portions Copyright [yyyy] [name of copyright owner]
   *
   * CDDL HEADER END
   */
  /*
   * Copyright 2010 Sun Microsystems, Inc.  All rights reserved.
   * Use is subject to license terms.
   */
  /*
!  * Copyright 2012 Nexenta Systems, Inc. All rights reserved.
   */
  
  #include <sys/systm.h>
  #include <sys/cmn_err.h>
  #include <nfs/nfs.h>
--- 16,33 ----
   * fields enclosed by brackets "[]" replaced with your own identifying
   * information: Portions Copyright [yyyy] [name of copyright owner]
   *
   * CDDL HEADER END
   */
+ 
  /*
   * Copyright 2010 Sun Microsystems, Inc.  All rights reserved.
   * Use is subject to license terms.
   */
+ 
  /*
!  * Copyright 2018 Nexenta Systems, Inc.
   */
  
  #include <sys/systm.h>
  #include <sys/cmn_err.h>
  #include <nfs/nfs.h>
*** 131,140 ****
--- 133,147 ----
          struct nfs4_svgetit_arg sarg;
          struct compound_state cs;
          struct statvfs64 sb;
  
          rfs4_init_compound_state(&cs);
+         /*
+          * This is global state checking, called once. We might be in
+          * non-global-zone context here (say a modload happens from a zone
+          * process) so in this case, we want the global-zone root vnode.
+          */
          cs.vp = rootvp;
          cs.fh.nfs_fh4_val = NULL;
          cs.cr = kcred;
  
          /*
*** 1299,1324 ****
          vnode_t *stubvp = NULL, *vp;
  
          vp = sarg->cs->vp;
          sarg->mntdfid_set = FALSE;
  
!         /* VROOT object, must untraverse */
!         if (vp->v_flag & VROOT) {
  
                  /* extra hold for vp since untraverse might rele */
                  VN_HOLD(vp);
!                 stubvp = untraverse(vp);
  
                  /*
!                  * If vp/stubvp are same, we must be at system
                   * root because untraverse returned same vp
                   * for a VROOT object.  sarg->vap was setup
                   * before we got here, so there's no need to do
                   * another getattr -- just use the one in sarg.
                   */
                  if (VN_CMP(vp, stubvp)) {
!                         ASSERT(VN_CMP(vp, rootdir));
                          vap = sarg->vap;
                  } else {
                          va.va_mask = AT_NODEID;
                          vap = &va;
                          error = rfs4_vop_getattr(stubvp, vap, 0, sarg->cs->cr);
--- 1306,1338 ----
          vnode_t *stubvp = NULL, *vp;
  
          vp = sarg->cs->vp;
          sarg->mntdfid_set = FALSE;
  
!         /*
!          * VROOT object or zone's root, must untraverse.
!          *
!          * NOTE: Not doing reality checks on curzone vs. compound
!          * state vnode because it will mismatch once at initialization
!          * if a non-global-zone triggers the module load, BUT in that case
!          * the vp is literally "/" which has VROOT set.
!          */
!         if ((vp->v_flag & VROOT) || VN_IS_CURZONEROOT(vp)) {
  
                  /* extra hold for vp since untraverse might rele */
                  VN_HOLD(vp);
!                 stubvp = untraverse(vp, ZONE_ROOTVP());
  
                  /*
!                  * If vp/stubvp are same, we must be at system-or-zone
                   * root because untraverse returned same vp
                   * for a VROOT object.  sarg->vap was setup
                   * before we got here, so there's no need to do
                   * another getattr -- just use the one in sarg.
                   */
                  if (VN_CMP(vp, stubvp)) {
!                         ASSERT(VN_IS_CURZONEROOT(vp));
                          vap = sarg->vap;
                  } else {
                          va.va_mask = AT_NODEID;
                          vap = &va;
                          error = rfs4_vop_getattr(stubvp, vap, 0, sarg->cs->cr);
*** 1373,1386 ****
                  if (sarg->op == NFS4ATTR_SETIT)
                          error = EINVAL;
                  break;          /* this attr is supported */
          case NFS4ATTR_GETIT:
          case NFS4ATTR_VERIT:
!                 if (! sarg->mntdfid_set)
                          error = rfs4_get_mntdfileid(cmd, sarg);
  
!                 if (! error && sarg->mntdfid_set) {
                          if (cmd == NFS4ATTR_GETIT)
                                  na->mounted_on_fileid = sarg->mounted_on_fileid;
                          else
                                  if (na->mounted_on_fileid !=
                                      sarg->mounted_on_fileid)
--- 1387,1400 ----
                  if (sarg->op == NFS4ATTR_SETIT)
                          error = EINVAL;
                  break;          /* this attr is supported */
          case NFS4ATTR_GETIT:
          case NFS4ATTR_VERIT:
!                 if (!sarg->mntdfid_set)
                          error = rfs4_get_mntdfileid(cmd, sarg);
  
!                 if (!error && sarg->mntdfid_set) {
                          if (cmd == NFS4ATTR_GETIT)
                                  na->mounted_on_fileid = sarg->mounted_on_fileid;
                          else
                                  if (na->mounted_on_fileid !=
                                      sarg->mounted_on_fileid)
*** 1593,1613 ****
                  if (sarg->op == NFS4ATTR_SETIT || sarg->op == NFS4ATTR_VERIT)
                          error = EINVAL;
                  break;  /* this attr is supported */
  
          case NFS4ATTR_GETIT:
                  fsl = fetch_referral(sarg->cs->vp, sarg->cs->cr);
                  if (fsl == NULL)
                          (void) memset(&(na->fs_locations), 0,
                              sizeof (fs_locations4));
                  else {
                          na->fs_locations = *fsl;
                          kmem_free(fsl, sizeof (fs_locations4));
                  }
!                 global_svstat_ptr[4][NFS_REFERRALS].value.ui64++;
                  break;
! 
          case NFS4ATTR_FREEIT:
                  if (sarg->op == NFS4ATTR_SETIT || sarg->op == NFS4ATTR_VERIT)
                          error = EINVAL;
                  rfs4_free_fs_locations4(&na->fs_locations);
                  break;
--- 1607,1631 ----
                  if (sarg->op == NFS4ATTR_SETIT || sarg->op == NFS4ATTR_VERIT)
                          error = EINVAL;
                  break;  /* this attr is supported */
  
          case NFS4ATTR_GETIT:
+         {
+                 kstat_named_t *stat =
+                     sarg->cs->exi->exi_ne->ne_globals->svstat[NFS_V4];
+ 
                  fsl = fetch_referral(sarg->cs->vp, sarg->cs->cr);
                  if (fsl == NULL)
                          (void) memset(&(na->fs_locations), 0,
                              sizeof (fs_locations4));
                  else {
                          na->fs_locations = *fsl;
                          kmem_free(fsl, sizeof (fs_locations4));
                  }
!                 stat[NFS_REFERRALS].value.ui64++;
                  break;
!         }
          case NFS4ATTR_FREEIT:
                  if (sarg->op == NFS4ATTR_SETIT || sarg->op == NFS4ATTR_VERIT)
                          error = EINVAL;
                  rfs4_free_fs_locations4(&na->fs_locations);
                  break;