smb_tree.c revision 55bf511df53aad0fdb7eb3fa349f0308cc05234c
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw/*
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * CDDL HEADER START
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw *
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * The contents of this file are subject to the terms of the
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * Common Development and Distribution License (the "License").
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * You may not use this file except in compliance with the License.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw *
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * or http://www.opensolaris.org/os/licensing.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * See the License for the specific language governing permissions
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * and limitations under the License.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw *
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * When distributing Covered Code, include this CDDL HEADER in each
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * If applicable, add the following below this CDDL HEADER, with the
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * fields enclosed by brackets "[]" replaced with your own identifying
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * information: Portions Copyright [yyyy] [name of copyright owner]
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw *
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * CDDL HEADER END
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw */
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw/*
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * Use is subject to license terms.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw */
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw#pragma ident "%Z%%M% %I% %E% SMI"
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw/*
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * General Structures Layout
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * -------------------------
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw *
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * This is a simplified diagram showing the relationship between most of the
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * main structures.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw *
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * +-------------------+
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * | SMB_INFO |
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * +-------------------+
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * |
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * |
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * v
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * +-------------------+ +-------------------+ +-------------------+
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * | SESSION |<----->| SESSION |......| SESSION |
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * +-------------------+ +-------------------+ +-------------------+
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * |
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * |
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * v
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * +-------------------+ +-------------------+ +-------------------+
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * | USER |<----->| USER |......| USER |
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * +-------------------+ +-------------------+ +-------------------+
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * |
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * |
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * v
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * +-------------------+ +-------------------+ +-------------------+
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * | TREE |<----->| TREE |......| TREE |
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * +-------------------+ +-------------------+ +-------------------+
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * | |
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * | |
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * | v
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * | +-------+ +-------+ +-------+
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * | | OFILE |<----->| OFILE |......| OFILE |
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * | +-------+ +-------+ +-------+
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * |
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * |
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * v
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * +-------+ +------+ +------+
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * | ODIR |<----->| ODIR |......| ODIR |
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * +-------+ +------+ +------+
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw *
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw *
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * Tree State Machine
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * ------------------
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw *
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * +-----------------------------+ T0
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * | SMB_TREE_STATE_CONNECTED |<----------- Creation/Allocation
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * +-----------------------------+
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * |
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * | T1
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * |
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * v
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * +------------------------------+
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * | SMB_TREE_STATE_DISCONNECTING |
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * +------------------------------+
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * |
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * | T2
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * |
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * v
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * +-----------------------------+ T3
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * | SMB_TREE_STATE_DISCONNECTED |----------> Deletion/Free
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * +-----------------------------+
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw *
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * SMB_TREE_STATE_CONNECTED
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw *
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * While in this state:
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * - The tree is queued in the list of trees of its user.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * - References will be given out if the tree is looked up.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * - Files under that tree can be accessed.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw *
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * SMB_TREE_STATE_DISCONNECTING
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw *
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * While in this state:
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * - The tree is queued in the list of trees of its user.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * - References will not be given out if the tree is looked up.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * - The files and directories open under the tree are being closed.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * - The resources associated with the tree remain.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw *
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * SMB_TREE_STATE_DISCONNECTED
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw *
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * While in this state:
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * - The tree is queued in the list of trees of its user.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * - References will not be given out if the tree is looked up.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * - The tree has no more files and directories opened.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * - The resources associated with the tree remain.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw *
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * Transition T0
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw *
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * This transition occurs in smb_tree_connect(). A new tree is created and
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * added to the list of trees of a user.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw *
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * Transition T1
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw *
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * This transition occurs in smb_tree_disconnect().
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw *
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * Transition T2
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw *
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * This transition occurs in smb_tree_release(). The resources associated
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * with the tree are freed as well as the tree structure. For the transition
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * to occur, the tree must be in the SMB_TREE_STATE_DISCONNECTED state and
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * the reference count be zero.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw *
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * Comments
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * --------
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw *
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * The state machine of the tree structures is controlled by 3 elements:
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * - The list of trees of the user it belongs to.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * - The mutex embedded in the structure itself.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * - The reference count.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw *
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * There's a mutex embedded in the tree structure used to protect its fields
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * and there's a lock embedded in the list of trees of a user. To
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * increment or to decrement the reference count the mutex must be entered.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * To insert the tree into the list of trees of the user and to remove
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * the tree from it, the lock must be entered in RW_WRITER mode.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw *
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * Rules of access to a tree structure:
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw *
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * 1) In order to avoid deadlocks, when both (mutex and lock of the user
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * list) have to be entered, the lock must be entered first.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw *
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * 2) All actions applied to a tree require a reference count.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw *
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * 3) There are 2 ways of getting a reference count. One is when the tree
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * is connected. The other when the user is looked up. This translates
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * into 2 functions: smb_tree_connect() and smb_tree_lookup_by_tid().
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw *
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * It should be noted that the reference count of a tree registers the
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * number of references to the tree in other structures (such as an smb
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * request). The reference count is not incremented in these 2 instances:
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw *
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * 1) The tree is connected. An tree is anchored by his state. If there's
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * no activity involving a tree currently connected, the reference
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * count of that tree is zero.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw *
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * 2) The tree is queued in the list of trees of the user. The fact of
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * being queued in that list is NOT registered by incrementing the
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * reference count.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw */
55bf511df53aad0fdb7eb3fa349f0308cc05234cas#include <sys/fsid.h>
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw#include <smbsrv/smb_incl.h>
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw#include <smbsrv/smb_fsops.h>
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw/* Static functions defined further down this file. */
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amwstatic void smb_tree_delete(smb_tree_t *);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amwstatic smb_tree_t *smb_tree_lookup_head(smb_llist_t *);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amwstatic smb_tree_t *smb_tree_lookup_next(smb_llist_t *, smb_tree_t *);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw/*
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * smb_tree_connect
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw */
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amwsmb_tree_t *
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amwsmb_tree_connect(
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw smb_user_t *user,
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw uint16_t access_flags,
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw char *sharename,
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw char *resource,
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw int32_t stype,
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw smb_node_t *snode,
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw fsvol_attr_t *vol_attr)
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw{
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw smb_tree_t *tree;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw uint16_t tid;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw if (smb_idpool_alloc(&user->u_tid_pool, &tid)) {
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw return (NULL);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw }
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw tree = kmem_cache_alloc(smb_info.si_cache_tree, KM_SLEEP);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw bzero(tree, sizeof (smb_tree_t));
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw if (smb_idpool_constructor(&tree->t_fid_pool)) {
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw smb_idpool_free(&user->u_tid_pool, tid);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw kmem_cache_free(smb_info.si_cache_tree, tree);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw return (NULL);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw }
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw if (smb_idpool_constructor(&tree->t_sid_pool)) {
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw smb_idpool_destructor(&tree->t_fid_pool);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw smb_idpool_free(&user->u_tid_pool, tid);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw kmem_cache_free(smb_info.si_cache_tree, tree);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw return (NULL);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw }
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw smb_llist_constructor(&tree->t_ofile_list, sizeof (smb_ofile_t),
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw offsetof(smb_ofile_t, f_lnd));
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw smb_llist_constructor(&tree->t_odir_list, sizeof (smb_odir_t),
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw offsetof(smb_odir_t, d_lnd));
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw (void) strlcpy(tree->t_sharename, sharename,
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw sizeof (tree->t_sharename));
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw (void) strlcpy(tree->t_resource, resource, sizeof (tree->t_resource));
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw mutex_init(&tree->t_mutex, NULL, MUTEX_DEFAULT, NULL);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw tree->t_user = user;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw tree->t_session = user->u_session;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw tree->t_refcnt = 1;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw tree->t_tid = tid;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw tree->t_access = access_flags;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw tree->t_res_type = stype;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw tree->t_snode = snode;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw tree->t_state = SMB_TREE_STATE_CONNECTED;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw tree->t_magic = SMB_TREE_MAGIC;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw switch (stype & STYPE_MASK) {
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw case STYPE_DISKTREE:
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw tree->t_fsd = snode->tree_fsd;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw (void) strlcpy(tree->t_typename, vol_attr->fs_typename,
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw SMB_TREE_TYPENAME_SZ);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw (void) utf8_strupr((char *)tree->t_typename);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw if (vol_attr->flags & FSOLF_READONLY)
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw tree->t_access = SMB_TREE_READ_ONLY;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw tree->t_acltype = smb_fsop_acltype(snode);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
55bf511df53aad0fdb7eb3fa349f0308cc05234cas if (strncasecmp(tree->t_typename, NFS, sizeof (NFS)) == 0)
55bf511df53aad0fdb7eb3fa349f0308cc05234cas tree->t_flags |= SMB_TREE_FLAG_NFS_MOUNTED;
55bf511df53aad0fdb7eb3fa349f0308cc05234cas
55bf511df53aad0fdb7eb3fa349f0308cc05234cas if (strncasecmp(tree->t_typename, "UFS", sizeof ("UFS")) == 0)
55bf511df53aad0fdb7eb3fa349f0308cc05234cas tree->t_flags |= SMB_TREE_FLAG_UFS;
55bf511df53aad0fdb7eb3fa349f0308cc05234cas
55bf511df53aad0fdb7eb3fa349f0308cc05234cas if (vfs_has_feature(snode->vp->v_vfsp, VFSFT_ACLONCREATE))
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw tree->t_flags |= SMB_TREE_FLAG_ACLONCREATE;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
55bf511df53aad0fdb7eb3fa349f0308cc05234cas if (vfs_has_feature(snode->vp->v_vfsp, VFSFT_ACEMASKONACCESS))
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw tree->t_flags |= SMB_TREE_FLAG_ACEMASKONACCESS;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
55bf511df53aad0fdb7eb3fa349f0308cc05234cas if (vfs_has_feature(snode->vp->v_vfsp, VFSFT_CASEINSENSITIVE))
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw tree->t_flags |= SMB_TREE_FLAG_IGNORE_CASE;
55bf511df53aad0fdb7eb3fa349f0308cc05234cas
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw break;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw case STYPE_IPC:
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw default:
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw tree->t_typename[0] = '\0';
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw break;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw }
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw smb_llist_enter(&user->u_tree_list, RW_WRITER);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw smb_llist_insert_head(&user->u_tree_list, tree);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw smb_llist_exit(&user->u_tree_list);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw atomic_inc_32(&user->u_session->s_tree_cnt);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw atomic_inc_32(&smb_info.open_trees);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw return (tree);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw}
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw/*
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * smb_tree_disconnect
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw *
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw *
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw */
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amwvoid
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amwsmb_tree_disconnect(
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw smb_tree_t *tree)
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw{
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw ASSERT(tree->t_magic == SMB_TREE_MAGIC);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw mutex_enter(&tree->t_mutex);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw ASSERT(tree->t_refcnt);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw switch (tree->t_state) {
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw case SMB_TREE_STATE_CONNECTED: {
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw /*
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * The tree is moved into a state indicating that the disconnect
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * process has started.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw */
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw tree->t_state = SMB_TREE_STATE_DISCONNECTING;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw mutex_exit(&tree->t_mutex);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw atomic_dec_32(&smb_info.open_trees);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw /*
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * The files opened under this tree are closed.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw */
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw smb_ofile_close_all(tree);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw /*
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * The directories opened under this tree are closed.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw */
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw smb_odir_close_all(tree);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw mutex_enter(&tree->t_mutex);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw tree->t_state = SMB_TREE_STATE_DISCONNECTED;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw /*FALLTHRU*/
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw }
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw case SMB_TREE_STATE_DISCONNECTED:
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw case SMB_TREE_STATE_DISCONNECTING:
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw break;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw default:
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw ASSERT(0);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw break;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw }
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw mutex_exit(&tree->t_mutex);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw}
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw/*
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * smb_tree_disconnect_all
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw *
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw *
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw */
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amwvoid
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amwsmb_tree_disconnect_all(
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw smb_user_t *user)
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw{
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw smb_tree_t *tree;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw ASSERT(user);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw ASSERT(user->u_magic == SMB_USER_MAGIC);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw tree = smb_tree_lookup_head(&user->u_tree_list);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw while (tree) {
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw ASSERT(tree->t_user == user);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw smb_tree_disconnect(tree);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw smb_tree_release(tree);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw tree = smb_tree_lookup_head(&user->u_tree_list);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw }
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw}
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw/*
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * smb_tree_close_all_by_pid
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw *
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw *
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw */
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amwvoid
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amwsmb_tree_close_all_by_pid(
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw smb_user_t *user,
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw uint16_t pid)
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw{
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw smb_tree_t *tree;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw ASSERT(user);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw ASSERT(user->u_magic == SMB_USER_MAGIC);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw tree = smb_tree_lookup_head(&user->u_tree_list);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw while (tree) {
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw smb_tree_t *next;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw ASSERT(tree->t_user == user);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw smb_ofile_close_all_by_pid(tree, pid);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw smb_odir_close_all_by_pid(tree, pid);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw next = smb_tree_lookup_next(&user->u_tree_list, tree);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw smb_tree_release(tree);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw tree = next;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw }
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw}
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw/*
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * smb_tree_release
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw *
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw *
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw */
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amwvoid
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amwsmb_tree_release(
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw smb_tree_t *tree)
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw{
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw ASSERT(tree);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw ASSERT(tree->t_magic == SMB_TREE_MAGIC);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw mutex_enter(&tree->t_mutex);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw ASSERT(tree->t_refcnt);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw tree->t_refcnt--;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw switch (tree->t_state) {
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw case SMB_TREE_STATE_DISCONNECTED:
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw if (tree->t_refcnt == 0) {
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw mutex_exit(&tree->t_mutex);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw smb_tree_delete(tree);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw return;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw }
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw break;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw case SMB_TREE_STATE_CONNECTED:
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw case SMB_TREE_STATE_DISCONNECTING:
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw break;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw default:
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw ASSERT(0);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw break;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw }
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw mutex_exit(&tree->t_mutex);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw}
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw/*
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * Find the appropriate tree for this request. The request credentials
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * set here override those set during uid lookup. In domain mode, the
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * user and tree credentials should be the same. In share mode, the
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * tree credentials (defined in the share definition) should override
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * the user credentials.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw */
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amwsmb_tree_t *
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amwsmb_tree_lookup_by_tid(
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw smb_user_t *user,
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw uint16_t tid)
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw{
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw smb_tree_t *tree;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw ASSERT(user);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw ASSERT(user->u_magic == SMB_USER_MAGIC);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw smb_llist_enter(&user->u_tree_list, RW_READER);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw tree = smb_llist_head(&user->u_tree_list);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw while (tree) {
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw ASSERT(tree->t_magic == SMB_TREE_MAGIC);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw ASSERT(tree->t_user == user);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw if (tree->t_tid == tid) {
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw mutex_enter(&tree->t_mutex);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw switch (tree->t_state) {
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw case SMB_TREE_STATE_CONNECTED:
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw /* The tree exists and is still connected. */
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw tree->t_refcnt++;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw mutex_exit(&tree->t_mutex);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw smb_llist_exit(&user->u_tree_list);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw return (tree);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw case SMB_TREE_STATE_DISCONNECTING:
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw case SMB_TREE_STATE_DISCONNECTED:
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw /*
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * The tree exists but is diconnected or is in
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * the process of being destroyed.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw */
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw mutex_exit(&tree->t_mutex);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw smb_llist_exit(&user->u_tree_list);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw return (NULL);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw default:
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw ASSERT(0);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw mutex_exit(&tree->t_mutex);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw smb_llist_exit(&user->u_tree_list);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw return (NULL);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw }
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw }
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw tree = smb_llist_next(&user->u_tree_list, tree);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw }
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw smb_llist_exit(&user->u_tree_list);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw return (NULL);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw}
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw/*
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * smb_tree_lookup_first_by_name
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw *
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * This function returns the first tree in the connected state that matches the
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * sharename passed in. If the tree provided is NULL the search starts from
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * the beginning of the list of trees of the user. It a tree is provided the
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * search starts just after that tree.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw */
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amwsmb_tree_t *
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amwsmb_tree_lookup_by_name(
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw smb_user_t *user,
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw char *sharename,
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw smb_tree_t *tree)
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw{
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw ASSERT(user);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw ASSERT(user->u_magic == SMB_USER_MAGIC);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw ASSERT(sharename);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw smb_llist_enter(&user->u_tree_list, RW_READER);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw if (tree) {
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw ASSERT(tree->t_magic == SMB_TREE_MAGIC);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw ASSERT(tree->t_user == user);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw tree = smb_llist_next(&user->u_tree_list, tree);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw } else {
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw tree = smb_llist_head(&user->u_tree_list);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw }
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw while (tree) {
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw ASSERT(tree->t_magic == SMB_TREE_MAGIC);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw ASSERT(tree->t_user == user);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw if (strcmp(tree->t_sharename, sharename) == 0) {
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw mutex_enter(&tree->t_mutex);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw switch (tree->t_state) {
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw case SMB_TREE_STATE_CONNECTED:
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw /* The tree exists and is still connected. */
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw tree->t_refcnt++;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw mutex_exit(&tree->t_mutex);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw smb_llist_exit(&user->u_tree_list);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw return (tree);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw case SMB_TREE_STATE_DISCONNECTING:
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw case SMB_TREE_STATE_DISCONNECTED:
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw /*
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * The tree exists but is diconnected or is in
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * the process of being destroyed.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw */
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw mutex_exit(&tree->t_mutex);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw break;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw default:
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw ASSERT(0);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw mutex_exit(&tree->t_mutex);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw break;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw }
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw }
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw tree = smb_llist_next(&user->u_tree_list, tree);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw }
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw smb_llist_exit(&user->u_tree_list);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw return (NULL);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw}
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw/*
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * smb_tree_lookup_first_by_fsd
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw *
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * This function returns the first tree in the connected state that matches the
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * fsd passed in. If the tree provided is NULL the search starts from
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * the beginning of the list of trees of the user. It a tree is provided the
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * search starts just after that tree.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw */
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amwsmb_tree_t *
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amwsmb_tree_lookup_by_fsd(
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw smb_user_t *user,
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw fs_desc_t *fsd,
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw smb_tree_t *tree)
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw{
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw ASSERT(user);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw ASSERT(user->u_magic == SMB_USER_MAGIC);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw ASSERT(fsd);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw smb_llist_enter(&user->u_tree_list, RW_READER);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw if (tree) {
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw ASSERT(tree->t_magic == SMB_TREE_MAGIC);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw ASSERT(tree->t_user == user);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw tree = smb_llist_next(&user->u_tree_list, tree);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw } else {
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw tree = smb_llist_head(&user->u_tree_list);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw }
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw while (tree) {
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw ASSERT(tree->t_magic == SMB_TREE_MAGIC);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw ASSERT(tree->t_user == user);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw if (fsd_cmp(&tree->t_fsd, fsd) == 0) {
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw mutex_enter(&tree->t_mutex);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw switch (tree->t_state) {
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw case SMB_TREE_STATE_CONNECTED:
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw /* The tree exists and is still connected. */
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw tree->t_refcnt++;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw mutex_exit(&tree->t_mutex);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw smb_llist_exit(&user->u_tree_list);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw return (tree);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw case SMB_TREE_STATE_DISCONNECTING:
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw case SMB_TREE_STATE_DISCONNECTED:
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw /*
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * The tree exists but is diconnected or is in
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * the process of being destroyed.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw */
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw mutex_exit(&tree->t_mutex);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw break;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw default:
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw ASSERT(0);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw mutex_exit(&tree->t_mutex);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw break;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw }
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw }
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw tree = smb_llist_next(&user->u_tree_list, tree);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw }
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw smb_llist_exit(&user->u_tree_list);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw return (NULL);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw}
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw/* *************************** Static Functions ***************************** */
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw/*
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * smb_tree_delete
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw *
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * This function releases all the resources associated with a tree. It also
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * removes the tree the caller passes from the list of trees of the user.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw *
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * The tree to destroy must be in the "destroying state" and the reference count
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * must be zero. This function assumes it's single threaded i.e. only one
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * thread will attempt to destroy a specific tree (this condition should be met
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * if the tree is is the "destroying state" and has a reference count of zero).
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw *
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * Entry:
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * tree Tree to destroy
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw *
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * Exit:
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * Nothing
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw *
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * Return:
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * Nothing
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw */
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amwstatic void
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amwsmb_tree_delete(smb_tree_t *tree)
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw{
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw ASSERT(tree);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw ASSERT(tree->t_magic == SMB_TREE_MAGIC);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw ASSERT(tree->t_state == SMB_TREE_STATE_DISCONNECTED);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw ASSERT(tree->t_refcnt == 0);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw /*
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * Let's remove the tree from the list of trees of the
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * user. This has to be done before any resources
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * associated with the tree are released.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw */
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw smb_llist_enter(&tree->t_user->u_tree_list, RW_WRITER);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw smb_llist_remove(&tree->t_user->u_tree_list, tree);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw smb_llist_exit(&tree->t_user->u_tree_list);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw tree->t_magic = (uint32_t)~SMB_TREE_MAGIC;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw smb_idpool_free(&tree->t_user->u_tid_pool, tree->t_tid);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw atomic_dec_32(&tree->t_session->s_tree_cnt);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw if (tree->t_snode) {
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw smb_node_release(tree->t_snode);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw }
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw mutex_destroy(&tree->t_mutex);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw /*
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * The list of open files and open directories should be empty.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw */
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw smb_llist_destructor(&tree->t_ofile_list);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw smb_llist_destructor(&tree->t_odir_list);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw smb_idpool_destructor(&tree->t_fid_pool);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw smb_idpool_destructor(&tree->t_sid_pool);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw kmem_cache_free(smb_info.si_cache_tree, tree);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw}
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw/*
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * smb_tree_lookup_head
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw *
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * This function returns the first tree in the list that is in the
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * SMB_TREE_STATE_CONNECTED. A reference is taken on the tree and
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * smb_tree_release() will have to be called for the tree returned.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw *
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * Entry:
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * lst List of trees (usually the list of trees of a user)
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw *
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * Exit:
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * Nothing
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw *
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * Return:
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * NULL No tree in the SMB_TREE_STATE_CONNECTED state was found.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * !NULL First tree in the list in the SMB_TREE_STATE_CONNECTED state.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw */
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amwstatic smb_tree_t *
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amwsmb_tree_lookup_head(
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw smb_llist_t *lst)
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw{
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw smb_tree_t *tree;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw smb_llist_enter(lst, RW_READER);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw tree = smb_llist_head(lst);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw while (tree) {
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw ASSERT(tree->t_magic == SMB_TREE_MAGIC);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw mutex_enter(&tree->t_mutex);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw if (tree->t_state == SMB_TREE_STATE_CONNECTED) {
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw tree->t_refcnt++;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw mutex_exit(&tree->t_mutex);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw break;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw } else if ((tree->t_state == SMB_TREE_STATE_DISCONNECTING) ||
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw (tree->t_state == SMB_TREE_STATE_DISCONNECTED)) {
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw mutex_exit(&tree->t_mutex);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw tree = smb_llist_next(lst, tree);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw } else {
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw ASSERT(0);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw mutex_exit(&tree->t_mutex);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw tree = smb_llist_next(lst, tree);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw }
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw }
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw smb_llist_exit(lst);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw return (tree);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw}
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw/*
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * smb_tree_lookup_next
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw *
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * This function returns the next tree in the list that is in the
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * SMB_TREE_STATE_CONNECTED. A reference is taken on the tree and
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * smb_tree_release() will have to be called for the tree returned.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw *
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * Entry:
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * lst List of trees (usually the list of trees of a user).
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * tree Starting tree.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw *
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * Exit:
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * Nothing
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw *
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * Return:
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * NULL No tree in the SMB_TREE_STATE_CONNECTED state was found.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * !NULL Next tree in the list in the SMB_TREE_STATE_CONNECTED state.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw */
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amwstatic smb_tree_t *
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amwsmb_tree_lookup_next(
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw smb_llist_t *lst,
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw smb_tree_t *tree)
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw{
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw smb_tree_t *next;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw ASSERT(lst);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw ASSERT(tree);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw ASSERT(tree->t_magic == SMB_TREE_MAGIC);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw ASSERT(tree->t_refcnt);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw smb_llist_enter(lst, RW_READER);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw next = smb_llist_next(lst, tree);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw while (next) {
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw ASSERT(next->t_magic == SMB_TREE_MAGIC);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw mutex_enter(&next->t_mutex);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw if (next->t_state == SMB_TREE_STATE_CONNECTED) {
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw next->t_refcnt++;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw mutex_exit(&next->t_mutex);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw break;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw } else if ((next->t_state == SMB_TREE_STATE_DISCONNECTING) ||
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw (next->t_state == SMB_TREE_STATE_DISCONNECTED)) {
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw mutex_exit(&next->t_mutex);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw next = smb_llist_next(lst, next);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw } else {
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw ASSERT(0);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw mutex_exit(&next->t_mutex);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw next = smb_llist_next(lst, next);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw }
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw }
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw smb_llist_exit(lst);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw return (next);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw}