--- old/usr/src/uts/common/fs/nfs/nfs4_state.c	Fri Oct 11 18:09:10 2019
+++ new/usr/src/uts/common/fs/nfs/nfs4_state.c	Fri Oct 11 18:09:10 2019
@@ -1133,7 +1133,7 @@
 rfs4_clear_client_state(struct nfs4clrst_args *clr)
 {
 	nfs4_srv_t *nsrv4;
-	nsrv4 = zone_getspecific(rfs4_zone_key, curzone);
+	nsrv4 = nfs4_get_srv();
 	(void) rfs4_dbe_walk(nsrv4->rfs4_client_tab, rfs4_client_scrub, clr);
 }
 
@@ -1492,7 +1492,7 @@
 {
 	rfs4_database_t *dbp;
 	nfs4_srv_t *nsrv4;
-	nsrv4 = zone_getspecific(rfs4_zone_key, curzone);
+	nsrv4 = nfs4_get_srv();
 
 	rfs4_set_deleg_policy(nsrv4, SRV_NEVER_DELEGATE);
 
@@ -1668,7 +1668,7 @@
 	 * from all server instances.
 	 */
 
-	nsrv4 = zone_getspecific(rfs4_zone_key, curzone);
+	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 */
@@ -1744,7 +1744,7 @@
 	scid_confirm_verf *scvp;
 	nfs4_srv_t *nsrv4;
 
-	nsrv4 = zone_getspecific(rfs4_zone_key, curzone);
+	nsrv4 = nfs4_get_srv();
 
 	/* Get a clientid to give to the client */
 	cidp = (cid *)&cp->rc_clientid;
@@ -1838,7 +1838,7 @@
 {
 	rfs4_client_t *cp;
 	nfs4_srv_t *nsrv4;
-	nsrv4 = zone_getspecific(rfs4_zone_key, curzone);
+	nsrv4 = nfs4_get_srv();
 
 
 	if (oldcp) {
@@ -1865,7 +1865,7 @@
 	rfs4_client_t *cp;
 	bool_t create = FALSE;
 	cid *cidp = (cid *)&clientid;
-	nfs4_srv_t *nsrv4 = zone_getspecific(rfs4_zone_key, curzone);
+	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))
@@ -1986,7 +1986,7 @@
 	rfs4_clntip_t *cp;
 	nfs4_srv_t *nsrv4;
 
-	nsrv4 = zone_getspecific(rfs4_zone_key, curzone);
+	nsrv4 = nfs4_get_srv();
 
 	rw_enter(&nsrv4->rfs4_findclient_lock, RW_READER);
 
@@ -2003,7 +2003,7 @@
 {
 	rfs4_clntip_t *cp;
 	bool_t create = FALSE;
-	nfs4_srv_t *nsrv4 = zone_getspecific(rfs4_zone_key, curzone);
+	nfs4_srv_t *nsrv4 = nfs4_get_srv();
 
 	rw_enter(&nsrv4->rfs4_findclient_lock, RW_READER);
 
@@ -2164,7 +2164,7 @@
 	seqid4 seqid = argp->ro_open_seqid;
 	rfs4_client_t *cp;
 	bool_t create = FALSE;
-	nfs4_srv_t *nsrv4 = zone_getspecific(rfs4_zone_key, curzone);
+	nfs4_srv_t *nsrv4 = nfs4_get_srv();
 
 	rw_enter(&nsrv4->rfs4_findclient_lock, RW_READER);
 
@@ -2214,7 +2214,7 @@
 {
 	rfs4_openowner_t *oo;
 	rfs4_openowner_t arg;
-	nfs4_srv_t *nsrv4 = zone_getspecific(rfs4_zone_key, curzone);
+	nfs4_srv_t *nsrv4 = nfs4_get_srv();
 
 	arg.ro_owner = *openowner;
 	arg.ro_open_seqid = seqid;
@@ -2362,7 +2362,7 @@
 	lock_owner4 *lockowner = (lock_owner4 *)arg;
 	rfs4_client_t *cp;
 	bool_t create = FALSE;
-	nfs4_srv_t *nsrv4 = zone_getspecific(rfs4_zone_key, curzone);
+	nfs4_srv_t *nsrv4 = nfs4_get_srv();
 
 	rw_enter(&nsrv4->rfs4_findclient_lock, RW_READER);
 
@@ -2391,7 +2391,7 @@
 rfs4_findlockowner(lock_owner4 *lockowner, bool_t *create)
 {
 	rfs4_lockowner_t *lo;
-	nfs4_srv_t *nsrv4 = zone_getspecific(rfs4_zone_key, curzone);
+	nfs4_srv_t *nsrv4 = nfs4_get_srv();
 
 	/* CSTYLED */
 	lo = (rfs4_lockowner_t *)rfs4_dbsearch(nsrv4->rfs4_lockowner_idx, lockowner,
@@ -2405,7 +2405,7 @@
 {
 	rfs4_lockowner_t *lo;
 	bool_t create = FALSE;
-	nfs4_srv_t *nsrv4 = zone_getspecific(rfs4_zone_key, curzone);
+	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);
@@ -2518,7 +2518,7 @@
 {
 	rfs4_file_t *fp;
 	rfs4_fcreate_arg arg;
-	nfs4_srv_t *nsrv4 = zone_getspecific(rfs4_zone_key, curzone);
+	nfs4_srv_t *nsrv4 = nfs4_get_srv();
 
 	arg.vp = vp;
 	arg.fh = fh;
@@ -2560,7 +2560,7 @@
 	rfs4_file_t *fp;
 	rfs4_fcreate_arg arg;
 	bool_t screate = *create;
-	nfs4_srv_t *nsrv4 = zone_getspecific(rfs4_zone_key, curzone);
+	nfs4_srv_t *nsrv4 = nfs4_get_srv();
 
 	if (screate == FALSE) {
 		mutex_enter(&vp->v_vsd_lock);
@@ -2747,7 +2747,7 @@
 {
 	rfs4_lo_state_t *lsp;
 	bool_t create = FALSE;
-	nfs4_srv_t *nsrv4 = zone_getspecific(rfs4_zone_key, curzone);
+	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);
@@ -2788,7 +2788,7 @@
 {
 	rfs4_lo_state_t *lsp;
 	rfs4_lo_state_t arg;
-	nfs4_srv_t *nsrv4 = zone_getspecific(rfs4_zone_key, curzone);
+	nfs4_srv_t *nsrv4 = nfs4_get_srv();
 
 	arg.rls_locker = lo;
 	arg.rls_state = sp;
@@ -2805,7 +2805,7 @@
 	stateid_t id;
 	nfs4_srv_t *nsrv4;
 
-	nsrv4 = zone_getspecific(rfs4_zone_key, curzone);
+	nsrv4 = nfs4_get_srv();
 
 	id.bits.boottime = nsrv4->rfs4_start_time;
 	id.bits.ident = eid;
@@ -3063,7 +3063,7 @@
 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);
+	nfs4_srv_t *nsrv4 = nfs4_get_srv();
 
 	ds.rds_client = sp->rs_owner->ro_client;
 	ds.rds_finfo = sp->rs_finfo;
@@ -3079,7 +3079,7 @@
 {
 	rfs4_deleg_state_t *dsp;
 	bool_t create = FALSE;
-	nfs4_srv_t *nsrv4 = zone_getspecific(rfs4_zone_key, curzone);
+	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);
@@ -3201,7 +3201,7 @@
 {
 	rfs4_state_t *sp;
 	rfs4_state_t key;
-	nfs4_srv_t *nsrv4 = zone_getspecific(rfs4_zone_key, curzone);
+	nfs4_srv_t *nsrv4 = nfs4_get_srv();
 
 	key.rs_owner = oo;
 	key.rs_finfo = fp;
@@ -3217,7 +3217,7 @@
 rfs4_findstate_by_file(rfs4_file_t *fp)
 {
 	bool_t create = FALSE;
-	nfs4_srv_t *nsrv4 = zone_getspecific(rfs4_zone_key, curzone);
+	nfs4_srv_t *nsrv4 = nfs4_get_srv();
 
 	return ((rfs4_state_t *)rfs4_dbsearch(nsrv4->rfs4_state_file_idx, fp,
 	    &create, fp, RFS4_DBS_VALID));
@@ -3270,7 +3270,7 @@
 {
 	rfs4_state_t *sp;
 	bool_t create = FALSE;
-	nfs4_srv_t *nsrv4 = zone_getspecific(rfs4_zone_key, curzone);
+	nfs4_srv_t *nsrv4 = nfs4_get_srv();
 
 	sp = (rfs4_state_t *)rfs4_dbsearch(nsrv4->rfs4_state_idx, id,
 	    &create, NULL, find_invalid);
@@ -3342,7 +3342,7 @@
 	cid *cidp = (cid *) cp;
 	nfs4_srv_t *nsrv4;
 
-	nsrv4 = zone_getspecific(rfs4_zone_key, curzone);
+	nsrv4 = nfs4_get_srv();
 
 	/*
 	 * If we are booted as a cluster node, check the embedded nodeid.
@@ -3374,7 +3374,7 @@
 {
 	nfs4_srv_t *nsrv4;
 
-	nsrv4 = zone_getspecific(rfs4_zone_key, curzone);
+	nsrv4 = nfs4_get_srv();
 
 	/* If we are booted as a cluster node, was stateid locally generated? */
 	if ((cluster_bootflags & CLUSTER_BOOTED) && foreign_stateid(id))
@@ -4108,17 +4108,21 @@
  * 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(struct exportinfo *exi)
+rfs4_clean_state_exi(nfs_export_t *ne, struct exportinfo *exi)
 {
+	nfs_globals_t *ng;
 	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;
+	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) {
@@ -4126,11 +4130,11 @@
 		return;
 	}
 
-	/* CSTYLED */
-	rfs4_dbe_walk(nsrv4->rfs4_lo_state_tab, rfs4_lo_state_walk_callout, exi);
+	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_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);
