Print this page
Add VZONEROOT flag because not all zone roots have VROOT set.
        
@@ -2392,12 +2392,19 @@
         zone_free_datasets(zone);
         list_destroy(&zone->zone_dl_list);
 
         cpu_uarray_free(zone->zone_ustate);
 
-        if (zone->zone_rootvp != NULL)
-                VN_RELE(zone->zone_rootvp);
+        if (zone->zone_rootvp != NULL) {
+                vnode_t *vp = zone->zone_rootvp;
+
+                mutex_enter(&vp->v_lock);
+                vp->v_flag &= ~VZONEROOT;
+                mutex_exit(&vp->v_lock);
+                VN_RELE(vp);
+                /* No need to worry about NULL-ing out zone_rootvp. */
+        }
         if (zone->zone_rootpath)
                 kmem_free(zone->zone_rootpath, zone->zone_rootpathlen);
         if (zone->zone_name != NULL)
                 kmem_free(zone->zone_name, ZONENAME_MAX);
         if (zone->zone_slabel != NULL)
@@ -3476,10 +3483,20 @@
                 if (error != ESTALE)
                         goto out;
         }
 
         ASSERT(error == 0);
+        mutex_enter(&vp->v_lock);
+        if (vp->v_flag & VZONEROOT) {
+                /* Wow, someone's already using this zone root! */
+                error = EEXIST; /* XXX KEBE ASKS, better errno? */
+                mutex_exit(&vp->v_lock);
+                VN_RELE(vp);
+                goto out;
+        }
+        vp->v_flag |= VZONEROOT;
+        mutex_exit(&vp->v_lock);
         zone->zone_rootvp = vp;         /* we hold a reference to vp */
         zone->zone_rootpath = path;
         zone->zone_rootpathlen = pathlen;
         if (pathlen > 5 && strcmp(path + pathlen - 5, "/lu/") == 0)
                 zone->zone_flags |= ZF_IS_SCRATCH;
@@ -5367,11 +5384,16 @@
         /*
          * Release the root vnode; we're not using it anymore.  Nor should any
          * other thread that might access it exist.
          */
         if (zone->zone_rootvp != NULL) {
-                VN_RELE(zone->zone_rootvp);
+                vnode_t *vp = zone->zone_rootvp;
+
+                mutex_enter(&vp->v_lock);
+                vp->v_flag &= ~VZONEROOT;
+                mutex_exit(&vp->v_lock);
+                VN_RELE(vp);
                 zone->zone_rootvp = NULL;
         }
 
         /* add to deathrow list */
         mutex_enter(&zone_deathrow_lock);