Exemplo n.º 1
0
/*
 * 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);
}
Exemplo n.º 2
0
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);
}