Print this page
Untrip aggressive assert AND use EXI_TO_ZONEROOTVP
Revert exi_zone to exi_zoneid, and install exi_ne backpointer
Hyperaggressive asserts pt 1/N
Ooops exi_zoneid isn't a variable again yet
Be far more judicious in the use of curzone-using macros.
(Merge and extra asserts by danmcd.)
Bad assertions
nfs_export_zone_init() can't assume called in zone-context.
curzone reality check and teardown changes to use the RIGHT zone
Try to remove assumption that zone's root vnode is marked VROOT

@@ -700,20 +700,21 @@
                         exi_ret = tnode->tree_exi;
                         break;
                 }
         }
 
-        ASSERT(exi_ret); /* Every visible should have its home exportinfo */
+        /* Every visible should have its home exportinfo */
+        ASSERT(exi_ret != NULL);
         return (exi_ret);
 }
 
 /*
  * For NFS V4.
  * Add or remove the newly exported or unexported security flavors of the
  * given exportinfo from its ancestors upto the system root.
  */
-void
+static void
 srv_secinfo_treeclimb(nfs_export_t *ne, exportinfo_t *exip, secinfo_t *sec,
     int seccnt, bool_t isadd)
 {
         treenode_t *tnode;
 

@@ -740,10 +741,11 @@
          * its pseudonode.
          * Note - for VROOT exports the implicitly allowed flavors were
          * transferred from the PSEUDO export in exportfs()
          */
         if (isadd && !(exip->exi_vp->v_flag & VROOT) &&
+            !VN_CMP(exip->exi_vp, EXI_TO_ZONEROOTVP(exip)) &&
             tnode->tree_vis->vis_seccnt > 0) {
                 srv_secinfo_add(&exip->exi_export.ex_secinfo,
                     &exip->exi_export.ex_seccnt, tnode->tree_vis->vis_secinfo,
                     tnode->tree_vis->vis_seccnt, FALSE);
         }

@@ -805,18 +807,18 @@
 export_link(nfs_export_t *ne, exportinfo_t *exi)
 {
         exportinfo_t **bckt;
 
         ASSERT(RW_WRITE_HELD(&ne->exported_lock));
-        ASSERT(exi->exi_zoneid == ne->ne_globals->nfs_zoneid);
 
         bckt = &ne->exptable[exptablehash(&exi->exi_fsid, &exi->exi_fid)];
         exp_hash_link(exi, fid_hash, bckt);
 
         bckt = &ne->exptable_path_hash[pkp_tab_hash(exi->exi_export.ex_path,
             strlen(exi->exi_export.ex_path))];
         exp_hash_link(exi, path_hash, bckt);
+        exi->exi_ne = ne;
 }
 
 /*
  * Helper functions for exi_id handling
  */

@@ -889,10 +891,11 @@
 void
 nfs_export_zone_init(nfs_globals_t *ng)
 {
         int i;
         nfs_export_t *ne;
+        zone_t *zone;
 
         ne = kmem_zalloc(sizeof (*ne), KM_SLEEP);
 
         rw_init(&ne->exported_lock, NULL, RW_DEFAULT, NULL);
 

@@ -913,11 +916,22 @@
         ne->exi_root->exi_export.ex_path[1] = '\0';
 
         ne->exi_root->exi_count = 1;
         mutex_init(&ne->exi_root->exi_lock, NULL, MUTEX_DEFAULT, NULL);
 
-        ne->exi_root->exi_vp = ZONE_ROOTVP();
+        /*
+         * Because we cannot:
+         *      ASSERT(curzone->zone_id == ng->nfs_zoneid);
+         * We grab the zone pointer explicitly (like netstacks do) and
+         * set the rootvp here.
+         *
+         * Subsequent exportinfo_t's that get export_link()ed to "ne" also
+         * will backpoint to "ne" such that exi->exi_ne->exi_root->exi_vp
+         * will get the zone's rootvp for a given exportinfo_t.
+         */
+        zone = zone_find_by_id_nolock(ng->nfs_zoneid);
+        ne->exi_root->exi_vp = zone->zone_rootvp;
         ne->exi_root->exi_zoneid = ng->nfs_zoneid;
 
         /*
          * Fill in ne->exi_rootfid later, in nfs_export_get_rootfid
          * because we can't correctly return errors here.

@@ -1393,10 +1407,11 @@
         exi->exi_fsid = fsid;
         exi->exi_fid = fid;
         exi->exi_vp = vp;
         exi->exi_count = 1;
         exi->exi_zoneid = crgetzoneid(cr);
+        ASSERT3U(exi->exi_zoneid, ==, curzone->zone_id);
         exi->exi_volatile_dev = (vfssw[vp->v_vfsp->vfs_fstype].vsw_flag &
             VSW_VOLATILEDEV) ? 1 : 0;
         mutex_init(&exi->exi_lock, NULL, MUTEX_DEFAULT, NULL);
         exi->exi_dvp = dvp;
 

@@ -1862,10 +1877,12 @@
 {
         ASSERT(RW_WRITE_HELD(&ne->exported_lock));
 
         exp_hash_unlink(exi, fid_hash);
         exp_hash_unlink(exi, path_hash);
+        ASSERT3P(exi->exi_ne, ==, ne);
+        exi->exi_ne = NULL;
 }
 
 /*
  * Unexport an exported filesystem
  */

@@ -1935,10 +1952,15 @@
 
         /*
          * If this was a public export, restore
          * the public filehandle to the root.
          */
+
+        /*
+         * XXX KEBE ASKS --> Should CRED() instead be
+         * exi->exi_zone->zone_kcred?
+         */
         if (exi == ne->exi_public) {
                 ne->exi_public = ne->exi_root;
 
                 nfslog_share_record(ne->exi_public, CRED());
         }

@@ -2169,11 +2191,12 @@
                 /*
                  * We have just failed finding a matching export.
                  * If we're at the root of this filesystem, then
                  * it's time to stop (with failure).
                  */
-                if (vp->v_flag & VROOT) {
+                ASSERT3P(vp->v_vfsp->vfs_zone, ==, curzone);
+                if ((vp->v_flag & VROOT) || VN_IS_CURZONEROOT(vp)) {
                         error = EINVAL;
                         break;
                 }
 
                 if (walk != NULL)