152 struct exportinfo *exi;
153 struct exportdata *kex;
154 fsid_t fsid;
155 int vpathlen;
156 int i;
157
158 ASSERT(RW_WRITE_HELD(&ne->exported_lock));
159
160 fsid = vp->v_vfsp->vfs_fsid;
161 exi = kmem_zalloc(sizeof (*exi), KM_SLEEP);
162 exi->exi_fsid = fsid;
163 exi->exi_fid = *fid;
164 exi->exi_vp = vp;
165 VN_HOLD(exi->exi_vp);
166 exi->exi_visible = vis_head;
167 exi->exi_count = 1;
168 /* Caller will set exi_zone... */
169 exi->exi_volatile_dev = (vfssw[vp->v_vfsp->vfs_fstype].vsw_flag &
170 VSW_VOLATILEDEV) ? 1 : 0;
171 mutex_init(&exi->exi_lock, NULL, MUTEX_DEFAULT, NULL);
172
173 /*
174 * Build up the template fhandle
175 */
176 exi->exi_fh.fh_fsid = fsid;
177 ASSERT(exi->exi_fid.fid_len <= sizeof (exi->exi_fh.fh_xdata));
178 exi->exi_fh.fh_xlen = exi->exi_fid.fid_len;
179 bcopy(exi->exi_fid.fid_data, exi->exi_fh.fh_xdata,
180 exi->exi_fid.fid_len);
181 exi->exi_fh.fh_len = sizeof (exi->exi_fh.fh_data);
182
183 kex = &exi->exi_export;
184 kex->ex_flags = EX_PSEUDO;
185
186 vpathlen = strlen(vp->v_path);
187 kex->ex_pathlen = vpathlen + strlen(PSEUDOFS_SUFFIX);
188 kex->ex_path = kmem_alloc(kex->ex_pathlen + 1, KM_SLEEP);
189
190 if (vpathlen)
191 (void) strncpy(kex->ex_path, vp->v_path, vpathlen);
823 * Walk up the tree and:
824 * 1. release pseudo exportinfo if it has no child
825 * 2. release visible in parent's exportinfo
826 * 3. delete non-exported leaf nodes from tree
827 *
828 * Deleting of nodes will start only if the unshared
829 * node was a leaf node.
830 * Deleting of nodes will finish when we reach a node which
831 * has children or is a real export, then we might still need
832 * to continue releasing visibles, until we reach VROOT or zone's root node.
833 */
834 void
835 treeclimb_unexport(nfs_export_t *ne, struct exportinfo *exip)
836 {
837 treenode_t *tnode, *old_nd;
838 treenode_t *connect_point = NULL;
839
840 ASSERT(RW_WRITE_HELD(&ne->exported_lock));
841 ASSERT(curzone == exip->exi_zone || curzone == global_zone);
842
843 tnode = exip->exi_tree;
844 /*
845 * The unshared exportinfo was unlinked in unexport().
846 * Zeroing tree_exi ensures that we will skip it.
847 */
848 tnode->tree_exi = NULL;
849
850 if (tnode->tree_vis != NULL) /* system root has tree_vis == NULL */
851 tnode->tree_vis->vis_exported = 0;
852
853 while (tnode != NULL) {
854
855 /*
856 * Stop at VROOT (or zone root) node which is exported or has
857 * child.
858 */
859 if (TREE_ROOT(tnode) &&
860 (TREE_EXPORTED(tnode) || tnode->tree_child_first != NULL))
861 break;
862
863 /* Release pseudo export if it has no child */
|
152 struct exportinfo *exi;
153 struct exportdata *kex;
154 fsid_t fsid;
155 int vpathlen;
156 int i;
157
158 ASSERT(RW_WRITE_HELD(&ne->exported_lock));
159
160 fsid = vp->v_vfsp->vfs_fsid;
161 exi = kmem_zalloc(sizeof (*exi), KM_SLEEP);
162 exi->exi_fsid = fsid;
163 exi->exi_fid = *fid;
164 exi->exi_vp = vp;
165 VN_HOLD(exi->exi_vp);
166 exi->exi_visible = vis_head;
167 exi->exi_count = 1;
168 /* Caller will set exi_zone... */
169 exi->exi_volatile_dev = (vfssw[vp->v_vfsp->vfs_fstype].vsw_flag &
170 VSW_VOLATILEDEV) ? 1 : 0;
171 mutex_init(&exi->exi_lock, NULL, MUTEX_DEFAULT, NULL);
172 exi->exi_zoneid = ne->ne_globals->nfs_zoneid;
173
174 /*
175 * Build up the template fhandle
176 */
177 exi->exi_fh.fh_fsid = fsid;
178 ASSERT(exi->exi_fid.fid_len <= sizeof (exi->exi_fh.fh_xdata));
179 exi->exi_fh.fh_xlen = exi->exi_fid.fid_len;
180 bcopy(exi->exi_fid.fid_data, exi->exi_fh.fh_xdata,
181 exi->exi_fid.fid_len);
182 exi->exi_fh.fh_len = sizeof (exi->exi_fh.fh_data);
183
184 kex = &exi->exi_export;
185 kex->ex_flags = EX_PSEUDO;
186
187 vpathlen = strlen(vp->v_path);
188 kex->ex_pathlen = vpathlen + strlen(PSEUDOFS_SUFFIX);
189 kex->ex_path = kmem_alloc(kex->ex_pathlen + 1, KM_SLEEP);
190
191 if (vpathlen)
192 (void) strncpy(kex->ex_path, vp->v_path, vpathlen);
824 * Walk up the tree and:
825 * 1. release pseudo exportinfo if it has no child
826 * 2. release visible in parent's exportinfo
827 * 3. delete non-exported leaf nodes from tree
828 *
829 * Deleting of nodes will start only if the unshared
830 * node was a leaf node.
831 * Deleting of nodes will finish when we reach a node which
832 * has children or is a real export, then we might still need
833 * to continue releasing visibles, until we reach VROOT or zone's root node.
834 */
835 void
836 treeclimb_unexport(nfs_export_t *ne, struct exportinfo *exip)
837 {
838 treenode_t *tnode, *old_nd;
839 treenode_t *connect_point = NULL;
840
841 ASSERT(RW_WRITE_HELD(&ne->exported_lock));
842 ASSERT(curzone == exip->exi_zone || curzone == global_zone);
843
844 /*
845 * exi_tree can be null for the zone root
846 * which means we're already at the "top"
847 * and there's nothing more to "climb".
848 */
849 tnode = exip->exi_tree;
850 if (tnode == NULL) {
851 /* Should only happen for... */
852 ASSERT(exip == ne->exi_root);
853 return;
854 }
855
856 /*
857 * The unshared exportinfo was unlinked in unexport().
858 * Zeroing tree_exi ensures that we will skip it.
859 */
860 tnode->tree_exi = NULL;
861
862 if (tnode->tree_vis != NULL) /* system root has tree_vis == NULL */
863 tnode->tree_vis->vis_exported = 0;
864
865 while (tnode != NULL) {
866
867 /*
868 * Stop at VROOT (or zone root) node which is exported or has
869 * child.
870 */
871 if (TREE_ROOT(tnode) &&
872 (TREE_EXPORTED(tnode) || tnode->tree_child_first != NULL))
873 break;
874
875 /* Release pseudo export if it has no child */
|