Print this page
Try to remove assumption that zone's root vnode is marked VROOT
@@ -140,11 +140,11 @@
* directories is added to filter lookup and readdir results
* to only contain dirnames which lead to descendant shares.
*
* A visible list has a per-file-system scope. Any exportinfo
* struct (real or pseudo) can have a visible list as long as
- * a) its export root is VROOT
+ * a) its export root is VROOT, or is the zone's root for in-zone NFS service
* b) a descendant of the export root is shared
*/
struct exportinfo *
pseudo_exportfs(nfs_export_t *ne, vnode_t *vp, fid_t *fid, struct exp_visible *vis_head,
struct exportdata *exdata)
@@ -656,14 +656,15 @@
error = vop_fid_pseudo(vp, &fid);
if (error)
break;
/*
- * The root of the file system needs special handling
+ * The root of the file system, or the zone's root for
+ * in-zone NFS service needs special handling
*/
- if (vp->v_flag & VROOT) {
- if (! exportdir) {
+ if (vp->v_flag & VROOT || VN_IS_CURZONEROOT(vp)) {
+ if (!exportdir) {
struct exportinfo *exi;
/*
* Check if this VROOT dir is already exported.
* If so, then attach the pseudonodes. If not,
@@ -693,11 +694,11 @@
new_exi = pseudo_exportfs(ne, vp, &fid,
vis_head, NULL);
vis_head = NULL;
}
- if (VN_CMP(vp, ZONE_ROOTVP())) {
+ if (VN_IS_CURZONEROOT(vp)) {
/* at system root */
/*
* If sharing "/", new_exi is shared exportinfo
* (exip). Otherwise, new_exi is exportinfo
* created by pseudo_exportfs() above.
@@ -823,11 +824,11 @@
*
* Deleting of nodes will start only if the unshared
* node was a leaf node.
* Deleting of nodes will finish when we reach a node which
* has children or is a real export, then we might still need
- * to continue releasing visibles, until we reach VROOT node.
+ * to continue releasing visibles, until we reach VROOT or zone's root node.
*/
void
treeclimb_unexport(nfs_export_t *ne, struct exportinfo *exip)
{
treenode_t *tnode, *old_nd;
@@ -845,11 +846,14 @@
if (tnode->tree_vis != NULL) /* system root has tree_vis == NULL */
tnode->tree_vis->vis_exported = 0;
while (tnode != NULL) {
- /* Stop at VROOT node which is exported or has child */
+ /*
+ * Stop at VROOT (or zone root) node which is exported or has
+ * child.
+ */
if (TREE_ROOT(tnode) &&
(TREE_EXPORTED(tnode) || tnode->tree_child_first != NULL))
break;
/* Release pseudo export if it has no child */
@@ -893,11 +897,11 @@
{
vnode_t *tvp, *nextvp;
tvp = vp;
for (;;) {
- if (! (tvp->v_flag & VROOT))
+ if (!(tvp->v_flag & VROOT) && !VN_IS_CURZONEROOT(tvp))
break;
/* lock vfs to prevent unmount of this vfs */
vfs_lock_wait(tvp->v_vfsp);
@@ -924,11 +928,11 @@
return (tvp);
}
/*
* Given an exportinfo, climb up to find the exportinfo for the VROOT
- * of the filesystem.
+ * (or zone root) of the filesystem.
*
* e.g. /
* |
* a (VROOT) pseudo-exportinfo
* |
@@ -973,16 +977,18 @@
bool_t vp_is_exported;
vp_is_exported = VN_CMP(vp, exi->exi_vp);
/*
- * An exported root vnode has a sub-dir shared if it has a visible list.
- * i.e. if it does not have a visible list, then there is no node in
- * this filesystem leads to any other shared node.
+ * An exported root vnode has a sub-dir shared if it has a visible
+ * list. i.e. if it does not have a visible list, then there is no
+ * node in this filesystem leads to any other shared node.
*/
- if (vp_is_exported && (vp->v_flag & VROOT))
+ if (vp_is_exported &&
+ ((vp->v_flag & VROOT) || VN_IS_CURZONEROOT(vp))) {
return (exi->exi_visible ? 1 : 0);
+ }
/*
* Only the exportinfo of a fs root node may have a visible list.
* Either it is a pseudo root node, or a real exported root node.
*/
@@ -1051,11 +1057,11 @@
/*
* Only a PSEUDO node has a visible list or an exported VROOT
* node may have a visible list.
*/
- if (! PSEUDO(exi))
+ if (!PSEUDO(exi))
exi = get_root_export(exi);
/* Get the fid of the vnode */
bzero(&fid, sizeof (fid));
@@ -1159,11 +1165,11 @@
{
/*
* Only a PSEUDO node has a visible list or an exported VROOT
* node may have a visible list.
*/
- if (! PSEUDO(exi))
+ if (!PSEUDO(exi))
exi = get_root_export(exi);
for (*visp = exi->exi_visible; *visp != NULL; *visp = (*visp)->vis_next)
if ((u_longlong_t)ino == (*visp)->vis_ino) {
return (1);