smb_tree.c revision da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0
/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License (the "License").
* You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
/*
* Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
#pragma ident "%Z%%M% %I% %E% SMI"
/*
* General Structures Layout
* -------------------------
*
* This is a simplified diagram showing the relationship between most of the
* main structures.
*
* +-------------------+
* | SMB_INFO |
* +-------------------+
* |
* |
* v
* +-------------------+ +-------------------+ +-------------------+
* | SESSION |<----->| SESSION |......| SESSION |
* +-------------------+ +-------------------+ +-------------------+
* |
* |
* v
* +-------------------+ +-------------------+ +-------------------+
* | USER |<----->| USER |......| USER |
* +-------------------+ +-------------------+ +-------------------+
* |
* |
* v
* +-------------------+ +-------------------+ +-------------------+
* | TREE |<----->| TREE |......| TREE |
* +-------------------+ +-------------------+ +-------------------+
* | |
* | |
* | v
* | +-------+ +-------+ +-------+
* | | OFILE |<----->| OFILE |......| OFILE |
* | +-------+ +-------+ +-------+
* |
* |
* v
* +-------+ +------+ +------+
* | ODIR |<----->| ODIR |......| ODIR |
* +-------+ +------+ +------+
*
*
* Tree State Machine
* ------------------
*
* +-----------------------------+ T0
* | SMB_TREE_STATE_CONNECTED |<----------- Creation/Allocation
* +-----------------------------+
* |
* | T1
* |
* v
* +------------------------------+
* | SMB_TREE_STATE_DISCONNECTING |
* +------------------------------+
* |
* | T2
* |
* v
* +-----------------------------+ T3
* +-----------------------------+
*
* SMB_TREE_STATE_CONNECTED
*
* While in this state:
* - The tree is queued in the list of trees of its user.
* - References will be given out if the tree is looked up.
* - Files under that tree can be accessed.
*
* SMB_TREE_STATE_DISCONNECTING
*
* While in this state:
* - The tree is queued in the list of trees of its user.
* - References will not be given out if the tree is looked up.
* - The files and directories open under the tree are being closed.
* - The resources associated with the tree remain.
*
* SMB_TREE_STATE_DISCONNECTED
*
* While in this state:
* - The tree is queued in the list of trees of its user.
* - References will not be given out if the tree is looked up.
* - The tree has no more files and directories opened.
* - The resources associated with the tree remain.
*
* Transition T0
*
* This transition occurs in smb_tree_connect(). A new tree is created and
* added to the list of trees of a user.
*
* Transition T1
*
* This transition occurs in smb_tree_disconnect().
*
* Transition T2
*
* This transition occurs in smb_tree_release(). The resources associated
* with the tree are freed as well as the tree structure. For the transition
* to occur, the tree must be in the SMB_TREE_STATE_DISCONNECTED state and
* the reference count be zero.
*
* Comments
* --------
*
* The state machine of the tree structures is controlled by 3 elements:
* - The list of trees of the user it belongs to.
* - The mutex embedded in the structure itself.
* - The reference count.
*
* There's a mutex embedded in the tree structure used to protect its fields
* and there's a lock embedded in the list of trees of a user. To
* increment or to decrement the reference count the mutex must be entered.
* To insert the tree into the list of trees of the user and to remove
* the tree from it, the lock must be entered in RW_WRITER mode.
*
* Rules of access to a tree structure:
*
* 1) In order to avoid deadlocks, when both (mutex and lock of the user
* list) have to be entered, the lock must be entered first.
*
* 2) All actions applied to a tree require a reference count.
*
* 3) There are 2 ways of getting a reference count. One is when the tree
* is connected. The other when the user is looked up. This translates
* into 2 functions: smb_tree_connect() and smb_tree_lookup_by_tid().
*
* It should be noted that the reference count of a tree registers the
* number of references to the tree in other structures (such as an smb
* request). The reference count is not incremented in these 2 instances:
*
* 1) The tree is connected. An tree is anchored by his state. If there's
* no activity involving a tree currently connected, the reference
* count of that tree is zero.
*
* 2) The tree is queued in the list of trees of the user. The fact of
* being queued in that list is NOT registered by incrementing the
* reference count.
*/
#include <smbsrv/smb_incl.h>
#include <smbsrv/smb_fsops.h>
/* Static functions defined further down this file. */
static void smb_tree_delete(smb_tree_t *);
/*
* smb_tree_connect
*/
char *sharename,
char *resource,
{
return (NULL);
}
return (NULL);
}
return (NULL);
}
sizeof (tree->t_sharename));
switch (stype & STYPE_MASK) {
case STYPE_DISKTREE:
}
}
}
break;
case STYPE_IPC:
default:
break;
}
return (tree);
}
/*
* smb_tree_disconnect
*
*
*/
void
{
case SMB_TREE_STATE_CONNECTED: {
/*
* The tree is moved into a state indicating that the disconnect
* process has started.
*/
/*
* The files opened under this tree are closed.
*/
/*
* The directories opened under this tree are closed.
*/
/*FALLTHRU*/
}
break;
default:
ASSERT(0);
break;
}
}
/*
* smb_tree_disconnect_all
*
*
*/
void
{
while (tree) {
}
}
/*
* smb_tree_close_all_by_pid
*
*
*/
void
{
while (tree) {
}
}
/*
* smb_tree_release
*
*
*/
void
{
return;
}
break;
case SMB_TREE_STATE_CONNECTED:
break;
default:
ASSERT(0);
break;
}
}
/*
* Find the appropriate tree for this request. The request credentials
* set here override those set during uid lookup. In domain mode, the
* user and tree credentials should be the same. In share mode, the
* tree credentials (defined in the share definition) should override
* the user credentials.
*/
{
while (tree) {
case SMB_TREE_STATE_CONNECTED:
/* The tree exists and is still connected. */
return (tree);
/*
* The tree exists but is diconnected or is in
* the process of being destroyed.
*/
return (NULL);
default:
ASSERT(0);
return (NULL);
}
}
}
return (NULL);
}
/*
* smb_tree_lookup_first_by_name
*
* This function returns the first tree in the connected state that matches the
* sharename passed in. If the tree provided is NULL the search starts from
* the beginning of the list of trees of the user. It a tree is provided the
* search starts just after that tree.
*/
char *sharename,
{
if (tree) {
} else {
}
while (tree) {
case SMB_TREE_STATE_CONNECTED:
/* The tree exists and is still connected. */
return (tree);
/*
* The tree exists but is diconnected or is in
* the process of being destroyed.
*/
break;
default:
ASSERT(0);
break;
}
}
}
return (NULL);
}
/*
* smb_tree_lookup_first_by_fsd
*
* This function returns the first tree in the connected state that matches the
* fsd passed in. If the tree provided is NULL the search starts from
* the beginning of the list of trees of the user. It a tree is provided the
* search starts just after that tree.
*/
{
if (tree) {
} else {
}
while (tree) {
case SMB_TREE_STATE_CONNECTED:
/* The tree exists and is still connected. */
return (tree);
/*
* The tree exists but is diconnected or is in
* the process of being destroyed.
*/
break;
default:
ASSERT(0);
break;
}
}
}
return (NULL);
}
/* *************************** Static Functions ***************************** */
/*
* smb_tree_delete
*
* This function releases all the resources associated with a tree. It also
* removes the tree the caller passes from the list of trees of the user.
*
* The tree to destroy 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 (this condition should be met
* if the tree is is the "destroying state" and has a reference count of zero).
*
* Entry:
* tree Tree to destroy
*
* Exit:
* Nothing
*
* Return:
* Nothing
*/
static void
{
/*
* Let's remove the tree from the list of trees of the
* user. This has to be done before any resources
* associated with the tree are released.
*/
}
/*
* The list of open files and open directories should be empty.
*/
}
/*
* smb_tree_lookup_head
*
* This function returns the first tree in the list that is in the
* SMB_TREE_STATE_CONNECTED. A reference is taken on the tree and
* smb_tree_release() will have to be called for the tree returned.
*
* Entry:
* lst List of trees (usually the list of trees of a user)
*
* Exit:
* Nothing
*
* Return:
* NULL No tree in the SMB_TREE_STATE_CONNECTED state was found.
* !NULL First tree in the list in the SMB_TREE_STATE_CONNECTED state.
*/
static smb_tree_t *
{
while (tree) {
break;
} else {
ASSERT(0);
}
}
return (tree);
}
/*
* smb_tree_lookup_next
*
* This function returns the next tree in the list that is in the
* SMB_TREE_STATE_CONNECTED. A reference is taken on the tree and
* smb_tree_release() will have to be called for the tree returned.
*
* Entry:
* lst List of trees (usually the list of trees of a user).
* tree Starting tree.
*
* Exit:
* Nothing
*
* Return:
* NULL No tree in the SMB_TREE_STATE_CONNECTED state was found.
* !NULL Next tree in the list in the SMB_TREE_STATE_CONNECTED state.
*/
static smb_tree_t *
{
while (next) {
break;
} else {
ASSERT(0);
}
}
return (next);
}