/* * Deallocate a tree: release all resources associated with a tree and * remove the tree from the user's tree list. * * The tree being destroyed must be in the "destroying" state and the * reference count must be zero. This function assumes it's single threaded * i.e. only one thread will attempt to destroy a specific tree, which * should be the case if the tree is in disconnected and has a reference * count of zero. */ static void smb_tree_dealloc(smb_tree_t *tree) { ASSERT(tree); ASSERT(tree->t_magic == SMB_TREE_MAGIC); ASSERT(tree->t_state == SMB_TREE_STATE_DISCONNECTED); ASSERT(tree->t_refcnt == 0); /* * Remove the tree from the user's tree list. This must be done * before any resources associated with the tree are released. */ smb_llist_enter(&tree->t_user->u_tree_list, RW_WRITER); smb_llist_remove(&tree->t_user->u_tree_list, tree); smb_llist_exit(&tree->t_user->u_tree_list); tree->t_magic = (uint32_t)~SMB_TREE_MAGIC; smb_idpool_free(&tree->t_user->u_tid_pool, tree->t_tid); atomic_dec_32(&tree->t_session->s_tree_cnt); if (tree->t_snode) smb_node_release(tree->t_snode); mutex_destroy(&tree->t_mutex); /* * The list of open files and open directories should be empty. */ smb_llist_destructor(&tree->t_ofile_list); smb_llist_destructor(&tree->t_odir_list); smb_idpool_destructor(&tree->t_fid_pool); smb_idpool_destructor(&tree->t_odid_pool); kmem_cache_free(tree->t_server->si_cache_tree, tree); }
void smb_kshare_fini(smb_server_t *sv) { smb_unshare_t *ux; while ((ux = list_head(&sv->sv_export.e_unexport_list.sl_list)) != NULL) { smb_slist_remove(&sv->sv_export.e_unexport_list, ux); kmem_cache_free(smb_kshare_cache_unexport, ux); } smb_slist_destructor(&sv->sv_export.e_unexport_list); smb_vfs_rele_all(&sv->sv_export); smb_llist_destructor(&sv->sv_export.e_vfs_list); }