1996-05-04 11:50:46 +04:00
/*
Unix SMB / Netbios implementation .
1999-12-21 12:25:59 +03:00
Version 3.0
1996-05-04 11:50:46 +04:00
Locking functions
1999-12-21 12:25:59 +03:00
Copyright ( C ) Andrew Tridgell 1992 - 1999
1996-05-04 11:50:46 +04: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 19:11:34 +04:00
Revision History :
12 aug 96 : Erik . Devriendt @ te6 . siemens . be
added support for shared memory implementation of share mode locking
1997-05-20 04:32:51 +04:00
May 1997. Jeremy Allison ( jallison @ whistle . com ) . Modified share mode
locking to deal with multiple share modes per open file .
1997-10-07 22:46:19 +04:00
September 1997. Jeremy Allison ( jallison @ whistle . com ) . Added oplock
support .
1999-12-21 12:25:59 +03:00
rewrtten completely to use new tdb code . Tridge , Dec ' 99
1996-05-04 11:50:46 +04:00
*/
# include "includes.h"
extern int DEBUGLEVEL ;
1999-12-21 12:25:59 +03:00
/* the locking database handle */
static TDB_CONTEXT * tdb ;
1997-10-20 12:46:00 +04:00
2000-01-14 03:50:48 +03:00
int global_smbpid ;
2000-01-14 07:32:57 +03:00
/****************************************************************************
remove any locks on this fd
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
void locking_close_file ( files_struct * fsp )
{
if ( ! lp_locking ( SNUM ( fsp - > conn ) ) ) return ;
2000-04-10 16:58:14 +04:00
brl_close ( fsp - > dev , fsp - > inode ,
2000-01-14 07:32:57 +03:00
getpid ( ) , fsp - > conn - > cnum , fsp - > fnum ) ;
}
1996-05-04 11:50:46 +04:00
/****************************************************************************
1998-07-23 04:10:26 +04:00
Utility function called to see if a file region is locked .
1996-05-04 11:50:46 +04:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
1998-08-15 11:27:34 +04:00
BOOL is_locked ( files_struct * fsp , connection_struct * conn ,
2000-01-13 15:09:36 +03:00
SMB_OFF_T count , SMB_OFF_T offset ,
2000-01-14 11:01:44 +03:00
enum brl_type lock_type )
1996-05-04 11:50:46 +04:00
{
1998-08-14 21:38:29 +04:00
int snum = SNUM ( conn ) ;
1999-12-21 12:25:59 +03:00
1998-08-14 21:38:29 +04:00
if ( count = = 0 )
return ( False ) ;
1996-05-04 11:50:46 +04:00
1998-08-14 21:38:29 +04:00
if ( ! lp_locking ( snum ) | | ! lp_strict_locking ( snum ) )
return ( False ) ;
1998-07-28 22:26:47 +04:00
2000-04-10 16:58:14 +04:00
return ! brl_locktest ( fsp - > dev , fsp - > inode ,
2000-01-14 03:50:48 +03:00
global_smbpid , getpid ( ) , conn - > cnum ,
2000-01-13 15:09:36 +03:00
offset , count , lock_type ) ;
1996-05-04 11:50:46 +04:00
}
/****************************************************************************
1998-07-23 04:10:26 +04:00
Utility function called by locking requests .
1996-05-04 11:50:46 +04:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
1998-08-15 11:27:34 +04:00
BOOL do_lock ( files_struct * fsp , connection_struct * conn ,
2000-01-14 11:01:44 +03:00
SMB_OFF_T count , SMB_OFF_T offset , enum brl_type lock_type ,
1998-07-23 04:10:26 +04:00
int * eclass , uint32 * ecode )
1996-05-04 11:50:46 +04:00
{
1999-12-21 12:25:59 +03:00
BOOL ok = False ;
if ( ! lp_locking ( SNUM ( conn ) ) )
return ( True ) ;
if ( count = = 0 ) {
* eclass = ERRDOS ;
* ecode = ERRnoaccess ;
return False ;
}
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 ) ) ;
2000-01-13 15:09:36 +03:00
if ( OPEN_FSP ( fsp ) & & fsp - > can_lock & & ( fsp - > conn = = conn ) ) {
2000-04-10 16:58:14 +04:00
ok = brl_lock ( fsp - > dev , fsp - > inode , fsp - > fnum ,
2000-01-14 03:50:48 +03:00
global_smbpid , getpid ( ) , conn - > cnum ,
2000-01-13 15:09:36 +03:00
offset , count ,
lock_type ) ;
}
1999-12-21 12:25:59 +03:00
if ( ! ok ) {
* eclass = ERRDOS ;
* ecode = ERRlock ;
return False ;
}
return True ; /* Got lock */
1996-05-04 11:50:46 +04:00
}
/****************************************************************************
1998-07-23 04:10:26 +04:00
Utility function called by unlocking requests .
1996-05-04 11:50:46 +04:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
1998-08-15 11:27:34 +04:00
BOOL do_unlock ( files_struct * fsp , connection_struct * conn ,
2000-01-13 15:09:36 +03:00
SMB_OFF_T count , SMB_OFF_T offset ,
int * eclass , uint32 * ecode )
1996-05-04 11:50:46 +04:00
{
1999-12-21 12:25:59 +03:00
BOOL ok = False ;
if ( ! lp_locking ( SNUM ( conn ) ) )
return ( True ) ;
DEBUG ( 10 , ( " do_unlock: unlock start=%.0f len=%.0f requested for file %s \n " ,
( double ) offset , ( double ) count , fsp - > fsp_name ) ) ;
2000-01-13 15:09:36 +03:00
if ( OPEN_FSP ( fsp ) & & fsp - > can_lock & & ( fsp - > conn = = conn ) ) {
2000-04-10 16:58:14 +04:00
ok = brl_unlock ( fsp - > dev , fsp - > inode , fsp - > fnum ,
2000-01-14 03:50:48 +03:00
global_smbpid , getpid ( ) , conn - > cnum ,
2000-01-13 15:09:36 +03:00
offset , count ) ;
}
1996-05-04 11:50:46 +04:00
1999-12-21 12:25:59 +03:00
if ( ! ok ) {
* eclass = ERRDOS ;
* ecode = ERRlock ;
return False ;
}
return True ; /* Did unlock */
1996-05-04 11:50:46 +04:00
}
1997-10-20 12:46:00 +04:00
/****************************************************************************
1998-07-23 04:10:26 +04:00
Initialise the locking functions .
1997-10-20 12:46:00 +04:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
1997-10-27 17:27:17 +03:00
BOOL locking_init ( int read_only )
1996-08-15 19:11:34 +04:00
{
2000-01-16 14:14:44 +03:00
brl_init ( read_only ) ;
2000-01-13 15:09:36 +03:00
1999-12-21 12:25:59 +03:00
if ( tdb ) return True ;
1997-10-29 05:18:08 +03:00
1999-12-21 12:25:59 +03:00
tdb = tdb_open ( lock_path ( " locking.tdb " ) ,
2000-01-03 02:00:27 +03:00
0 , TDB_CLEAR_IF_FIRST ,
1999-12-21 12:25:59 +03:00
read_only ? O_RDONLY : O_RDWR | O_CREAT ,
0644 ) ;
1998-07-29 07:08:05 +04:00
1999-12-21 12:25:59 +03:00
if ( ! tdb ) {
1999-12-13 16:27:58 +03:00
DEBUG ( 0 , ( " ERROR: Failed to initialise share modes \n " ) ) ;
return False ;
}
1997-10-20 12:46:00 +04:00
1999-12-13 16:27:58 +03:00
return True ;
1996-05-04 11:50:46 +04:00
}
/*******************************************************************
1998-07-23 04:10:26 +04:00
Deinitialize the share_mode management .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
1997-10-20 12:46:00 +04:00
BOOL locking_end ( void )
1996-05-04 11:50:46 +04:00
{
1999-12-21 12:25:59 +03:00
if ( tdb & & tdb_close ( tdb ) ! = 0 ) return False ;
1997-10-29 05:18:08 +03:00
return True ;
1996-05-04 11:50:46 +04:00
}
1999-12-21 12:25:59 +03:00
/*******************************************************************
form a static locking key for a dev / inode pair
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
static TDB_DATA locking_key ( SMB_DEV_T dev , SMB_INO_T inode )
{
static struct locking_key key ;
TDB_DATA kbuf ;
key . dev = dev ;
key . inode = inode ;
kbuf . dptr = ( char * ) & key ;
kbuf . dsize = sizeof ( key ) ;
return kbuf ;
}
static TDB_DATA locking_key_fsp ( files_struct * fsp )
{
2000-04-10 16:58:14 +04:00
return locking_key ( fsp - > dev , fsp - > inode ) ;
1999-12-21 12:25:59 +03:00
}
1996-05-04 11:50:46 +04:00
1997-05-20 04:32:51 +04:00
/*******************************************************************
1998-07-23 04:10:26 +04:00
Lock a hash bucket entry .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
1998-08-14 21:38:29 +04:00
BOOL lock_share_entry ( connection_struct * conn ,
1999-12-21 12:25:59 +03:00
SMB_DEV_T dev , SMB_INO_T inode )
1997-10-18 03:08:07 +04:00
{
1999-12-21 12:25:59 +03:00
return tdb_lockchain ( tdb , locking_key ( dev , inode ) ) = = 0 ;
1997-10-18 03:08:07 +04:00
}
1997-05-20 04:32:51 +04:00
/*******************************************************************
1998-07-23 04:10:26 +04:00
Unlock a hash bucket entry .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
1998-08-14 21:38:29 +04:00
BOOL unlock_share_entry ( connection_struct * conn ,
1999-12-21 12:25:59 +03:00
SMB_DEV_T dev , SMB_INO_T inode )
1997-05-20 04:32:51 +04:00
{
1999-12-21 12:25:59 +03:00
return tdb_unlockchain ( tdb , locking_key ( dev , inode ) ) = = 0 ;
1996-05-04 11:50:46 +04:00
}
2000-04-10 16:58:14 +04:00
/*******************************************************************
Lock a hash bucket entry . use a fsp for convenience
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
BOOL lock_share_entry_fsp ( files_struct * fsp )
{
return tdb_lockchain ( tdb , locking_key ( fsp - > dev , fsp - > inode ) ) = = 0 ;
}
/*******************************************************************
Unlock a hash bucket entry .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
BOOL unlock_share_entry_fsp ( files_struct * fsp )
{
return tdb_unlockchain ( tdb , locking_key ( fsp - > dev , fsp - > inode ) ) = = 0 ;
}
1996-05-04 11:50:46 +04:00
/*******************************************************************
1998-07-23 04:10:26 +04:00
Get all share mode entries for a dev / inode pair .
1997-10-20 12:46:00 +04:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
1998-08-14 21:38:29 +04:00
int get_share_modes ( connection_struct * conn ,
1999-12-21 12:25:59 +03:00
SMB_DEV_T dev , SMB_INO_T inode ,
1997-10-20 12:46:00 +04:00
share_mode_entry * * shares )
1997-05-20 04:32:51 +04:00
{
1999-12-21 12:25:59 +03:00
TDB_DATA dbuf ;
struct locking_data * data ;
int ret ;
1999-12-22 03:08:25 +03:00
* shares = NULL ;
1999-12-21 12:25:59 +03:00
dbuf = tdb_fetch ( tdb , locking_key ( dev , inode ) ) ;
if ( ! dbuf . dptr ) return 0 ;
data = ( struct locking_data * ) dbuf . dptr ;
ret = data - > num_share_mode_entries ;
* shares = ( share_mode_entry * ) memdup ( dbuf . dptr + sizeof ( * data ) , ret * sizeof ( * * shares ) ) ;
free ( dbuf . dptr ) ;
if ( ! * shares ) return 0 ;
return ret ;
}
/*******************************************************************
Del the share mode of a file for this process
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
void del_share_mode ( files_struct * fsp )
{
TDB_DATA dbuf ;
struct locking_data * data ;
int i , del_count = 0 ;
share_mode_entry * shares ;
pid_t pid = getpid ( ) ;
/* read in the existing share modes */
dbuf = tdb_fetch ( tdb , locking_key_fsp ( fsp ) ) ;
if ( ! dbuf . dptr ) return ;
data = ( struct locking_data * ) dbuf . dptr ;
shares = ( share_mode_entry * ) ( dbuf . dptr + sizeof ( * data ) ) ;
/* find any with our pid and delete it by overwriting with the rest of the data
from the record */
for ( i = 0 ; i < data - > num_share_mode_entries ; ) {
if ( shares [ i ] . pid = = pid & &
memcmp ( & shares [ i ] . time ,
& fsp - > open_time , sizeof ( struct timeval ) ) = = 0 ) {
data - > num_share_mode_entries - - ;
memmove ( & shares [ i ] , & shares [ i + 1 ] ,
dbuf . dsize - ( sizeof ( * data ) + ( i + 1 ) * sizeof ( * shares ) ) ) ;
del_count + + ;
} else {
i + + ;
}
}
/* the record has shrunk a bit */
dbuf . dsize - = del_count * sizeof ( * shares ) ;
/* store it back in the database */
tdb_store ( tdb , locking_key_fsp ( fsp ) , dbuf , TDB_REPLACE ) ;
free ( dbuf . dptr ) ;
1997-05-20 04:32:51 +04:00
}
/*******************************************************************
1999-12-21 12:25:59 +03:00
fill a share mode entry
1997-05-20 04:32:51 +04:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
1999-12-21 12:25:59 +03:00
static void fill_share_mode ( char * p , files_struct * fsp , uint16 port , uint16 op_type )
1997-05-20 04:32:51 +04:00
{
1999-12-21 12:25:59 +03:00
share_mode_entry * e = ( share_mode_entry * ) p ;
e - > pid = getpid ( ) ;
e - > share_mode = fsp - > share_mode ;
e - > op_port = port ;
e - > op_type = op_type ;
memcpy ( ( char * ) & e - > time , ( char * ) & fsp - > open_time , sizeof ( struct timeval ) ) ;
1997-05-20 04:32:51 +04:00
}
/*******************************************************************
1998-07-23 04:10:26 +04:00
Set the share mode of a file . Return False on fail , True on success .
1997-05-20 04:32:51 +04:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
1999-12-21 12:25:59 +03:00
BOOL set_share_mode ( files_struct * fsp , uint16 port , uint16 op_type )
1997-05-20 04:32:51 +04:00
{
1999-12-21 12:25:59 +03:00
TDB_DATA dbuf ;
struct locking_data * data ;
share_mode_entry * shares ;
char * p = NULL ;
int size ;
/* read in the existing share modes if any */
dbuf = tdb_fetch ( tdb , locking_key_fsp ( fsp ) ) ;
if ( ! dbuf . dptr ) {
/* we'll need to create a new record */
pstring fname ;
pstrcpy ( fname , fsp - > conn - > connectpath ) ;
pstrcat ( fname , " / " ) ;
pstrcat ( fname , fsp - > fsp_name ) ;
size = sizeof ( * data ) + sizeof ( * shares ) + strlen ( fname ) + 1 ;
p = ( char * ) malloc ( size ) ;
data = ( struct locking_data * ) p ;
shares = ( share_mode_entry * ) ( p + sizeof ( * data ) ) ;
data - > num_share_mode_entries = 1 ;
pstrcpy ( p + sizeof ( * data ) + sizeof ( * shares ) , fname ) ;
fill_share_mode ( p + sizeof ( * data ) , fsp , port , op_type ) ;
dbuf . dptr = p ;
dbuf . dsize = size ;
tdb_store ( tdb , locking_key_fsp ( fsp ) , dbuf , TDB_REPLACE ) ;
free ( p ) ;
return True ;
}
/* we're adding to an existing entry - this is a bit fiddly */
data = ( struct locking_data * ) dbuf . dptr ;
shares = ( share_mode_entry * ) ( dbuf . dptr + sizeof ( * data ) ) ;
data - > num_share_mode_entries + + ;
size = dbuf . dsize + sizeof ( * shares ) ;
p = malloc ( size ) ;
memcpy ( p , dbuf . dptr , sizeof ( * data ) ) ;
fill_share_mode ( p + sizeof ( * data ) , fsp , port , op_type ) ;
memcpy ( p + sizeof ( * data ) + sizeof ( * shares ) , dbuf . dptr + sizeof ( * data ) ,
dbuf . dsize - sizeof ( * data ) ) ;
free ( dbuf . dptr ) ;
dbuf . dptr = p ;
dbuf . dsize = size ;
tdb_store ( tdb , locking_key_fsp ( fsp ) , dbuf , TDB_REPLACE ) ;
free ( p ) ;
return True ;
1996-05-04 11:50:46 +04:00
}
1999-12-21 12:25:59 +03:00
/*******************************************************************
a generic in - place modification call for share mode entries
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
static BOOL mod_share_mode ( files_struct * fsp ,
void ( * mod_fn ) ( share_mode_entry * , SMB_DEV_T , SMB_INO_T , void * ) ,
void * param )
{
TDB_DATA dbuf ;
struct locking_data * data ;
int i ;
share_mode_entry * shares ;
pid_t pid = getpid ( ) ;
int need_store = 0 ;
/* read in the existing share modes */
dbuf = tdb_fetch ( tdb , locking_key_fsp ( fsp ) ) ;
if ( ! dbuf . dptr ) return False ;
data = ( struct locking_data * ) dbuf . dptr ;
shares = ( share_mode_entry * ) ( dbuf . dptr + sizeof ( * data ) ) ;
/* find any with our pid and call the supplied function */
for ( i = 0 ; i < data - > num_share_mode_entries ; i + + ) {
if ( pid = = shares [ i ] . pid & &
shares [ i ] . share_mode = = fsp - > share_mode & &
memcmp ( & shares [ i ] . time ,
& fsp - > open_time , sizeof ( struct timeval ) ) = = 0 ) {
2000-04-10 16:58:14 +04:00
mod_fn ( & shares [ i ] , fsp - > dev , fsp - > inode , param ) ;
1999-12-21 12:25:59 +03:00
need_store = 1 ;
}
}
/* if the mod fn was called then store it back */
if ( need_store ) {
tdb_store ( tdb , locking_key_fsp ( fsp ) , dbuf , TDB_REPLACE ) ;
}
free ( dbuf . dptr ) ;
return need_store ;
}
1998-10-23 07:34:50 +04:00
/*******************************************************************
Static function that actually does the work for the generic function
below .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
static void remove_share_oplock_fn ( share_mode_entry * entry , SMB_DEV_T dev , SMB_INO_T inode ,
void * param )
{
1999-12-21 12:25:59 +03:00
DEBUG ( 10 , ( " remove_share_oplock_fn: removing oplock info for entry dev=%x ino=%.0f \n " ,
( unsigned int ) dev , ( double ) inode ) ) ;
/* Delete the oplock info. */
entry - > op_port = 0 ;
entry - > op_type = NO_OPLOCK ;
1998-10-23 07:34:50 +04:00
}
1996-05-04 11:50:46 +04:00
/*******************************************************************
1998-07-23 04:10:26 +04:00
Remove an oplock port and mode entry from a share mode .
1996-05-04 11:50:46 +04:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
1999-12-21 12:25:59 +03:00
BOOL remove_share_oplock ( files_struct * fsp )
1998-10-23 07:34:50 +04:00
{
1999-12-21 12:25:59 +03:00
return mod_share_mode ( fsp , remove_share_oplock_fn , NULL ) ;
1998-10-23 07:34:50 +04:00
}
/*******************************************************************
Static function that actually does the work for the generic function
below .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
1999-12-13 16:27:58 +03:00
static void downgrade_share_oplock_fn ( share_mode_entry * entry , SMB_DEV_T dev , SMB_INO_T inode ,
void * param )
{
1999-12-21 12:25:59 +03:00
DEBUG ( 10 , ( " downgrade_share_oplock_fn: downgrading oplock info for entry dev=%x ino=%.0f \n " ,
( unsigned int ) dev , ( double ) inode ) ) ;
entry - > op_type = LEVEL_II_OPLOCK ;
1999-12-13 16:27:58 +03:00
}
/*******************************************************************
Downgrade a oplock type from exclusive to level II .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
1999-12-21 12:25:59 +03:00
BOOL downgrade_share_oplock ( files_struct * fsp )
1999-12-13 16:27:58 +03:00
{
1999-12-21 12:25:59 +03:00
return mod_share_mode ( fsp , downgrade_share_oplock_fn , NULL ) ;
1999-12-13 16:27:58 +03:00
}
1999-12-21 12:25:59 +03:00
1999-12-13 16:27:58 +03:00
/*******************************************************************
Static function that actually does the work for the generic function
below .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
struct mod_val {
int new_share_mode ;
uint16 new_oplock ;
} ;
1998-10-23 07:34:50 +04:00
static void modify_share_mode_fn ( share_mode_entry * entry , SMB_DEV_T dev , SMB_INO_T inode ,
void * param )
{
1999-12-13 16:27:58 +03:00
struct mod_val * mvp = ( struct mod_val * ) param ;
DEBUG ( 10 , ( " modify_share_mode_fn: changing share mode info from %x to %x for entry dev=%x ino=%.0f \n " ,
entry - > share_mode , mvp - > new_share_mode , ( unsigned int ) dev , ( double ) inode ) ) ;
DEBUG ( 10 , ( " modify_share_mode_fn: changing oplock state from %x to %x for entry dev=%x ino=%.0f \n " ,
entry - > op_type , ( int ) mvp - > new_oplock , ( unsigned int ) dev , ( double ) inode ) ) ;
/* Change the share mode info. */
entry - > share_mode = mvp - > new_share_mode ;
entry - > op_type = mvp - > new_oplock ;
1998-10-23 07:34:50 +04:00
}
/*******************************************************************
Modify a share mode on a file . Used by the delete open file code .
Return False on fail , True on success .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
1999-12-21 12:25:59 +03:00
BOOL modify_share_mode ( files_struct * fsp , int new_mode , uint16 new_oplock )
1996-05-04 11:50:46 +04:00
{
1999-12-13 16:27:58 +03:00
struct mod_val mv ;
mv . new_share_mode = new_mode ;
1999-12-21 12:25:59 +03:00
mv . new_oplock = new_oplock ;
1999-12-13 16:27:58 +03:00
1999-12-21 12:25:59 +03:00
return mod_share_mode ( fsp , modify_share_mode_fn , ( void * ) & mv ) ;
1997-10-20 12:46:00 +04:00
}
1997-05-20 04:32:51 +04:00
1998-07-23 04:10:26 +04:00
1999-12-21 12:25:59 +03:00
/****************************************************************************
traverse the whole database with this function , calling traverse_callback
on each share mode
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2000-02-07 03:24:04 +03:00
static int traverse_fn ( TDB_CONTEXT * the_tdb , TDB_DATA kbuf , TDB_DATA dbuf ,
void * state )
1997-05-20 04:32:51 +04:00
{
1999-12-21 12:25:59 +03:00
struct locking_data * data ;
share_mode_entry * shares ;
char * name ;
int i ;
1) added void* state argument to tdb_traverse. guess what! there were
two places i found where it was appropriate to _use_ that third argument,
in locking.c and brlock.c! there was a static traverse_function and
i removed the static variable, typecast it to a void*, passed it to
tdb_traverse and re-cast it back to the traverse_function inside the
tdb_traverse function. this makes the use of tdb_traverse() reentrant,
which is never going to happen, i know, i just don't like to see
statics lying about when there's no need for them.
as i had to do in samba-tng, all uses of tdb_traverse modified to take
the new void* state argument.
2) disabled rpcclient: referring people to use SAMBA_TNG rpcclient.
i don't know how the other samba team members would react if i deleted
rpcclient from cvs main. damn, that code's so old, it's unreal.
20 rpcclient commands, instead of about 70 in SAMBA_TNG.
(This used to be commit 49d7f0afbc1c5425d53019e234d54ddf205c8e9a)
2000-02-04 07:59:31 +03:00
SHAREMODE_FN ( traverse_callback ) = ( SHAREMODE_FN_CAST ( ) ) state ;
1999-12-21 12:25:59 +03:00
data = ( struct locking_data * ) dbuf . dptr ;
shares = ( share_mode_entry * ) ( dbuf . dptr + sizeof ( * data ) ) ;
name = dbuf . dptr + sizeof ( * data ) + data - > num_share_mode_entries * sizeof ( * shares ) ;
for ( i = 0 ; i < data - > num_share_mode_entries ; i + + ) {
traverse_callback ( & shares [ i ] , name ) ;
}
return 0 ;
1996-05-04 11:50:46 +04:00
}
1997-10-02 03:32:22 +04:00
/*******************************************************************
1999-12-21 12:25:59 +03:00
Call the specified function on each entry under management by the
share mode system .
1997-10-02 03:32:22 +04:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
1) added void* state argument to tdb_traverse. guess what! there were
two places i found where it was appropriate to _use_ that third argument,
in locking.c and brlock.c! there was a static traverse_function and
i removed the static variable, typecast it to a void*, passed it to
tdb_traverse and re-cast it back to the traverse_function inside the
tdb_traverse function. this makes the use of tdb_traverse() reentrant,
which is never going to happen, i know, i just don't like to see
statics lying about when there's no need for them.
as i had to do in samba-tng, all uses of tdb_traverse modified to take
the new void* state argument.
2) disabled rpcclient: referring people to use SAMBA_TNG rpcclient.
i don't know how the other samba team members would react if i deleted
rpcclient from cvs main. damn, that code's so old, it's unreal.
20 rpcclient commands, instead of about 70 in SAMBA_TNG.
(This used to be commit 49d7f0afbc1c5425d53019e234d54ddf205c8e9a)
2000-02-04 07:59:31 +03:00
int share_mode_forall ( SHAREMODE_FN ( fn ) )
1997-10-02 03:32:22 +04:00
{
1999-12-21 12:25:59 +03:00
if ( ! tdb ) return 0 ;
1) added void* state argument to tdb_traverse. guess what! there were
two places i found where it was appropriate to _use_ that third argument,
in locking.c and brlock.c! there was a static traverse_function and
i removed the static variable, typecast it to a void*, passed it to
tdb_traverse and re-cast it back to the traverse_function inside the
tdb_traverse function. this makes the use of tdb_traverse() reentrant,
which is never going to happen, i know, i just don't like to see
statics lying about when there's no need for them.
as i had to do in samba-tng, all uses of tdb_traverse modified to take
the new void* state argument.
2) disabled rpcclient: referring people to use SAMBA_TNG rpcclient.
i don't know how the other samba team members would react if i deleted
rpcclient from cvs main. damn, that code's so old, it's unreal.
20 rpcclient commands, instead of about 70 in SAMBA_TNG.
(This used to be commit 49d7f0afbc1c5425d53019e234d54ddf205c8e9a)
2000-02-04 07:59:31 +03:00
return tdb_traverse ( tdb , traverse_fn , ( void * ) fn ) ;
1997-10-02 03:32:22 +04:00
}