Print this page
Add VZONEROOT flag because not all zone roots have VROOT set.
        
*** 2392,2403 ****
          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_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)
--- 2392,2410 ----
          zone_free_datasets(zone);
          list_destroy(&zone->zone_dl_list);
  
          cpu_uarray_free(zone->zone_ustate);
  
!         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,3485 ****
--- 3483,3502 ----
                  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,5377 ****
          /*
           * 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);
                  zone->zone_rootvp = NULL;
          }
  
          /* add to deathrow list */
          mutex_enter(&zone_deathrow_lock);
--- 5384,5399 ----
          /*
           * 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) {
!                 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);