Print this page
curzone reality check and teardown changes to use the RIGHT zone

@@ -479,11 +479,11 @@
  */
 
 #define TREE_ROOT(t) \
         ((t)->tree_exi != NULL && \
         (((t)->tree_exi->exi_vp->v_flag & VROOT) || \
-        VN_IS_CURZONEROOT((t)->tree_exi->exi_vp)))
+        VN_CMP((t)->tree_exi->exi_zone->zone_rootvp, (t)->tree_exi->exi_vp)))
 
 #define TREE_EXPORTED(t) \
         ((t)->tree_exi && !PSEUDO((t)->tree_exi))
 
 #define EXPTABLESIZE   256

@@ -531,17 +531,31 @@
         struct charset_cache    *exi_charset;
         unsigned                exi_volatile_dev:1;
         unsigned                exi_moved:1;
         int                     exi_id;
         avl_node_t              exi_id_link;
-        zoneid_t                exi_zoneid;
+        /*
+         * Soft-reference/backpointer to the zone.  The ZSD callbacks we have
+         * invoke cleanup code that crosses into OTHER cleanup functions that
+         * may assume same-zone context and attempt to find their own ZSD,
+         * using "curzone" when in fact "curzone" is global when called from
+         * NFS's ZSD cleanup (see lm_unexport->nlm_unexport for an example).
+         *
+         * During ZSD shutdown or destroy callbacks, the zone structure
+         * does not have its mutex held, and it has just-enough references
+         * to not free from underneath us.  This field is not a proper
+         * referenced-held zone pointer, and only ZSD callbacks should use
+         * it.
+         */
+        struct zone             *exi_zone;
 #ifdef VOLATILE_FH_TEST
         uint32_t                exi_volatile_id;
         struct ex_vol_rename    *exi_vol_rename;
         kmutex_t                exi_vol_rename_lock;
 #endif /* VOLATILE_FH_TEST */
 };
+#define exi_zoneid exi_zone->zone_id
 
 typedef struct exportinfo exportinfo_t;
 typedef struct exportdata exportdata_t;
 typedef struct secinfo secinfo_t;