Print this page
Try to remove assumption that zone's root vnode is marked VROOT

*** 140,150 **** * 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 * 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) --- 140,150 ---- * 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, 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,669 **** error = vop_fid_pseudo(vp, &fid); if (error) break; /* ! * The root of the file system needs special handling */ ! if (vp->v_flag & VROOT) { ! if (! exportdir) { struct exportinfo *exi; /* * Check if this VROOT dir is already exported. * If so, then attach the pseudonodes. If not, --- 656,670 ---- error = vop_fid_pseudo(vp, &fid); if (error) break; /* ! * The root of the file system, or the zone's root for ! * in-zone NFS service needs special handling */ ! 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,703 **** new_exi = pseudo_exportfs(ne, vp, &fid, vis_head, NULL); vis_head = NULL; } ! if (VN_CMP(vp, ZONE_ROOTVP())) { /* at system root */ /* * If sharing "/", new_exi is shared exportinfo * (exip). Otherwise, new_exi is exportinfo * created by pseudo_exportfs() above. --- 694,704 ---- new_exi = pseudo_exportfs(ne, vp, &fid, vis_head, NULL); vis_head = NULL; } ! 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,833 **** * * 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. */ void treeclimb_unexport(nfs_export_t *ne, struct exportinfo *exip) { treenode_t *tnode, *old_nd; --- 824,834 ---- * * 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 or zone's root node. */ void treeclimb_unexport(nfs_export_t *ne, struct exportinfo *exip) { treenode_t *tnode, *old_nd;
*** 845,855 **** 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 */ if (TREE_ROOT(tnode) && (TREE_EXPORTED(tnode) || tnode->tree_child_first != NULL)) break; /* Release pseudo export if it has no child */ --- 846,859 ---- if (tnode->tree_vis != NULL) /* system root has tree_vis == NULL */ tnode->tree_vis->vis_exported = 0; while (tnode != NULL) { ! /* ! * 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,903 **** { vnode_t *tvp, *nextvp; tvp = vp; for (;;) { ! if (! (tvp->v_flag & VROOT)) break; /* lock vfs to prevent unmount of this vfs */ vfs_lock_wait(tvp->v_vfsp); --- 897,907 ---- { vnode_t *tvp, *nextvp; tvp = vp; for (;;) { ! 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,934 **** return (tvp); } /* * Given an exportinfo, climb up to find the exportinfo for the VROOT ! * of the filesystem. * * e.g. / * | * a (VROOT) pseudo-exportinfo * | --- 928,938 ---- return (tvp); } /* * Given an exportinfo, climb up to find the exportinfo for the VROOT ! * (or zone root) of the filesystem. * * e.g. / * | * a (VROOT) pseudo-exportinfo * |
*** 973,988 **** 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. */ ! if (vp_is_exported && (vp->v_flag & VROOT)) 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. */ --- 977,994 ---- 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. */ ! 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,1061 **** /* * Only a PSEUDO node has a visible list or an exported VROOT * node may have a visible list. */ ! if (! PSEUDO(exi)) exi = get_root_export(exi); /* Get the fid of the vnode */ bzero(&fid, sizeof (fid)); --- 1057,1067 ---- /* * Only a PSEUDO node has a visible list or an exported VROOT * node may have a visible list. */ ! if (!PSEUDO(exi)) exi = get_root_export(exi); /* Get the fid of the vnode */ bzero(&fid, sizeof (fid));
*** 1159,1169 **** { /* * Only a PSEUDO node has a visible list or an exported VROOT * node may have a visible list. */ ! 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); --- 1165,1175 ---- { /* * Only a PSEUDO node has a visible list or an exported VROOT * node may have a visible list. */ ! 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);