smb_ofile.c revision 8c10a8659ac31335ed870a1711c0182623f72fd6
/*
* 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 2008 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 |
* +-------+ +------+ +------+
*
*
* Ofile State Machine
* ------------------
*
* +-------------------------+ T0
* | SMB_OFILE_STATE_OPEN |<----------- Creation/Allocation
* +-------------------------+
* |
* | T1
* |
* v
* +-------------------------+
* | SMB_OFILE_STATE_CLOSING |
* +-------------------------+
* |
* | T2
* |
* v
* +-------------------------+ T3
* +-------------------------+
*
* SMB_OFILE_STATE_OPEN
*
* While in this state:
* - The ofile is queued in the list of ofiles of its tree.
* - References will be given out if the ofile is looked up.
*
* SMB_OFILE_STATE_CLOSING
*
* While in this state:
* - The ofile is queued in the list of ofiles of its tree.
* - References will not be given out if the ofile is looked up.
* - The file is closed and the locks held are being released.
* - The resources associated with the ofile remain.
*
* SMB_OFILE_STATE_CLOSED
*
* While in this state:
* - The ofile is queued in the list of ofiles of its tree.
* - References will not be given out if the ofile is looked up.
* - The resources associated with the ofile remain.
*
* Transition T0
*
* This transition occurs in smb_ofile_open(). A new ofile is created and
* added to the list of ofiles of a tree.
*
* Transition T1
*
* This transition occurs in smb_ofile_close().
*
* Transition T2
*
* This transition occurs in smb_ofile_release(). The resources associated
* with the ofile are freed as well as the ofile structure. For the
* transition to occur, the ofile must be in the SMB_OFILE_STATE_CLOSED
* state and the reference count be zero.
*
* Comments
* --------
*
* The state machine of the ofile structures is controlled by 3 elements:
* - The list of ofiles of the tree it belongs to.
* - The mutex embedded in the structure itself.
* - The reference count.
*
* There's a mutex embedded in the ofile structure used to protect its fields
* and there's a lock embedded in the list of ofiles of a tree. To
* increment or to decrement the reference count the mutex must be entered.
* To insert the ofile into the list of ofiles of the tree and to remove
* the ofile from it, the lock must be entered in RW_WRITER mode.
*
* Rules of access to a ofile structure:
*
* 1) In order to avoid deadlocks, when both (mutex and lock of the ofile
* list) have to be entered, the lock must be entered first.
*
* 2) All actions applied to an ofile require a reference count.
*
* 3) There are 2 ways of getting a reference count. One is when the ofile
* is opened. The other one when the ofile is looked up. This translates
* into 2 functions: smb_ofile_open() and smb_ofile_lookup_by_fid().
*
* It should be noted that the reference count of an ofile registers the
* number of references to the ofile in other structures (such as an smb
* request). The reference count is not incremented in these 2 instances:
*
* 1) The ofile is open. An ofile is anchored by his state. If there's
* no activity involving an ofile currently open, the reference count
* of that ofile is zero.
*
* 2) The ofile is queued in the list of ofiles of its tree. The fact of
* being queued in that list is NOT registered by incrementing the
* reference count.
*/
#include <smbsrv/smb_incl.h>
#include <smbsrv/smb_kproto.h>
#include <smbsrv/smb_fsops.h>
/* Static functions defined further down this file. */
/*
* smb_ofile_open
*
*
*/
char *pipe_name,
{
return (NULL);
}
if (ftype == SMB_FTYPE_MESG_PIPE) {
} else {
/*
* Add this bit for the file's owner even if it's not
* specified in the request (Windows behavior).
*/
}
!= 0) {
of);
return (NULL);
}
}
}
return (of);
}
/*
* smb_ofile_close
*
*
*/
int
{
int rc = 0;
case SMB_OFILE_STATE_OPEN: {
} else {
}
/*
* Share reservations cannot be removed until the
* readonly bit has been set (if needed), above.
* See comments in smb_open_subr().
*/
/*
* Cancel any notify change requests related
* to this open instance.
*/
}
return (rc);
}
case SMB_OFILE_STATE_CLOSED:
case SMB_OFILE_STATE_CLOSING:
break;
default:
ASSERT(0);
break;
}
return (rc);
}
/*
* smb_ofile_close_all
*
*
*/
void
{
while (of) {
}
}
/*
* smb_ofiles_close_by_pid
*
*
*/
void
{
while (of) {
} else {
}
}
}
/*
* smb_ofile_release
*
*/
void
{
case SMB_OFILE_STATE_OPEN:
case SMB_OFILE_STATE_CLOSING:
break;
case SMB_OFILE_STATE_CLOSED:
return;
}
break;
default:
ASSERT(0);
break;
}
}
/*
* smb_ofile_lookup_by_fid
*
* Find the open file whose fid matches the one specified in the request.
* If we can't find the fid or the shares (trees) don't match, we have a
* bad fid.
*/
{
while (of) {
return (NULL);
}
break;
}
}
return (of);
}
/*
* smb_ofile_set_flags
*
* Return value:
*
* Current flags value
*
*/
void
{
}
/*
* smb_ofile_seek
*
* Return value:
*
* 0 Success
* EINVAL Unknown mode
* EOVERFLOW offset too big
*
*/
int
{
u_offset_t newoff = 0;
int rc = 0;
switch (mode) {
case SMB_SEEK_SET:
if (off < 0)
newoff = 0;
else
break;
case SMB_SEEK_CUR:
newoff = 0;
else
break;
case SMB_SEEK_END:
newoff = 0;
else
break;
default:
return (EINVAL);
}
/*
* See comments at the beginning of smb_seek.c.
* If the offset is greater than UINT_MAX, we will return an error.
*/
} else {
}
return (rc);
}
/*
* smb_ofile_close_timestamp_update
*
*
*/
void
{
unsigned int what = 0;
what |= SMB_AT_MTIME;
}
/*
* NODE_FLAGS_SYNCATIME is set whenever something is
* written to a file. Compliant volumes don't update
* atime upon write, so don't update the atime if the
* volume is compliant.
*/
what |= SMB_AT_ATIME;
}
}
/*
* smb_ofile_is_open
*
*/
{
}
return (rc);
}
/* *************************** Static Functions ***************************** */
/*
* smb_ofile_close_and_next
*
* This function closes the file passed in (if appropriate) and returns the
* next open file in the list of open files of the tree of the open file passed
* in. It requires that the list of open files of the tree be entered in
* RW_READER mode before being called.
*/
static smb_ofile_t *
{
case SMB_OFILE_STATE_OPEN:
/* The file is still open. */
(void) smb_ofile_close(of, 0);
break;
case SMB_OFILE_STATE_CLOSING:
case SMB_OFILE_STATE_CLOSED:
/*
* The ofile exists but is closed or
* in the process being closed.
*/
break;
default:
ASSERT(0);
break;
}
return (next_of);
}
/*
* smb_ofile_delete
*
*
*/
static void
{
/*
* Let's remove the ofile from the list of ofiles of the tree. This has
* to be done before any resources associated with the ofile are
* released.
*/
} else {
}
}
/*
* smb_ofile_access
*
* This function will check to see if the access requested is granted.
* Returns NT status codes.
*/
{
return (NT_STATUS_SUCCESS);
/*
* If the request is for something
* I don't grant it is an error
*/
(access & ACCESS_SYSTEM_SECURITY)) {
return (NT_STATUS_PRIVILEGE_NOT_HELD);
}
return (NT_STATUS_ACCESS_DENIED);
}
return (NT_STATUS_SUCCESS);
}