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)