704 if (VN_IS_CURZONEROOT(vp)) {
705 /* at system root */
706 /*
707 * If sharing "/", new_exi is shared exportinfo
708 * (exip). Otherwise, new_exi is exportinfo
709 * created by pseudo_exportfs() above.
710 */
711 ne->ns_root = tree_prepend_node(tree_head, NULL,
712 new_exi);
713
714 /* Update the change timestamp */
715 tree_update_change(ne, ne->ns_root, &now);
716
717 break;
718 }
719
720 /*
721 * Traverse across the mountpoint and continue the
722 * climb on the mounted-on filesystem.
723 */
724 vp = untraverse(vp);
725 exportdir = 0;
726 continue;
727 }
728
729 /*
730 * Do a getattr to obtain the nodeid (inode num)
731 * for this vnode.
732 */
733 va.va_mask = AT_NODEID;
734 error = VOP_GETATTR(vp, &va, 0, CRED(), NULL);
735 if (error)
736 break;
737
738 /*
739 * Add this directory fid to visible list
740 */
741 visp = kmem_alloc(sizeof (*visp), KM_SLEEP);
742 VN_HOLD(vp);
743 visp->vis_vp = vp;
744 visp->vis_fid = fid; /* structure copy */
893 old_nd = tnode;
894 tnode = tnode->tree_parent;
895
896 /* Remove itself, if this is a leaf and non-exported node */
897 if (old_nd->tree_child_first == NULL &&
898 !TREE_EXPORTED(old_nd)) {
899 tree_remove_node(ne, old_nd);
900 connect_point = tnode;
901 }
902 }
903
904 /* Update the change timestamp */
905 if (connect_point != NULL)
906 tree_update_change(ne, connect_point, NULL);
907 }
908
909 /*
910 * Traverse backward across mountpoint from the
911 * root vnode of a filesystem to its mounted-on
912 * vnode.
913 *
914 * Callers to this function have confirmed the use of curzone is safe here.
915 */
916 vnode_t *
917 untraverse(vnode_t *vp)
918 {
919 vnode_t *tvp, *nextvp;
920
921 tvp = vp;
922 for (;;) {
923 if (!(tvp->v_flag & VROOT) && !VN_IS_CURZONEROOT(tvp))
924 break;
925
926 /* lock vfs to prevent unmount of this vfs */
927 vfs_lock_wait(tvp->v_vfsp);
928
929 if ((nextvp = tvp->v_vfsp->vfs_vnodecovered) == NULL) {
930 vfs_unlock(tvp->v_vfsp);
931 break;
932 }
933
934 /*
935 * Hold nextvp to prevent unmount. After unlock vfs and
936 * rele tvp, any number of overlays could be unmounted.
937 * Putting a hold on vfs_vnodecovered will only allow
938 * tvp's vfs to be unmounted. Of course if caller placed
939 * extra hold on vp before calling untraverse, the following
940 * hold would not be needed. Since prev actions of caller
941 * are unknown, we need to hold here just to be safe.
942 */
943 VN_HOLD(nextvp);
|
704 if (VN_IS_CURZONEROOT(vp)) {
705 /* at system root */
706 /*
707 * If sharing "/", new_exi is shared exportinfo
708 * (exip). Otherwise, new_exi is exportinfo
709 * created by pseudo_exportfs() above.
710 */
711 ne->ns_root = tree_prepend_node(tree_head, NULL,
712 new_exi);
713
714 /* Update the change timestamp */
715 tree_update_change(ne, ne->ns_root, &now);
716
717 break;
718 }
719
720 /*
721 * Traverse across the mountpoint and continue the
722 * climb on the mounted-on filesystem.
723 */
724 vp = untraverse(ne, vp);
725 exportdir = 0;
726 continue;
727 }
728
729 /*
730 * Do a getattr to obtain the nodeid (inode num)
731 * for this vnode.
732 */
733 va.va_mask = AT_NODEID;
734 error = VOP_GETATTR(vp, &va, 0, CRED(), NULL);
735 if (error)
736 break;
737
738 /*
739 * Add this directory fid to visible list
740 */
741 visp = kmem_alloc(sizeof (*visp), KM_SLEEP);
742 VN_HOLD(vp);
743 visp->vis_vp = vp;
744 visp->vis_fid = fid; /* structure copy */
893 old_nd = tnode;
894 tnode = tnode->tree_parent;
895
896 /* Remove itself, if this is a leaf and non-exported node */
897 if (old_nd->tree_child_first == NULL &&
898 !TREE_EXPORTED(old_nd)) {
899 tree_remove_node(ne, old_nd);
900 connect_point = tnode;
901 }
902 }
903
904 /* Update the change timestamp */
905 if (connect_point != NULL)
906 tree_update_change(ne, connect_point, NULL);
907 }
908
909 /*
910 * Traverse backward across mountpoint from the
911 * root vnode of a filesystem to its mounted-on
912 * vnode.
913 */
914 vnode_t *
915 untraverse(nfs_export_t *ne, vnode_t *vp)
916 {
917 vnode_t *tvp, *nextvp;
918 vnode_t *zone_rootvp = ne->exi_root->exi_vp;
919
920 tvp = vp;
921 for (;;) {
922 if (!(tvp->v_flag & VROOT) && !VN_CMP(tvp, zone_rootvp))
923 break;
924
925 /* lock vfs to prevent unmount of this vfs */
926 vfs_lock_wait(tvp->v_vfsp);
927
928 if ((nextvp = tvp->v_vfsp->vfs_vnodecovered) == NULL) {
929 vfs_unlock(tvp->v_vfsp);
930 break;
931 }
932
933 /*
934 * Hold nextvp to prevent unmount. After unlock vfs and
935 * rele tvp, any number of overlays could be unmounted.
936 * Putting a hold on vfs_vnodecovered will only allow
937 * tvp's vfs to be unmounted. Of course if caller placed
938 * extra hold on vp before calling untraverse, the following
939 * hold would not be needed. Since prev actions of caller
940 * are unknown, we need to hold here just to be safe.
941 */
942 VN_HOLD(nextvp);
|