Print this page
Fix NFS design problems re. multiple zone keys
Make NFS server zone-specific data all have the same lifetime
Fix rfs4_clean_state_exi
Fix exi_cache_reclaim
Fix mistakes in zone keys work
More fixes re. exi_zoneid and exi_tree
(danmcd -> Keep some ASSERT()s around for readability.)
        
*** 1131,1141 ****
   */
  void
  rfs4_clear_client_state(struct nfs4clrst_args *clr)
  {
          nfs4_srv_t *nsrv4;
!         nsrv4 = zone_getspecific(rfs4_zone_key, curzone);
          (void) rfs4_dbe_walk(nsrv4->rfs4_client_tab, rfs4_client_scrub, clr);
  }
  
  /*
   * Used to initialize the NFSv4 server's state or database.  All of
--- 1131,1141 ----
   */
  void
  rfs4_clear_client_state(struct nfs4clrst_args *clr)
  {
          nfs4_srv_t *nsrv4;
!         nsrv4 = nfs4_get_srv();
          (void) rfs4_dbe_walk(nsrv4->rfs4_client_tab, rfs4_client_scrub, clr);
  }
  
  /*
   * Used to initialize the NFSv4 server's state or database.  All of
*** 1490,1500 ****
  void
  rfs4_state_zone_fini()
  {
          rfs4_database_t *dbp;
          nfs4_srv_t *nsrv4;
!         nsrv4 = zone_getspecific(rfs4_zone_key, curzone);
  
          rfs4_set_deleg_policy(nsrv4, SRV_NEVER_DELEGATE);
  
          /*
           * Clean up any dangling stable storage structures BEFORE calling
--- 1490,1500 ----
  void
  rfs4_state_zone_fini()
  {
          rfs4_database_t *dbp;
          nfs4_srv_t *nsrv4;
!         nsrv4 = nfs4_get_srv();
  
          rfs4_set_deleg_policy(nsrv4, SRV_NEVER_DELEGATE);
  
          /*
           * Clean up any dangling stable storage structures BEFORE calling
*** 1666,1676 ****
           * since the state files are written to all DSS
           * paths we must remove this leaf file instance
           * from all server instances.
           */
  
!         nsrv4 = zone_getspecific(rfs4_zone_key, curzone);
          mutex_enter(&nsrv4->servinst_lock);
          for (sip = nsrv4->nfs4_cur_servinst; sip != NULL; sip = sip->prev) {
                  /* remove the leaf file associated with this server instance */
                  rfs4_dss_remove_leaf(sip, NFS4_DSS_STATE_LEAF, leaf);
          }
--- 1666,1676 ----
           * since the state files are written to all DSS
           * paths we must remove this leaf file instance
           * from all server instances.
           */
  
!         nsrv4 = nfs4_get_srv();
          mutex_enter(&nsrv4->servinst_lock);
          for (sip = nsrv4->nfs4_cur_servinst; sip != NULL; sip = sip->prev) {
                  /* remove the leaf file associated with this server instance */
                  rfs4_dss_remove_leaf(sip, NFS4_DSS_STATE_LEAF, leaf);
          }
*** 1742,1752 ****
          struct sockaddr *ca;
          cid *cidp;
          scid_confirm_verf *scvp;
          nfs4_srv_t *nsrv4;
  
!         nsrv4 = zone_getspecific(rfs4_zone_key, curzone);
  
          /* Get a clientid to give to the client */
          cidp = (cid *)&cp->rc_clientid;
          cidp->impl_id.start_time = nsrv4->rfs4_start_time;
          cidp->impl_id.c_id = (uint32_t)rfs4_dbe_getid(cp->rc_dbe);
--- 1742,1752 ----
          struct sockaddr *ca;
          cid *cidp;
          scid_confirm_verf *scvp;
          nfs4_srv_t *nsrv4;
  
!         nsrv4 = nfs4_get_srv();
  
          /* Get a clientid to give to the client */
          cidp = (cid *)&cp->rc_clientid;
          cidp->impl_id.start_time = nsrv4->rfs4_start_time;
          cidp->impl_id.c_id = (uint32_t)rfs4_dbe_getid(cp->rc_dbe);
*** 1836,1846 ****
  rfs4_client_t *
  rfs4_findclient(nfs_client_id4 *client, bool_t *create, rfs4_client_t *oldcp)
  {
          rfs4_client_t *cp;
          nfs4_srv_t *nsrv4;
!         nsrv4 = zone_getspecific(rfs4_zone_key, curzone);
  
  
          if (oldcp) {
                  rw_enter(&nsrv4->rfs4_findclient_lock, RW_WRITER);
                  rfs4_dbe_hide(oldcp->rc_dbe);
--- 1836,1846 ----
  rfs4_client_t *
  rfs4_findclient(nfs_client_id4 *client, bool_t *create, rfs4_client_t *oldcp)
  {
          rfs4_client_t *cp;
          nfs4_srv_t *nsrv4;
!         nsrv4 = nfs4_get_srv();
  
  
          if (oldcp) {
                  rw_enter(&nsrv4->rfs4_findclient_lock, RW_WRITER);
                  rfs4_dbe_hide(oldcp->rc_dbe);
*** 1863,1873 ****
  rfs4_findclient_by_id(clientid4 clientid, bool_t find_unconfirmed)
  {
          rfs4_client_t *cp;
          bool_t create = FALSE;
          cid *cidp = (cid *)&clientid;
!         nfs4_srv_t *nsrv4 = zone_getspecific(rfs4_zone_key, curzone);
  
          /* If we're a cluster and the nodeid isn't right, short-circuit */
          if (cluster_bootflags & CLUSTER_BOOTED && foreign_clientid(cidp))
                  return (NULL);
  
--- 1863,1873 ----
  rfs4_findclient_by_id(clientid4 clientid, bool_t find_unconfirmed)
  {
          rfs4_client_t *cp;
          bool_t create = FALSE;
          cid *cidp = (cid *)&clientid;
!         nfs4_srv_t *nsrv4 = nfs4_get_srv();
  
          /* If we're a cluster and the nodeid isn't right, short-circuit */
          if (cluster_bootflags & CLUSTER_BOOTED && foreign_clientid(cidp))
                  return (NULL);
  
*** 1984,1994 ****
  rfs4_find_clntip(struct sockaddr *addr, bool_t *create)
  {
          rfs4_clntip_t *cp;
          nfs4_srv_t *nsrv4;
  
!         nsrv4 = zone_getspecific(rfs4_zone_key, curzone);
  
          rw_enter(&nsrv4->rfs4_findclient_lock, RW_READER);
  
          cp = (rfs4_clntip_t *)rfs4_dbsearch(nsrv4->rfs4_clntip_idx, addr,
              create, addr, RFS4_DBS_VALID);
--- 1984,1994 ----
  rfs4_find_clntip(struct sockaddr *addr, bool_t *create)
  {
          rfs4_clntip_t *cp;
          nfs4_srv_t *nsrv4;
  
!         nsrv4 = nfs4_get_srv();
  
          rw_enter(&nsrv4->rfs4_findclient_lock, RW_READER);
  
          cp = (rfs4_clntip_t *)rfs4_dbsearch(nsrv4->rfs4_clntip_idx, addr,
              create, addr, RFS4_DBS_VALID);
*** 2001,2011 ****
  void
  rfs4_invalidate_clntip(struct sockaddr *addr)
  {
          rfs4_clntip_t *cp;
          bool_t create = FALSE;
!         nfs4_srv_t *nsrv4 = zone_getspecific(rfs4_zone_key, curzone);
  
          rw_enter(&nsrv4->rfs4_findclient_lock, RW_READER);
  
          cp = (rfs4_clntip_t *)rfs4_dbsearch(nsrv4->rfs4_clntip_idx, addr,
              &create, NULL, RFS4_DBS_VALID);
--- 2001,2011 ----
  void
  rfs4_invalidate_clntip(struct sockaddr *addr)
  {
          rfs4_clntip_t *cp;
          bool_t create = FALSE;
!         nfs4_srv_t *nsrv4 = nfs4_get_srv();
  
          rw_enter(&nsrv4->rfs4_findclient_lock, RW_READER);
  
          cp = (rfs4_clntip_t *)rfs4_dbsearch(nsrv4->rfs4_clntip_idx, addr,
              &create, NULL, RFS4_DBS_VALID);
*** 2162,2172 ****
          rfs4_openowner_t *argp = (rfs4_openowner_t *)arg;
          open_owner4 *openowner = &argp->ro_owner;
          seqid4 seqid = argp->ro_open_seqid;
          rfs4_client_t *cp;
          bool_t create = FALSE;
!         nfs4_srv_t *nsrv4 = zone_getspecific(rfs4_zone_key, curzone);
  
          rw_enter(&nsrv4->rfs4_findclient_lock, RW_READER);
  
          cp = (rfs4_client_t *)rfs4_dbsearch(nsrv4->rfs4_clientid_idx,
              &openowner->clientid,
--- 2162,2172 ----
          rfs4_openowner_t *argp = (rfs4_openowner_t *)arg;
          open_owner4 *openowner = &argp->ro_owner;
          seqid4 seqid = argp->ro_open_seqid;
          rfs4_client_t *cp;
          bool_t create = FALSE;
!         nfs4_srv_t *nsrv4 = nfs4_get_srv();
  
          rw_enter(&nsrv4->rfs4_findclient_lock, RW_READER);
  
          cp = (rfs4_client_t *)rfs4_dbsearch(nsrv4->rfs4_clientid_idx,
              &openowner->clientid,
*** 2212,2222 ****
  rfs4_openowner_t *
  rfs4_findopenowner(open_owner4 *openowner, bool_t *create, seqid4 seqid)
  {
          rfs4_openowner_t *oo;
          rfs4_openowner_t arg;
!         nfs4_srv_t *nsrv4 = zone_getspecific(rfs4_zone_key, curzone);
  
          arg.ro_owner = *openowner;
          arg.ro_open_seqid = seqid;
          /* CSTYLED */
          oo = (rfs4_openowner_t *)rfs4_dbsearch(nsrv4->rfs4_openowner_idx, openowner,
--- 2212,2222 ----
  rfs4_openowner_t *
  rfs4_findopenowner(open_owner4 *openowner, bool_t *create, seqid4 seqid)
  {
          rfs4_openowner_t *oo;
          rfs4_openowner_t arg;
!         nfs4_srv_t *nsrv4 = nfs4_get_srv();
  
          arg.ro_owner = *openowner;
          arg.ro_open_seqid = seqid;
          /* CSTYLED */
          oo = (rfs4_openowner_t *)rfs4_dbsearch(nsrv4->rfs4_openowner_idx, openowner,
*** 2360,2370 ****
  {
          rfs4_lockowner_t *lo = (rfs4_lockowner_t *)u_entry;
          lock_owner4 *lockowner = (lock_owner4 *)arg;
          rfs4_client_t *cp;
          bool_t create = FALSE;
!         nfs4_srv_t *nsrv4 = zone_getspecific(rfs4_zone_key, curzone);
  
          rw_enter(&nsrv4->rfs4_findclient_lock, RW_READER);
  
          cp = (rfs4_client_t *)rfs4_dbsearch(nsrv4->rfs4_clientid_idx,
              &lockowner->clientid,
--- 2360,2370 ----
  {
          rfs4_lockowner_t *lo = (rfs4_lockowner_t *)u_entry;
          lock_owner4 *lockowner = (lock_owner4 *)arg;
          rfs4_client_t *cp;
          bool_t create = FALSE;
!         nfs4_srv_t *nsrv4 = nfs4_get_srv();
  
          rw_enter(&nsrv4->rfs4_findclient_lock, RW_READER);
  
          cp = (rfs4_client_t *)rfs4_dbsearch(nsrv4->rfs4_clientid_idx,
              &lockowner->clientid,
*** 2389,2399 ****
  
  rfs4_lockowner_t *
  rfs4_findlockowner(lock_owner4 *lockowner, bool_t *create)
  {
          rfs4_lockowner_t *lo;
!         nfs4_srv_t *nsrv4 = zone_getspecific(rfs4_zone_key, curzone);
  
          /* CSTYLED */
          lo = (rfs4_lockowner_t *)rfs4_dbsearch(nsrv4->rfs4_lockowner_idx, lockowner,
              create, lockowner, RFS4_DBS_VALID);
  
--- 2389,2399 ----
  
  rfs4_lockowner_t *
  rfs4_findlockowner(lock_owner4 *lockowner, bool_t *create)
  {
          rfs4_lockowner_t *lo;
!         nfs4_srv_t *nsrv4 = nfs4_get_srv();
  
          /* CSTYLED */
          lo = (rfs4_lockowner_t *)rfs4_dbsearch(nsrv4->rfs4_lockowner_idx, lockowner,
              create, lockowner, RFS4_DBS_VALID);
  
*** 2403,2413 ****
  rfs4_lockowner_t *
  rfs4_findlockowner_by_pid(pid_t pid)
  {
          rfs4_lockowner_t *lo;
          bool_t create = FALSE;
!         nfs4_srv_t *nsrv4 = zone_getspecific(rfs4_zone_key, curzone);
  
          lo = (rfs4_lockowner_t *)rfs4_dbsearch(nsrv4->rfs4_lockowner_pid_idx,
              (void *)(uintptr_t)pid, &create, NULL, RFS4_DBS_VALID);
  
          return (lo);
--- 2403,2413 ----
  rfs4_lockowner_t *
  rfs4_findlockowner_by_pid(pid_t pid)
  {
          rfs4_lockowner_t *lo;
          bool_t create = FALSE;
!         nfs4_srv_t *nsrv4 = nfs4_get_srv();
  
          lo = (rfs4_lockowner_t *)rfs4_dbsearch(nsrv4->rfs4_lockowner_pid_idx,
              (void *)(uintptr_t)pid, &create, NULL, RFS4_DBS_VALID);
  
          return (lo);
*** 2516,2526 ****
  rfs4_file_t *
  rfs4_findfile(vnode_t *vp, nfs_fh4 *fh, bool_t *create)
  {
          rfs4_file_t *fp;
          rfs4_fcreate_arg arg;
!         nfs4_srv_t *nsrv4 = zone_getspecific(rfs4_zone_key, curzone);
  
          arg.vp = vp;
          arg.fh = fh;
  
          if (*create == TRUE)
--- 2516,2526 ----
  rfs4_file_t *
  rfs4_findfile(vnode_t *vp, nfs_fh4 *fh, bool_t *create)
  {
          rfs4_file_t *fp;
          rfs4_fcreate_arg arg;
!         nfs4_srv_t *nsrv4 = nfs4_get_srv();
  
          arg.vp = vp;
          arg.fh = fh;
  
          if (*create == TRUE)
*** 2558,2568 ****
  rfs4_findfile_withlock(vnode_t *vp, nfs_fh4 *fh, bool_t *create)
  {
          rfs4_file_t *fp;
          rfs4_fcreate_arg arg;
          bool_t screate = *create;
!         nfs4_srv_t *nsrv4 = zone_getspecific(rfs4_zone_key, curzone);
  
          if (screate == FALSE) {
                  mutex_enter(&vp->v_vsd_lock);
                  fp = (rfs4_file_t *)vsd_get(vp, nfs4_srv_vkey);
                  if (fp) {
--- 2558,2568 ----
  rfs4_findfile_withlock(vnode_t *vp, nfs_fh4 *fh, bool_t *create)
  {
          rfs4_file_t *fp;
          rfs4_fcreate_arg arg;
          bool_t screate = *create;
!         nfs4_srv_t *nsrv4 = nfs4_get_srv();
  
          if (screate == FALSE) {
                  mutex_enter(&vp->v_vsd_lock);
                  fp = (rfs4_file_t *)vsd_get(vp, nfs4_srv_vkey);
                  if (fp) {
*** 2745,2755 ****
  static rfs4_lo_state_t *
  rfs4_findlo_state(stateid_t *id, bool_t lock_fp)
  {
          rfs4_lo_state_t *lsp;
          bool_t create = FALSE;
!         nfs4_srv_t *nsrv4 = zone_getspecific(rfs4_zone_key, curzone);
  
          lsp = (rfs4_lo_state_t *)rfs4_dbsearch(nsrv4->rfs4_lo_state_idx, id,
              &create, NULL, RFS4_DBS_VALID);
          if (lock_fp == TRUE && lsp != NULL)
                  rw_enter(&lsp->rls_state->rs_finfo->rf_file_rwlock, RW_READER);
--- 2745,2755 ----
  static rfs4_lo_state_t *
  rfs4_findlo_state(stateid_t *id, bool_t lock_fp)
  {
          rfs4_lo_state_t *lsp;
          bool_t create = FALSE;
!         nfs4_srv_t *nsrv4 = nfs4_get_srv();
  
          lsp = (rfs4_lo_state_t *)rfs4_dbsearch(nsrv4->rfs4_lo_state_idx, id,
              &create, NULL, RFS4_DBS_VALID);
          if (lock_fp == TRUE && lsp != NULL)
                  rw_enter(&lsp->rls_state->rs_finfo->rf_file_rwlock, RW_READER);
*** 2786,2796 ****
  rfs4_findlo_state_by_owner(rfs4_lockowner_t *lo, rfs4_state_t *sp,
      bool_t *create)
  {
          rfs4_lo_state_t *lsp;
          rfs4_lo_state_t arg;
!         nfs4_srv_t *nsrv4 = zone_getspecific(rfs4_zone_key, curzone);
  
          arg.rls_locker = lo;
          arg.rls_state = sp;
  
          lsp = (rfs4_lo_state_t *)rfs4_dbsearch(nsrv4->rfs4_lo_state_owner_idx,
--- 2786,2796 ----
  rfs4_findlo_state_by_owner(rfs4_lockowner_t *lo, rfs4_state_t *sp,
      bool_t *create)
  {
          rfs4_lo_state_t *lsp;
          rfs4_lo_state_t arg;
!         nfs4_srv_t *nsrv4 = nfs4_get_srv();
  
          arg.rls_locker = lo;
          arg.rls_state = sp;
  
          lsp = (rfs4_lo_state_t *)rfs4_dbsearch(nsrv4->rfs4_lo_state_owner_idx,
*** 2803,2813 ****
  get_stateid(id_t eid)
  {
          stateid_t id;
          nfs4_srv_t *nsrv4;
  
!         nsrv4 = zone_getspecific(rfs4_zone_key, curzone);
  
          id.bits.boottime = nsrv4->rfs4_start_time;
          id.bits.ident = eid;
          id.bits.chgseq = 0;
          id.bits.type = 0;
--- 2803,2813 ----
  get_stateid(id_t eid)
  {
          stateid_t id;
          nfs4_srv_t *nsrv4;
  
!         nsrv4 = nfs4_get_srv();
  
          id.bits.boottime = nsrv4->rfs4_start_time;
          id.bits.ident = eid;
          id.bits.chgseq = 0;
          id.bits.type = 0;
*** 3061,3071 ****
  
  rfs4_deleg_state_t *
  rfs4_finddeleg(rfs4_state_t *sp, bool_t *create)
  {
          rfs4_deleg_state_t ds, *dsp;
!         nfs4_srv_t *nsrv4 = zone_getspecific(rfs4_zone_key, curzone);
  
          ds.rds_client = sp->rs_owner->ro_client;
          ds.rds_finfo = sp->rs_finfo;
  
          dsp = (rfs4_deleg_state_t *)rfs4_dbsearch(nsrv4->rfs4_deleg_idx, &ds,
--- 3061,3071 ----
  
  rfs4_deleg_state_t *
  rfs4_finddeleg(rfs4_state_t *sp, bool_t *create)
  {
          rfs4_deleg_state_t ds, *dsp;
!         nfs4_srv_t *nsrv4 = nfs4_get_srv();
  
          ds.rds_client = sp->rs_owner->ro_client;
          ds.rds_finfo = sp->rs_finfo;
  
          dsp = (rfs4_deleg_state_t *)rfs4_dbsearch(nsrv4->rfs4_deleg_idx, &ds,
*** 3077,3087 ****
  rfs4_deleg_state_t *
  rfs4_finddelegstate(stateid_t *id)
  {
          rfs4_deleg_state_t *dsp;
          bool_t create = FALSE;
!         nfs4_srv_t *nsrv4 = zone_getspecific(rfs4_zone_key, curzone);
  
          dsp = (rfs4_deleg_state_t *)rfs4_dbsearch(nsrv4->rfs4_deleg_state_idx,
              id, &create, NULL, RFS4_DBS_VALID);
  
          return (dsp);
--- 3077,3087 ----
  rfs4_deleg_state_t *
  rfs4_finddelegstate(stateid_t *id)
  {
          rfs4_deleg_state_t *dsp;
          bool_t create = FALSE;
!         nfs4_srv_t *nsrv4 = nfs4_get_srv();
  
          dsp = (rfs4_deleg_state_t *)rfs4_dbsearch(nsrv4->rfs4_deleg_state_idx,
              id, &create, NULL, RFS4_DBS_VALID);
  
          return (dsp);
*** 3199,3209 ****
  rfs4_findstate_by_owner_file(rfs4_openowner_t *oo, rfs4_file_t *fp,
      bool_t *create)
  {
          rfs4_state_t *sp;
          rfs4_state_t key;
!         nfs4_srv_t *nsrv4 = zone_getspecific(rfs4_zone_key, curzone);
  
          key.rs_owner = oo;
          key.rs_finfo = fp;
  
          sp = (rfs4_state_t *)rfs4_dbsearch(nsrv4->rfs4_state_owner_file_idx,
--- 3199,3209 ----
  rfs4_findstate_by_owner_file(rfs4_openowner_t *oo, rfs4_file_t *fp,
      bool_t *create)
  {
          rfs4_state_t *sp;
          rfs4_state_t key;
!         nfs4_srv_t *nsrv4 = nfs4_get_srv();
  
          key.rs_owner = oo;
          key.rs_finfo = fp;
  
          sp = (rfs4_state_t *)rfs4_dbsearch(nsrv4->rfs4_state_owner_file_idx,
*** 3215,3225 ****
  /* This returns ANY state struct that refers to this file */
  static rfs4_state_t *
  rfs4_findstate_by_file(rfs4_file_t *fp)
  {
          bool_t create = FALSE;
!         nfs4_srv_t *nsrv4 = zone_getspecific(rfs4_zone_key, curzone);
  
          return ((rfs4_state_t *)rfs4_dbsearch(nsrv4->rfs4_state_file_idx, fp,
              &create, fp, RFS4_DBS_VALID));
  }
  
--- 3215,3225 ----
  /* This returns ANY state struct that refers to this file */
  static rfs4_state_t *
  rfs4_findstate_by_file(rfs4_file_t *fp)
  {
          bool_t create = FALSE;
!         nfs4_srv_t *nsrv4 = nfs4_get_srv();
  
          return ((rfs4_state_t *)rfs4_dbsearch(nsrv4->rfs4_state_file_idx, fp,
              &create, fp, RFS4_DBS_VALID));
  }
  
*** 3268,3278 ****
  static rfs4_state_t *
  rfs4_findstate(stateid_t *id, rfs4_dbsearch_type_t find_invalid, bool_t lock_fp)
  {
          rfs4_state_t *sp;
          bool_t create = FALSE;
!         nfs4_srv_t *nsrv4 = zone_getspecific(rfs4_zone_key, curzone);
  
          sp = (rfs4_state_t *)rfs4_dbsearch(nsrv4->rfs4_state_idx, id,
              &create, NULL, find_invalid);
          if (lock_fp == TRUE && sp != NULL)
                  rw_enter(&sp->rs_finfo->rf_file_rwlock, RW_READER);
--- 3268,3278 ----
  static rfs4_state_t *
  rfs4_findstate(stateid_t *id, rfs4_dbsearch_type_t find_invalid, bool_t lock_fp)
  {
          rfs4_state_t *sp;
          bool_t create = FALSE;
!         nfs4_srv_t *nsrv4 = nfs4_get_srv();
  
          sp = (rfs4_state_t *)rfs4_dbsearch(nsrv4->rfs4_state_idx, id,
              &create, NULL, find_invalid);
          if (lock_fp == TRUE && sp != NULL)
                  rw_enter(&sp->rs_finfo->rf_file_rwlock, RW_READER);
*** 3340,3350 ****
  rfs4_check_clientid(clientid4 *cp, int setclid_confirm)
  {
          cid *cidp = (cid *) cp;
          nfs4_srv_t *nsrv4;
  
!         nsrv4 = zone_getspecific(rfs4_zone_key, curzone);
  
          /*
           * If we are booted as a cluster node, check the embedded nodeid.
           * If it indicates that this clientid was generated on another node,
           * inform the client accordingly.
--- 3340,3350 ----
  rfs4_check_clientid(clientid4 *cp, int setclid_confirm)
  {
          cid *cidp = (cid *) cp;
          nfs4_srv_t *nsrv4;
  
!         nsrv4 = nfs4_get_srv();
  
          /*
           * If we are booted as a cluster node, check the embedded nodeid.
           * If it indicates that this clientid was generated on another node,
           * inform the client accordingly.
*** 3372,3382 ****
  static nfsstat4
  what_stateid_error(stateid_t *id, stateid_type_t type)
  {
          nfs4_srv_t *nsrv4;
  
!         nsrv4 = zone_getspecific(rfs4_zone_key, curzone);
  
          /* If we are booted as a cluster node, was stateid locally generated? */
          if ((cluster_bootflags & CLUSTER_BOOTED) && foreign_stateid(id))
                  return (NFS4ERR_STALE_STATEID);
  
--- 3372,3382 ----
  static nfsstat4
  what_stateid_error(stateid_t *id, stateid_type_t type)
  {
          nfs4_srv_t *nsrv4;
  
!         nsrv4 = nfs4_get_srv();
  
          /* If we are booted as a cluster node, was stateid locally generated? */
          if ((cluster_bootflags & CLUSTER_BOOTED) && foreign_stateid(id))
                  return (NFS4ERR_STALE_STATEID);
  
*** 4106,4137 ****
  /*
   * Given a directory that is being unexported, cleanup/release all
   * state in the server that refers to objects residing underneath this
   * particular export.  The ordering of the release is important.
   * Lock_owner, then state and then file.
   */
  void
! rfs4_clean_state_exi(struct exportinfo *exi)
  {
          nfs4_srv_t *nsrv4;
  
!         /* curzone mightn't be exi_zone, so use exi_zone instead. */
!         ASSERT(exi->exi_zone == curzone || curzone == global_zone);
!         nsrv4 = zone_getspecific(rfs4_zone_key, exi->exi_zone);
!         if (nsrv4 == NULL) /* NOTE: NFSv4 cleanup MAY have already happened. */
!                 return;
          mutex_enter(&nsrv4->state_lock);
  
          if (nsrv4->nfs4_server_state == NULL) {
                  mutex_exit(&nsrv4->state_lock);
                  return;
          }
  
!         /* CSTYLED */
!         rfs4_dbe_walk(nsrv4->rfs4_lo_state_tab, rfs4_lo_state_walk_callout, exi);
          rfs4_dbe_walk(nsrv4->rfs4_state_tab, rfs4_state_walk_callout, exi);
!         /* CSTYLED */
!         rfs4_dbe_walk(nsrv4->rfs4_deleg_state_tab, rfs4_deleg_state_walk_callout, exi);
          rfs4_dbe_walk(nsrv4->rfs4_file_tab, rfs4_file_walk_callout, exi);
  
          mutex_exit(&nsrv4->state_lock);
  }
--- 4106,4141 ----
  /*
   * Given a directory that is being unexported, cleanup/release all
   * state in the server that refers to objects residing underneath this
   * particular export.  The ordering of the release is important.
   * Lock_owner, then state and then file.
+  *
+  * NFS zones note: nfs_export.c:unexport() calls this from a
+  * thread in the global zone for NGZ data structures, so we
+  * CANNOT use zone_getspecific anywhere in this code path.
   */
  void
! rfs4_clean_state_exi(nfs_export_t *ne, struct exportinfo *exi)
  {
+         nfs_globals_t *ng;
          nfs4_srv_t *nsrv4;
  
!         ng = ne->ne_globals;
!         ASSERT(ng->nfs_zoneid == exi->exi_zoneid);
!         nsrv4 = ng->nfs4_srv;
! 
          mutex_enter(&nsrv4->state_lock);
  
          if (nsrv4->nfs4_server_state == NULL) {
                  mutex_exit(&nsrv4->state_lock);
                  return;
          }
  
!         rfs4_dbe_walk(nsrv4->rfs4_lo_state_tab,
!             rfs4_lo_state_walk_callout, exi);
          rfs4_dbe_walk(nsrv4->rfs4_state_tab, rfs4_state_walk_callout, exi);
!         rfs4_dbe_walk(nsrv4->rfs4_deleg_state_tab,
!             rfs4_deleg_state_walk_callout, exi);
          rfs4_dbe_walk(nsrv4->rfs4_file_tab, rfs4_file_walk_callout, exi);
  
          mutex_exit(&nsrv4->state_lock);
  }