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
        
*** 18,35 ****
   *
   * CDDL HEADER END
   */
  
  /*
!  * Copyright 2015 Nexenta Systems, Inc.  All rights reserved.
   * Copyright (c) 1994, 2010, Oracle and/or its affiliates. All rights reserved.
   * Copyright (c) 2013 by Delphix. All rights reserved.
   */
  
  /* Copyright (c) 1983, 1984, 1985, 1986, 1987, 1988, 1989 AT&T */
  /* All Rights Reserved */
  
  #include <sys/param.h>
  #include <sys/types.h>
  #include <sys/systm.h>
  #include <sys/cred.h>
  #include <sys/buf.h>
--- 18,36 ----
   *
   * CDDL HEADER END
   */
  
  /*
!  * Copyright 2018 Nexenta Systems, Inc.
   * Copyright (c) 1994, 2010, Oracle and/or its affiliates. All rights reserved.
   * Copyright (c) 2013 by Delphix. All rights reserved.
   */
  
  /* Copyright (c) 1983, 1984, 1985, 1986, 1987, 1988, 1989 AT&T */
  /* All Rights Reserved */
  
+ 
  #include <sys/param.h>
  #include <sys/types.h>
  #include <sys/systm.h>
  #include <sys/cred.h>
  #include <sys/buf.h>
*** 66,82 ****
  
  #include <inet/ip.h>
  #include <inet/ip6.h>
  
  /*
   * These are the interface routines for the server side of the
   * Network File System.  See the NFS version 3 protocol specification
   * for a description of this interface.
   */
  
- static writeverf3 write3verf;
- 
  static int      sattr3_to_vattr(sattr3 *, struct vattr *);
  static int      vattr_to_fattr3(struct vattr *, fattr3 *);
  static int      vattr_to_wcc_attr(struct vattr *, wcc_attr *);
  static void     vattr_to_pre_op_attr(struct vattr *, pre_op_attr *);
  static void     vattr_to_wcc_data(struct vattr *, struct vattr *, wcc_data *);
--- 67,88 ----
  
  #include <inet/ip.h>
  #include <inet/ip6.h>
  
  /*
+  * Zone global variables of NFSv3 server
+  */
+ typedef struct nfs3_srv {
+         writeverf3      write3verf;
+ } nfs3_srv_t;
+ 
+ /*
   * These are the interface routines for the server side of the
   * Network File System.  See the NFS version 3 protocol specification
   * for a description of this interface.
   */
  
  static int      sattr3_to_vattr(sattr3 *, struct vattr *);
  static int      vattr_to_fattr3(struct vattr *, fattr3 *);
  static int      vattr_to_wcc_attr(struct vattr *, wcc_attr *);
  static void     vattr_to_pre_op_attr(struct vattr *, pre_op_attr *);
  static void     vattr_to_wcc_data(struct vattr *, struct vattr *, wcc_data *);
*** 84,93 ****
--- 90,108 ----
  
  extern int nfs_loaned_buffers;
  
  u_longlong_t nfs3_srv_caller_id;
  
+ static nfs3_srv_t *
+ nfs3_get_srv(void)
+ {
+         nfs_globals_t *ng = nfs_srv_getzg();
+         nfs3_srv_t *srv = ng->nfs3_srv;
+         ASSERT(srv != NULL);
+         return (srv);
+ }
+ 
  /* ARGSUSED */
  void
  rfs3_getattr(GETATTR3args *args, GETATTR3res *resp, struct exportinfo *exi,
      struct svc_req *req, cred_t *cr, bool_t ro)
  {
*** 95,106 ****
          vnode_t *vp;
          struct vattr va;
  
          vp = nfs3_fhtovp(&args->object, exi);
  
!         DTRACE_NFSV3_4(op__getattr__start, struct svc_req *, req,
!             cred_t *, cr, vnode_t *, vp, GETATTR3args *, args);
  
          if (vp == NULL) {
                  error = ESTALE;
                  goto out;
          }
--- 110,122 ----
          vnode_t *vp;
          struct vattr va;
  
          vp = nfs3_fhtovp(&args->object, exi);
  
!         DTRACE_NFSV3_5(op__getattr__start, struct svc_req *, req,
!             cred_t *, cr, vnode_t *, vp, struct exportinfo *, exi,
!             GETATTR3args *, args);
  
          if (vp == NULL) {
                  error = ESTALE;
                  goto out;
          }
*** 117,128 ****
                  error = vattr_to_fattr3(&va, &resp->resok.obj_attributes);
                  if (error)
                          goto out;
                  resp->status = NFS3_OK;
  
!                 DTRACE_NFSV3_4(op__getattr__done, struct svc_req *, req,
!                     cred_t *, cr, vnode_t *, vp, GETATTR3res *, resp);
  
                  VN_RELE(vp);
  
                  return;
          }
--- 133,145 ----
                  error = vattr_to_fattr3(&va, &resp->resok.obj_attributes);
                  if (error)
                          goto out;
                  resp->status = NFS3_OK;
  
!                 DTRACE_NFSV3_5(op__getattr__done, struct svc_req *, req,
!                     cred_t *, cr, vnode_t *, vp, struct exportinfo *, exi,
!                     GETATTR3res *, resp);
  
                  VN_RELE(vp);
  
                  return;
          }
*** 132,143 ****
                  curthread->t_flag &= ~T_WOULDBLOCK;
                  resp->status = NFS3ERR_JUKEBOX;
          } else
                  resp->status = puterrno3(error);
  
!         DTRACE_NFSV3_4(op__getattr__done, struct svc_req *, req,
!             cred_t *, cr, vnode_t *, vp, GETATTR3res *, resp);
  
          if (vp != NULL)
                  VN_RELE(vp);
  }
  
--- 149,161 ----
                  curthread->t_flag &= ~T_WOULDBLOCK;
                  resp->status = NFS3ERR_JUKEBOX;
          } else
                  resp->status = puterrno3(error);
  
!         DTRACE_NFSV3_5(op__getattr__done, struct svc_req *, req,
!             cred_t *, cr, vnode_t *, vp, struct exportinfo *, exi,
!             GETATTR3res *, resp);
  
          if (vp != NULL)
                  VN_RELE(vp);
  }
  
*** 166,177 ****
          bvap = NULL;
          avap = NULL;
  
          vp = nfs3_fhtovp(&args->object, exi);
  
!         DTRACE_NFSV3_4(op__setattr__start, struct svc_req *, req,
!             cred_t *, cr, vnode_t *, vp, SETATTR3args *, args);
  
          if (vp == NULL) {
                  error = ESTALE;
                  goto out;
          }
--- 184,196 ----
          bvap = NULL;
          avap = NULL;
  
          vp = nfs3_fhtovp(&args->object, exi);
  
!         DTRACE_NFSV3_5(op__setattr__start, struct svc_req *, req,
!             cred_t *, cr, vnode_t *, vp, struct exportinfo *, exi,
!             SETATTR3args *, args);
  
          if (vp == NULL) {
                  error = ESTALE;
                  goto out;
          }
*** 328,339 ****
                  nbl_end_crit(vp);
  
          resp->status = NFS3_OK;
          vattr_to_wcc_data(bvap, avap, &resp->resok.obj_wcc);
  
!         DTRACE_NFSV3_4(op__setattr__done, struct svc_req *, req,
!             cred_t *, cr, vnode_t *, vp, SETATTR3res *, resp);
  
          VN_RELE(vp);
  
          return;
  
--- 347,359 ----
                  nbl_end_crit(vp);
  
          resp->status = NFS3_OK;
          vattr_to_wcc_data(bvap, avap, &resp->resok.obj_wcc);
  
!         DTRACE_NFSV3_5(op__setattr__done, struct svc_req *, req,
!             cred_t *, cr, vnode_t *, vp, struct exportinfo *, exi,
!             SETATTR3res *, resp);
  
          VN_RELE(vp);
  
          return;
  
*** 342,353 ****
                  curthread->t_flag &= ~T_WOULDBLOCK;
                  resp->status = NFS3ERR_JUKEBOX;
          } else
                  resp->status = puterrno3(error);
  out1:
!         DTRACE_NFSV3_4(op__setattr__done, struct svc_req *, req,
!             cred_t *, cr, vnode_t *, vp, SETATTR3res *, resp);
  
          if (vp != NULL) {
                  if (in_crit)
                          nbl_end_crit(vp);
                  VN_RELE(vp);
--- 362,374 ----
                  curthread->t_flag &= ~T_WOULDBLOCK;
                  resp->status = NFS3ERR_JUKEBOX;
          } else
                  resp->status = puterrno3(error);
  out1:
!         DTRACE_NFSV3_5(op__setattr__done, struct svc_req *, req,
!             cred_t *, cr, vnode_t *, vp, struct exportinfo *, exi,
!             SETATTR3res *, resp);
  
          if (vp != NULL) {
                  if (in_crit)
                          nbl_end_crit(vp);
                  VN_RELE(vp);
*** 388,407 ****
          /*
           * Allow lookups from the root - the default
           * location of the public filehandle.
           */
          if (exi != NULL && (exi->exi_export.ex_flags & EX_PUBLIC)) {
!                 dvp = rootdir;
                  VN_HOLD(dvp);
  
!                 DTRACE_NFSV3_4(op__lookup__start, struct svc_req *, req,
!                     cred_t *, cr, vnode_t *, dvp, LOOKUP3args *, args);
          } else {
                  dvp = nfs3_fhtovp(&args->what.dir, exi);
  
!                 DTRACE_NFSV3_4(op__lookup__start, struct svc_req *, req,
!                     cred_t *, cr, vnode_t *, dvp, LOOKUP3args *, args);
  
                  if (dvp == NULL) {
                          error = ESTALE;
                          goto out;
                  }
--- 409,431 ----
          /*
           * Allow lookups from the root - the default
           * location of the public filehandle.
           */
          if (exi != NULL && (exi->exi_export.ex_flags & EX_PUBLIC)) {
!                 ASSERT3U(exi->exi_zoneid, ==, curzone->zone_id);
!                 dvp = ZONE_ROOTVP();
                  VN_HOLD(dvp);
  
!                 DTRACE_NFSV3_5(op__lookup__start, struct svc_req *, req,
!                     cred_t *, cr, vnode_t *, dvp, struct exportinfo *, exi,
!                     LOOKUP3args *, args);
          } else {
                  dvp = nfs3_fhtovp(&args->what.dir, exi);
  
!                 DTRACE_NFSV3_5(op__lookup__start, struct svc_req *, req,
!                     cred_t *, cr, vnode_t *, dvp, struct exportinfo *, exi,
!                     LOOKUP3args *, args);
  
                  if (dvp == NULL) {
                          error = ESTALE;
                          goto out;
                  }
*** 419,432 ****
                  resp->status = NFS3ERR_ACCES;
                  goto out1;
          }
  
          fhp = &args->what.dir;
          if (strcmp(args->what.name, "..") == 0 &&
              EQFID(&exi->exi_fid, FH3TOFIDP(fhp))) {
                  if ((exi->exi_export.ex_flags & EX_NOHIDE) &&
!                     (dvp->v_flag & VROOT)) {
                          /*
                           * special case for ".." and 'nohide'exported root
                           */
                          if (rfs_climb_crossmnt(&dvp, &exi, cr) != 0) {
                                  resp->status = NFS3ERR_ACCES;
--- 443,457 ----
                  resp->status = NFS3ERR_ACCES;
                  goto out1;
          }
  
          fhp = &args->what.dir;
+         ASSERT3U(curzone->zone_id, ==, exi->exi_zoneid); /* exi is non-NULL */
          if (strcmp(args->what.name, "..") == 0 &&
              EQFID(&exi->exi_fid, FH3TOFIDP(fhp))) {
                  if ((exi->exi_export.ex_flags & EX_NOHIDE) &&
!                     ((dvp->v_flag & VROOT) || VN_IS_CURZONEROOT(dvp))) {
                          /*
                           * special case for ".." and 'nohide'exported root
                           */
                          if (rfs_climb_crossmnt(&dvp, &exi, cr) != 0) {
                                  resp->status = NFS3ERR_ACCES;
*** 453,462 ****
--- 478,488 ----
           */
          if (PUBLIC_FH3(&args->what.dir)) {
                  publicfh_flag = TRUE;
  
                  exi_rele(exi);
+                 exi = NULL;
  
                  error = rfs_publicfh_mclookup(name, dvp, cr, &vp,
                      &exi, &sec);
  
                  /*
*** 536,546 ****
          }
  
          va.va_mask = AT_ALL;
          vap = rfs4_delegated_getattr(vp, &va, 0, cr) ? NULL : &va;
  
-         exi_rele(exi);
          VN_RELE(vp);
  
          resp->status = NFS3_OK;
          vattr_to_post_op_attr(vap, &resp->resok.obj_attributes);
          vattr_to_post_op_attr(dvap, &resp->resok.dir_attributes);
--- 562,571 ----
*** 551,563 ****
           * Then set RPC status to AUTH_TOOWEAK in common_dispatch.
           */
          if (auth_weak)
                  resp->status = (enum nfsstat3)WNFSERR_CLNT_FLAVOR;
  
!         DTRACE_NFSV3_4(op__lookup__done, struct svc_req *, req,
!             cred_t *, cr, vnode_t *, dvp, LOOKUP3res *, resp);
          VN_RELE(dvp);
  
          return;
  
  out:
          if (curthread->t_flag & T_WOULDBLOCK) {
--- 576,590 ----
           * Then set RPC status to AUTH_TOOWEAK in common_dispatch.
           */
          if (auth_weak)
                  resp->status = (enum nfsstat3)WNFSERR_CLNT_FLAVOR;
  
!         DTRACE_NFSV3_5(op__lookup__done, struct svc_req *, req,
!             cred_t *, cr, vnode_t *, dvp, struct exportinfo *, exi,
!             LOOKUP3res *, resp);
          VN_RELE(dvp);
+         exi_rele(exi);
  
          return;
  
  out:
          if (curthread->t_flag & T_WOULDBLOCK) {
*** 564,579 ****
                  curthread->t_flag &= ~T_WOULDBLOCK;
                  resp->status = NFS3ERR_JUKEBOX;
          } else
                  resp->status = puterrno3(error);
  out1:
          if (exi != NULL)
                  exi_rele(exi);
  
-         DTRACE_NFSV3_4(op__lookup__done, struct svc_req *, req,
-             cred_t *, cr, vnode_t *, dvp, LOOKUP3res *, resp);
- 
          if (dvp != NULL)
                  VN_RELE(dvp);
          vattr_to_post_op_attr(dvap, &resp->resfail.dir_attributes);
  
  }
--- 591,607 ----
                  curthread->t_flag &= ~T_WOULDBLOCK;
                  resp->status = NFS3ERR_JUKEBOX;
          } else
                  resp->status = puterrno3(error);
  out1:
+         DTRACE_NFSV3_5(op__lookup__done, struct svc_req *, req,
+             cred_t *, cr, vnode_t *, dvp, struct exportinfo *, exi,
+             LOOKUP3res *, resp);
+ 
          if (exi != NULL)
                  exi_rele(exi);
  
          if (dvp != NULL)
                  VN_RELE(dvp);
          vattr_to_post_op_attr(dvap, &resp->resfail.dir_attributes);
  
  }
*** 601,612 ****
  
          vap = NULL;
  
          vp = nfs3_fhtovp(&args->object, exi);
  
!         DTRACE_NFSV3_4(op__access__start, struct svc_req *, req,
!             cred_t *, cr, vnode_t *, vp, ACCESS3args *, args);
  
          if (vp == NULL) {
                  error = ESTALE;
                  goto out;
          }
--- 629,641 ----
  
          vap = NULL;
  
          vp = nfs3_fhtovp(&args->object, exi);
  
!         DTRACE_NFSV3_5(op__access__start, struct svc_req *, req,
!             cred_t *, cr, vnode_t *, vp, struct exportinfo *, exi,
!             ACCESS3args *, args);
  
          if (vp == NULL) {
                  error = ESTALE;
                  goto out;
          }
*** 712,723 ****
          vap = rfs4_delegated_getattr(vp, &va, 0, cr) ? NULL : &va;
  
          resp->status = NFS3_OK;
          vattr_to_post_op_attr(vap, &resp->resok.obj_attributes);
  
!         DTRACE_NFSV3_4(op__access__done, struct svc_req *, req,
!             cred_t *, cr, vnode_t *, vp, ACCESS3res *, resp);
  
          VN_RELE(vp);
  
          return;
  
--- 741,753 ----
          vap = rfs4_delegated_getattr(vp, &va, 0, cr) ? NULL : &va;
  
          resp->status = NFS3_OK;
          vattr_to_post_op_attr(vap, &resp->resok.obj_attributes);
  
!         DTRACE_NFSV3_5(op__access__done, struct svc_req *, req,
!             cred_t *, cr, vnode_t *, vp, struct exportinfo *, exi,
!             ACCESS3res *, resp);
  
          VN_RELE(vp);
  
          return;
  
*** 725,736 ****
          if (curthread->t_flag & T_WOULDBLOCK) {
                  curthread->t_flag &= ~T_WOULDBLOCK;
                  resp->status = NFS3ERR_JUKEBOX;
          } else
                  resp->status = puterrno3(error);
!         DTRACE_NFSV3_4(op__access__done, struct svc_req *, req,
!             cred_t *, cr, vnode_t *, vp, ACCESS3res *, resp);
          if (vp != NULL)
                  VN_RELE(vp);
          vattr_to_post_op_attr(vap, &resp->resfail.obj_attributes);
  }
  
--- 755,767 ----
          if (curthread->t_flag & T_WOULDBLOCK) {
                  curthread->t_flag &= ~T_WOULDBLOCK;
                  resp->status = NFS3ERR_JUKEBOX;
          } else
                  resp->status = puterrno3(error);
!         DTRACE_NFSV3_5(op__access__done, struct svc_req *, req,
!             cred_t *, cr, vnode_t *, vp, struct exportinfo *, exi,
!             ACCESS3res *, resp);
          if (vp != NULL)
                  VN_RELE(vp);
          vattr_to_post_op_attr(vap, &resp->resfail.obj_attributes);
  }
  
*** 759,770 ****
  
          vap = NULL;
  
          vp = nfs3_fhtovp(&args->symlink, exi);
  
!         DTRACE_NFSV3_4(op__readlink__start, struct svc_req *, req,
!             cred_t *, cr, vnode_t *, vp, READLINK3args *, args);
  
          if (vp == NULL) {
                  error = ESTALE;
                  goto out;
          }
--- 790,802 ----
  
          vap = NULL;
  
          vp = nfs3_fhtovp(&args->symlink, exi);
  
!         DTRACE_NFSV3_5(op__readlink__start, struct svc_req *, req,
!             cred_t *, cr, vnode_t *, vp, struct exportinfo *, exi,
!             READLINK3args *, args);
  
          if (vp == NULL) {
                  error = ESTALE;
                  goto out;
          }
*** 809,822 ****
          data = kmem_alloc(MAXPATHLEN + 1, KM_SLEEP);
  
          if (is_referral) {
                  char *s;
                  size_t strsz;
  
                  /* Get an artificial symlink based on a referral */
                  s = build_symlink(vp, cr, &strsz);
!                 global_svstat_ptr[3][NFS_REFERLINKS].value.ui64++;
                  DTRACE_PROBE2(nfs3serv__func__referral__reflink,
                      vnode_t *, vp, char *, s);
                  if (s == NULL)
                          error = EINVAL;
                  else {
--- 841,855 ----
          data = kmem_alloc(MAXPATHLEN + 1, KM_SLEEP);
  
          if (is_referral) {
                  char *s;
                  size_t strsz;
+                 kstat_named_t *stat = exi->exi_ne->ne_globals->svstat[NFS_V3];
  
                  /* Get an artificial symlink based on a referral */
                  s = build_symlink(vp, cr, &strsz);
!                 stat[NFS_REFERLINKS].value.ui64++;
                  DTRACE_PROBE2(nfs3serv__func__referral__reflink,
                      vnode_t *, vp, char *, s);
                  if (s == NULL)
                          error = EINVAL;
                  else {
*** 880,891 ****
  
          resp->status = NFS3_OK;
          vattr_to_post_op_attr(vap, &resp->resok.symlink_attributes);
          resp->resok.data = name;
  
!         DTRACE_NFSV3_4(op__readlink__done, struct svc_req *, req,
!             cred_t *, cr, vnode_t *, vp, READLINK3res *, resp);
          VN_RELE(vp);
  
          if (name != data)
                  kmem_free(data, MAXPATHLEN + 1);
  
--- 913,925 ----
  
          resp->status = NFS3_OK;
          vattr_to_post_op_attr(vap, &resp->resok.symlink_attributes);
          resp->resok.data = name;
  
!         DTRACE_NFSV3_5(op__readlink__done, struct svc_req *, req,
!             cred_t *, cr, vnode_t *, vp, struct exportinfo *, exi,
!             READLINK3res *, resp);
          VN_RELE(vp);
  
          if (name != data)
                  kmem_free(data, MAXPATHLEN + 1);
  
*** 896,907 ****
                  curthread->t_flag &= ~T_WOULDBLOCK;
                  resp->status = NFS3ERR_JUKEBOX;
          } else
                  resp->status = puterrno3(error);
  out1:
!         DTRACE_NFSV3_4(op__readlink__done, struct svc_req *, req,
!             cred_t *, cr, vnode_t *, vp, READLINK3res *, resp);
          if (vp != NULL)
                  VN_RELE(vp);
          vattr_to_post_op_attr(vap, &resp->resfail.symlink_attributes);
  }
  
--- 930,942 ----
                  curthread->t_flag &= ~T_WOULDBLOCK;
                  resp->status = NFS3ERR_JUKEBOX;
          } else
                  resp->status = puterrno3(error);
  out1:
!         DTRACE_NFSV3_5(op__readlink__done, struct svc_req *, req,
!             cred_t *, cr, vnode_t *, vp, struct exportinfo *, exi,
!             READLINK3res *, resp);
          if (vp != NULL)
                  VN_RELE(vp);
          vattr_to_post_op_attr(vap, &resp->resfail.symlink_attributes);
  }
  
*** 947,959 ****
  
          vap = NULL;
  
          vp = nfs3_fhtovp(&args->file, exi);
  
!         DTRACE_NFSV3_4(op__read__start, struct svc_req *, req,
!             cred_t *, cr, vnode_t *, vp, READ3args *, args);
  
          if (vp == NULL) {
                  error = ESTALE;
                  goto out;
          }
  
--- 982,996 ----
  
          vap = NULL;
  
          vp = nfs3_fhtovp(&args->file, exi);
  
!         DTRACE_NFSV3_5(op__read__start, struct svc_req *, req,
!             cred_t *, cr, vnode_t *, vp, struct exportinfo *, exi,
!             READ3args *, args);
  
+ 
          if (vp == NULL) {
                  error = ESTALE;
                  goto out;
          }
  
*** 1203,1214 ****
                  resp->resok.data.data_val = (caddr_t)mp->b_datap->db_base;
                  (resp->resok).wlist = NULL;
          }
  
  done:
!         DTRACE_NFSV3_4(op__read__done, struct svc_req *, req,
!             cred_t *, cr, vnode_t *, vp, READ3res *, resp);
  
          VN_RELE(vp);
  
          if (iovp != NULL)
                  kmem_free(iovp, iovcnt * sizeof (struct iovec));
--- 1240,1252 ----
                  resp->resok.data.data_val = (caddr_t)mp->b_datap->db_base;
                  (resp->resok).wlist = NULL;
          }
  
  done:
!         DTRACE_NFSV3_5(op__read__done, struct svc_req *, req,
!             cred_t *, cr, vnode_t *, vp, struct exportinfo *, exi,
!             READ3res *, resp);
  
          VN_RELE(vp);
  
          if (iovp != NULL)
                  kmem_free(iovp, iovcnt * sizeof (struct iovec));
*** 1220,1231 ****
                  curthread->t_flag &= ~T_WOULDBLOCK;
                  resp->status = NFS3ERR_JUKEBOX;
          } else
                  resp->status = puterrno3(error);
  out1:
!         DTRACE_NFSV3_4(op__read__done, struct svc_req *, req,
!             cred_t *, cr, vnode_t *, vp, READ3res *, resp);
  
          if (vp != NULL) {
                  if (need_rwunlock)
                          VOP_RWUNLOCK(vp, V_WRITELOCK_FALSE, &ct);
                  if (in_crit)
--- 1258,1270 ----
                  curthread->t_flag &= ~T_WOULDBLOCK;
                  resp->status = NFS3ERR_JUKEBOX;
          } else
                  resp->status = puterrno3(error);
  out1:
!         DTRACE_NFSV3_5(op__read__done, struct svc_req *, req,
!             cred_t *, cr, vnode_t *, vp, struct exportinfo *, exi,
!             READ3res *, resp);
  
          if (vp != NULL) {
                  if (need_rwunlock)
                          VOP_RWUNLOCK(vp, V_WRITELOCK_FALSE, &ct);
                  if (in_crit)
*** 1266,1275 ****
--- 1305,1315 ----
  
  void
  rfs3_write(WRITE3args *args, WRITE3res *resp, struct exportinfo *exi,
      struct svc_req *req, cred_t *cr, bool_t ro)
  {
+         nfs3_srv_t *ns;
          int error;
          vnode_t *vp;
          struct vattr *bvap = NULL;
          struct vattr bva;
          struct vattr *avap = NULL;
*** 1286,1303 ****
          int rwlock_ret = -1;
          caller_context_t ct;
  
          vp = nfs3_fhtovp(&args->file, exi);
  
!         DTRACE_NFSV3_4(op__write__start, struct svc_req *, req,
!             cred_t *, cr, vnode_t *, vp, WRITE3args *, args);
  
          if (vp == NULL) {
                  error = ESTALE;
                  goto err;
          }
  
          if (is_system_labeled()) {
                  bslabel_t *clabel = req->rq_label;
  
                  ASSERT(clabel != NULL);
                  DTRACE_PROBE2(tx__rfs3__log__info__opwrite__clabel, char *,
--- 1326,1347 ----
          int rwlock_ret = -1;
          caller_context_t ct;
  
          vp = nfs3_fhtovp(&args->file, exi);
  
!         DTRACE_NFSV3_5(op__write__start, struct svc_req *, req,
!             cred_t *, cr, vnode_t *, vp, struct exportinfo *, exi,
!             WRITE3args *, args);
  
          if (vp == NULL) {
                  error = ESTALE;
                  goto err;
          }
  
+         ASSERT3U(curzone->zone_id, ==, exi->exi_zoneid); /* exi is non-NULL. */
+         ns = nfs3_get_srv();
+ 
          if (is_system_labeled()) {
                  bslabel_t *clabel = req->rq_label;
  
                  ASSERT(clabel != NULL);
                  DTRACE_PROBE2(tx__rfs3__log__info__opwrite__clabel, char *,
*** 1381,1391 ****
          if (args->count == 0) {
                  resp->status = NFS3_OK;
                  vattr_to_wcc_data(bvap, avap, &resp->resok.file_wcc);
                  resp->resok.count = 0;
                  resp->resok.committed = args->stable;
!                 resp->resok.verf = write3verf;
                  goto out;
          }
  
          if (args->mblk != NULL) {
                  iovcnt = 0;
--- 1425,1435 ----
          if (args->count == 0) {
                  resp->status = NFS3_OK;
                  vattr_to_wcc_data(bvap, avap, &resp->resok.file_wcc);
                  resp->resok.count = 0;
                  resp->resok.committed = args->stable;
!                 resp->resok.verf = ns->write3verf;
                  goto out;
          }
  
          if (args->mblk != NULL) {
                  iovcnt = 0;
*** 1483,1493 ****
  
          resp->status = NFS3_OK;
          vattr_to_wcc_data(bvap, avap, &resp->resok.file_wcc);
          resp->resok.count = args->count - uio.uio_resid;
          resp->resok.committed = args->stable;
!         resp->resok.verf = write3verf;
          goto out;
  
  err:
          if (curthread->t_flag & T_WOULDBLOCK) {
                  curthread->t_flag &= ~T_WOULDBLOCK;
--- 1527,1537 ----
  
          resp->status = NFS3_OK;
          vattr_to_wcc_data(bvap, avap, &resp->resok.file_wcc);
          resp->resok.count = args->count - uio.uio_resid;
          resp->resok.committed = args->stable;
!         resp->resok.verf = ns->write3verf;
          goto out;
  
  err:
          if (curthread->t_flag & T_WOULDBLOCK) {
                  curthread->t_flag &= ~T_WOULDBLOCK;
*** 1495,1506 ****
          } else
                  resp->status = puterrno3(error);
  err1:
          vattr_to_wcc_data(bvap, avap, &resp->resfail.file_wcc);
  out:
!         DTRACE_NFSV3_4(op__write__done, struct svc_req *, req,
!             cred_t *, cr, vnode_t *, vp, WRITE3res *, resp);
  
          if (vp != NULL) {
                  if (rwlock_ret != -1)
                          VOP_RWUNLOCK(vp, V_WRITELOCK_TRUE, &ct);
                  if (in_crit)
--- 1539,1551 ----
          } else
                  resp->status = puterrno3(error);
  err1:
          vattr_to_wcc_data(bvap, avap, &resp->resfail.file_wcc);
  out:
!         DTRACE_NFSV3_5(op__write__done, struct svc_req *, req,
!             cred_t *, cr, vnode_t *, vp, struct exportinfo *, exi,
!             WRITE3res *, resp);
  
          if (vp != NULL) {
                  if (rwlock_ret != -1)
                          VOP_RWUNLOCK(vp, V_WRITELOCK_TRUE, &ct);
                  if (in_crit)
*** 1541,1552 ****
          dbvap = NULL;
          davap = NULL;
  
          dvp = nfs3_fhtovp(&args->where.dir, exi);
  
!         DTRACE_NFSV3_4(op__create__start, struct svc_req *, req,
!             cred_t *, cr, vnode_t *, dvp, CREATE3args *, args);
  
          if (dvp == NULL) {
                  error = ESTALE;
                  goto out;
          }
--- 1586,1598 ----
          dbvap = NULL;
          davap = NULL;
  
          dvp = nfs3_fhtovp(&args->where.dir, exi);
  
!         DTRACE_NFSV3_5(op__create__start, struct svc_req *, req,
!             cred_t *, cr, vnode_t *, dvp, struct exportinfo *, exi,
!             CREATE3args *, args);
  
          if (dvp == NULL) {
                  error = ESTALE;
                  goto out;
          }
*** 1841,1852 ****
  
          resp->status = NFS3_OK;
          vattr_to_post_op_attr(vap, &resp->resok.obj_attributes);
          vattr_to_wcc_data(dbvap, davap, &resp->resok.dir_wcc);
  
!         DTRACE_NFSV3_4(op__create__done, struct svc_req *, req,
!             cred_t *, cr, vnode_t *, dvp, CREATE3res *, resp);
  
          VN_RELE(dvp);
          return;
  
  out:
--- 1887,1899 ----
  
          resp->status = NFS3_OK;
          vattr_to_post_op_attr(vap, &resp->resok.obj_attributes);
          vattr_to_wcc_data(dbvap, davap, &resp->resok.dir_wcc);
  
!         DTRACE_NFSV3_5(op__create__done, struct svc_req *, req,
!             cred_t *, cr, vnode_t *, dvp, struct exportinfo *, exi,
!             CREATE3res *, resp);
  
          VN_RELE(dvp);
          return;
  
  out:
*** 1854,1865 ****
                  curthread->t_flag &= ~T_WOULDBLOCK;
                  resp->status = NFS3ERR_JUKEBOX;
          } else
                  resp->status = puterrno3(error);
  out1:
!         DTRACE_NFSV3_4(op__create__done, struct svc_req *, req,
!             cred_t *, cr, vnode_t *, dvp, CREATE3res *, resp);
  
          if (name != NULL && name != args->where.name)
                  kmem_free(name, MAXPATHLEN + 1);
  
          if (tvp != NULL) {
--- 1901,1913 ----
                  curthread->t_flag &= ~T_WOULDBLOCK;
                  resp->status = NFS3ERR_JUKEBOX;
          } else
                  resp->status = puterrno3(error);
  out1:
!         DTRACE_NFSV3_5(op__create__done, struct svc_req *, req,
!             cred_t *, cr, vnode_t *, dvp, struct exportinfo *, exi,
!             CREATE3res *, resp);
  
          if (name != NULL && name != args->where.name)
                  kmem_free(name, MAXPATHLEN + 1);
  
          if (tvp != NULL) {
*** 1898,1909 ****
          dbvap = NULL;
          davap = NULL;
  
          dvp = nfs3_fhtovp(&args->where.dir, exi);
  
!         DTRACE_NFSV3_4(op__mkdir__start, struct svc_req *, req,
!             cred_t *, cr, vnode_t *, dvp, MKDIR3args *, args);
  
          if (dvp == NULL) {
                  error = ESTALE;
                  goto out;
          }
--- 1946,1958 ----
          dbvap = NULL;
          davap = NULL;
  
          dvp = nfs3_fhtovp(&args->where.dir, exi);
  
!         DTRACE_NFSV3_5(op__mkdir__start, struct svc_req *, req,
!             cred_t *, cr, vnode_t *, dvp, struct exportinfo *, exi,
!             MKDIR3args *, args);
  
          if (dvp == NULL) {
                  error = ESTALE;
                  goto out;
          }
*** 1998,2009 ****
  
          resp->status = NFS3_OK;
          vattr_to_post_op_attr(vap, &resp->resok.obj_attributes);
          vattr_to_wcc_data(dbvap, davap, &resp->resok.dir_wcc);
  
!         DTRACE_NFSV3_4(op__mkdir__done, struct svc_req *, req,
!             cred_t *, cr, vnode_t *, dvp, MKDIR3res *, resp);
          VN_RELE(dvp);
  
          return;
  
  out:
--- 2047,2059 ----
  
          resp->status = NFS3_OK;
          vattr_to_post_op_attr(vap, &resp->resok.obj_attributes);
          vattr_to_wcc_data(dbvap, davap, &resp->resok.dir_wcc);
  
!         DTRACE_NFSV3_5(op__mkdir__done, struct svc_req *, req,
!             cred_t *, cr, vnode_t *, dvp, struct exportinfo *, exi,
!             MKDIR3res *, resp);
          VN_RELE(dvp);
  
          return;
  
  out:
*** 2011,2022 ****
                  curthread->t_flag &= ~T_WOULDBLOCK;
                  resp->status = NFS3ERR_JUKEBOX;
          } else
                  resp->status = puterrno3(error);
  out1:
!         DTRACE_NFSV3_4(op__mkdir__done, struct svc_req *, req,
!             cred_t *, cr, vnode_t *, dvp, MKDIR3res *, resp);
          if (dvp != NULL)
                  VN_RELE(dvp);
          vattr_to_wcc_data(dbvap, davap, &resp->resfail.dir_wcc);
  }
  
--- 2061,2073 ----
                  curthread->t_flag &= ~T_WOULDBLOCK;
                  resp->status = NFS3ERR_JUKEBOX;
          } else
                  resp->status = puterrno3(error);
  out1:
!         DTRACE_NFSV3_5(op__mkdir__done, struct svc_req *, req,
!             cred_t *, cr, vnode_t *, dvp, struct exportinfo *, exi,
!             MKDIR3res *, resp);
          if (dvp != NULL)
                  VN_RELE(dvp);
          vattr_to_wcc_data(dbvap, davap, &resp->resfail.dir_wcc);
  }
  
*** 2047,2058 ****
          dbvap = NULL;
          davap = NULL;
  
          dvp = nfs3_fhtovp(&args->where.dir, exi);
  
!         DTRACE_NFSV3_4(op__symlink__start, struct svc_req *, req,
!             cred_t *, cr, vnode_t *, dvp, SYMLINK3args *, args);
  
          if (dvp == NULL) {
                  error = ESTALE;
                  goto err;
          }
--- 2098,2110 ----
          dbvap = NULL;
          davap = NULL;
  
          dvp = nfs3_fhtovp(&args->where.dir, exi);
  
!         DTRACE_NFSV3_5(op__symlink__start, struct svc_req *, req,
!             cred_t *, cr, vnode_t *, dvp, struct exportinfo *, exi,
!             SYMLINK3args *, args);
  
          if (dvp == NULL) {
                  error = ESTALE;
                  goto err;
          }
*** 2185,2196 ****
          if (name != NULL && name != args->where.name)
                  kmem_free(name, MAXPATHLEN + 1);
          if (symdata != NULL && symdata != args->symlink.symlink_data)
                  kmem_free(symdata, MAXPATHLEN + 1);
  
!         DTRACE_NFSV3_4(op__symlink__done, struct svc_req *, req,
!             cred_t *, cr, vnode_t *, dvp, SYMLINK3res *, resp);
  
          if (dvp != NULL)
                  VN_RELE(dvp);
  }
  
--- 2237,2249 ----
          if (name != NULL && name != args->where.name)
                  kmem_free(name, MAXPATHLEN + 1);
          if (symdata != NULL && symdata != args->symlink.symlink_data)
                  kmem_free(symdata, MAXPATHLEN + 1);
  
!         DTRACE_NFSV3_5(op__symlink__done, struct svc_req *, req,
!             cred_t *, cr, vnode_t *, dvp, struct exportinfo *, exi,
!             SYMLINK3res *, resp);
  
          if (dvp != NULL)
                  VN_RELE(dvp);
  }
  
*** 2223,2234 ****
          dbvap = NULL;
          davap = NULL;
  
          dvp = nfs3_fhtovp(&args->where.dir, exi);
  
!         DTRACE_NFSV3_4(op__mknod__start, struct svc_req *, req,
!             cred_t *, cr, vnode_t *, dvp, MKNOD3args *, args);
  
          if (dvp == NULL) {
                  error = ESTALE;
                  goto out;
          }
--- 2276,2288 ----
          dbvap = NULL;
          davap = NULL;
  
          dvp = nfs3_fhtovp(&args->where.dir, exi);
  
!         DTRACE_NFSV3_5(op__mknod__start, struct svc_req *, req,
!             cred_t *, cr, vnode_t *, dvp, struct exportinfo *, exi,
!             MKNOD3args *, args);
  
          if (dvp == NULL) {
                  error = ESTALE;
                  goto out;
          }
*** 2370,2381 ****
  
          VN_RELE(vp);
  
          vattr_to_post_op_attr(vap, &resp->resok.obj_attributes);
          vattr_to_wcc_data(dbvap, davap, &resp->resok.dir_wcc);
!         DTRACE_NFSV3_4(op__mknod__done, struct svc_req *, req,
!             cred_t *, cr, vnode_t *, dvp, MKNOD3res *, resp);
          VN_RELE(dvp);
          return;
  
  out:
          if (curthread->t_flag & T_WOULDBLOCK) {
--- 2424,2436 ----
  
          VN_RELE(vp);
  
          vattr_to_post_op_attr(vap, &resp->resok.obj_attributes);
          vattr_to_wcc_data(dbvap, davap, &resp->resok.dir_wcc);
!         DTRACE_NFSV3_5(op__mknod__done, struct svc_req *, req,
!             cred_t *, cr, vnode_t *, dvp, struct exportinfo *, exi,
!             MKNOD3res *, resp);
          VN_RELE(dvp);
          return;
  
  out:
          if (curthread->t_flag & T_WOULDBLOCK) {
*** 2382,2393 ****
                  curthread->t_flag &= ~T_WOULDBLOCK;
                  resp->status = NFS3ERR_JUKEBOX;
          } else
                  resp->status = puterrno3(error);
  out1:
!         DTRACE_NFSV3_4(op__mknod__done, struct svc_req *, req,
!             cred_t *, cr, vnode_t *, dvp, MKNOD3res *, resp);
          if (dvp != NULL)
                  VN_RELE(dvp);
          vattr_to_wcc_data(dbvap, davap, &resp->resfail.dir_wcc);
  }
  
--- 2437,2449 ----
                  curthread->t_flag &= ~T_WOULDBLOCK;
                  resp->status = NFS3ERR_JUKEBOX;
          } else
                  resp->status = puterrno3(error);
  out1:
!         DTRACE_NFSV3_5(op__mknod__done, struct svc_req *, req,
!             cred_t *, cr, vnode_t *, dvp, struct exportinfo *, exi,
!             MKNOD3res *, resp);
          if (dvp != NULL)
                  VN_RELE(dvp);
          vattr_to_wcc_data(dbvap, davap, &resp->resfail.dir_wcc);
  }
  
*** 2415,2426 ****
          bvap = NULL;
          avap = NULL;
  
          vp = nfs3_fhtovp(&args->object.dir, exi);
  
!         DTRACE_NFSV3_4(op__remove__start, struct svc_req *, req,
!             cred_t *, cr, vnode_t *, vp, REMOVE3args *, args);
  
          if (vp == NULL) {
                  error = ESTALE;
                  goto err;
          }
--- 2471,2483 ----
          bvap = NULL;
          avap = NULL;
  
          vp = nfs3_fhtovp(&args->object.dir, exi);
  
!         DTRACE_NFSV3_5(op__remove__start, struct svc_req *, req,
!             cred_t *, cr, vnode_t *, vp, struct exportinfo *, exi,
!             REMOVE3args *, args);
  
          if (vp == NULL) {
                  error = ESTALE;
                  goto err;
          }
*** 2524,2535 ****
          } else
                  resp->status = puterrno3(error);
  err1:
          vattr_to_wcc_data(bvap, avap, &resp->resfail.dir_wcc);
  out:
!         DTRACE_NFSV3_4(op__remove__done, struct svc_req *, req,
!             cred_t *, cr, vnode_t *, vp, REMOVE3res *, resp);
  
          if (name != NULL && name != args->object.name)
                  kmem_free(name, MAXPATHLEN + 1);
  
          if (vp != NULL)
--- 2581,2593 ----
          } else
                  resp->status = puterrno3(error);
  err1:
          vattr_to_wcc_data(bvap, avap, &resp->resfail.dir_wcc);
  out:
!         DTRACE_NFSV3_5(op__remove__done, struct svc_req *, req,
!             cred_t *, cr, vnode_t *, vp, struct exportinfo *, exi,
!             REMOVE3res *, resp);
  
          if (name != NULL && name != args->object.name)
                  kmem_free(name, MAXPATHLEN + 1);
  
          if (vp != NULL)
*** 2559,2570 ****
          bvap = NULL;
          avap = NULL;
  
          vp = nfs3_fhtovp(&args->object.dir, exi);
  
!         DTRACE_NFSV3_4(op__rmdir__start, struct svc_req *, req,
!             cred_t *, cr, vnode_t *, vp, RMDIR3args *, args);
  
          if (vp == NULL) {
                  error = ESTALE;
                  goto err;
          }
--- 2617,2629 ----
          bvap = NULL;
          avap = NULL;
  
          vp = nfs3_fhtovp(&args->object.dir, exi);
  
!         DTRACE_NFSV3_5(op__rmdir__start, struct svc_req *, req,
!             cred_t *, cr, vnode_t *, vp, struct exportinfo *, exi,
!             RMDIR3args *, args);
  
          if (vp == NULL) {
                  error = ESTALE;
                  goto err;
          }
*** 2616,2626 ****
          if (name == NULL) {
                  resp->status = NFS3ERR_INVAL;
                  goto err1;
          }
  
!         error = VOP_RMDIR(vp, name, rootdir, cr, NULL, 0);
  
          if (name != args->object.name)
                  kmem_free(name, MAXPATHLEN + 1);
  
          ava.va_mask = AT_ALL;
--- 2675,2686 ----
          if (name == NULL) {
                  resp->status = NFS3ERR_INVAL;
                  goto err1;
          }
  
!         ASSERT3U(exi->exi_zoneid, ==, curzone->zone_id);
!         error = VOP_RMDIR(vp, name, ZONE_ROOTVP(), cr, NULL, 0);
  
          if (name != args->object.name)
                  kmem_free(name, MAXPATHLEN + 1);
  
          ava.va_mask = AT_ALL;
*** 2654,2665 ****
          } else
                  resp->status = puterrno3(error);
  err1:
          vattr_to_wcc_data(bvap, avap, &resp->resfail.dir_wcc);
  out:
!         DTRACE_NFSV3_4(op__rmdir__done, struct svc_req *, req,
!             cred_t *, cr, vnode_t *, vp, RMDIR3res *, resp);
          if (vp != NULL)
                  VN_RELE(vp);
  
  }
  
--- 2714,2726 ----
          } else
                  resp->status = puterrno3(error);
  err1:
          vattr_to_wcc_data(bvap, avap, &resp->resfail.dir_wcc);
  out:
!         DTRACE_NFSV3_5(op__rmdir__done, struct svc_req *, req,
!             cred_t *, cr, vnode_t *, vp, struct exportinfo *, exi,
!             RMDIR3res *, resp);
          if (vp != NULL)
                  VN_RELE(vp);
  
  }
  
*** 2700,2711 ****
          tavap = NULL;
          tvp = NULL;
  
          fvp = nfs3_fhtovp(&args->from.dir, exi);
  
!         DTRACE_NFSV3_4(op__rename__start, struct svc_req *, req,
!             cred_t *, cr, vnode_t *, fvp, RENAME3args *, args);
  
          if (fvp == NULL) {
                  error = ESTALE;
                  goto err;
          }
--- 2761,2773 ----
          tavap = NULL;
          tvp = NULL;
  
          fvp = nfs3_fhtovp(&args->from.dir, exi);
  
!         DTRACE_NFSV3_5(op__rename__start, struct svc_req *, req,
!             cred_t *, cr, vnode_t *, fvp, struct exportinfo *, exi,
!             RENAME3args *, args);
  
          if (fvp == NULL) {
                  error = ESTALE;
                  goto err;
          }
*** 2818,2831 ****
                  resp->status = NFS3ERR_JUKEBOX;
                  goto err1;
          }
  
          /*
!          * Check for renaming over a delegated file.  Check rfs4_deleg_policy
           * first to avoid VOP_LOOKUP if possible.
           */
!         if (rfs4_deleg_policy != SRV_NEVER_DELEGATE &&
              VOP_LOOKUP(tvp, toname, &targvp, NULL, 0, NULL, cr,
              NULL, NULL, NULL) == 0) {
  
                  if (rfs4_check_delegated(FWRITE, targvp, TRUE)) {
                          VN_RELE(targvp);
--- 2880,2893 ----
                  resp->status = NFS3ERR_JUKEBOX;
                  goto err1;
          }
  
          /*
!          * Check for renaming over a delegated file.  Check nfs4_deleg_policy
           * first to avoid VOP_LOOKUP if possible.
           */
!         if (nfs4_get_deleg_policy() != SRV_NEVER_DELEGATE &&
              VOP_LOOKUP(tvp, toname, &targvp, NULL, 0, NULL, cr,
              NULL, NULL, NULL) == 0) {
  
                  if (rfs4_check_delegated(FWRITE, targvp, TRUE)) {
                          VN_RELE(targvp);
*** 2885,2896 ****
          if (name != NULL && name != args->from.name)
                  kmem_free(name, MAXPATHLEN + 1);
          if (toname != NULL && toname != args->to.name)
                  kmem_free(toname, MAXPATHLEN + 1);
  
!         DTRACE_NFSV3_4(op__rename__done, struct svc_req *, req,
!             cred_t *, cr, vnode_t *, fvp, RENAME3res *, resp);
          if (fvp != NULL)
                  VN_RELE(fvp);
          if (tvp != NULL)
                  VN_RELE(tvp);
  }
--- 2947,2959 ----
          if (name != NULL && name != args->from.name)
                  kmem_free(name, MAXPATHLEN + 1);
          if (toname != NULL && toname != args->to.name)
                  kmem_free(toname, MAXPATHLEN + 1);
  
!         DTRACE_NFSV3_5(op__rename__done, struct svc_req *, req,
!             cred_t *, cr, vnode_t *, fvp, struct exportinfo *, exi,
!             RENAME3res *, resp);
          if (fvp != NULL)
                  VN_RELE(fvp);
          if (tvp != NULL)
                  VN_RELE(tvp);
  }
*** 2926,2937 ****
          avap = NULL;
          dvp = NULL;
  
          vp = nfs3_fhtovp(&args->file, exi);
  
!         DTRACE_NFSV3_4(op__link__start, struct svc_req *, req,
!             cred_t *, cr, vnode_t *, vp, LINK3args *, args);
  
          if (vp == NULL) {
                  error = ESTALE;
                  goto out;
          }
--- 2989,3001 ----
          avap = NULL;
          dvp = NULL;
  
          vp = nfs3_fhtovp(&args->file, exi);
  
!         DTRACE_NFSV3_5(op__link__start, struct svc_req *, req,
!             cred_t *, cr, vnode_t *, vp, struct exportinfo *, exi,
!             LINK3args *, args);
  
          if (vp == NULL) {
                  error = ESTALE;
                  goto out;
          }
*** 3039,3050 ****
  
          resp->status = NFS3_OK;
          vattr_to_post_op_attr(vap, &resp->resok.file_attributes);
          vattr_to_wcc_data(bvap, avap, &resp->resok.linkdir_wcc);
  
!         DTRACE_NFSV3_4(op__link__done, struct svc_req *, req,
!             cred_t *, cr, vnode_t *, vp, LINK3res *, resp);
  
          VN_RELE(vp);
  
          return;
  
--- 3103,3115 ----
  
          resp->status = NFS3_OK;
          vattr_to_post_op_attr(vap, &resp->resok.file_attributes);
          vattr_to_wcc_data(bvap, avap, &resp->resok.linkdir_wcc);
  
!         DTRACE_NFSV3_5(op__link__done, struct svc_req *, req,
!             cred_t *, cr, vnode_t *, vp, struct exportinfo *, exi,
!             LINK3res *, resp);
  
          VN_RELE(vp);
  
          return;
  
*** 3056,3067 ****
                  resp->status = puterrno3(error);
  out1:
          if (name != NULL && name != args->link.name)
                  kmem_free(name, MAXPATHLEN + 1);
  
!         DTRACE_NFSV3_4(op__link__done, struct svc_req *, req,
!             cred_t *, cr, vnode_t *, vp, LINK3res *, resp);
  
          if (vp != NULL)
                  VN_RELE(vp);
          if (dvp != NULL)
                  VN_RELE(dvp);
--- 3121,3133 ----
                  resp->status = puterrno3(error);
  out1:
          if (name != NULL && name != args->link.name)
                  kmem_free(name, MAXPATHLEN + 1);
  
!         DTRACE_NFSV3_5(op__link__done, struct svc_req *, req,
!             cred_t *, cr, vnode_t *, vp, struct exportinfo *, exi,
!             LINK3res *, resp);
  
          if (vp != NULL)
                  VN_RELE(vp);
          if (dvp != NULL)
                  VN_RELE(dvp);
*** 3125,3136 ****
  
          vap = NULL;
  
          vp = nfs3_fhtovp(&args->dir, exi);
  
!         DTRACE_NFSV3_4(op__readdir__start, struct svc_req *, req,
!             cred_t *, cr, vnode_t *, vp, READDIR3args *, args);
  
          if (vp == NULL) {
                  error = ESTALE;
                  goto out;
          }
--- 3191,3203 ----
  
          vap = NULL;
  
          vp = nfs3_fhtovp(&args->dir, exi);
  
!         DTRACE_NFSV3_5(op__readdir__start, struct svc_req *, req,
!             cred_t *, cr, vnode_t *, vp, struct exportinfo *, exi,
!             READDIR3args *, args);
  
          if (vp == NULL) {
                  error = ESTALE;
                  goto out;
          }
*** 3290,3301 ****
          resp->resok.reply.eof = iseof;
          resp->resok.size = count - uio.uio_resid;
          resp->resok.count = args->count;
          resp->resok.freecount = count;
  
!         DTRACE_NFSV3_4(op__readdir__done, struct svc_req *, req,
!             cred_t *, cr, vnode_t *, vp, READDIR3res *, resp);
  
          VN_RELE(vp);
  
          return;
  
--- 3357,3369 ----
          resp->resok.reply.eof = iseof;
          resp->resok.size = count - uio.uio_resid;
          resp->resok.count = args->count;
          resp->resok.freecount = count;
  
!         DTRACE_NFSV3_5(op__readdir__done, struct svc_req *, req,
!             cred_t *, cr, vnode_t *, vp, struct exportinfo *, exi,
!             READDIR3res *, resp);
  
          VN_RELE(vp);
  
          return;
  
*** 3304,3316 ****
                  curthread->t_flag &= ~T_WOULDBLOCK;
                  resp->status = NFS3ERR_JUKEBOX;
          } else
                  resp->status = puterrno3(error);
  out1:
!         DTRACE_NFSV3_4(op__readdir__done, struct svc_req *, req,
!             cred_t *, cr, vnode_t *, vp, READDIR3res *, resp);
  
          if (vp != NULL) {
                  VOP_RWUNLOCK(vp, V_WRITELOCK_FALSE, NULL);
                  VN_RELE(vp);
          }
          vattr_to_post_op_attr(vap, &resp->resfail.dir_attributes);
--- 3372,3387 ----
                  curthread->t_flag &= ~T_WOULDBLOCK;
                  resp->status = NFS3ERR_JUKEBOX;
          } else
                  resp->status = puterrno3(error);
  out1:
!         vattr_to_post_op_attr(vap, &resp->resfail.dir_attributes);
  
+         DTRACE_NFSV3_5(op__readdir__done, struct svc_req *, req,
+             cred_t *, cr, vnode_t *, vp, struct exportinfo *, exi,
+             READDIR3res *, resp);
+ 
          if (vp != NULL) {
                  VOP_RWUNLOCK(vp, V_WRITELOCK_FALSE, NULL);
                  VN_RELE(vp);
          }
          vattr_to_post_op_attr(vap, &resp->resfail.dir_attributes);
*** 3396,3407 ****
  
          vap = NULL;
  
          vp = nfs3_fhtovp(&args->dir, exi);
  
!         DTRACE_NFSV3_4(op__readdirplus__start, struct svc_req *, req,
!             cred_t *, cr, vnode_t *, vp, READDIRPLUS3args *, args);
  
          if (vp == NULL) {
                  error = ESTALE;
                  goto out;
          }
--- 3467,3479 ----
  
          vap = NULL;
  
          vp = nfs3_fhtovp(&args->dir, exi);
  
!         DTRACE_NFSV3_5(op__readdirplus__start, struct svc_req *, req,
!             cred_t *, cr, vnode_t *, vp, struct exportinfo *, exi,
!             READDIRPLUS3args *, args);
  
          if (vp == NULL) {
                  error = ESTALE;
                  goto out;
          }
*** 3679,3694 ****
          resp->resok.reply.eof = iseof;
          resp->resok.size = nents;
          resp->resok.count = args->dircount - ret;
          resp->resok.maxcount = args->maxcount;
  
!         DTRACE_NFSV3_4(op__readdirplus__done, struct svc_req *, req,
!             cred_t *, cr, vnode_t *, vp, READDIRPLUS3res *, resp);
!         if (ndata != data)
!                 kmem_free(data, args->dircount);
  
- 
          VN_RELE(vp);
  
          return;
  
  out:
--- 3751,3764 ----
          resp->resok.reply.eof = iseof;
          resp->resok.size = nents;
          resp->resok.count = args->dircount - ret;
          resp->resok.maxcount = args->maxcount;
  
!         DTRACE_NFSV3_5(op__readdirplus__done, struct svc_req *, req,
!             cred_t *, cr, vnode_t *, vp, struct exportinfo *, exi,
!             READDIRPLUS3res *, resp);
  
          VN_RELE(vp);
  
          return;
  
  out:
*** 3697,3709 ****
                  resp->status = NFS3ERR_JUKEBOX;
          } else {
                  resp->status = puterrno3(error);
          }
  out1:
!         DTRACE_NFSV3_4(op__readdirplus__done, struct svc_req *, req,
!             cred_t *, cr, vnode_t *, vp, READDIRPLUS3res *, resp);
  
          if (vp != NULL) {
                  VOP_RWUNLOCK(vp, V_WRITELOCK_FALSE, NULL);
                  VN_RELE(vp);
          }
  
--- 3767,3782 ----
                  resp->status = NFS3ERR_JUKEBOX;
          } else {
                  resp->status = puterrno3(error);
          }
  out1:
!         vattr_to_post_op_attr(vap, &resp->resfail.dir_attributes);
  
+         DTRACE_NFSV3_5(op__readdirplus__done, struct svc_req *, req,
+             cred_t *, cr, vnode_t *, vp, struct exportinfo *, exi,
+             READDIRPLUS3res *, resp);
+ 
          if (vp != NULL) {
                  VOP_RWUNLOCK(vp, V_WRITELOCK_FALSE, NULL);
                  VN_RELE(vp);
          }
  
*** 3744,3755 ****
  
          vap = NULL;
  
          vp = nfs3_fhtovp(&args->fsroot, exi);
  
!         DTRACE_NFSV3_4(op__fsstat__start, struct svc_req *, req,
!             cred_t *, cr, vnode_t *, vp, FSSTAT3args *, args);
  
          if (vp == NULL) {
                  error = ESTALE;
                  goto out;
          }
--- 3817,3829 ----
  
          vap = NULL;
  
          vp = nfs3_fhtovp(&args->fsroot, exi);
  
!         DTRACE_NFSV3_5(op__fsstat__start, struct svc_req *, req,
!             cred_t *, cr, vnode_t *, vp, struct exportinfo *, exi,
!             FSSTAT3args *, args);
  
          if (vp == NULL) {
                  error = ESTALE;
                  goto out;
          }
*** 3795,3806 ****
          resp->resok.tfiles = (size3)sb.f_files;
          resp->resok.ffiles = (size3)sb.f_ffree;
          resp->resok.afiles = (size3)sb.f_favail;
          resp->resok.invarsec = 0;
  
!         DTRACE_NFSV3_4(op__fsstat__done, struct svc_req *, req,
!             cred_t *, cr, vnode_t *, vp, FSSTAT3res *, resp);
          VN_RELE(vp);
  
          return;
  
  out:
--- 3869,3881 ----
          resp->resok.tfiles = (size3)sb.f_files;
          resp->resok.ffiles = (size3)sb.f_ffree;
          resp->resok.afiles = (size3)sb.f_favail;
          resp->resok.invarsec = 0;
  
!         DTRACE_NFSV3_5(op__fsstat__done, struct svc_req *, req,
!             cred_t *, cr, vnode_t *, vp, struct exportinfo *, exi,
!             FSSTAT3res *, resp);
          VN_RELE(vp);
  
          return;
  
  out:
*** 3808,3819 ****
                  curthread->t_flag &= ~T_WOULDBLOCK;
                  resp->status = NFS3ERR_JUKEBOX;
          } else
                  resp->status = puterrno3(error);
  out1:
!         DTRACE_NFSV3_4(op__fsstat__done, struct svc_req *, req,
!             cred_t *, cr, vnode_t *, vp, FSSTAT3res *, resp);
  
          if (vp != NULL)
                  VN_RELE(vp);
          vattr_to_post_op_attr(vap, &resp->resfail.obj_attributes);
  }
--- 3883,3895 ----
                  curthread->t_flag &= ~T_WOULDBLOCK;
                  resp->status = NFS3ERR_JUKEBOX;
          } else
                  resp->status = puterrno3(error);
  out1:
!         DTRACE_NFSV3_5(op__fsstat__done, struct svc_req *, req,
!             cred_t *, cr, vnode_t *, vp, struct exportinfo *, exi,
!             FSSTAT3res *, resp);
  
          if (vp != NULL)
                  VN_RELE(vp);
          vattr_to_post_op_attr(vap, &resp->resfail.obj_attributes);
  }
*** 3837,3848 ****
          ulong_t l = 0;
          int error;
  
          vp = nfs3_fhtovp(&args->fsroot, exi);
  
!         DTRACE_NFSV3_4(op__fsinfo__start, struct svc_req *, req,
!             cred_t *, cr, vnode_t *, vp, FSINFO3args *, args);
  
          if (vp == NULL) {
                  if (curthread->t_flag & T_WOULDBLOCK) {
                          curthread->t_flag &= ~T_WOULDBLOCK;
                          resp->status = NFS3ERR_JUKEBOX;
--- 3913,3925 ----
          ulong_t l = 0;
          int error;
  
          vp = nfs3_fhtovp(&args->fsroot, exi);
  
!         DTRACE_NFSV3_5(op__fsinfo__start, struct svc_req *, req,
!             cred_t *, cr, vnode_t *, vp, struct exportinfo *, exi,
!             FSINFO3args *, args);
  
          if (vp == NULL) {
                  if (curthread->t_flag & T_WOULDBLOCK) {
                          curthread->t_flag &= ~T_WOULDBLOCK;
                          resp->status = NFS3ERR_JUKEBOX;
*** 3912,3931 ****
          resp->resok.time_delta.seconds = 0;
          resp->resok.time_delta.nseconds = 1000;
          resp->resok.properties = FSF3_LINK | FSF3_SYMLINK |
              FSF3_HOMOGENEOUS | FSF3_CANSETTIME;
  
!         DTRACE_NFSV3_4(op__fsinfo__done, struct svc_req *, req,
!             cred_t *, cr, vnode_t *, vp, FSINFO3res *, resp);
  
          VN_RELE(vp);
  
          return;
  
  out:
!         DTRACE_NFSV3_4(op__fsinfo__done, struct svc_req *, req,
!             cred_t *, cr, vnode_t *, NULL, FSINFO3res *, resp);
          if (vp != NULL)
                  VN_RELE(vp);
  }
  
  void *
--- 3989,4010 ----
          resp->resok.time_delta.seconds = 0;
          resp->resok.time_delta.nseconds = 1000;
          resp->resok.properties = FSF3_LINK | FSF3_SYMLINK |
              FSF3_HOMOGENEOUS | FSF3_CANSETTIME;
  
!         DTRACE_NFSV3_5(op__fsinfo__done, struct svc_req *, req,
!             cred_t *, cr, vnode_t *, vp, struct exportinfo *, exi,
!             FSINFO3res *, resp);
  
          VN_RELE(vp);
  
          return;
  
  out:
!         DTRACE_NFSV3_5(op__fsinfo__done, struct svc_req *, req,
!             cred_t *, cr, vnode_t *, NULL, struct exportinfo *, exi,
!             FSINFO3res *, resp);
          if (vp != NULL)
                  VN_RELE(vp);
  }
  
  void *
*** 3947,3958 ****
  
          vap = NULL;
  
          vp = nfs3_fhtovp(&args->object, exi);
  
!         DTRACE_NFSV3_4(op__pathconf__start, struct svc_req *, req,
!             cred_t *, cr, vnode_t *, vp, PATHCONF3args *, args);
  
          if (vp == NULL) {
                  error = ESTALE;
                  goto out;
          }
--- 4026,4038 ----
  
          vap = NULL;
  
          vp = nfs3_fhtovp(&args->object, exi);
  
!         DTRACE_NFSV3_5(op__pathconf__start, struct svc_req *, req,
!             cred_t *, cr, vnode_t *, vp, struct exportinfo *, exi,
!             PATHCONF3args *, args);
  
          if (vp == NULL) {
                  error = ESTALE;
                  goto out;
          }
*** 4004,4015 ****
  
          resp->status = NFS3_OK;
          vattr_to_post_op_attr(vap, &resp->resok.obj_attributes);
          resp->resok.info.case_insensitive = FALSE;
          resp->resok.info.case_preserving = TRUE;
!         DTRACE_NFSV3_4(op__pathconf__done, struct svc_req *, req,
!             cred_t *, cr, vnode_t *, vp, PATHCONF3res *, resp);
          VN_RELE(vp);
          return;
  
  out:
          if (curthread->t_flag & T_WOULDBLOCK) {
--- 4084,4096 ----
  
          resp->status = NFS3_OK;
          vattr_to_post_op_attr(vap, &resp->resok.obj_attributes);
          resp->resok.info.case_insensitive = FALSE;
          resp->resok.info.case_preserving = TRUE;
!         DTRACE_NFSV3_5(op__pathconf__done, struct svc_req *, req,
!             cred_t *, cr, vnode_t *, vp, struct exportinfo *, exi,
!             PATHCONF3res *, resp);
          VN_RELE(vp);
          return;
  
  out:
          if (curthread->t_flag & T_WOULDBLOCK) {
*** 4016,4027 ****
                  curthread->t_flag &= ~T_WOULDBLOCK;
                  resp->status = NFS3ERR_JUKEBOX;
          } else
                  resp->status = puterrno3(error);
  out1:
!         DTRACE_NFSV3_4(op__pathconf__done, struct svc_req *, req,
!             cred_t *, cr, vnode_t *, vp, PATHCONF3res *, resp);
          if (vp != NULL)
                  VN_RELE(vp);
          vattr_to_post_op_attr(vap, &resp->resfail.obj_attributes);
  }
  
--- 4097,4109 ----
                  curthread->t_flag &= ~T_WOULDBLOCK;
                  resp->status = NFS3ERR_JUKEBOX;
          } else
                  resp->status = puterrno3(error);
  out1:
!         DTRACE_NFSV3_5(op__pathconf__done, struct svc_req *, req,
!             cred_t *, cr, vnode_t *, vp, struct exportinfo *, exi,
!             PATHCONF3res *, resp);
          if (vp != NULL)
                  VN_RELE(vp);
          vattr_to_post_op_attr(vap, &resp->resfail.obj_attributes);
  }
  
*** 4034,4043 ****
--- 4116,4126 ----
  
  void
  rfs3_commit(COMMIT3args *args, COMMIT3res *resp, struct exportinfo *exi,
      struct svc_req *req, cred_t *cr, bool_t ro)
  {
+         nfs3_srv_t *ns;
          int error;
          vnode_t *vp;
          struct vattr *bvap;
          struct vattr bva;
          struct vattr *avap;
*** 4046,4063 ****
          bvap = NULL;
          avap = NULL;
  
          vp = nfs3_fhtovp(&args->file, exi);
  
!         DTRACE_NFSV3_4(op__commit__start, struct svc_req *, req,
!             cred_t *, cr, vnode_t *, vp, COMMIT3args *, args);
  
          if (vp == NULL) {
                  error = ESTALE;
                  goto out;
          }
  
          bva.va_mask = AT_ALL;
          error = VOP_GETATTR(vp, &bva, 0, cr, NULL);
  
          /*
           * If we can't get the attributes, then we can't do the
--- 4129,4149 ----
          bvap = NULL;
          avap = NULL;
  
          vp = nfs3_fhtovp(&args->file, exi);
  
!         DTRACE_NFSV3_5(op__commit__start, struct svc_req *, req,
!             cred_t *, cr, vnode_t *, vp, struct exportinfo *, exi,
!             COMMIT3args *, args);
  
          if (vp == NULL) {
                  error = ESTALE;
                  goto out;
          }
  
+         ASSERT3U(curzone->zone_id, ==, exi->exi_zoneid); /* exi is non-NULL. */
+         ns = nfs3_get_srv();
          bva.va_mask = AT_ALL;
          error = VOP_GETATTR(vp, &bva, 0, cr, NULL);
  
          /*
           * If we can't get the attributes, then we can't do the
*** 4106,4119 ****
          if (error)
                  goto out;
  
          resp->status = NFS3_OK;
          vattr_to_wcc_data(bvap, avap, &resp->resok.file_wcc);
!         resp->resok.verf = write3verf;
  
!         DTRACE_NFSV3_4(op__commit__done, struct svc_req *, req,
!             cred_t *, cr, vnode_t *, vp, COMMIT3res *, resp);
  
          VN_RELE(vp);
  
          return;
  
--- 4192,4206 ----
          if (error)
                  goto out;
  
          resp->status = NFS3_OK;
          vattr_to_wcc_data(bvap, avap, &resp->resok.file_wcc);
!         resp->resok.verf = ns->write3verf;
  
!         DTRACE_NFSV3_5(op__commit__done, struct svc_req *, req,
!             cred_t *, cr, vnode_t *, vp, struct exportinfo *, exi,
!             COMMIT3res *, resp);
  
          VN_RELE(vp);
  
          return;
  
*** 4122,4133 ****
                  curthread->t_flag &= ~T_WOULDBLOCK;
                  resp->status = NFS3ERR_JUKEBOX;
          } else
                  resp->status = puterrno3(error);
  out1:
!         DTRACE_NFSV3_4(op__commit__done, struct svc_req *, req,
!             cred_t *, cr, vnode_t *, vp, COMMIT3res *, resp);
  
          if (vp != NULL)
                  VN_RELE(vp);
          vattr_to_wcc_data(bvap, avap, &resp->resfail.file_wcc);
  }
--- 4209,4221 ----
                  curthread->t_flag &= ~T_WOULDBLOCK;
                  resp->status = NFS3ERR_JUKEBOX;
          } else
                  resp->status = puterrno3(error);
  out1:
!         DTRACE_NFSV3_5(op__commit__done, struct svc_req *, req,
!             cred_t *, cr, vnode_t *, vp, struct exportinfo *, exi,
!             COMMIT3res *, resp);
  
          if (vp != NULL)
                  VN_RELE(vp);
          vattr_to_wcc_data(bvap, avap, &resp->resfail.file_wcc);
  }
*** 4201,4211 ****
          }
  
          return (0);
  }
  
! static ftype3 vt_to_nf3[] = {
          0, NF3REG, NF3DIR, NF3BLK, NF3CHR, NF3LNK, NF3FIFO, 0, 0, NF3SOCK, 0
  };
  
  static int
  vattr_to_fattr3(struct vattr *vap, fattr3 *fap)
--- 4289,4299 ----
          }
  
          return (0);
  }
  
! static const ftype3 vt_to_nf3[] = {
          0, NF3REG, NF3DIR, NF3BLK, NF3CHR, NF3LNK, NF3FIFO, 0, 0, NF3SOCK, 0
  };
  
  static int
  vattr_to_fattr3(struct vattr *vap, fattr3 *fap)
*** 4283,4306 ****
  }
  
  static void
  vattr_to_wcc_data(struct vattr *bvap, struct vattr *avap, wcc_data *wccp)
  {
- 
          vattr_to_pre_op_attr(bvap, &wccp->before);
          vattr_to_post_op_attr(avap, &wccp->after);
  }
  
  void
! rfs3_srvrinit(void)
  {
          struct rfs3_verf_overlay {
                  uint_t id; /* a "unique" identifier */
                  int ts; /* a unique timestamp */
          } *verfp;
          timestruc_t now;
  
          /*
           * The following algorithm attempts to find a unique verifier
           * to be used as the write verifier returned from the server
           * to the client.  It is important that this verifier change
           * whenever the server reboots.  Of secondary importance, it
--- 4371,4413 ----
  }
  
  static void
  vattr_to_wcc_data(struct vattr *bvap, struct vattr *avap, wcc_data *wccp)
  {
          vattr_to_pre_op_attr(bvap, &wccp->before);
          vattr_to_post_op_attr(avap, &wccp->after);
  }
  
+ static int
+ rdma_setup_read_data3(READ3args *args, READ3resok *rok)
+ {
+         struct clist    *wcl;
+         int             wlist_len;
+         count3          count = rok->count;
+ 
+         wcl = args->wlist;
+         if (rdma_setup_read_chunks(wcl, count, &wlist_len) == FALSE)
+                 return (FALSE);
+ 
+         wcl = args->wlist;
+         rok->wlist_len = wlist_len;
+         rok->wlist = wcl;
+         return (TRUE);
+ }
+ 
  void
! rfs3_srv_zone_init(nfs_globals_t *ng)
  {
+         nfs3_srv_t *ns;
          struct rfs3_verf_overlay {
                  uint_t id; /* a "unique" identifier */
                  int ts; /* a unique timestamp */
          } *verfp;
          timestruc_t now;
  
+         ns = kmem_zalloc(sizeof (*ns), KM_SLEEP);
+ 
          /*
           * The following algorithm attempts to find a unique verifier
           * to be used as the write verifier returned from the server
           * to the client.  It is important that this verifier change
           * whenever the server reboots.  Of secondary importance, it
*** 4320,4362 ****
  #ifndef lint
          /*
           * We ASSERT that this constant logic expression is
           * always true because in the past, it wasn't.
           */
!         ASSERT(sizeof (*verfp) <= sizeof (write3verf));
  #endif
  
          gethrestime(&now);
!         verfp = (struct rfs3_verf_overlay *)&write3verf;
          verfp->ts = (int)now.tv_sec;
          verfp->id = zone_get_hostid(NULL);
  
          if (verfp->id == 0)
                  verfp->id = (uint_t)now.tv_nsec;
  
!         nfs3_srv_caller_id = fs_new_caller_id();
! 
  }
  
! static int
! rdma_setup_read_data3(READ3args *args, READ3resok *rok)
  {
!         struct clist    *wcl;
!         int             wlist_len;
!         count3          count = rok->count;
  
!         wcl = args->wlist;
!         if (rdma_setup_read_chunks(wcl, count, &wlist_len) == FALSE) {
!                 return (FALSE);
!         }
  
!         wcl = args->wlist;
!         rok->wlist_len = wlist_len;
!         rok->wlist = wcl;
!         return (TRUE);
  }
  
  void
  rfs3_srvrfini(void)
  {
          /* Nothing to do */
  }
--- 4427,4466 ----
  #ifndef lint
          /*
           * We ASSERT that this constant logic expression is
           * always true because in the past, it wasn't.
           */
!         ASSERT(sizeof (*verfp) <= sizeof (ns->write3verf));
  #endif
  
          gethrestime(&now);
!         verfp = (struct rfs3_verf_overlay *)&ns->write3verf;
          verfp->ts = (int)now.tv_sec;
          verfp->id = zone_get_hostid(NULL);
  
          if (verfp->id == 0)
                  verfp->id = (uint_t)now.tv_nsec;
  
!         ng->nfs3_srv = ns;
  }
  
! void
! rfs3_srv_zone_fini(nfs_globals_t *ng)
  {
!         nfs3_srv_t *ns = ng->nfs3_srv;
  
!         ng->nfs3_srv = NULL;
  
!         kmem_free(ns, sizeof (*ns));
  }
  
+ void
+ rfs3_srvrinit(void)
+ {
+         nfs3_srv_caller_id = fs_new_caller_id();
+ }
+ 
  void
  rfs3_srvrfini(void)
  {
          /* Nothing to do */
  }