1996-05-04 07:50:46 +00:00
/*
Unix SMB / Netbios implementation .
Version 1.9 .
Locking functions
1998-01-22 13:27:43 +00:00
Copyright ( C ) Andrew Tridgell 1992 - 1998
1996-05-04 07:50:46 +00:00
This program is free software ; you can redistribute it and / or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation ; either version 2 of the License , or
( at your option ) any later version .
This program is distributed in the hope that it will be useful ,
but WITHOUT ANY WARRANTY ; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the
GNU General Public License for more details .
You should have received a copy of the GNU General Public License
along with this program ; if not , write to the Free Software
Foundation , Inc . , 675 Mass Ave , Cambridge , MA 0213 9 , USA .
1996-08-15 15:11:34 +00:00
Revision History :
12 aug 96 : Erik . Devriendt @ te6 . siemens . be
added support for shared memory implementation of share mode locking
1997-05-20 00:32:51 +00:00
May 1997. Jeremy Allison ( jallison @ whistle . com ) . Modified share mode
locking to deal with multiple share modes per open file .
1997-10-07 18:46:19 +00:00
September 1997. Jeremy Allison ( jallison @ whistle . com ) . Added oplock
support .
1996-05-04 07:50:46 +00:00
*/
# include "includes.h"
extern int DEBUGLEVEL ;
1997-10-20 08:46:00 +00:00
static struct share_ops * share_ops ;
1998-07-28 18:15:31 +00:00
/****************************************************************************
Utility function to map a lock type correctly depending on the real open
mode of a file .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
static int map_lock_type ( files_struct * fsp , int lock_type )
{
1998-08-11 23:28:35 +00:00
if ( ( lock_type = = F_WRLCK ) & & ( fsp - > fd_ptr - > real_open_flags = = O_RDONLY ) ) {
1998-07-28 18:15:31 +00:00
/*
* Many UNIX ' s cannot get a write lock on a file opened read - only .
* Win32 locking semantics allow this .
* Do the best we can and attempt a read - only lock .
*/
1998-07-29 00:27:23 +00:00
DEBUG ( 10 , ( " map_lock_type: Downgrading write lock to read due to read-only file. \n " ) ) ;
1998-07-28 18:15:31 +00:00
return F_RDLCK ;
1998-08-11 23:28:35 +00:00
} else if ( ( lock_type = = F_RDLCK ) & & ( fsp - > fd_ptr - > real_open_flags = = O_WRONLY ) ) {
1998-07-28 18:15:31 +00:00
/*
* Ditto for read locks on write only files .
*/
1998-07-29 00:27:23 +00:00
DEBUG ( 10 , ( " map_lock_type: Changing read lock to write due to write-only file. \n " ) ) ;
1998-07-28 18:15:31 +00:00
return F_WRLCK ;
}
/*
* This return should be the most normal , as we attempt
* to always open files read / write .
*/
return lock_type ;
}
1996-05-04 07:50:46 +00:00
/****************************************************************************
1998-07-23 00:10:26 +00:00
Utility function called to see if a file region is locked .
1996-05-04 07:50:46 +00:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
1998-08-15 07:27:34 +00:00
BOOL is_locked ( files_struct * fsp , connection_struct * conn ,
1998-09-04 00:23:28 +00:00
SMB_OFF_T count , SMB_OFF_T offset , int lock_type )
1996-05-04 07:50:46 +00:00
{
1998-08-14 17:38:29 +00:00
int snum = SNUM ( conn ) ;
1996-05-04 07:50:46 +00:00
1998-08-14 17:38:29 +00:00
if ( count = = 0 )
return ( False ) ;
1996-05-04 07:50:46 +00:00
1998-08-14 17:38:29 +00:00
if ( ! lp_locking ( snum ) | | ! lp_strict_locking ( snum ) )
return ( False ) ;
1998-07-28 18:26:47 +00:00
1998-08-14 17:38:29 +00:00
/*
* Note that most UNIX ' s can * test * for a write lock on
* a read - only fd , just not * set * a write lock on a read - only
* fd . So we don ' t need to use map_lock_type here .
*/
1998-09-04 00:23:28 +00:00
return ( fcntl_lock ( fsp - > fd_ptr - > fd , SMB_F_GETLK , offset , count , lock_type ) ) ;
1996-05-04 07:50:46 +00:00
}
/****************************************************************************
1998-07-23 00:10:26 +00:00
Utility function called by locking requests .
1996-05-04 07:50:46 +00:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
1998-08-15 07:27:34 +00:00
BOOL do_lock ( files_struct * fsp , connection_struct * conn ,
1998-09-04 00:23:28 +00:00
SMB_OFF_T count , SMB_OFF_T offset , int lock_type ,
1998-07-23 00:10:26 +00:00
int * eclass , uint32 * ecode )
1996-05-04 07:50:46 +00:00
{
BOOL ok = False ;
1998-08-14 17:38:29 +00:00
if ( ! lp_locking ( SNUM ( conn ) ) )
1996-05-04 07:50:46 +00:00
return ( True ) ;
if ( count = = 0 ) {
* eclass = ERRDOS ;
* ecode = ERRnoaccess ;
return False ;
}
1998-09-04 00:23:28 +00:00
DEBUG ( 10 , ( " do_lock: lock type %d start=%.0f len=%.0f requested for file %s \n " ,
lock_type , ( double ) offset , ( double ) count , fsp - > fsp_name ) ) ;
1998-08-20 19:28:37 +00:00
1998-08-15 07:27:34 +00:00
if ( OPEN_FSP ( fsp ) & & fsp - > can_lock & & ( fsp - > conn = = conn ) )
1998-09-04 00:23:28 +00:00
ok = fcntl_lock ( fsp - > fd_ptr - > fd , SMB_F_SETLK , offset , count ,
1998-07-28 18:15:31 +00:00
map_lock_type ( fsp , lock_type ) ) ;
1996-05-04 07:50:46 +00:00
if ( ! ok ) {
* eclass = ERRDOS ;
* ecode = ERRlock ;
return False ;
}
return True ; /* Got lock */
}
/****************************************************************************
1998-07-23 00:10:26 +00:00
Utility function called by unlocking requests .
1996-05-04 07:50:46 +00:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
1998-08-15 07:27:34 +00:00
BOOL do_unlock ( files_struct * fsp , connection_struct * conn ,
1998-09-04 00:23:28 +00:00
SMB_OFF_T count , SMB_OFF_T offset , int * eclass , uint32 * ecode )
1996-05-04 07:50:46 +00:00
{
BOOL ok = False ;
1998-08-14 17:38:29 +00:00
if ( ! lp_locking ( SNUM ( conn ) ) )
1996-05-04 07:50:46 +00:00
return ( True ) ;
1998-09-04 00:23:28 +00:00
DEBUG ( 10 , ( " do_unlock: unlock start=%.0f len=%.0f requested for file %s \n " ,
( double ) offset , ( double ) count , fsp - > fsp_name ) ) ;
1998-08-20 19:28:37 +00:00
1998-08-15 07:27:34 +00:00
if ( OPEN_FSP ( fsp ) & & fsp - > can_lock & & ( fsp - > conn = = conn ) )
1998-09-04 00:23:28 +00:00
ok = fcntl_lock ( fsp - > fd_ptr - > fd , SMB_F_SETLK , offset , count , F_UNLCK ) ;
1996-05-04 07:50:46 +00:00
if ( ! ok ) {
* eclass = ERRDOS ;
* ecode = ERRlock ;
return False ;
}
return True ; /* Did unlock */
}
1997-10-20 08:46:00 +00:00
/****************************************************************************
1998-07-23 00:10:26 +00:00
Initialise the locking functions .
1997-10-20 08:46:00 +00:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
1998-07-23 00:10:26 +00:00
1997-10-27 14:27:17 +00:00
BOOL locking_init ( int read_only )
1996-08-15 15:11:34 +00:00
{
1998-09-04 00:23:28 +00:00
if ( share_ops )
return True ;
1997-10-29 02:18:08 +00:00
1997-10-20 08:46:00 +00:00
# ifdef FAST_SHARE_MODES
1998-09-04 00:23:28 +00:00
share_ops = locking_shm_init ( read_only ) ;
1998-07-29 03:08:05 +00:00
# else
1998-09-04 00:23:28 +00:00
share_ops = locking_slow_init ( read_only ) ;
1998-07-29 03:08:05 +00:00
# endif
1998-09-04 00:23:28 +00:00
if ( ! share_ops ) {
DEBUG ( 0 , ( " ERROR: Failed to initialise share modes! \n " ) ) ;
return False ;
}
1997-10-20 08:46:00 +00:00
1998-09-04 00:23:28 +00:00
return True ;
1996-05-04 07:50:46 +00:00
}
/*******************************************************************
1998-07-23 00:10:26 +00:00
Deinitialize the share_mode management .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
1997-10-20 08:46:00 +00:00
BOOL locking_end ( void )
1996-05-04 07:50:46 +00:00
{
1997-10-29 02:18:08 +00:00
if ( share_ops )
return share_ops - > stop_mgmt ( ) ;
return True ;
1996-05-04 07:50:46 +00:00
}
1997-05-20 00:32:51 +00:00
/*******************************************************************
1998-07-23 00:10:26 +00:00
Lock a hash bucket entry .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
1998-08-14 17:38:29 +00:00
BOOL lock_share_entry ( connection_struct * conn ,
1998-08-31 20:20:54 +00:00
SMB_DEV_T dev , SMB_INO_T inode , int * ptok )
1997-10-17 23:08:07 +00:00
{
1998-08-14 17:38:29 +00:00
return share_ops - > lock_entry ( conn , dev , inode , ptok ) ;
1997-10-17 23:08:07 +00:00
}
1997-05-20 00:32:51 +00:00
/*******************************************************************
1998-07-23 00:10:26 +00:00
Unlock a hash bucket entry .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
1998-08-14 17:38:29 +00:00
BOOL unlock_share_entry ( connection_struct * conn ,
1998-08-31 20:20:54 +00:00
SMB_DEV_T dev , SMB_INO_T inode , int token )
1997-05-20 00:32:51 +00:00
{
1998-08-14 17:38:29 +00:00
return share_ops - > unlock_entry ( conn , dev , inode , token ) ;
1996-05-04 07:50:46 +00:00
}
/*******************************************************************
1998-07-23 00:10:26 +00:00
Get all share mode entries for a dev / inode pair .
1997-10-20 08:46:00 +00:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
1998-08-14 17:38:29 +00:00
int get_share_modes ( connection_struct * conn ,
1998-08-31 20:20:54 +00:00
int token , SMB_DEV_T dev , SMB_INO_T inode ,
1997-10-20 08:46:00 +00:00
share_mode_entry * * shares )
1997-05-20 00:32:51 +00:00
{
1998-08-14 17:38:29 +00:00
return share_ops - > get_entries ( conn , token , dev , inode , shares ) ;
1997-05-20 00:32:51 +00:00
}
/*******************************************************************
1998-07-23 00:10:26 +00:00
Del the share mode of a file .
1997-05-20 00:32:51 +00:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
1998-08-15 07:27:34 +00:00
void del_share_mode ( int token , files_struct * fsp )
1997-05-20 00:32:51 +00:00
{
1998-08-15 07:27:34 +00:00
share_ops - > del_entry ( token , fsp ) ;
1997-05-20 00:32:51 +00:00
}
/*******************************************************************
1998-07-23 00:10:26 +00:00
Set the share mode of a file . Return False on fail , True on success .
1997-05-20 00:32:51 +00:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
1998-08-15 07:27:34 +00:00
BOOL set_share_mode ( int token , files_struct * fsp , uint16 port , uint16 op_type )
1997-05-20 00:32:51 +00:00
{
1998-08-15 07:27:34 +00:00
return share_ops - > set_entry ( token , fsp , port , op_type ) ;
1996-05-04 07:50:46 +00:00
}
/*******************************************************************
1998-07-23 00:10:26 +00:00
Remove an oplock port and mode entry from a share mode .
1996-05-04 07:50:46 +00:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
1998-08-15 07:27:34 +00:00
BOOL remove_share_oplock ( files_struct * fsp , int token )
1996-05-04 07:50:46 +00:00
{
1998-08-15 07:27:34 +00:00
return share_ops - > remove_oplock ( fsp , token ) ;
1997-10-20 08:46:00 +00:00
}
1997-05-20 00:32:51 +00:00
/*******************************************************************
1998-07-23 00:10:26 +00:00
Call the specified function on each entry under management by the
share mode system .
1997-05-20 00:32:51 +00:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
1998-07-23 00:10:26 +00:00
1997-10-20 08:46:00 +00:00
int share_mode_forall ( void ( * fn ) ( share_mode_entry * , char * ) )
1997-05-20 00:32:51 +00:00
{
1997-10-20 08:46:00 +00:00
return share_ops - > forall ( fn ) ;
1996-05-04 07:50:46 +00:00
}
1997-10-01 23:32:22 +00:00
/*******************************************************************
1998-07-23 00:10:26 +00:00
Dump the state of the system .
1997-10-01 23:32:22 +00:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
1998-07-23 00:10:26 +00:00
1997-10-20 08:46:00 +00:00
void share_status ( FILE * f )
1997-10-01 23:32:22 +00:00
{
1997-10-20 08:46:00 +00:00
share_ops - > status ( f ) ;
1997-10-01 23:32:22 +00:00
}