1998-08-19 05:49:57 +04:00
/*
2002-01-30 09:08:46 +03:00
Unix SMB / CIFS implementation .
1998-08-19 05:49:57 +04:00
Blocking Locking functions
2003-02-27 04:04:34 +03:00
Copyright ( C ) Jeremy Allison 1998 - 2003
2008-11-03 19:56:55 +03:00
1998-08-19 05:49:57 +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
2007-07-09 23:25:36 +04:00
the Free Software Foundation ; either version 3 of the License , or
1998-08-19 05:49:57 +04:00
( at your option ) any later version .
2008-11-03 19:56:55 +03:00
1998-08-19 05:49:57 +04:00
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 .
2008-11-03 19:56:55 +03:00
1998-08-19 05:49:57 +04:00
You should have received a copy of the GNU General Public License
2007-07-10 04:52:41 +04:00
along with this program . If not , see < http : //www.gnu.org/licenses/>.
1998-08-19 05:49:57 +04:00
*/
# include "includes.h"
2006-07-18 01:09:02 +04:00
# undef DBGC_CLASS
# define DBGC_CLASS DBGC_LOCKING
2001-10-02 08:29:50 +04:00
1998-08-19 05:49:57 +04:00
/****************************************************************************
This is the structure to queue to implement blocking locks .
notify . It consists of the requesting SMB and the expiry time .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2008-11-04 15:25:07 +03:00
typedef struct blocking_lock_record {
struct blocking_lock_record * next ;
struct blocking_lock_record * prev ;
2003-07-24 10:56:56 +04:00
int com_type ;
files_struct * fsp ;
2006-07-18 05:05:51 +04:00
struct timeval expire_time ;
2003-07-24 10:56:56 +04:00
int lock_num ;
2008-10-14 03:59:36 +04:00
uint64_t offset ;
uint64_t count ;
uint32_t lock_pid ;
uint32_t blocking_pid ; /* PID that blocks us. */
2006-04-10 19:33:04 +04:00
enum brl_flavour lock_flav ;
enum brl_type lock_type ;
2003-07-24 10:56:56 +04:00
char * inbuf ;
int length ;
2008-01-04 23:56:23 +03:00
bool encrypted ;
1998-08-19 05:49:57 +04:00
} blocking_lock_record ;
2006-07-18 01:09:02 +04:00
/* dlink list we store pending lock records on. */
2004-08-21 04:43:21 +04:00
static blocking_lock_record * blocking_lock_queue ;
1998-08-19 05:49:57 +04:00
2006-07-18 01:09:02 +04:00
/* dlink list we move cancelled lock records onto. */
static blocking_lock_record * blocking_lock_cancelled_queue ;
2007-03-20 00:52:27 +03:00
/* The event that makes us process our blocking lock queue */
static struct timed_event * brl_timeout ;
1998-08-19 05:49:57 +04:00
/****************************************************************************
1998-08-20 23:28:37 +04:00
Determine if this is a secondary element of a chained SMB .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2007-10-19 04:40:25 +04:00
static bool in_chained_smb ( void )
1998-08-20 23:28:37 +04:00
{
2003-07-24 10:56:56 +04:00
return ( chain_size ! = 0 ) ;
1998-08-20 23:28:37 +04:00
}
2007-05-20 01:53:28 +04:00
static void received_unlock_msg ( struct messaging_context * msg ,
void * private_data ,
uint32_t msg_type ,
struct server_id server_id ,
DATA_BLOB * data ) ;
2007-03-20 00:52:27 +03:00
static void process_blocking_lock_queue ( void ) ;
static void brl_timeout_fn ( struct event_context * event_ctx ,
struct timed_event * te ,
const struct timeval * now ,
void * private_data )
{
SMB_ASSERT ( brl_timeout = = te ) ;
TALLOC_FREE ( brl_timeout ) ;
change_to_root_user ( ) ; /* TODO: Possibly run all timed events as
* root */
process_blocking_lock_queue ( ) ;
}
/****************************************************************************
After a change to blocking_lock_queue , recalculate the timed_event for the
next processing .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2007-10-19 04:40:25 +04:00
static bool recalc_brl_timeout ( void )
2007-03-20 00:52:27 +03:00
{
blocking_lock_record * brl ;
struct timeval next_timeout ;
TALLOC_FREE ( brl_timeout ) ;
next_timeout = timeval_zero ( ) ;
for ( brl = blocking_lock_queue ; brl ; brl = brl - > next ) {
if ( timeval_is_zero ( & brl - > expire_time ) ) {
2007-05-20 00:57:12 +04:00
/*
* If we ' re blocked on pid 0xFFFFFFFF this is
* a POSIX lock , so calculate a timeout of
* 10 seconds into the future .
*/
if ( brl - > blocking_pid = = 0xFFFFFFFF ) {
struct timeval psx_to = timeval_current_ofs ( 10 , 0 ) ;
next_timeout = timeval_min ( & next_timeout , & psx_to ) ;
}
2007-03-20 00:52:27 +03:00
continue ;
}
if ( timeval_is_zero ( & next_timeout ) ) {
next_timeout = brl - > expire_time ;
}
else {
next_timeout = timeval_min ( & next_timeout ,
& brl - > expire_time ) ;
}
}
if ( timeval_is_zero ( & next_timeout ) ) {
return True ;
}
if ( ! ( brl_timeout = event_add_timed ( smbd_event_context ( ) , NULL ,
next_timeout , " brl_timeout " ,
brl_timeout_fn , NULL ) ) ) {
return False ;
}
return True ;
}
2003-02-27 04:04:34 +03:00
1998-08-20 23:28:37 +04:00
/****************************************************************************
Function to push a blocking lock request onto the lock queue .
1998-08-19 05:49:57 +04:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2007-10-19 04:40:25 +04:00
bool push_blocking_lock_request ( struct byte_range_lock * br_lck ,
2008-01-04 23:56:23 +03:00
const struct smb_request * req ,
2006-04-10 19:33:04 +04:00
files_struct * fsp ,
int lock_timeout ,
int lock_num ,
2008-10-14 03:59:36 +04:00
uint32_t lock_pid ,
2006-04-10 19:33:04 +04:00
enum brl_type lock_type ,
enum brl_flavour lock_flav ,
2008-10-14 03:59:36 +04:00
uint64_t offset ,
uint64_t count ,
uint32_t blocking_pid )
1998-08-19 05:49:57 +04:00
{
2007-10-19 04:40:25 +04:00
static bool set_lock_msg ;
2008-01-04 23:56:23 +03:00
size_t length = smb_len ( req - > inbuf ) + 4 ;
2006-09-18 11:52:16 +04:00
blocking_lock_record * blr ;
2003-07-24 10:56:56 +04:00
NTSTATUS status ;
if ( in_chained_smb ( ) ) {
DEBUG ( 0 , ( " push_blocking_lock_request: cannot queue a chained request (currently). \n " ) ) ;
return False ;
}
/*
* Now queue an entry on the blocking lock queue . We setup
* the expiration time here .
*/
2003-02-27 04:04:34 +03:00
2008-11-04 15:25:07 +03:00
blr = talloc ( NULL , struct blocking_lock_record ) ;
if ( blr = = NULL ) {
2003-07-24 10:56:56 +04:00
DEBUG ( 0 , ( " push_blocking_lock_request: Malloc fail ! \n " ) ) ;
return False ;
}
2006-04-10 19:33:04 +04:00
blr - > next = NULL ;
blr - > prev = NULL ;
2008-11-04 15:25:07 +03:00
blr - > inbuf = TALLOC_ARRAY ( blr , char , length ) ;
if ( blr - > inbuf = = NULL ) {
2003-07-24 10:56:56 +04:00
DEBUG ( 0 , ( " push_blocking_lock_request: Malloc fail (2)! \n " ) ) ;
2008-11-04 15:25:07 +03:00
TALLOC_FREE ( blr ) ;
2003-07-24 10:56:56 +04:00
return False ;
}
1998-08-19 05:49:57 +04:00
2008-11-03 00:33:20 +03:00
blr - > com_type = req - > cmd ;
2006-04-10 19:33:04 +04:00
blr - > fsp = fsp ;
2006-07-18 05:05:51 +04:00
if ( lock_timeout = = - 1 ) {
blr - > expire_time . tv_sec = 0 ;
blr - > expire_time . tv_usec = 0 ; /* Never expire. */
} else {
blr - > expire_time = timeval_current_ofs ( lock_timeout / 1000 ,
( lock_timeout % 1000 ) * 1000 ) ;
}
2003-07-24 10:56:56 +04:00
blr - > lock_num = lock_num ;
blr - > lock_pid = lock_pid ;
2007-05-20 00:57:12 +04:00
blr - > blocking_pid = blocking_pid ;
2006-04-10 19:33:04 +04:00
blr - > lock_flav = lock_flav ;
blr - > lock_type = lock_type ;
2003-07-24 10:56:56 +04:00
blr - > offset = offset ;
blr - > count = count ;
2008-01-04 23:56:23 +03:00
memcpy ( blr - > inbuf , req - > inbuf , length ) ;
2003-07-24 10:56:56 +04:00
blr - > length = length ;
2008-01-04 23:56:23 +03:00
blr - > encrypted = req - > encrypted ;
2003-07-24 10:56:56 +04:00
/* Add a pending lock record for this. */
2007-05-14 17:01:28 +04:00
status = brl_lock ( smbd_messaging_context ( ) , br_lck ,
2006-04-10 19:33:04 +04:00
lock_pid ,
procid_self ( ) ,
offset ,
count ,
2006-07-29 23:14:24 +04:00
lock_type = = READ_LOCK ? PENDING_READ_LOCK : PENDING_WRITE_LOCK ,
2006-04-10 19:33:04 +04:00
blr - > lock_flav ,
2007-05-20 00:57:12 +04:00
lock_timeout ? True : False , /* blocking_lock. */
NULL ) ;
2003-07-24 10:56:56 +04:00
if ( ! NT_STATUS_IS_OK ( status ) ) {
DEBUG ( 0 , ( " push_blocking_lock_request: failed to add PENDING_LOCK record. \n " ) ) ;
2006-07-18 01:09:02 +04:00
DLIST_REMOVE ( blocking_lock_queue , blr ) ;
2008-11-04 15:25:07 +03:00
TALLOC_FREE ( blr ) ;
2003-07-24 10:56:56 +04:00
return False ;
}
2006-09-18 11:52:16 +04:00
DLIST_ADD_END ( blocking_lock_queue , blr , blocking_lock_record * ) ;
2007-03-20 00:52:27 +03:00
recalc_brl_timeout ( ) ;
2003-07-24 10:56:56 +04:00
/* Ensure we'll receive messages when this is unlocked. */
if ( ! set_lock_msg ) {
2007-05-20 01:53:28 +04:00
messaging_register ( smbd_messaging_context ( ) , NULL ,
MSG_SMB_UNLOCK , received_unlock_msg ) ;
2003-07-24 10:56:56 +04:00
set_lock_msg = True ;
}
1998-08-21 05:30:29 +04:00
2008-01-05 12:17:33 +03:00
DEBUG ( 3 , ( " push_blocking_lock_request: lock request length=%u blocked with "
2006-07-18 05:05:51 +04:00
" expiry time (%u sec. %u usec) (+%d msec) for fnum = %d, name = %s \n " ,
2008-01-05 12:17:33 +03:00
( unsigned int ) length , ( unsigned int ) blr - > expire_time . tv_sec ,
2006-07-18 05:05:51 +04:00
( unsigned int ) blr - > expire_time . tv_usec , lock_timeout ,
2003-07-24 10:56:56 +04:00
blr - > fsp - > fnum , blr - > fsp - > fsp_name ) ) ;
1998-08-19 05:49:57 +04:00
2003-07-24 10:56:56 +04:00
/* Push the MID of this packet on the signing queue. */
2008-01-04 23:56:23 +03:00
srv_defer_sign_response ( SVAL ( req - > inbuf , smb_mid ) ) ;
2003-07-24 10:56:56 +04:00
return True ;
1998-08-19 05:49:57 +04:00
}
1998-08-20 23:28:37 +04:00
/****************************************************************************
Return a lockingX success SMB .
1998-08-19 05:49:57 +04:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
1998-08-20 23:28:37 +04:00
static void reply_lockingX_success ( blocking_lock_record * blr )
1998-08-19 05:49:57 +04:00
{
2007-08-14 14:06:33 +04:00
struct smb_request * req ;
1998-08-19 05:49:57 +04:00
2007-08-30 23:48:31 +04:00
if ( ! ( req = talloc ( talloc_tos ( ) , struct smb_request ) ) ) {
2007-08-14 14:06:33 +04:00
smb_panic ( " Could not allocate smb_request " ) ;
}
2008-01-04 23:56:23 +03:00
init_smb_request ( req , ( uint8 * ) blr - > inbuf , 0 , blr - > encrypted ) ;
2008-11-03 23:55:05 +03:00
req - > inbuf = ( uint8_t * ) ( blr - > inbuf ) ;
2007-08-14 14:06:33 +04:00
reply_outbuf ( req , 2 , 0 ) ;
1998-08-19 05:49:57 +04:00
2003-07-24 10:56:56 +04:00
/*
* As this message is a lockingX call we must handle
* any following chained message correctly .
* This is normally handled in construct_reply ( ) ,
* but as that calls switch_message , we can ' t use
* that here and must set up the chain info manually .
*/
1998-08-19 05:49:57 +04:00
2007-08-27 16:04:09 +04:00
chain_reply ( req ) ;
1998-08-19 05:49:57 +04:00
2008-01-04 23:56:23 +03:00
if ( ! srv_send_smb ( smbd_server_fd ( ) ,
( char * ) req - > outbuf ,
IS_CONN_ENCRYPTED ( blr - > fsp - > conn ) ) ) {
exit_server_cleanly ( " send_blocking_reply: srv_send_smb failed. " ) ;
2007-08-14 14:06:33 +04:00
}
1998-08-20 23:28:37 +04:00
}
/****************************************************************************
Return a generic lock fail error blocking call .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2001-08-27 12:19:43 +04:00
static void generic_blocking_lock_error ( blocking_lock_record * blr , NTSTATUS status )
1998-08-20 23:28:37 +04:00
{
2007-08-14 14:06:33 +04:00
char outbuf [ smb_size ] ;
2001-06-09 05:38:54 +04:00
char * inbuf = blr - > inbuf ;
2007-08-14 14:06:33 +04:00
2001-06-09 05:38:54 +04:00
construct_reply_common ( inbuf , outbuf ) ;
1998-08-20 23:28:37 +04:00
2002-03-11 02:18:44 +03:00
/* whenever a timeout is given w2k maps LOCK_NOT_GRANTED to
FILE_LOCK_CONFLICT ! ( tridge ) */
if ( NT_STATUS_EQUAL ( status , NT_STATUS_LOCK_NOT_GRANTED ) ) {
status = NT_STATUS_FILE_LOCK_CONFLICT ;
}
2006-07-18 01:09:02 +04:00
if ( NT_STATUS_EQUAL ( status , NT_STATUS_FILE_LOCK_CONFLICT ) ) {
/* Store the last lock error. */
files_struct * fsp = blr - > fsp ;
2008-01-05 00:59:26 +03:00
if ( fsp ) {
fsp - > last_lock_failure . context . smbpid = blr - > lock_pid ;
fsp - > last_lock_failure . context . tid = fsp - > conn - > cnum ;
fsp - > last_lock_failure . context . pid = procid_self ( ) ;
fsp - > last_lock_failure . start = blr - > offset ;
fsp - > last_lock_failure . size = blr - > count ;
fsp - > last_lock_failure . fnum = fsp - > fnum ;
fsp - > last_lock_failure . lock_type = READ_LOCK ; /* Don't care. */
fsp - > last_lock_failure . lock_flav = blr - > lock_flav ;
}
2006-07-18 01:09:02 +04:00
}
2001-08-27 12:19:43 +04:00
ERROR_NT ( status ) ;
2008-01-05 00:59:26 +03:00
if ( ! srv_send_smb ( smbd_server_fd ( ) , outbuf , blr - > encrypted ) ) {
2008-01-04 23:56:23 +03:00
exit_server_cleanly ( " generic_blocking_lock_error: srv_send_smb failed. " ) ;
2006-07-18 01:09:02 +04:00
}
1998-08-19 05:49:57 +04:00
}
/****************************************************************************
1998-08-20 23:28:37 +04:00
Return a lock fail error for a lockingX call . Undo all the locks we have
obtained first .
1998-08-19 05:49:57 +04:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2001-08-27 12:19:43 +04:00
static void reply_lockingX_error ( blocking_lock_record * blr , NTSTATUS status )
1998-08-19 05:49:57 +04:00
{
2001-08-27 12:19:43 +04:00
char * inbuf = blr - > inbuf ;
files_struct * fsp = blr - > fsp ;
uint16 num_ulocks = SVAL ( inbuf , smb_vwv6 ) ;
2008-10-14 03:59:36 +04:00
uint64_t count = ( uint64_t ) 0 , offset = ( uint64_t ) 0 ;
2006-07-11 22:01:26 +04:00
uint32 lock_pid ;
2001-08-27 12:19:43 +04:00
unsigned char locktype = CVAL ( inbuf , smb_vwv3 ) ;
2007-10-19 04:40:25 +04:00
bool large_file_format = ( locktype & LOCKING_ANDX_LARGE_FILES ) ;
2008-11-01 19:22:15 +03:00
uint8_t * data ;
2001-08-27 12:19:43 +04:00
int i ;
2008-11-01 19:22:15 +03:00
data = ( uint8_t * ) smb_buf ( inbuf )
+ ( ( large_file_format ? 20 : 10 ) * num_ulocks ) ;
2008-11-03 19:56:55 +03:00
2001-08-27 12:19:43 +04:00
/*
* Data now points at the beginning of the list
* of smb_lkrng structs .
*/
/*
* Ensure we don ' t do a remove on the lock that just failed ,
* as under POSIX rules , if we have a lock already there , we
* will delete it ( and we shouldn ' t ) . . . . .
*/
2008-11-03 19:56:55 +03:00
2001-08-27 12:19:43 +04:00
for ( i = blr - > lock_num - 1 ; i > = 0 ; i - - ) {
2007-10-19 04:40:25 +04:00
bool err ;
2008-11-03 19:56:55 +03:00
2001-08-27 12:19:43 +04:00
lock_pid = get_lock_pid ( data , i , large_file_format ) ;
count = get_lock_count ( data , i , large_file_format ) ;
offset = get_lock_offset ( data , i , large_file_format , & err ) ;
2008-11-03 19:56:55 +03:00
2001-08-27 12:19:43 +04:00
/*
* We know err cannot be set as if it was the lock
* request would never have been queued . JRA .
*/
2008-11-03 19:56:55 +03:00
2007-05-14 17:01:28 +04:00
do_unlock ( smbd_messaging_context ( ) ,
fsp ,
2006-04-10 19:33:04 +04:00
lock_pid ,
count ,
offset ,
WINDOWS_LOCK ) ;
2001-08-27 12:19:43 +04:00
}
2008-11-03 19:56:55 +03:00
2001-08-27 12:19:43 +04:00
generic_blocking_lock_error ( blr , status ) ;
1998-08-20 23:28:37 +04:00
}
/****************************************************************************
Return a lock fail error .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2001-08-27 12:19:43 +04:00
static void blocking_lock_reply_error ( blocking_lock_record * blr , NTSTATUS status )
1998-08-20 23:28:37 +04:00
{
2001-08-27 12:19:43 +04:00
switch ( blr - > com_type ) {
case SMBlockingX :
reply_lockingX_error ( blr , status ) ;
break ;
2006-04-10 19:33:04 +04:00
case SMBtrans2 :
case SMBtranss2 :
{
2007-08-14 14:06:33 +04:00
char outbuf [ smb_size ] ;
2006-04-10 19:33:04 +04:00
char * inbuf = blr - > inbuf ;
construct_reply_common ( inbuf , outbuf ) ;
/* construct_reply_common has done us the favor to pre-fill the
* command field with SMBtranss2 which is wrong : - )
*/
SCVAL ( outbuf , smb_com , SMBtrans2 ) ;
ERROR_NT ( status ) ;
2008-01-04 23:56:23 +03:00
if ( ! srv_send_smb ( smbd_server_fd ( ) ,
outbuf ,
IS_CONN_ENCRYPTED ( blr - > fsp - > conn ) ) ) {
exit_server_cleanly ( " blocking_lock_reply_error: srv_send_smb failed. " ) ;
2006-04-10 19:33:04 +04:00
}
break ;
}
2001-08-27 12:19:43 +04:00
default :
DEBUG ( 0 , ( " blocking_lock_reply_error: PANIC - unknown type on blocking lock queue - exiting.! \n " ) ) ;
exit_server ( " PANIC - unknown type on blocking lock queue " ) ;
}
1998-08-20 23:28:37 +04:00
}
/****************************************************************************
Attempt to finish off getting all pending blocking locks for a lockingX call .
Returns True if we want to be removed from the list .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2007-10-19 04:40:25 +04:00
static bool process_lockingX ( blocking_lock_record * blr )
1998-08-19 05:49:57 +04:00
{
2001-08-27 12:19:43 +04:00
char * inbuf = blr - > inbuf ;
unsigned char locktype = CVAL ( inbuf , smb_vwv3 ) ;
files_struct * fsp = blr - > fsp ;
uint16 num_ulocks = SVAL ( inbuf , smb_vwv6 ) ;
uint16 num_locks = SVAL ( inbuf , smb_vwv7 ) ;
2008-10-14 03:59:36 +04:00
uint64_t count = ( uint64_t ) 0 , offset = ( uint64_t ) 0 ;
2006-07-11 22:01:26 +04:00
uint32 lock_pid ;
2007-10-19 04:40:25 +04:00
bool large_file_format = ( locktype & LOCKING_ANDX_LARGE_FILES ) ;
2008-11-01 19:22:15 +03:00
uint8_t * data ;
2001-08-27 21:52:23 +04:00
NTSTATUS status = NT_STATUS_OK ;
2001-08-27 12:19:43 +04:00
2008-11-01 19:22:15 +03:00
data = ( uint8_t * ) smb_buf ( inbuf )
+ ( ( large_file_format ? 20 : 10 ) * num_ulocks ) ;
2001-08-27 12:19:43 +04:00
/*
* Data now points at the beginning of the list
* of smb_lkrng structs .
*/
2006-07-18 05:05:51 +04:00
2001-08-27 12:19:43 +04:00
for ( ; blr - > lock_num < num_locks ; blr - > lock_num + + ) {
2006-07-18 05:05:51 +04:00
struct byte_range_lock * br_lck = NULL ;
2007-10-19 04:40:25 +04:00
bool err ;
2001-08-27 12:19:43 +04:00
lock_pid = get_lock_pid ( data , blr - > lock_num , large_file_format ) ;
count = get_lock_count ( data , blr - > lock_num , large_file_format ) ;
offset = get_lock_offset ( data , blr - > lock_num , large_file_format , & err ) ;
2008-11-03 19:56:55 +03:00
2001-08-27 12:19:43 +04:00
/*
* We know err cannot be set as if it was the lock
* request would never have been queued . JRA .
*/
errno = 0 ;
2007-05-14 17:01:28 +04:00
br_lck = do_lock ( smbd_messaging_context ( ) ,
fsp ,
2006-04-10 19:33:04 +04:00
lock_pid ,
count ,
offset ,
2006-07-18 01:09:02 +04:00
( ( locktype & LOCKING_ANDX_SHARED_LOCK ) ?
READ_LOCK : WRITE_LOCK ) ,
2006-04-10 19:33:04 +04:00
WINDOWS_LOCK ,
2006-07-18 05:05:51 +04:00
True ,
2007-05-20 00:57:12 +04:00
& status ,
& blr - > blocking_pid ) ;
2006-07-18 05:05:51 +04:00
TALLOC_FREE ( br_lck ) ;
2006-04-10 19:33:04 +04:00
if ( NT_STATUS_IS_ERR ( status ) ) {
break ;
}
2001-08-27 12:19:43 +04:00
}
if ( blr - > lock_num = = num_locks ) {
/*
* Success - we got all the locks .
*/
2008-11-03 19:56:55 +03:00
2001-08-27 12:19:43 +04:00
DEBUG ( 3 , ( " process_lockingX file = %s, fnum=%d type=%d num_locks=%d \n " ,
fsp - > fsp_name , fsp - > fnum , ( unsigned int ) locktype , num_locks ) ) ;
reply_lockingX_success ( blr ) ;
return True ;
2008-11-04 16:35:44 +03:00
}
2008-11-03 19:56:55 +03:00
2008-11-04 16:35:44 +03:00
if ( ! NT_STATUS_EQUAL ( status , NT_STATUS_LOCK_NOT_GRANTED ) & &
! NT_STATUS_EQUAL ( status , NT_STATUS_FILE_LOCK_CONFLICT ) ) {
/*
* We have other than a " can't get lock "
* error . Free any locks we had and return an error .
* Return True so we get dequeued .
*/
2001-08-27 12:19:43 +04:00
blocking_lock_reply_error ( blr , status ) ;
return True ;
}
/*
* Still can ' t get all the locks - keep waiting .
*/
2008-11-03 19:56:55 +03:00
2001-08-27 12:19:43 +04:00
DEBUG ( 10 , ( " process_lockingX: only got %d locks of %d needed for file %s, fnum = %d. \
Waiting . . . . \ n " ,
blr - > lock_num , num_locks , fsp - > fsp_name , fsp - > fnum ) ) ;
2008-11-03 19:56:55 +03:00
2001-08-27 12:19:43 +04:00
return False ;
1998-08-19 05:49:57 +04:00
}
2006-04-10 19:33:04 +04:00
/****************************************************************************
Attempt to get the posix lock request from a SMBtrans2 call .
Returns True if we want to be removed from the list .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2007-10-19 04:40:25 +04:00
static bool process_trans2 ( blocking_lock_record * blr )
2006-04-10 19:33:04 +04:00
{
2007-08-03 18:33:38 +04:00
struct smb_request * req ;
2006-04-10 19:33:04 +04:00
char params [ 2 ] ;
NTSTATUS status ;
2007-05-14 17:01:28 +04:00
struct byte_range_lock * br_lck = do_lock ( smbd_messaging_context ( ) ,
blr - > fsp ,
2006-07-18 05:05:51 +04:00
blr - > lock_pid ,
blr - > count ,
blr - > offset ,
blr - > lock_type ,
blr - > lock_flav ,
True ,
2007-05-20 00:57:12 +04:00
& status ,
& blr - > blocking_pid ) ;
2006-07-18 05:05:51 +04:00
TALLOC_FREE ( br_lck ) ;
2006-04-10 19:33:04 +04:00
if ( ! NT_STATUS_IS_OK ( status ) ) {
if ( ERROR_WAS_LOCK_DENIED ( status ) ) {
/* Still can't get the lock, just keep waiting. */
return False ;
}
/*
* We have other than a " can't get lock "
* error . Send an error and return True so we get dequeued .
*/
blocking_lock_reply_error ( blr , status ) ;
return True ;
}
/* We finally got the lock, return success. */
2007-08-03 18:33:38 +04:00
2007-08-30 23:48:31 +04:00
if ( ! ( req = talloc ( talloc_tos ( ) , struct smb_request ) ) ) {
2007-08-03 18:33:38 +04:00
blocking_lock_reply_error ( blr , NT_STATUS_NO_MEMORY ) ;
return True ;
}
2008-01-04 23:56:23 +03:00
init_smb_request ( req , ( uint8 * ) blr - > inbuf , 0 , blr - > encrypted ) ;
2008-11-03 23:55:05 +03:00
req - > inbuf = ( uint8_t * ) ( blr - > inbuf ) ;
2007-08-03 18:33:38 +04:00
SCVAL ( req - > inbuf , smb_com , SMBtrans2 ) ;
2006-04-10 19:33:04 +04:00
SSVAL ( params , 0 , 0 ) ;
2006-08-14 20:53:14 +04:00
/* Fake up max_data_bytes here - we know it fits. */
2008-01-04 23:56:23 +03:00
send_trans2_replies ( blr - > fsp - > conn , req , params , 2 , NULL , 0 , 0xffff ) ;
2006-04-10 19:33:04 +04:00
return True ;
}
1998-08-20 23:28:37 +04:00
/****************************************************************************
Process a blocking lock SMB .
Returns True if we want to be removed from the list .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2007-10-19 04:40:25 +04:00
static bool blocking_lock_record_process ( blocking_lock_record * blr )
1998-08-20 23:28:37 +04:00
{
2003-07-24 10:56:56 +04:00
switch ( blr - > com_type ) {
case SMBlockingX :
return process_lockingX ( blr ) ;
2006-04-10 19:33:04 +04:00
case SMBtrans2 :
case SMBtranss2 :
return process_trans2 ( blr ) ;
2003-07-24 10:56:56 +04:00
default :
DEBUG ( 0 , ( " blocking_lock_record_process: PANIC - unknown type on blocking lock queue - exiting.! \n " ) ) ;
exit_server ( " PANIC - unknown type on blocking lock queue " ) ;
}
return False ; /* Keep compiler happy. */
1998-08-20 23:28:37 +04:00
}
1998-08-19 05:49:57 +04:00
/****************************************************************************
2006-07-18 01:09:02 +04:00
Cancel entries by fnum from the blocking lock pending queue .
1998-08-19 05:49:57 +04:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2006-07-18 01:09:02 +04:00
void cancel_pending_lock_requests_by_fid ( files_struct * fsp , struct byte_range_lock * br_lck )
1998-08-19 05:49:57 +04:00
{
2004-08-21 04:43:21 +04:00
blocking_lock_record * blr , * next = NULL ;
1998-08-19 05:49:57 +04:00
2004-08-21 04:43:21 +04:00
for ( blr = blocking_lock_queue ; blr ; blr = next ) {
2008-11-04 16:29:33 +03:00
unsigned char locktype = 0 ;
2004-08-21 04:43:21 +04:00
next = blr - > next ;
2008-11-04 16:29:33 +03:00
if ( blr - > fsp - > fnum ! = fsp - > fnum ) {
continue ;
}
2006-07-18 01:09:02 +04:00
2008-11-04 16:29:33 +03:00
if ( blr - > com_type = = SMBlockingX ) {
locktype = CVAL ( blr - > inbuf , smb_vwv3 ) ;
}
1998-08-21 05:30:29 +04:00
2008-11-04 16:29:33 +03:00
if ( br_lck ) {
DEBUG ( 10 , ( " remove_pending_lock_requests_by_fid - "
" removing request type %d for file %s fnum "
" = %d \n " , blr - > com_type , fsp - > fsp_name ,
fsp - > fnum ) ) ;
1998-08-19 05:49:57 +04:00
2008-11-04 16:29:33 +03:00
brl_lock_cancel ( br_lck ,
2006-04-10 19:33:04 +04:00
blr - > lock_pid ,
procid_self ( ) ,
blr - > offset ,
blr - > count ,
blr - > lock_flav ) ;
2008-11-04 16:29:33 +03:00
blocking_lock_cancel ( fsp ,
blr - > lock_pid ,
blr - > offset ,
blr - > count ,
blr - > lock_flav ,
locktype ,
NT_STATUS_RANGE_NOT_LOCKED ) ;
2003-07-24 10:56:56 +04:00
}
2008-11-04 16:29:33 +03:00
/* We're closing the file fsp here, so ensure
* we don ' t have a dangling pointer . */
blr - > fsp = NULL ;
2003-07-24 10:56:56 +04:00
}
1998-08-19 05:49:57 +04:00
}
/****************************************************************************
Delete entries by mid from the blocking lock pending queue . Always send reply .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
void remove_pending_lock_requests_by_mid ( int mid )
{
2004-08-21 04:43:21 +04:00
blocking_lock_record * blr , * next = NULL ;
1998-08-19 05:49:57 +04:00
2004-08-21 04:43:21 +04:00
for ( blr = blocking_lock_queue ; blr ; blr = next ) {
2008-11-04 16:33:20 +03:00
files_struct * fsp ;
struct byte_range_lock * br_lck ;
2004-08-21 04:43:21 +04:00
next = blr - > next ;
1998-08-21 05:30:29 +04:00
2008-11-04 16:33:20 +03:00
if ( SVAL ( blr - > inbuf , smb_mid ) ! = mid ) {
continue ;
}
fsp = blr - > fsp ;
br_lck = brl_get_locks ( talloc_tos ( ) , fsp ) ;
1998-08-21 05:30:29 +04:00
2008-11-04 16:33:20 +03:00
if ( br_lck ) {
DEBUG ( 10 , ( " remove_pending_lock_requests_by_mid - "
" removing request type %d for file %s fnum "
" = %d \n " , blr - > com_type , fsp - > fsp_name ,
fsp - > fnum ) ) ;
brl_lock_cancel ( br_lck ,
2006-04-10 19:33:04 +04:00
blr - > lock_pid ,
procid_self ( ) ,
blr - > offset ,
blr - > count ,
blr - > lock_flav ) ;
2008-11-04 16:33:20 +03:00
TALLOC_FREE ( br_lck ) ;
2003-07-24 10:56:56 +04:00
}
2008-11-04 16:33:20 +03:00
blocking_lock_reply_error ( blr , NT_STATUS_FILE_LOCK_CONFLICT ) ;
DLIST_REMOVE ( blocking_lock_queue , blr ) ;
TALLOC_FREE ( blr ) ;
2003-07-24 10:56:56 +04:00
}
1998-08-19 05:49:57 +04:00
}
2007-01-30 23:49:37 +03:00
/****************************************************************************
Is this mid a blocking lock request on the queue ?
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2007-10-19 04:40:25 +04:00
bool blocking_lock_was_deferred ( int mid )
2007-01-30 23:49:37 +03:00
{
blocking_lock_record * blr , * next = NULL ;
for ( blr = blocking_lock_queue ; blr ; blr = next ) {
next = blr - > next ;
if ( SVAL ( blr - > inbuf , smb_mid ) = = mid ) {
return True ;
}
}
return False ;
}
2003-02-27 04:04:34 +03:00
/****************************************************************************
Set a flag as an unlock request affects one of our pending locks .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2007-05-20 01:53:28 +04:00
static void received_unlock_msg ( struct messaging_context * msg ,
void * private_data ,
uint32_t msg_type ,
struct server_id server_id ,
DATA_BLOB * data )
2003-02-27 04:04:34 +03:00
{
DEBUG ( 10 , ( " received_unlock_msg \n " ) ) ;
2006-07-18 05:05:51 +04:00
process_blocking_lock_queue ( ) ;
2003-02-27 04:04:34 +03:00
}
1998-08-19 05:49:57 +04:00
/****************************************************************************
Process the blocking lock queue . Note that this is only called as root .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2007-03-20 00:52:27 +03:00
static void process_blocking_lock_queue ( void )
1998-08-19 05:49:57 +04:00
{
2006-07-18 05:05:51 +04:00
struct timeval tv_curr = timeval_current ( ) ;
2004-08-21 04:43:21 +04:00
blocking_lock_record * blr , * next = NULL ;
2007-10-19 04:40:25 +04:00
bool recalc_timeout = False ;
2003-07-24 10:56:56 +04:00
/*
* Go through the queue and see if we can get any of the locks .
*/
2004-08-21 04:43:21 +04:00
for ( blr = blocking_lock_queue ; blr ; blr = next ) {
2003-07-24 10:56:56 +04:00
connection_struct * conn = NULL ;
uint16 vuid ;
files_struct * fsp = NULL ;
2004-08-21 04:43:21 +04:00
next = blr - > next ;
2003-07-24 10:56:56 +04:00
/*
* Ensure we don ' t have any old chain_fsp values
* sitting around . . . .
*/
chain_size = 0 ;
fsp = blr - > fsp ;
conn = conn_find ( SVAL ( blr - > inbuf , smb_tid ) ) ;
vuid = ( lp_security ( ) = = SEC_SHARE ) ? UID_FIELD_INVALID :
SVAL ( blr - > inbuf , smb_uid ) ;
DEBUG ( 5 , ( " process_blocking_lock_queue: examining pending lock fnum = %d for file %s \n " ,
fsp - > fnum , fsp - > fsp_name ) ) ;
2007-08-30 00:49:09 +04:00
if ( ! change_to_user ( conn , vuid ) ) {
2008-01-06 18:15:45 +03:00
struct byte_range_lock * br_lck = brl_get_locks ( talloc_tos ( ) , fsp ) ;
2006-04-10 19:33:04 +04:00
2003-07-24 10:56:56 +04:00
/*
2007-08-30 00:49:09 +04:00
* Remove the entry and return an error to the client .
2003-07-24 10:56:56 +04:00
*/
2006-04-10 19:33:04 +04:00
if ( br_lck ) {
2006-07-18 01:09:02 +04:00
brl_lock_cancel ( br_lck ,
2006-04-10 19:33:04 +04:00
blr - > lock_pid ,
procid_self ( ) ,
blr - > offset ,
blr - > count ,
blr - > lock_flav ) ;
2006-07-11 22:01:26 +04:00
TALLOC_FREE ( br_lck ) ;
2006-04-10 19:33:04 +04:00
}
2003-07-24 10:56:56 +04:00
2007-08-30 00:49:09 +04:00
DEBUG ( 0 , ( " process_blocking_lock_queue: Unable to become user vuid=%d. \n " ,
vuid ) ) ;
blocking_lock_reply_error ( blr , NT_STATUS_ACCESS_DENIED ) ;
2006-07-18 01:09:02 +04:00
DLIST_REMOVE ( blocking_lock_queue , blr ) ;
2008-11-04 15:25:07 +03:00
TALLOC_FREE ( blr ) ;
2007-03-20 00:52:27 +03:00
recalc_timeout = True ;
2003-07-24 10:56:56 +04:00
continue ;
}
2007-08-30 00:49:09 +04:00
if ( ! set_current_service ( conn , SVAL ( blr - > inbuf , smb_flg ) , True ) ) {
2008-01-06 18:15:45 +03:00
struct byte_range_lock * br_lck = brl_get_locks ( talloc_tos ( ) , fsp ) ;
2006-04-10 19:33:04 +04:00
2003-07-24 10:56:56 +04:00
/*
* Remove the entry and return an error to the client .
*/
2006-04-10 19:33:04 +04:00
if ( br_lck ) {
2006-07-18 01:09:02 +04:00
brl_lock_cancel ( br_lck ,
2006-04-10 19:33:04 +04:00
blr - > lock_pid ,
procid_self ( ) ,
blr - > offset ,
blr - > count ,
blr - > lock_flav ) ;
2006-07-11 22:01:26 +04:00
TALLOC_FREE ( br_lck ) ;
2006-04-10 19:33:04 +04:00
}
2003-07-24 10:56:56 +04:00
2007-08-30 00:49:09 +04:00
DEBUG ( 0 , ( " process_blocking_lock_queue: Unable to become service Error was %s. \n " , strerror ( errno ) ) ) ;
2006-04-10 19:33:04 +04:00
blocking_lock_reply_error ( blr , NT_STATUS_ACCESS_DENIED ) ;
2006-07-18 01:09:02 +04:00
DLIST_REMOVE ( blocking_lock_queue , blr ) ;
2008-11-04 15:25:07 +03:00
TALLOC_FREE ( blr ) ;
2007-03-20 00:52:27 +03:00
recalc_timeout = True ;
2007-08-30 00:49:09 +04:00
change_to_root_user ( ) ;
2003-07-24 10:56:56 +04:00
continue ;
}
2007-08-30 00:49:09 +04:00
/*
* Go through the remaining locks and try and obtain them .
* The call returns True if all locks were obtained successfully
* and False if we still need to wait .
*/
2006-04-10 19:33:04 +04:00
2007-08-30 00:49:09 +04:00
if ( blocking_lock_record_process ( blr ) ) {
2008-01-06 18:15:45 +03:00
struct byte_range_lock * br_lck = brl_get_locks ( talloc_tos ( ) , fsp ) ;
2003-07-24 10:56:56 +04:00
2006-04-10 19:33:04 +04:00
if ( br_lck ) {
2006-07-18 01:09:02 +04:00
brl_lock_cancel ( br_lck ,
2006-04-10 19:33:04 +04:00
blr - > lock_pid ,
procid_self ( ) ,
blr - > offset ,
blr - > count ,
blr - > lock_flav ) ;
2006-07-11 22:01:26 +04:00
TALLOC_FREE ( br_lck ) ;
2006-04-10 19:33:04 +04:00
}
2003-07-24 10:56:56 +04:00
2006-07-18 01:09:02 +04:00
DLIST_REMOVE ( blocking_lock_queue , blr ) ;
2008-11-04 15:25:07 +03:00
TALLOC_FREE ( blr ) ;
2007-03-20 00:52:27 +03:00
recalc_timeout = True ;
2003-07-24 10:56:56 +04:00
change_to_root_user ( ) ;
continue ;
}
2007-08-30 00:49:09 +04:00
change_to_root_user ( ) ;
2003-07-24 10:56:56 +04:00
/*
2007-08-30 00:49:09 +04:00
* We couldn ' t get the locks for this record on the list .
* If the time has expired , return a lock error .
2003-07-24 10:56:56 +04:00
*/
2007-08-30 00:49:09 +04:00
if ( ! timeval_is_zero ( & blr - > expire_time ) & & timeval_compare ( & blr - > expire_time , & tv_curr ) < = 0 ) {
2008-01-06 18:15:45 +03:00
struct byte_range_lock * br_lck = brl_get_locks ( talloc_tos ( ) , fsp ) ;
2006-04-10 19:33:04 +04:00
2007-08-30 00:49:09 +04:00
/*
* Lock expired - throw away all previously
* obtained locks and return lock error .
*/
2006-04-10 19:33:04 +04:00
if ( br_lck ) {
2007-08-30 00:49:09 +04:00
DEBUG ( 5 , ( " process_blocking_lock_queue: pending lock fnum = %d for file %s timed out. \n " ,
fsp - > fnum , fsp - > fsp_name ) ) ;
2006-07-18 01:09:02 +04:00
brl_lock_cancel ( br_lck ,
2006-04-10 19:33:04 +04:00
blr - > lock_pid ,
procid_self ( ) ,
blr - > offset ,
blr - > count ,
blr - > lock_flav ) ;
2006-07-11 22:01:26 +04:00
TALLOC_FREE ( br_lck ) ;
2006-04-10 19:33:04 +04:00
}
2003-07-24 10:56:56 +04:00
2007-08-30 00:49:09 +04:00
blocking_lock_reply_error ( blr , NT_STATUS_FILE_LOCK_CONFLICT ) ;
2006-07-18 01:09:02 +04:00
DLIST_REMOVE ( blocking_lock_queue , blr ) ;
2008-11-04 15:25:07 +03:00
TALLOC_FREE ( blr ) ;
2007-03-20 00:52:27 +03:00
recalc_timeout = True ;
2003-07-24 10:56:56 +04:00
}
}
2007-03-20 00:52:27 +03:00
if ( recalc_timeout ) {
recalc_brl_timeout ( ) ;
}
1998-08-19 05:49:57 +04:00
}
2006-07-18 01:09:02 +04:00
/****************************************************************************
Handle a cancel message . Lock already moved onto the cancel queue .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
# define MSG_BLOCKING_LOCK_CANCEL_SIZE (sizeof(blocking_lock_record *) + sizeof(NTSTATUS))
2007-05-20 01:53:28 +04:00
static void process_blocking_lock_cancel_message ( struct messaging_context * ctx ,
void * private_data ,
uint32_t msg_type ,
struct server_id server_id ,
DATA_BLOB * data )
2006-07-18 01:09:02 +04:00
{
NTSTATUS err ;
2007-05-20 01:53:28 +04:00
const char * msg = ( const char * ) data - > data ;
2006-07-18 01:09:02 +04:00
blocking_lock_record * blr ;
2007-05-20 01:53:28 +04:00
if ( data - > data = = NULL ) {
2007-06-16 01:58:49 +04:00
smb_panic ( " process_blocking_lock_cancel_message: null msg " ) ;
2006-07-18 01:09:02 +04:00
}
2007-05-20 01:53:28 +04:00
if ( data - > length ! = MSG_BLOCKING_LOCK_CANCEL_SIZE ) {
2006-07-18 01:09:02 +04:00
DEBUG ( 0 , ( " process_blocking_lock_cancel_message: "
2007-05-20 01:53:28 +04:00
" Got invalid msg len %d \n " , ( int ) data - > length ) ) ;
2007-06-16 01:58:49 +04:00
smb_panic ( " process_blocking_lock_cancel_message: bad msg " ) ;
2006-07-18 01:09:02 +04:00
}
memcpy ( & blr , msg , sizeof ( blr ) ) ;
memcpy ( & err , & msg [ sizeof ( blr ) ] , sizeof ( NTSTATUS ) ) ;
DEBUG ( 10 , ( " process_blocking_lock_cancel_message: returning error %s \n " ,
nt_errstr ( err ) ) ) ;
blocking_lock_reply_error ( blr , err ) ;
DLIST_REMOVE ( blocking_lock_cancelled_queue , blr ) ;
2008-11-04 15:25:07 +03:00
TALLOC_FREE ( blr ) ;
2006-07-18 01:09:02 +04:00
}
/****************************************************************************
Send ourselves a blocking lock cancelled message . Handled asynchronously above .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2007-10-19 04:40:25 +04:00
bool blocking_lock_cancel ( files_struct * fsp ,
2006-07-18 01:09:02 +04:00
uint32 lock_pid ,
2008-10-14 03:59:36 +04:00
uint64_t offset ,
uint64_t count ,
2006-07-18 01:09:02 +04:00
enum brl_flavour lock_flav ,
unsigned char locktype ,
NTSTATUS err )
{
2007-10-19 04:40:25 +04:00
static bool initialized ;
2006-07-18 01:09:02 +04:00
char msg [ MSG_BLOCKING_LOCK_CANCEL_SIZE ] ;
blocking_lock_record * blr ;
if ( ! initialized ) {
/* Register our message. */
2007-05-20 01:53:28 +04:00
messaging_register ( smbd_messaging_context ( ) , NULL ,
MSG_SMB_BLOCKING_LOCK_CANCEL ,
process_blocking_lock_cancel_message ) ;
2006-07-18 01:09:02 +04:00
initialized = True ;
}
for ( blr = blocking_lock_queue ; blr ; blr = blr - > next ) {
if ( fsp = = blr - > fsp & &
lock_pid = = blr - > lock_pid & &
offset = = blr - > offset & &
count = = blr - > count & &
lock_flav = = blr - > lock_flav ) {
break ;
}
}
if ( ! blr ) {
return False ;
}
/* Check the flags are right. */
if ( blr - > com_type = = SMBlockingX & &
( locktype & LOCKING_ANDX_LARGE_FILES ) ! =
( CVAL ( blr - > inbuf , smb_vwv3 ) & LOCKING_ANDX_LARGE_FILES ) ) {
return False ;
}
/* Move to cancelled queue. */
DLIST_REMOVE ( blocking_lock_queue , blr ) ;
DLIST_ADD ( blocking_lock_cancelled_queue , blr ) ;
/* Create the message. */
memcpy ( msg , & blr , sizeof ( blr ) ) ;
memcpy ( & msg [ sizeof ( blr ) ] , & err , sizeof ( NTSTATUS ) ) ;
2007-05-15 00:31:28 +04:00
messaging_send_buf ( smbd_messaging_context ( ) , procid_self ( ) ,
MSG_SMB_BLOCKING_LOCK_CANCEL ,
( uint8 * ) & msg , sizeof ( msg ) ) ;
2006-07-18 01:09:02 +04:00
return True ;
}