From 3f153e592b420ed79688b97559de9586a0f7b6fd Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 19 Aug 1998 01:49:57 +0000 Subject: Blocking lock code split out... Jeremy. (This used to be commit 9cdb148ef56dc8f74891f5c6e9cae10142bd4c6e) --- source3/smbd/blocking.c | 375 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 375 insertions(+) create mode 100644 source3/smbd/blocking.c (limited to 'source3/smbd/blocking.c') diff --git a/source3/smbd/blocking.c b/source3/smbd/blocking.c new file mode 100644 index 0000000000..294dafc405 --- /dev/null +++ b/source3/smbd/blocking.c @@ -0,0 +1,375 @@ +/* + Unix SMB/Netbios implementation. + Version 1.9. + Blocking Locking functions + Copyright (C) Jeremy Allison 1998 + + 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 02139, USA. +*/ + +#include "includes.h" +extern int DEBUGLEVEL; +extern int Client; + +/**************************************************************************** + This is the structure to queue to implement blocking locks. + notify. It consists of the requesting SMB and the expiry time. +*****************************************************************************/ + +typedef struct { + ubi_slNode msg_next; + time_t expire_time; + int lock_num; + char *inbuf; + int length; +} blocking_lock_record; + +static ubi_slList blocking_lock_queue = { NULL, (ubi_slNodePtr)&blocking_lock_queue, 0}; + +/**************************************************************************** + Destructor for the above structure. +****************************************************************************/ + +static void free_blocking_lock_record(blocking_lock_record *blr) +{ + free(blr->inbuf); + free((char *)blr); +} + +/**************************************************************************** + Function to push a blocking lockingX request onto the lock queue. + NB. We can only get away with this as the CIFS spec only includes + SMB_COM_LOCKING_ANDX as a head SMB, ie. it is not one that is ever + generated as part of a chain. +****************************************************************************/ + +BOOL push_blocking_lock_request( char *inbuf, int length, int lock_timeout, int lock_num) +{ + blocking_lock_record *blr; + files_struct *fsp = file_fsp(inbuf,smb_vwv2); + + /* + * Now queue an entry on the blocking lock queue. We setup + * the expiration time here. + */ + + if((blr = (blocking_lock_record *)malloc(sizeof(blocking_lock_record))) == NULL) { + DEBUG(0,("push_blocking_lock_request: Malloc fail !\n" )); + return False; + } + + if((blr->inbuf = (char *)malloc(length)) == NULL) { + DEBUG(0,("push_blocking_lock_request: Malloc fail (2)!\n" )); + free((char *)blr); + return False; + } + + memcpy(blr->inbuf, inbuf, length); + blr->length = length; + blr->lock_num = lock_num; + blr->expire_time = (lock_timeout == -1) ? (time_t)-1 : time(NULL) + (time_t)lock_timeout; + + ubi_slAddTail(&blocking_lock_queue, blr); + + DEBUG(3,("push_blocking_lock_request: lock request blocked with expiry time %d \ +for fnum = %d, name = %s\n", (int)blr->expire_time, fsp->fnum, fsp->fsp_name )); + + return True; +} + +/**************************************************************************** + Return a blocking lock success SMB. +*****************************************************************************/ + +static void blocking_lock_reply_success(blocking_lock_record *blr) +{ + extern int chain_size; + extern char *OutBuffer; + char *outbuf = OutBuffer; + int bufsize = BUFFER_SIZE; + char *inbuf = blr->inbuf; + int outsize = 0; + + construct_reply_common(inbuf, outbuf); + set_message(outbuf,2,0,True); + + /* + * 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. + */ + + chain_size = 0; + + outsize = chain_reply(inbuf,outbuf,blr->length,bufsize); + + outsize += chain_size; + + if(outsize > 4) + smb_setlen(outbuf,outsize - 4); + + send_smb(Client,outbuf); +} + +/**************************************************************************** + Return a lock fail error. Undo all the locks we have obtained first. +*****************************************************************************/ + +static void blocking_lock_reply_error(blocking_lock_record *blr, int eclass, int32 ecode) +{ + extern char *OutBuffer; + char *outbuf = OutBuffer; + char *inbuf = blr->inbuf; + files_struct *fsp = file_fsp(inbuf,smb_vwv2); + connection_struct *conn = conn_find(SVAL(inbuf,smb_tid)); + uint16 num_ulocks = SVAL(inbuf,smb_vwv6); + uint32 count, offset; + char *data; + int i; + + data = smb_buf(inbuf) + 10*num_ulocks; + + /* + * Data now points at the beginning of the list + * of smb_lkrng structs. + */ + + for(i = blr->lock_num; i >= 0; i--) { + int dummy1; + uint32 dummy2; + count = IVAL(data,SMB_LKLEN_OFFSET(i)); + offset = IVAL(data,SMB_LKOFF_OFFSET(i)); + do_unlock(fsp,conn,count,offset,&dummy1,&dummy2); + } + + construct_reply_common(inbuf, outbuf); + + if(eclass == 0) /* NT Error. */ + SSVAL(outbuf,smb_flg2, SVAL(outbuf,smb_flg2) | FLAGS2_32_BIT_ERROR_CODES); + + ERROR(eclass,ecode); + send_smb(Client,outbuf); +} + +/**************************************************************************** + Attempt to finish off getting all pending blocking locks. + Returns True if we want to be removed from the list. +*****************************************************************************/ + +static BOOL blocking_lock_record_process(blocking_lock_record *blr) +{ + char *inbuf = blr->inbuf; + unsigned char locktype = CVAL(inbuf,smb_vwv3); + files_struct *fsp = file_fsp(inbuf,smb_vwv2); + connection_struct *conn = conn_find(SVAL(inbuf,smb_tid)); + uint16 num_ulocks = SVAL(inbuf,smb_vwv6); + uint16 num_locks = SVAL(inbuf,smb_vwv7); + uint32 count, offset; + char *data; + int eclass=0; + uint32 ecode=0; + + data = smb_buf(inbuf) + 10*num_ulocks; + + /* + * Data now points at the beginning of the list + * of smb_lkrng structs. + */ + + for(; blr->lock_num < num_locks; blr->lock_num++) { + count = IVAL(data,SMB_LKLEN_OFFSET(blr->lock_num)); + offset = IVAL(data,SMB_LKOFF_OFFSET(blr->lock_num)); + if(!do_lock(fsp,conn,count,offset, ((locktype & 1) ? F_RDLCK : F_WRLCK), + &eclass, &ecode)) + break; + } + + if(blr->lock_num == num_locks) { + + /* + * Success - we got all the locks. + */ + + DEBUG(3,("blocking_lock_record_process fnum=%d type=%d num_locks=%d\n", + fsp->fnum, (unsigned int)locktype, num_locks) ); + + blocking_lock_reply_success(blr); + return True; + + } else if((errno != EACCES) && (errno != EAGAIN)) { + + /* + * We have other than a "can't get lock" POSIX + * error. Free any locks we had and return an error. + * Return True so we get dequeued. + */ + + blocking_lock_reply_error(blr, eclass, ecode); + return True; + } + + /* + * Still can't get all the locks - keep waiting. + */ + + DEBUG(10,("blocking_lock_record_process: only got %d locks of %d needed for fnum = %d. \ +Waiting....\n", blr->lock_num, num_locks, fsp->fnum)); + + return False; +} + +/**************************************************************************** + Delete entries by fnum from the blocking lock pending queue. +*****************************************************************************/ + +void remove_pending_lock_requests_by_fid(files_struct *fsp) +{ + blocking_lock_record *blr = (blocking_lock_record *)ubi_slFirst( &blocking_lock_queue ); + blocking_lock_record *prev = NULL; + + while(blr != NULL) { + files_struct *req_fsp = file_fsp(blr->inbuf,smb_vwv2); + + if(req_fsp == fsp) { + free_blocking_lock_record((blocking_lock_record *)ubi_slRemNext( &blocking_lock_queue, prev)); + blr = (blocking_lock_record *)(prev ? ubi_slNext(prev) : ubi_slFirst(&blocking_lock_queue)); + continue; + } + + prev = blr; + blr = (blocking_lock_record *)ubi_slNext(blr); + } +} + +/**************************************************************************** + Delete entries by mid from the blocking lock pending queue. Always send reply. +*****************************************************************************/ + +void remove_pending_lock_requests_by_mid(int mid) +{ + blocking_lock_record *blr = (blocking_lock_record *)ubi_slFirst( &blocking_lock_queue ); + blocking_lock_record *prev = NULL; + + while(blr != NULL) { + if(SVAL(blr->inbuf,smb_mid) == mid) { + blocking_lock_reply_error(blr,0,NT_STATUS_CANCELLED); + free_blocking_lock_record((blocking_lock_record *)ubi_slRemNext( &blocking_lock_queue, prev)); + blr = (blocking_lock_record *)(prev ? ubi_slNext(prev) : ubi_slFirst(&blocking_lock_queue)); + continue; + } + + prev = blr; + blr = (blocking_lock_record *)ubi_slNext(blr); + } +} + +/**************************************************************************** + Process the blocking lock queue. Note that this is only called as root. +*****************************************************************************/ + +void process_blocking_lock_queue(time_t t) +{ + blocking_lock_record *blr = (blocking_lock_record *)ubi_slFirst( &blocking_lock_queue ); + blocking_lock_record *prev = NULL; + + if(blr == NULL) + return; + + /* + * Go through the queue and see if we can get any of the locks. + */ + + while(blr != NULL) { + files_struct *fsp = NULL; + connection_struct *conn = NULL; + uint16 vuid; + + /* + * Ensure we don't have any old chain_fnum values + * sitting around.... + */ + file_chain_reset(); + + conn = conn_find(SVAL(blr->inbuf,smb_tid)); + fsp = file_fsp(blr->inbuf,smb_vwv2); + 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 )); + + if((blr->expire_time != -1) && (blr->expire_time > t)) { + /* + * Lock expired - throw away all previously + * obtained locks and return lock error. + */ + DEBUG(5,("process_blocking_lock_queue: pending lock fnum = %d for file %s timed out.\n", + fsp->fnum, fsp->fsp_name )); + + blocking_lock_reply_error(blr,ERRSRV,ERRaccess); + free_blocking_lock_record((blocking_lock_record *)ubi_slRemNext( &blocking_lock_queue, prev)); + blr = (blocking_lock_record *)(prev ? ubi_slNext(prev) : ubi_slFirst(&blocking_lock_queue)); + continue; + } + + if(!become_user(conn,vuid)) { + DEBUG(0,("process_blocking_lock_queue: Unable to become user vuid=%d.\n", + vuid )); + /* + * Remove the entry and return an error to the client. + */ + blocking_lock_reply_error(blr,ERRSRV,ERRaccess); + free_blocking_lock_record((blocking_lock_record *)ubi_slRemNext( &blocking_lock_queue, prev)); + blr = (blocking_lock_record *)(prev ? ubi_slNext(prev) : ubi_slFirst(&blocking_lock_queue)); + continue; + } + + if(!become_service(conn,True)) { + DEBUG(0,("process_blocking_lock_queue: Unable to become service Error was %s.\n", strerror(errno) )); + /* + * Remove the entry and return an error to the client. + */ + blocking_lock_reply_error(blr,ERRSRV,ERRaccess); + free_blocking_lock_record((blocking_lock_record *)ubi_slRemNext( &blocking_lock_queue, prev)); + blr = (blocking_lock_record *)(prev ? ubi_slNext(prev) : ubi_slFirst(&blocking_lock_queue)); + unbecome_user(); + continue; + } + + /* + * 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. + */ + + if(blocking_lock_record_process(blr)) { + free_blocking_lock_record((blocking_lock_record *)ubi_slRemNext( &blocking_lock_queue, prev)); + blr = (blocking_lock_record *)(prev ? ubi_slNext(prev) : ubi_slFirst(&blocking_lock_queue)); + unbecome_user(); + continue; + } + + unbecome_user(); + + /* + * Move to the next in the list. + */ + prev = blr; + blr = (blocking_lock_record *)ubi_slNext(blr); + } +} + -- cgit From dc76502cd8a950f6aff84ce4eedfd9d2b30d3dcc Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 20 Aug 1998 19:28:37 +0000 Subject: Turning on blocking locking code. NB. Blocking lock requests that are not the head of an SMB request (ie. are part of a chain) will not be queued - this will be fixed when we move to the new chain code. In practice, this doesn't seem to cause much of a problem (in my admittedly limited testing) bug a debug level zero message will be placed in the log when this happens to help determine how real the problem is. smbd/locking.c: New debug messages. smbd/blocking.c: New blocking code - handles SMBlock, SMBlockread and SMBlockingX smbd/chgpasswd.c: Fix for master fd leak. smbd/files.c: Tidyup comment. smbd/nttrans.c: Added fnum to debug message. smbd/process.c: Made chain_reply() use construct_reply_common(). Added blocking lock queue processing into idle loop. smbd/reply.c: Added queue pushes for SMBlock, SMBlockread and SMBlockingX. Jeremy. (This used to be commit e1dd03ecda0bc6d7eaa31070c83774bb5679fd1b) --- source3/smbd/blocking.c | 284 ++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 249 insertions(+), 35 deletions(-) (limited to 'source3/smbd/blocking.c') diff --git a/source3/smbd/blocking.c b/source3/smbd/blocking.c index 294dafc405..1aa80b2797 100644 --- a/source3/smbd/blocking.c +++ b/source3/smbd/blocking.c @@ -22,6 +22,8 @@ #include "includes.h" extern int DEBUGLEVEL; extern int Client; +extern int chain_size; +extern char *OutBuffer; /**************************************************************************** This is the structure to queue to implement blocking locks. @@ -30,6 +32,7 @@ extern int Client; typedef struct { ubi_slNode msg_next; + int com_type; time_t expire_time; int lock_num; char *inbuf; @@ -49,10 +52,16 @@ static void free_blocking_lock_record(blocking_lock_record *blr) } /**************************************************************************** - Function to push a blocking lockingX request onto the lock queue. - NB. We can only get away with this as the CIFS spec only includes - SMB_COM_LOCKING_ANDX as a head SMB, ie. it is not one that is ever - generated as part of a chain. + Determine if this is a secondary element of a chained SMB. + **************************************************************************/ + +static BOOL in_chained_smb(void) +{ + return (chain_size != 0); +} + +/**************************************************************************** + Function to push a blocking lock request onto the lock queue. ****************************************************************************/ BOOL push_blocking_lock_request( char *inbuf, int length, int lock_timeout, int lock_num) @@ -60,6 +69,11 @@ BOOL push_blocking_lock_request( char *inbuf, int length, int lock_timeout, int blocking_lock_record *blr; files_struct *fsp = file_fsp(inbuf,smb_vwv2); + 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. @@ -76,27 +90,38 @@ BOOL push_blocking_lock_request( char *inbuf, int length, int lock_timeout, int return False; } + blr->com_type = CVAL(inbuf,smb_com); + blr->expire_time = (lock_timeout == -1) ? (time_t)-1 : time(NULL) + (time_t)lock_timeout; + blr->lock_num = lock_num; memcpy(blr->inbuf, inbuf, length); blr->length = length; - blr->lock_num = lock_num; - blr->expire_time = (lock_timeout == -1) ? (time_t)-1 : time(NULL) + (time_t)lock_timeout; ubi_slAddTail(&blocking_lock_queue, blr); - DEBUG(3,("push_blocking_lock_request: lock request blocked with expiry time %d \ -for fnum = %d, name = %s\n", (int)blr->expire_time, fsp->fnum, fsp->fsp_name )); + DEBUG(3,("push_blocking_lock_request: lock request length=%d blocked with expiry time %d \ +for fnum = %d, name = %s\n", length, (int)blr->expire_time, fsp->fnum, fsp->fsp_name )); return True; } /**************************************************************************** - Return a blocking lock success SMB. + Return a smd with a given size. +*****************************************************************************/ + +static void send_blocking_reply(char *outbuf, int outsize) +{ + if(outsize > 4) + smb_setlen(outbuf,outsize - 4); + + send_smb(Client,outbuf); +} + +/**************************************************************************** + Return a lockingX success SMB. *****************************************************************************/ -static void blocking_lock_reply_success(blocking_lock_record *blr) +static void reply_lockingX_success(blocking_lock_record *blr) { - extern int chain_size; - extern char *OutBuffer; char *outbuf = OutBuffer; int bufsize = BUFFER_SIZE; char *inbuf = blr->inbuf; @@ -113,26 +138,37 @@ static void blocking_lock_reply_success(blocking_lock_record *blr) * that here and must set up the chain info manually. */ - chain_size = 0; - outsize = chain_reply(inbuf,outbuf,blr->length,bufsize); outsize += chain_size; - if(outsize > 4) - smb_setlen(outbuf,outsize - 4); + send_blocking_reply(outbuf,outsize); +} + +/**************************************************************************** + Return a generic lock fail error blocking call. +*****************************************************************************/ + +static void generic_blocking_lock_error(blocking_lock_record *blr, int eclass, int32 ecode) +{ + char *outbuf = OutBuffer; + char *inbuf = blr->inbuf; + construct_reply_common(inbuf, outbuf); + + if(eclass == 0) /* NT Error. */ + SSVAL(outbuf,smb_flg2, SVAL(outbuf,smb_flg2) | FLAGS2_32_BIT_ERROR_CODES); + ERROR(eclass,ecode); send_smb(Client,outbuf); } /**************************************************************************** - Return a lock fail error. Undo all the locks we have obtained first. + Return a lock fail error for a lockingX call. Undo all the locks we have + obtained first. *****************************************************************************/ -static void blocking_lock_reply_error(blocking_lock_record *blr, int eclass, int32 ecode) +static void reply_lockingX_error(blocking_lock_record *blr, int eclass, int32 ecode) { - extern char *OutBuffer; - char *outbuf = OutBuffer; char *inbuf = blr->inbuf; files_struct *fsp = file_fsp(inbuf,smb_vwv2); connection_struct *conn = conn_find(SVAL(inbuf,smb_tid)); @@ -156,21 +192,159 @@ static void blocking_lock_reply_error(blocking_lock_record *blr, int eclass, int do_unlock(fsp,conn,count,offset,&dummy1,&dummy2); } + generic_blocking_lock_error(blr, eclass, ecode); +} + +/**************************************************************************** + Return a lock fail error. +*****************************************************************************/ + +static void blocking_lock_reply_error(blocking_lock_record *blr, int eclass, int32 ecode) +{ + switch(blr->com_type) { + case SMBlock: + generic_blocking_lock_error(blr, eclass, ecode); + break; + case SMBlockread: + generic_blocking_lock_error(blr, eclass, ecode); + break; + case SMBlockingX: + reply_lockingX_error(blr, eclass, ecode); + break; + 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"); + } +} + +/**************************************************************************** + Attempt to finish off getting all pending blocking locks for a lockread call. + Returns True if we want to be removed from the list. +*****************************************************************************/ + +static BOOL process_lockread(blocking_lock_record *blr) +{ + char *outbuf = OutBuffer; + char *inbuf = blr->inbuf; + int nread = -1; + char *data; + int outsize = 0; + uint32 startpos, numtoread; + int eclass; + uint32 ecode; + connection_struct *conn = conn_find(SVAL(inbuf,smb_tid)); + files_struct *fsp = file_fsp(inbuf,smb_vwv0); + + numtoread = SVAL(inbuf,smb_vwv1); + startpos = IVAL(inbuf,smb_vwv2); + + numtoread = MIN(BUFFER_SIZE-outsize,numtoread); + data = smb_buf(outbuf) + 3; + + if(!do_lock( fsp, conn, numtoread, startpos, F_RDLCK, &eclass, &ecode)) { + if((errno != EACCES) && (errno != EAGAIN)) { + /* + * We have other than a "can't get lock" POSIX + * error. Send an error. + * Return True so we get dequeued. + */ + + generic_blocking_lock_error(blr, eclass, ecode); + return True; + } + + /* + * Still waiting for lock.... + */ + + DEBUG(10,("process_lockread: failed to get lock for file = %s. Still waiting....\n", + fsp->fsp_name)); + return False; + } + + nread = read_file(fsp,data,startpos,numtoread); + + if (nread < 0) { + generic_blocking_lock_error(blr,ERRDOS,ERRnoaccess); + return True; + } + construct_reply_common(inbuf, outbuf); + outsize = set_message(outbuf,5,3,True); - if(eclass == 0) /* NT Error. */ - SSVAL(outbuf,smb_flg2, SVAL(outbuf,smb_flg2) | FLAGS2_32_BIT_ERROR_CODES); + outsize += nread; + SSVAL(outbuf,smb_vwv0,nread); + SSVAL(outbuf,smb_vwv5,nread+3); + SSVAL(smb_buf(outbuf),1,nread); - ERROR(eclass,ecode); - send_smb(Client,outbuf); + DEBUG(3, ( "process_lockread file = %s, fnum=%d num=%d nread=%d\n", + fsp->fsp_name, fsp->fnum, numtoread, nread ) ); + + send_blocking_reply(outbuf,outsize); + return True; } /**************************************************************************** - Attempt to finish off getting all pending blocking locks. + Attempt to finish off getting all pending blocking locks for a lock call. Returns True if we want to be removed from the list. *****************************************************************************/ -static BOOL blocking_lock_record_process(blocking_lock_record *blr) +static BOOL process_lock(blocking_lock_record *blr) +{ + char *outbuf = OutBuffer; + char *inbuf = blr->inbuf; + int outsize; + uint32 count,offset; + int eclass; + uint32 ecode; + connection_struct *conn = conn_find(SVAL(inbuf,smb_tid)); + files_struct *fsp = file_fsp(inbuf,smb_vwv0); + + count = IVAL(inbuf,smb_vwv1); + offset = IVAL(inbuf,smb_vwv3); + + errno = 0; + if (!do_lock(fsp, conn, count, offset, F_WRLCK, &eclass, &ecode)) { + if((errno != EACCES) && (errno != EAGAIN)) { + + /* + * We have other than a "can't get lock" POSIX + * error. Send an error. + * Return True so we get dequeued. + */ + + blocking_lock_reply_error(blr, eclass, ecode); + return True; + } + + /* + * Still can't get the lock - keep waiting. + */ + + DEBUG(10,("process_lock: failed to get lock for file = %s. Still waiting....\n", + fsp->fsp_name)); + return False; + } + + /* + * Success - we got the lock. + */ + + DEBUG(3,("process_lock : file=%s fnum=%d ofs=%d cnt=%d\n", + fsp->fsp_name, fsp->fnum, (int)offset, (int)count)); + + construct_reply_common(inbuf, outbuf); + outsize = set_message(outbuf,0,0,True); + send_blocking_reply(outbuf,outsize); + return True; +} + +/**************************************************************************** + Attempt to finish off getting all pending blocking locks for a lockingX call. + Returns True if we want to be removed from the list. +*****************************************************************************/ + +static BOOL process_lockingX(blocking_lock_record *blr) { char *inbuf = blr->inbuf; unsigned char locktype = CVAL(inbuf,smb_vwv3); @@ -193,6 +367,7 @@ static BOOL blocking_lock_record_process(blocking_lock_record *blr) for(; blr->lock_num < num_locks; blr->lock_num++) { count = IVAL(data,SMB_LKLEN_OFFSET(blr->lock_num)); offset = IVAL(data,SMB_LKOFF_OFFSET(blr->lock_num)); + errno = 0; if(!do_lock(fsp,conn,count,offset, ((locktype & 1) ? F_RDLCK : F_WRLCK), &eclass, &ecode)) break; @@ -204,10 +379,10 @@ static BOOL blocking_lock_record_process(blocking_lock_record *blr) * Success - we got all the locks. */ - DEBUG(3,("blocking_lock_record_process fnum=%d type=%d num_locks=%d\n", - fsp->fnum, (unsigned int)locktype, num_locks) ); + DEBUG(3,("process_lockingX file = %s, fnum=%d type=%d num_locks=%d\n", + fsp->fsp_name, fsp->fnum, (unsigned int)locktype, num_locks) ); - blocking_lock_reply_success(blr); + reply_lockingX_success(blr); return True; } else if((errno != EACCES) && (errno != EAGAIN)) { @@ -226,12 +401,52 @@ static BOOL blocking_lock_record_process(blocking_lock_record *blr) * Still can't get all the locks - keep waiting. */ - DEBUG(10,("blocking_lock_record_process: only got %d locks of %d needed for fnum = %d. \ -Waiting....\n", blr->lock_num, num_locks, fsp->fnum)); + 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)); return False; } +/**************************************************************************** + Process a blocking lock SMB. + Returns True if we want to be removed from the list. +*****************************************************************************/ + +static BOOL blocking_lock_record_process(blocking_lock_record *blr) +{ + switch(blr->com_type) { + case SMBlock: + return process_lock(blr); + case SMBlockread: + return process_lockread(blr); + case SMBlockingX: + return process_lockingX(blr); + 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. */ +} + +/**************************************************************************** + Get the files_struct given a particular queued SMB. +*****************************************************************************/ + +static files_struct *get_fsp_from_blr(blocking_lock_record *blr) +{ + switch(blr->com_type) { + case SMBlock: + case SMBlockread: + return file_fsp(blr->inbuf,smb_vwv0); + case SMBlockingX: + return file_fsp(blr->inbuf,smb_vwv2); + default: + DEBUG(0,("get_fsp_from_blr: PANIC - unknown type on blocking lock queue - exiting.!\n")); + exit_server("PANIC - unknown type on blocking lock queue"); + } + return NULL; /* Keep compiler happy. */ +} + /**************************************************************************** Delete entries by fnum from the blocking lock pending queue. *****************************************************************************/ @@ -242,7 +457,7 @@ void remove_pending_lock_requests_by_fid(files_struct *fsp) blocking_lock_record *prev = NULL; while(blr != NULL) { - files_struct *req_fsp = file_fsp(blr->inbuf,smb_vwv2); + files_struct *req_fsp = get_fsp_from_blr(blr); if(req_fsp == fsp) { free_blocking_lock_record((blocking_lock_record *)ubi_slRemNext( &blocking_lock_queue, prev)); @@ -294,18 +509,18 @@ void process_blocking_lock_queue(time_t t) */ while(blr != NULL) { - files_struct *fsp = NULL; connection_struct *conn = NULL; uint16 vuid; + files_struct *fsp = get_fsp_from_blr(blr); /* * Ensure we don't have any old chain_fnum values * sitting around.... */ + chain_size = 0; file_chain_reset(); conn = conn_find(SVAL(blr->inbuf,smb_tid)); - fsp = file_fsp(blr->inbuf,smb_vwv2); vuid = (lp_security() == SEC_SHARE) ? UID_FIELD_INVALID : SVAL(blr->inbuf,smb_uid); @@ -372,4 +587,3 @@ void process_blocking_lock_queue(time_t t) blr = (blocking_lock_record *)ubi_slNext(blr); } } - -- cgit From 81b580fd2248221c61e3d4dac03862fb1fd8fde5 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Fri, 21 Aug 1998 01:30:29 +0000 Subject: Fixes for the problem in blocking locks with file_fsp returning the chain_fsp on close (if you don't know what this means, consider yourself lucky - this one took a day to track down :-). Jeremy. (This used to be commit 193cb5382464173e99a538867a266d793f0ceab5) --- source3/smbd/blocking.c | 69 ++++++++++++++++++++++++++++--------------------- 1 file changed, 40 insertions(+), 29 deletions(-) (limited to 'source3/smbd/blocking.c') diff --git a/source3/smbd/blocking.c b/source3/smbd/blocking.c index 1aa80b2797..2241b7aa8d 100644 --- a/source3/smbd/blocking.c +++ b/source3/smbd/blocking.c @@ -33,6 +33,7 @@ extern char *OutBuffer; typedef struct { ubi_slNode msg_next; int com_type; + files_struct *fsp; time_t expire_time; int lock_num; char *inbuf; @@ -51,6 +52,25 @@ static void free_blocking_lock_record(blocking_lock_record *blr) free((char *)blr); } +/**************************************************************************** + Get the files_struct given a particular queued SMB. +*****************************************************************************/ + +static files_struct *get_fsp_from_pkt(char *inbuf) +{ + switch(CVAL(inbuf,smb_com)) { + case SMBlock: + case SMBlockread: + return file_fsp(inbuf,smb_vwv0); + case SMBlockingX: + return file_fsp(inbuf,smb_vwv2); + default: + DEBUG(0,("get_fsp_from_pkt: PANIC - unknown type on blocking lock queue - exiting.!\n")); + exit_server("PANIC - unknown type on blocking lock queue"); + } + return NULL; /* Keep compiler happy. */ +} + /**************************************************************************** Determine if this is a secondary element of a chained SMB. **************************************************************************/ @@ -67,7 +87,6 @@ static BOOL in_chained_smb(void) BOOL push_blocking_lock_request( char *inbuf, int length, int lock_timeout, int lock_num) { blocking_lock_record *blr; - files_struct *fsp = file_fsp(inbuf,smb_vwv2); if(in_chained_smb() ) { DEBUG(0,("push_blocking_lock_request: cannot queue a chained request (currently).\n")); @@ -91,6 +110,7 @@ BOOL push_blocking_lock_request( char *inbuf, int length, int lock_timeout, int } blr->com_type = CVAL(inbuf,smb_com); + blr->fsp = get_fsp_from_pkt(inbuf); blr->expire_time = (lock_timeout == -1) ? (time_t)-1 : time(NULL) + (time_t)lock_timeout; blr->lock_num = lock_num; memcpy(blr->inbuf, inbuf, length); @@ -98,8 +118,10 @@ BOOL push_blocking_lock_request( char *inbuf, int length, int lock_timeout, int ubi_slAddTail(&blocking_lock_queue, blr); + DEBUG(3,("push_blocking_lock_request: lock request length=%d blocked with expiry time %d \ -for fnum = %d, name = %s\n", length, (int)blr->expire_time, fsp->fnum, fsp->fsp_name )); +for fnum = %d, name = %s\n", length, (int)blr->expire_time, + blr->fsp->fnum, blr->fsp->fsp_name )); return True; } @@ -170,7 +192,7 @@ static void generic_blocking_lock_error(blocking_lock_record *blr, int eclass, i static void reply_lockingX_error(blocking_lock_record *blr, int eclass, int32 ecode) { char *inbuf = blr->inbuf; - files_struct *fsp = file_fsp(inbuf,smb_vwv2); + files_struct *fsp = blr->fsp; connection_struct *conn = conn_find(SVAL(inbuf,smb_tid)); uint16 num_ulocks = SVAL(inbuf,smb_vwv6); uint32 count, offset; @@ -233,7 +255,7 @@ static BOOL process_lockread(blocking_lock_record *blr) int eclass; uint32 ecode; connection_struct *conn = conn_find(SVAL(inbuf,smb_tid)); - files_struct *fsp = file_fsp(inbuf,smb_vwv0); + files_struct *fsp = blr->fsp; numtoread = SVAL(inbuf,smb_vwv1); startpos = IVAL(inbuf,smb_vwv2); @@ -298,7 +320,7 @@ static BOOL process_lock(blocking_lock_record *blr) int eclass; uint32 ecode; connection_struct *conn = conn_find(SVAL(inbuf,smb_tid)); - files_struct *fsp = file_fsp(inbuf,smb_vwv0); + files_struct *fsp = blr->fsp; count = IVAL(inbuf,smb_vwv1); offset = IVAL(inbuf,smb_vwv3); @@ -348,7 +370,7 @@ static BOOL process_lockingX(blocking_lock_record *blr) { char *inbuf = blr->inbuf; unsigned char locktype = CVAL(inbuf,smb_vwv3); - files_struct *fsp = file_fsp(inbuf,smb_vwv2); + files_struct *fsp = blr->fsp; connection_struct *conn = conn_find(SVAL(inbuf,smb_tid)); uint16 num_ulocks = SVAL(inbuf,smb_vwv6); uint16 num_locks = SVAL(inbuf,smb_vwv7); @@ -428,25 +450,6 @@ static BOOL blocking_lock_record_process(blocking_lock_record *blr) return False; /* Keep compiler happy. */ } -/**************************************************************************** - Get the files_struct given a particular queued SMB. -*****************************************************************************/ - -static files_struct *get_fsp_from_blr(blocking_lock_record *blr) -{ - switch(blr->com_type) { - case SMBlock: - case SMBlockread: - return file_fsp(blr->inbuf,smb_vwv0); - case SMBlockingX: - return file_fsp(blr->inbuf,smb_vwv2); - default: - DEBUG(0,("get_fsp_from_blr: PANIC - unknown type on blocking lock queue - exiting.!\n")); - exit_server("PANIC - unknown type on blocking lock queue"); - } - return NULL; /* Keep compiler happy. */ -} - /**************************************************************************** Delete entries by fnum from the blocking lock pending queue. *****************************************************************************/ @@ -457,9 +460,11 @@ void remove_pending_lock_requests_by_fid(files_struct *fsp) blocking_lock_record *prev = NULL; while(blr != NULL) { - files_struct *req_fsp = get_fsp_from_blr(blr); + if(blr->fsp->fnum == fsp->fnum) { + + 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 )); - if(req_fsp == fsp) { free_blocking_lock_record((blocking_lock_record *)ubi_slRemNext( &blocking_lock_queue, prev)); blr = (blocking_lock_record *)(prev ? ubi_slNext(prev) : ubi_slFirst(&blocking_lock_queue)); continue; @@ -481,6 +486,11 @@ void remove_pending_lock_requests_by_mid(int mid) while(blr != NULL) { if(SVAL(blr->inbuf,smb_mid) == mid) { + files_struct *fsp = blr->fsp; + + 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 )); + blocking_lock_reply_error(blr,0,NT_STATUS_CANCELLED); free_blocking_lock_record((blocking_lock_record *)ubi_slRemNext( &blocking_lock_queue, prev)); blr = (blocking_lock_record *)(prev ? ubi_slNext(prev) : ubi_slFirst(&blocking_lock_queue)); @@ -511,14 +521,15 @@ void process_blocking_lock_queue(time_t t) while(blr != NULL) { connection_struct *conn = NULL; uint16 vuid; - files_struct *fsp = get_fsp_from_blr(blr); + files_struct *fsp = NULL; /* - * Ensure we don't have any old chain_fnum values + * Ensure we don't have any old chain_fsp values * sitting around.... */ chain_size = 0; file_chain_reset(); + fsp = blr->fsp; conn = conn_find(SVAL(blr->inbuf,smb_tid)); vuid = (lp_security() == SEC_SHARE) ? UID_FIELD_INVALID : -- cgit From 06cc91f9a631a23dcd4902d710b89e4b7584c459 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Fri, 11 Sep 1998 01:24:30 +0000 Subject: Added ssize_t to configure code. Got 'religion' about using size_t and ssize_t for read/write stuff as part of the code to expose 64 bits to the client. This checkin does all the 'easy' stuff - such as all the read/write/lock calls - but now comes the harder parts (open & friends) and all the file enquiry functions..... Jeremy. (This used to be commit 36544fe5476f7770bd5748574fc54be7b3ee4d4a) --- source3/smbd/blocking.c | 50 ++++++++++++++++++++++++++++++++++++------------- 1 file changed, 37 insertions(+), 13 deletions(-) (limited to 'source3/smbd/blocking.c') diff --git a/source3/smbd/blocking.c b/source3/smbd/blocking.c index 2241b7aa8d..051e276ca7 100644 --- a/source3/smbd/blocking.c +++ b/source3/smbd/blocking.c @@ -195,11 +195,13 @@ static void reply_lockingX_error(blocking_lock_record *blr, int eclass, int32 ec files_struct *fsp = blr->fsp; connection_struct *conn = conn_find(SVAL(inbuf,smb_tid)); uint16 num_ulocks = SVAL(inbuf,smb_vwv6); - uint32 count, offset; + SMB_OFF_T count, offset; + unsigned char locktype = CVAL(inbuf,smb_vwv3); + BOOL large_file_format = (locktype & LOCKING_ANDX_LARGE_FILES); char *data; int i; - data = smb_buf(inbuf) + 10*num_ulocks; + data = smb_buf(inbuf) + ((large_file_format ? 20 : 10)*num_ulocks); /* * Data now points at the beginning of the list @@ -209,8 +211,18 @@ static void reply_lockingX_error(blocking_lock_record *blr, int eclass, int32 ec for(i = blr->lock_num; i >= 0; i--) { int dummy1; uint32 dummy2; - count = IVAL(data,SMB_LKLEN_OFFSET(i)); - offset = IVAL(data,SMB_LKOFF_OFFSET(i)); + if(!large_file_format) { + count = IVAL(data,SMB_LKLEN_OFFSET(i)); + offset = IVAL(data,SMB_LKOFF_OFFSET(i)); + } +#ifdef LARGE_SMB_OFF_T + else { + count = (((SMB_OFF_T) IVAL(data,SMB_LARGE_LKLEN_OFFSET_HIGH(i))) << 32) | + ((SMB_OFF_T) IVAL(data,SMB_LARGE_LKLEN_OFFSET_LOW(i))); + offset = (((SMB_OFF_T) IVAL(data,SMB_LARGE_LKOFF_OFFSET_HIGH(i))) << 32) | + ((SMB_OFF_T) IVAL(data,SMB_LARGE_LKOFF_OFFSET_LOW(i))); + } +#endif do_unlock(fsp,conn,count,offset,&dummy1,&dummy2); } @@ -248,10 +260,11 @@ static BOOL process_lockread(blocking_lock_record *blr) { char *outbuf = OutBuffer; char *inbuf = blr->inbuf; - int nread = -1; + ssize_t nread = -1; char *data; int outsize = 0; - uint32 startpos, numtoread; + SMB_OFF_T startpos; + size_t numtoread; int eclass; uint32 ecode; connection_struct *conn = conn_find(SVAL(inbuf,smb_tid)); @@ -316,7 +329,7 @@ static BOOL process_lock(blocking_lock_record *blr) char *outbuf = OutBuffer; char *inbuf = blr->inbuf; int outsize; - uint32 count,offset; + SMB_OFF_T count,offset; int eclass; uint32 ecode; connection_struct *conn = conn_find(SVAL(inbuf,smb_tid)); @@ -352,8 +365,8 @@ static BOOL process_lock(blocking_lock_record *blr) * Success - we got the lock. */ - DEBUG(3,("process_lock : file=%s fnum=%d ofs=%d cnt=%d\n", - fsp->fsp_name, fsp->fnum, (int)offset, (int)count)); + DEBUG(3,("process_lock : file=%s fnum=%d offset=%.0f count=%.0f\n", + fsp->fsp_name, fsp->fnum, (double)offset, (double)count)); construct_reply_common(inbuf, outbuf); outsize = set_message(outbuf,0,0,True); @@ -374,12 +387,13 @@ static BOOL process_lockingX(blocking_lock_record *blr) connection_struct *conn = conn_find(SVAL(inbuf,smb_tid)); uint16 num_ulocks = SVAL(inbuf,smb_vwv6); uint16 num_locks = SVAL(inbuf,smb_vwv7); - uint32 count, offset; + SMB_OFF_T count, offset; + BOOL large_file_format = (locktype & LOCKING_ANDX_LARGE_FILES); char *data; int eclass=0; uint32 ecode=0; - data = smb_buf(inbuf) + 10*num_ulocks; + data = smb_buf(inbuf) + ((large_file_format ? 20 : 10)*num_ulocks); /* * Data now points at the beginning of the list @@ -387,8 +401,18 @@ static BOOL process_lockingX(blocking_lock_record *blr) */ for(; blr->lock_num < num_locks; blr->lock_num++) { - count = IVAL(data,SMB_LKLEN_OFFSET(blr->lock_num)); - offset = IVAL(data,SMB_LKOFF_OFFSET(blr->lock_num)); + if(!large_file_format) { + count = IVAL(data,SMB_LKLEN_OFFSET(blr->lock_num)); + offset = IVAL(data,SMB_LKOFF_OFFSET(blr->lock_num)); + } +#ifdef LARGE_SMB_OFF_T + else { + count = (((SMB_OFF_T) IVAL(data,SMB_LARGE_LKLEN_OFFSET_HIGH(blr->lock_num))) << 32) | + ((SMB_OFF_T) IVAL(data,SMB_LARGE_LKLEN_OFFSET_LOW(blr->lock_num))); + offset = (((SMB_OFF_T) IVAL(data,SMB_LARGE_LKOFF_OFFSET_HIGH(blr->lock_num))) << 32) | + ((SMB_OFF_T) IVAL(data,SMB_LARGE_LKOFF_OFFSET_LOW(blr->lock_num))); + } +#endif errno = 0; if(!do_lock(fsp,conn,count,offset, ((locktype & 1) ? F_RDLCK : F_WRLCK), &eclass, &ecode)) -- cgit From 27d0bef143fbc4d7547c022046c094bbdbd0bfc1 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Fri, 11 Sep 1998 19:14:27 +0000 Subject: Ok - this is the 'expose 64 bit to the clients' checkin. I have tested it by creating a 'holey' 20GB file - checking that it shows up correctl in the NT file view (it does) and am busily copying it to NULL: on the NT box. All good so far.... :-). Also implemented NT 'delete on close' semantics. Jeremy. (This used to be commit 1654faee80648583e6a47ab7eda990fefdf85124) --- source3/smbd/blocking.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source3/smbd/blocking.c') diff --git a/source3/smbd/blocking.c b/source3/smbd/blocking.c index 051e276ca7..27a5183952 100644 --- a/source3/smbd/blocking.c +++ b/source3/smbd/blocking.c @@ -222,7 +222,7 @@ static void reply_lockingX_error(blocking_lock_record *blr, int eclass, int32 ec offset = (((SMB_OFF_T) IVAL(data,SMB_LARGE_LKOFF_OFFSET_HIGH(i))) << 32) | ((SMB_OFF_T) IVAL(data,SMB_LARGE_LKOFF_OFFSET_LOW(i))); } -#endif +#endif /* LARGE_SMB_OFF_T */ do_unlock(fsp,conn,count,offset,&dummy1,&dummy2); } @@ -412,7 +412,7 @@ static BOOL process_lockingX(blocking_lock_record *blr) offset = (((SMB_OFF_T) IVAL(data,SMB_LARGE_LKOFF_OFFSET_HIGH(blr->lock_num))) << 32) | ((SMB_OFF_T) IVAL(data,SMB_LARGE_LKOFF_OFFSET_LOW(blr->lock_num))); } -#endif +#endif /* LARGE_SMB_OFF_T */ errno = 0; if(!do_lock(fsp,conn,count,offset, ((locktype & 1) ? F_RDLCK : F_WRLCK), &eclass, &ecode)) -- cgit From 1ea570da834fa72c88dd35a86fdf68ae5ecbeb19 Mon Sep 17 00:00:00 2001 From: Richard Sharpe Date: Sat, 26 Sep 1998 00:41:20 +0000 Subject: Small update to clitar.c to omit warnings about servers not letting us change the date unless tar_real_noisy is True. Also updated a few places where variables are declared but not set. (This used to be commit b46f1024c939ee9ecb8deb9c844acbd4b5f109c6) --- source3/smbd/blocking.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'source3/smbd/blocking.c') diff --git a/source3/smbd/blocking.c b/source3/smbd/blocking.c index 27a5183952..32b6d010a4 100644 --- a/source3/smbd/blocking.c +++ b/source3/smbd/blocking.c @@ -195,7 +195,7 @@ static void reply_lockingX_error(blocking_lock_record *blr, int eclass, int32 ec files_struct *fsp = blr->fsp; connection_struct *conn = conn_find(SVAL(inbuf,smb_tid)); uint16 num_ulocks = SVAL(inbuf,smb_vwv6); - SMB_OFF_T count, offset; + SMB_OFF_T count = (SMB_OFF_T) 0, offset = (SMB_OFF_T) 0; unsigned char locktype = CVAL(inbuf,smb_vwv3); BOOL large_file_format = (locktype & LOCKING_ANDX_LARGE_FILES); char *data; @@ -329,7 +329,7 @@ static BOOL process_lock(blocking_lock_record *blr) char *outbuf = OutBuffer; char *inbuf = blr->inbuf; int outsize; - SMB_OFF_T count,offset; + SMB_OFF_T count = 0, offset = 0; int eclass; uint32 ecode; connection_struct *conn = conn_find(SVAL(inbuf,smb_tid)); @@ -387,7 +387,7 @@ static BOOL process_lockingX(blocking_lock_record *blr) connection_struct *conn = conn_find(SVAL(inbuf,smb_tid)); uint16 num_ulocks = SVAL(inbuf,smb_vwv6); uint16 num_locks = SVAL(inbuf,smb_vwv7); - SMB_OFF_T count, offset; + SMB_OFF_T count = 0, offset = 0; BOOL large_file_format = (locktype & LOCKING_ANDX_LARGE_FILES); char *data; int eclass=0; -- cgit From 3db52feb1f3b2c07ce0b06ad4a7099fa6efe3fc7 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Mon, 13 Dec 1999 13:27:58 +0000 Subject: first pass at updating head branch to be to be the same as the SAMBA_2_0 branch (This used to be commit 453a822a76780063dff23526c35408866d0c0154) --- source3/smbd/blocking.c | 55 +++++++++++++++++++++++++++---------------------- 1 file changed, 30 insertions(+), 25 deletions(-) (limited to 'source3/smbd/blocking.c') diff --git a/source3/smbd/blocking.c b/source3/smbd/blocking.c index 32b6d010a4..16882be2bb 100644 --- a/source3/smbd/blocking.c +++ b/source3/smbd/blocking.c @@ -211,18 +211,16 @@ static void reply_lockingX_error(blocking_lock_record *blr, int eclass, int32 ec for(i = blr->lock_num; i >= 0; i--) { int dummy1; uint32 dummy2; - if(!large_file_format) { - count = IVAL(data,SMB_LKLEN_OFFSET(i)); - offset = IVAL(data,SMB_LKOFF_OFFSET(i)); - } -#ifdef LARGE_SMB_OFF_T - else { - count = (((SMB_OFF_T) IVAL(data,SMB_LARGE_LKLEN_OFFSET_HIGH(i))) << 32) | - ((SMB_OFF_T) IVAL(data,SMB_LARGE_LKLEN_OFFSET_LOW(i))); - offset = (((SMB_OFF_T) IVAL(data,SMB_LARGE_LKOFF_OFFSET_HIGH(i))) << 32) | - ((SMB_OFF_T) IVAL(data,SMB_LARGE_LKOFF_OFFSET_LOW(i))); - } -#endif /* LARGE_SMB_OFF_T */ + BOOL err; + + count = get_lock_count( data, i, large_file_format, &err); + offset = get_lock_offset( data, i, large_file_format, &err); + + /* + * We know err cannot be set as if it was the lock + * request would never have been queued. JRA. + */ + do_unlock(fsp,conn,count,offset,&dummy1,&dummy2); } @@ -313,7 +311,7 @@ static BOOL process_lockread(blocking_lock_record *blr) SSVAL(smb_buf(outbuf),1,nread); DEBUG(3, ( "process_lockread file = %s, fnum=%d num=%d nread=%d\n", - fsp->fsp_name, fsp->fnum, numtoread, nread ) ); + fsp->fsp_name, fsp->fnum, (int)numtoread, (int)nread ) ); send_blocking_reply(outbuf,outsize); return True; @@ -401,18 +399,15 @@ static BOOL process_lockingX(blocking_lock_record *blr) */ for(; blr->lock_num < num_locks; blr->lock_num++) { - if(!large_file_format) { - count = IVAL(data,SMB_LKLEN_OFFSET(blr->lock_num)); - offset = IVAL(data,SMB_LKOFF_OFFSET(blr->lock_num)); - } -#ifdef LARGE_SMB_OFF_T - else { - count = (((SMB_OFF_T) IVAL(data,SMB_LARGE_LKLEN_OFFSET_HIGH(blr->lock_num))) << 32) | - ((SMB_OFF_T) IVAL(data,SMB_LARGE_LKLEN_OFFSET_LOW(blr->lock_num))); - offset = (((SMB_OFF_T) IVAL(data,SMB_LARGE_LKOFF_OFFSET_HIGH(blr->lock_num))) << 32) | - ((SMB_OFF_T) IVAL(data,SMB_LARGE_LKOFF_OFFSET_LOW(blr->lock_num))); - } -#endif /* LARGE_SMB_OFF_T */ + BOOL err; + + count = get_lock_count( data, blr->lock_num, large_file_format, &err); + offset = get_lock_offset( data, blr->lock_num, large_file_format, &err); + + /* + * We know err cannot be set as if it was the lock + * request would never have been queued. JRA. + */ errno = 0; if(!do_lock(fsp,conn,count,offset, ((locktype & 1) ? F_RDLCK : F_WRLCK), &eclass, &ecode)) @@ -526,6 +521,16 @@ file %s fnum = %d\n", blr->com_type, fsp->fsp_name, fsp->fnum )); } } +/**************************************************************************** + Return True if the blocking lock queue has entries. +*****************************************************************************/ + +BOOL blocking_locks_pending(void) +{ + blocking_lock_record *blr = (blocking_lock_record *)ubi_slFirst( &blocking_lock_queue ); + return (blr == NULL ? False : True); +} + /**************************************************************************** Process the blocking lock queue. Note that this is only called as root. *****************************************************************************/ -- cgit From 826446ddef1ef0f462c02932d11e3713f00497c7 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Thu, 13 Jan 2000 12:10:48 +0000 Subject: changes to reflect the new syntax of the locking calls. (This used to be commit 44117df2c908d473b3e1a1020b22af6d584809ef) --- source3/smbd/blocking.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'source3/smbd/blocking.c') diff --git a/source3/smbd/blocking.c b/source3/smbd/blocking.c index 16882be2bb..5e7d4a0c87 100644 --- a/source3/smbd/blocking.c +++ b/source3/smbd/blocking.c @@ -274,7 +274,7 @@ static BOOL process_lockread(blocking_lock_record *blr) numtoread = MIN(BUFFER_SIZE-outsize,numtoread); data = smb_buf(outbuf) + 3; - if(!do_lock( fsp, conn, numtoread, startpos, F_RDLCK, &eclass, &ecode)) { + if(!do_lock( fsp, conn, numtoread, startpos, READ_LOCK, &eclass, &ecode)) { if((errno != EACCES) && (errno != EAGAIN)) { /* * We have other than a "can't get lock" POSIX @@ -337,7 +337,7 @@ static BOOL process_lock(blocking_lock_record *blr) offset = IVAL(inbuf,smb_vwv3); errno = 0; - if (!do_lock(fsp, conn, count, offset, F_WRLCK, &eclass, &ecode)) { + if (!do_lock(fsp, conn, count, offset, WRITE_LOCK, &eclass, &ecode)) { if((errno != EACCES) && (errno != EAGAIN)) { /* @@ -409,7 +409,7 @@ static BOOL process_lockingX(blocking_lock_record *blr) * request would never have been queued. JRA. */ errno = 0; - if(!do_lock(fsp,conn,count,offset, ((locktype & 1) ? F_RDLCK : F_WRLCK), + if(!do_lock(fsp,conn,count,offset, ((locktype & 1) ? READ_LOCK : WRITE_LOCK), &eclass, &ecode)) break; } -- cgit From 3a6c2069d77176bfa2b379ef711034396c477791 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Fri, 14 Jan 2000 01:41:04 +0000 Subject: Added "inherit permissions" patch. Fixed locking bug found by Andrew. Jeremy. (This used to be commit 38dffd360dc2e44bfc9e751f017e24f81ff0f2fa) --- source3/smbd/blocking.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) (limited to 'source3/smbd/blocking.c') diff --git a/source3/smbd/blocking.c b/source3/smbd/blocking.c index 5e7d4a0c87..292eb2455e 100644 --- a/source3/smbd/blocking.c +++ b/source3/smbd/blocking.c @@ -208,7 +208,13 @@ static void reply_lockingX_error(blocking_lock_record *blr, int eclass, int32 ec * of smb_lkrng structs. */ - for(i = blr->lock_num; i >= 0; i--) { + /* + * 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) ..... + */ + + for(i = blr->lock_num - 1; i >= 0; i--) { int dummy1; uint32 dummy2; BOOL err; -- cgit From b5e7e4277d87c9eaa663f92c081a869b34170380 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 25 Jan 2000 22:57:51 +0000 Subject: First set of speed improvements from Ying Chen . Inline several commonly used functions as macros. Jeremy. (This used to be commit fc0219c7cc4b83e6db17d5b3be70d74fd7971089) --- source3/smbd/blocking.c | 1 - 1 file changed, 1 deletion(-) (limited to 'source3/smbd/blocking.c') diff --git a/source3/smbd/blocking.c b/source3/smbd/blocking.c index 292eb2455e..c90f475b46 100644 --- a/source3/smbd/blocking.c +++ b/source3/smbd/blocking.c @@ -22,7 +22,6 @@ #include "includes.h" extern int DEBUGLEVEL; extern int Client; -extern int chain_size; extern char *OutBuffer; /**************************************************************************** -- cgit From 2fa922611bf7160e2c1ce80c11b50006448bf98d Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Tue, 11 Apr 2000 13:55:53 +0000 Subject: finally got sick of the "extern int Client" code and the stupid assumption that we have one socket everywhere while doing so I discovered a few bugs! 1) the clientgen session retarget code if used from smbd or nmbd would cause a crash as it called close_sockets() which closed our main socket! fixed by removing close_sockets() completely - it is unnecessary 2) the caching in client_addr() and client_name() was bogus - it could easily get fooled and give the wrong result. fixed. 3) the retarget could could recurse, allowing an easy denial of service attack on nmbd. fixed. (This used to be commit 5937ab14d222696e40a3fc6f0e6a536f2d7305d3) --- source3/smbd/blocking.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'source3/smbd/blocking.c') diff --git a/source3/smbd/blocking.c b/source3/smbd/blocking.c index c90f475b46..ea8d2fd053 100644 --- a/source3/smbd/blocking.c +++ b/source3/smbd/blocking.c @@ -21,7 +21,6 @@ #include "includes.h" extern int DEBUGLEVEL; -extern int Client; extern char *OutBuffer; /**************************************************************************** @@ -134,7 +133,7 @@ static void send_blocking_reply(char *outbuf, int outsize) if(outsize > 4) smb_setlen(outbuf,outsize - 4); - send_smb(Client,outbuf); + send_smb(smbd_server_fd(),outbuf); } /**************************************************************************** @@ -180,7 +179,7 @@ static void generic_blocking_lock_error(blocking_lock_record *blr, int eclass, i SSVAL(outbuf,smb_flg2, SVAL(outbuf,smb_flg2) | FLAGS2_32_BIT_ERROR_CODES); ERROR(eclass,ecode); - send_smb(Client,outbuf); + send_smb(smbd_server_fd(),outbuf); } /**************************************************************************** -- cgit From f6be38cae223f1ad3f4ecc5b81d14c44d92f58ba Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 11 Apr 2000 19:44:54 +0000 Subject: include/byteorder.h: ALIGN4/ALIGN2 macros. include/includes.h: Added SMB_BIG_UINT_BITS. lib/util.c: Removed align2/align4 - use macros. libsmb/namequery.c: Use ALIGN2. locking/locking.c: Replace do_lock, do_unlock, args with SMB_BIG_UINT, not SMB_OFF_T. Needed to move to hiding POSIX locks at a lower layer. nmbd/nmbd_processlogon.c: Use ALIGN2/ALIGN4 macros. smbd/blocking.c: Replace do_lock, do_unlock, args with SMB_BIG_UINT, not SMB_OFF_T. smbd/reply.c: Replace do_lock, do_unlock, args with SMB_BIG_UINT, not SMB_OFF_T. Jeremy. (This used to be commit 491eea8a20bf80d426625479326211dc975857a6) --- source3/smbd/blocking.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'source3/smbd/blocking.c') diff --git a/source3/smbd/blocking.c b/source3/smbd/blocking.c index ea8d2fd053..ddf7de3f5b 100644 --- a/source3/smbd/blocking.c +++ b/source3/smbd/blocking.c @@ -193,7 +193,7 @@ static void reply_lockingX_error(blocking_lock_record *blr, int eclass, int32 ec files_struct *fsp = blr->fsp; connection_struct *conn = conn_find(SVAL(inbuf,smb_tid)); uint16 num_ulocks = SVAL(inbuf,smb_vwv6); - SMB_OFF_T count = (SMB_OFF_T) 0, offset = (SMB_OFF_T) 0; + SMB_BIG_UINT count = (SMB_BIG_UINT)0, offset = (SMB_BIG_UINT) 0; unsigned char locktype = CVAL(inbuf,smb_vwv3); BOOL large_file_format = (locktype & LOCKING_ANDX_LARGE_FILES); char *data; @@ -217,7 +217,7 @@ static void reply_lockingX_error(blocking_lock_record *blr, int eclass, int32 ec uint32 dummy2; BOOL err; - count = get_lock_count( data, i, large_file_format, &err); + count = get_lock_count( data, i, large_file_format); offset = get_lock_offset( data, i, large_file_format, &err); /* @@ -278,7 +278,7 @@ static BOOL process_lockread(blocking_lock_record *blr) numtoread = MIN(BUFFER_SIZE-outsize,numtoread); data = smb_buf(outbuf) + 3; - if(!do_lock( fsp, conn, numtoread, startpos, READ_LOCK, &eclass, &ecode)) { + if(!do_lock( fsp, conn, (SMB_BIG_UINT)numtoread, (SMB_BIG_UINT)startpos, READ_LOCK, &eclass, &ecode)) { if((errno != EACCES) && (errno != EAGAIN)) { /* * We have other than a "can't get lock" POSIX @@ -341,7 +341,7 @@ static BOOL process_lock(blocking_lock_record *blr) offset = IVAL(inbuf,smb_vwv3); errno = 0; - if (!do_lock(fsp, conn, count, offset, WRITE_LOCK, &eclass, &ecode)) { + if (!do_lock(fsp, conn, (SMB_BIG_UINT)count, (SMB_BIG_UINT)offset, WRITE_LOCK, &eclass, &ecode)) { if((errno != EACCES) && (errno != EAGAIN)) { /* @@ -389,7 +389,7 @@ static BOOL process_lockingX(blocking_lock_record *blr) connection_struct *conn = conn_find(SVAL(inbuf,smb_tid)); uint16 num_ulocks = SVAL(inbuf,smb_vwv6); uint16 num_locks = SVAL(inbuf,smb_vwv7); - SMB_OFF_T count = 0, offset = 0; + SMB_BIG_UINT count = (SMB_BIG_UINT)0, offset = (SMB_BIG_UINT)0; BOOL large_file_format = (locktype & LOCKING_ANDX_LARGE_FILES); char *data; int eclass=0; @@ -405,7 +405,7 @@ static BOOL process_lockingX(blocking_lock_record *blr) for(; blr->lock_num < num_locks; blr->lock_num++) { BOOL err; - count = get_lock_count( data, blr->lock_num, large_file_format, &err); + count = get_lock_count( data, blr->lock_num, large_file_format); offset = get_lock_offset( data, blr->lock_num, large_file_format, &err); /* -- cgit From 045469493c2870cb1d63c964b18afc5e2210dcd5 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 4 May 2000 21:57:28 +0000 Subject: rpc_server/srv_lsa.c: Bring into sync with 2.0.x. rpc_server/srv_pipe_hnd.c: Bring into sync with 2.0.x. smbd/blocking.c: Improve blocking debug reporting. utils/torture.c: Added check for NT locking bug. Jeremy. (This used to be commit e8ff6d3fb5537c39611a5784bf7216ae812acd27) --- source3/smbd/blocking.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source3/smbd/blocking.c') diff --git a/source3/smbd/blocking.c b/source3/smbd/blocking.c index ddf7de3f5b..e8dc29f80a 100644 --- a/source3/smbd/blocking.c +++ b/source3/smbd/blocking.c @@ -117,8 +117,8 @@ BOOL push_blocking_lock_request( char *inbuf, int length, int lock_timeout, int ubi_slAddTail(&blocking_lock_queue, blr); - DEBUG(3,("push_blocking_lock_request: lock request length=%d blocked with expiry time %d \ -for fnum = %d, name = %s\n", length, (int)blr->expire_time, + DEBUG(3,("push_blocking_lock_request: lock request length=%d blocked with expiry time %d (+%d) \ +for fnum = %d, name = %s\n", length, (int)blr->expire_time, lock_timeout, blr->fsp->fnum, blr->fsp->fsp_name )); return True; -- cgit From 49a0e6d5989656c1b3c9c063a20308ca4ee5d73b Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Wed, 10 May 2000 10:41:59 +0000 Subject: more merging voodoo this adds "#define OLD_NTDOMAIN 1" in lots of places. Don't panic - this isn't permanent, it should go after another few merge steps have been done (This used to be commit 92109d7b3c06f240452d39f669ecb8c9c86ab610) --- source3/smbd/blocking.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'source3/smbd/blocking.c') diff --git a/source3/smbd/blocking.c b/source3/smbd/blocking.c index e8dc29f80a..16caf8b52e 100644 --- a/source3/smbd/blocking.c +++ b/source3/smbd/blocking.c @@ -1,3 +1,5 @@ +#define OLD_NTDOMAIN 1 + /* Unix SMB/Netbios implementation. Version 1.9. @@ -631,3 +633,5 @@ void process_blocking_lock_queue(time_t t) blr = (blocking_lock_record *)ubi_slNext(blr); } } + +#undef OLD_NTDOMAIN -- cgit From da3053048c3d224a20d6383ac6682d31059cd46c Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Sun, 11 Mar 2001 00:32:10 +0000 Subject: Merge of new 2.2 code into HEAD (Gerald I hate you :-) :-). Allows new SAMR RPC code to merge with new passdb code. Currently rpcclient doesn't compile. I'm working on it... Jeremy. (This used to be commit 0be41d5158ea4e645e93e8cd30617c038416e549) --- source3/smbd/blocking.c | 4 ---- 1 file changed, 4 deletions(-) (limited to 'source3/smbd/blocking.c') diff --git a/source3/smbd/blocking.c b/source3/smbd/blocking.c index 16caf8b52e..e8dc29f80a 100644 --- a/source3/smbd/blocking.c +++ b/source3/smbd/blocking.c @@ -1,5 +1,3 @@ -#define OLD_NTDOMAIN 1 - /* Unix SMB/Netbios implementation. Version 1.9. @@ -633,5 +631,3 @@ void process_blocking_lock_queue(time_t t) blr = (blocking_lock_record *)ubi_slNext(blr); } } - -#undef OLD_NTDOMAIN -- cgit From f63ee18c684af33342de2c5757f9fdf0b7d84997 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Sat, 9 Jun 2001 01:38:54 +0000 Subject: *Wonderful* patch from Andrew Bartlett that will help ensure tdb's are cleaned on clients abending connections. Thanks Andrew ! Jeremy. (This used to be commit 1b3977c5367a0b713b194f369abd9872ae01ac2a) --- source3/smbd/blocking.c | 22 ++++++++++++---------- 1 file changed, 12 insertions(+), 10 deletions(-) (limited to 'source3/smbd/blocking.c') diff --git a/source3/smbd/blocking.c b/source3/smbd/blocking.c index e8dc29f80a..cebad5ce35 100644 --- a/source3/smbd/blocking.c +++ b/source3/smbd/blocking.c @@ -130,10 +130,11 @@ for fnum = %d, name = %s\n", length, (int)blr->expire_time, lock_timeout, static void send_blocking_reply(char *outbuf, int outsize) { - if(outsize > 4) - smb_setlen(outbuf,outsize - 4); + if(outsize > 4) + smb_setlen(outbuf,outsize - 4); - send_smb(smbd_server_fd(),outbuf); + if (!send_smb(smbd_server_fd(),outbuf)) + exit_server("send_blocking_reply: send_smb failed.\n"); } /**************************************************************************** @@ -171,15 +172,16 @@ static void reply_lockingX_success(blocking_lock_record *blr) static void generic_blocking_lock_error(blocking_lock_record *blr, int eclass, int32 ecode) { - char *outbuf = OutBuffer; - char *inbuf = blr->inbuf; - construct_reply_common(inbuf, outbuf); + char *outbuf = OutBuffer; + char *inbuf = blr->inbuf; + construct_reply_common(inbuf, outbuf); - if(eclass == 0) /* NT Error. */ - SSVAL(outbuf,smb_flg2, SVAL(outbuf,smb_flg2) | FLAGS2_32_BIT_ERROR_CODES); + if(eclass == 0) /* NT Error. */ + SSVAL(outbuf,smb_flg2, SVAL(outbuf,smb_flg2) | FLAGS2_32_BIT_ERROR_CODES); - ERROR(eclass,ecode); - send_smb(smbd_server_fd(),outbuf); + ERROR(eclass,ecode); + if (!send_smb(smbd_server_fd(),outbuf)) + exit_server("generic_blocking_lock_error: send_smb failed.\n"); } /**************************************************************************** -- cgit From 91b8a8d1d21b810b6aca44ce647837669efd6dcf Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Thu, 21 Jun 2001 09:10:42 +0000 Subject: next_token() was supposed to be a reentrant replacement for strtok(), but the code suffered from bitrot and is not now reentrant. That means we can get bizarre behaviour i've fixed this by making next_token() reentrant and creating a next_token_nr() that is a small non-reentrant wrapper for those lumps of code (mostly smbclient) that have come to rely on the non-reentrant behaviour (This used to be commit 674ee2f1d12b0afc164a9e9072758fd1c5e54df7) --- source3/smbd/blocking.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) (limited to 'source3/smbd/blocking.c') diff --git a/source3/smbd/blocking.c b/source3/smbd/blocking.c index cebad5ce35..843f3d07a6 100644 --- a/source3/smbd/blocking.c +++ b/source3/smbd/blocking.c @@ -265,7 +265,7 @@ static BOOL process_lockread(blocking_lock_record *blr) char *outbuf = OutBuffer; char *inbuf = blr->inbuf; ssize_t nread = -1; - char *data; + char *data, *p; int outsize = 0; SMB_OFF_T startpos; size_t numtoread; @@ -309,12 +309,15 @@ static BOOL process_lockread(blocking_lock_record *blr) } construct_reply_common(inbuf, outbuf); - outsize = set_message(outbuf,5,3,True); + outsize = set_message(outbuf,5,0,True); outsize += nread; SSVAL(outbuf,smb_vwv0,nread); SSVAL(outbuf,smb_vwv5,nread+3); - SSVAL(smb_buf(outbuf),1,nread); + p = smb_buf(outbuf); + *p++ = 1; + SSVAL(p,0,nread); p += 2; + set_message_end(outbuf, p+nread); DEBUG(3, ( "process_lockread file = %s, fnum=%d num=%d nread=%d\n", fsp->fsp_name, fsp->fnum, (int)numtoread, (int)nread ) ); -- cgit From 5b69009b25886bfa8b07e3ac885064ffa730f9bf Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Mon, 2 Jul 2001 02:42:41 +0000 Subject: Fixed the nastiest locking bug to track down.... smb_pids are sent in the lockingX calls - use that instead of smb_pid in the packet. Jeremy. (This used to be commit a3925cb9c6303ce24e5fecad6c8f3a0ba78b9ee0) --- source3/smbd/blocking.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) (limited to 'source3/smbd/blocking.c') diff --git a/source3/smbd/blocking.c b/source3/smbd/blocking.c index 843f3d07a6..48d3c8a24a 100644 --- a/source3/smbd/blocking.c +++ b/source3/smbd/blocking.c @@ -196,6 +196,7 @@ static void reply_lockingX_error(blocking_lock_record *blr, int eclass, int32 ec connection_struct *conn = conn_find(SVAL(inbuf,smb_tid)); uint16 num_ulocks = SVAL(inbuf,smb_vwv6); SMB_BIG_UINT count = (SMB_BIG_UINT)0, offset = (SMB_BIG_UINT) 0; + uint16 lock_pid; unsigned char locktype = CVAL(inbuf,smb_vwv3); BOOL large_file_format = (locktype & LOCKING_ANDX_LARGE_FILES); char *data; @@ -219,6 +220,7 @@ static void reply_lockingX_error(blocking_lock_record *blr, int eclass, int32 ec uint32 dummy2; BOOL err; + 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); @@ -227,7 +229,7 @@ static void reply_lockingX_error(blocking_lock_record *blr, int eclass, int32 ec * request would never have been queued. JRA. */ - do_unlock(fsp,conn,count,offset,&dummy1,&dummy2); + do_unlock(fsp,conn,lock_pid,count,offset,&dummy1,&dummy2); } generic_blocking_lock_error(blr, eclass, ecode); @@ -280,7 +282,7 @@ static BOOL process_lockread(blocking_lock_record *blr) numtoread = MIN(BUFFER_SIZE-outsize,numtoread); data = smb_buf(outbuf) + 3; - if(!do_lock( fsp, conn, (SMB_BIG_UINT)numtoread, (SMB_BIG_UINT)startpos, READ_LOCK, &eclass, &ecode)) { + if(!do_lock( fsp, conn, SVAL(inbuf,smb_pid), (SMB_BIG_UINT)numtoread, (SMB_BIG_UINT)startpos, READ_LOCK, &eclass, &ecode)) { if((errno != EACCES) && (errno != EAGAIN)) { /* * We have other than a "can't get lock" POSIX @@ -346,7 +348,7 @@ static BOOL process_lock(blocking_lock_record *blr) offset = IVAL(inbuf,smb_vwv3); errno = 0; - if (!do_lock(fsp, conn, (SMB_BIG_UINT)count, (SMB_BIG_UINT)offset, WRITE_LOCK, &eclass, &ecode)) { + if (!do_lock(fsp, conn, SVAL(inbuf,smb_pid), (SMB_BIG_UINT)count, (SMB_BIG_UINT)offset, WRITE_LOCK, &eclass, &ecode)) { if((errno != EACCES) && (errno != EAGAIN)) { /* @@ -395,6 +397,7 @@ static BOOL process_lockingX(blocking_lock_record *blr) uint16 num_ulocks = SVAL(inbuf,smb_vwv6); uint16 num_locks = SVAL(inbuf,smb_vwv7); SMB_BIG_UINT count = (SMB_BIG_UINT)0, offset = (SMB_BIG_UINT)0; + uint16 lock_pid; BOOL large_file_format = (locktype & LOCKING_ANDX_LARGE_FILES); char *data; int eclass=0; @@ -410,6 +413,7 @@ static BOOL process_lockingX(blocking_lock_record *blr) for(; blr->lock_num < num_locks; blr->lock_num++) { BOOL err; + 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); @@ -418,7 +422,7 @@ static BOOL process_lockingX(blocking_lock_record *blr) * request would never have been queued. JRA. */ errno = 0; - if(!do_lock(fsp,conn,count,offset, ((locktype & 1) ? READ_LOCK : WRITE_LOCK), + if(!do_lock(fsp,conn,count,lock_pid,offset, ((locktype & 1) ? READ_LOCK : WRITE_LOCK), &eclass, &ecode)) break; } -- cgit From e8e98c9ea0690e3acf1126b50882e59e1056c7b3 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Mon, 27 Aug 2001 08:19:43 +0000 Subject: converted smbd to use NTSTATUS by default major changes include: - added NSTATUS type - added automatic mapping between dos and nt error codes - changed all ERROR() calls to ERROR_DOS() and many to ERROR_NT() these calls auto-translate to the client error code system - got rid of the cached error code and the writebmpx code We eventually will need to also: - get rid of BOOL, so we don't lose error info - replace all ERROR_DOS() calls with ERROR_NT() calls but that is too much for one night (This used to be commit 83d9896c1ea8be796192b51a4678c2a3b87f7518) --- source3/smbd/blocking.c | 474 +++++++++++++++++++++++------------------------- 1 file changed, 231 insertions(+), 243 deletions(-) (limited to 'source3/smbd/blocking.c') diff --git a/source3/smbd/blocking.c b/source3/smbd/blocking.c index 48d3c8a24a..697e1df194 100644 --- a/source3/smbd/blocking.c +++ b/source3/smbd/blocking.c @@ -170,16 +170,13 @@ static void reply_lockingX_success(blocking_lock_record *blr) Return a generic lock fail error blocking call. *****************************************************************************/ -static void generic_blocking_lock_error(blocking_lock_record *blr, int eclass, int32 ecode) +static void generic_blocking_lock_error(blocking_lock_record *blr, NTSTATUS status) { char *outbuf = OutBuffer; char *inbuf = blr->inbuf; construct_reply_common(inbuf, outbuf); - if(eclass == 0) /* NT Error. */ - SSVAL(outbuf,smb_flg2, SVAL(outbuf,smb_flg2) | FLAGS2_32_BIT_ERROR_CODES); - - ERROR(eclass,ecode); + ERROR_NT(status); if (!send_smb(smbd_server_fd(),outbuf)) exit_server("generic_blocking_lock_error: send_smb failed.\n"); } @@ -189,72 +186,68 @@ static void generic_blocking_lock_error(blocking_lock_record *blr, int eclass, i obtained first. *****************************************************************************/ -static void reply_lockingX_error(blocking_lock_record *blr, int eclass, int32 ecode) +static void reply_lockingX_error(blocking_lock_record *blr, NTSTATUS status) { - char *inbuf = blr->inbuf; - files_struct *fsp = blr->fsp; - connection_struct *conn = conn_find(SVAL(inbuf,smb_tid)); - uint16 num_ulocks = SVAL(inbuf,smb_vwv6); - SMB_BIG_UINT count = (SMB_BIG_UINT)0, offset = (SMB_BIG_UINT) 0; - uint16 lock_pid; - unsigned char locktype = CVAL(inbuf,smb_vwv3); - BOOL large_file_format = (locktype & LOCKING_ANDX_LARGE_FILES); - char *data; - int i; - - data = smb_buf(inbuf) + ((large_file_format ? 20 : 10)*num_ulocks); - - /* - * 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) ..... - */ - - for(i = blr->lock_num - 1; i >= 0; i--) { - int dummy1; - uint32 dummy2; - BOOL err; - - 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); - - /* - * We know err cannot be set as if it was the lock - * request would never have been queued. JRA. - */ - - do_unlock(fsp,conn,lock_pid,count,offset,&dummy1,&dummy2); - } - - generic_blocking_lock_error(blr, eclass, ecode); + char *inbuf = blr->inbuf; + files_struct *fsp = blr->fsp; + connection_struct *conn = conn_find(SVAL(inbuf,smb_tid)); + uint16 num_ulocks = SVAL(inbuf,smb_vwv6); + SMB_BIG_UINT count = (SMB_BIG_UINT)0, offset = (SMB_BIG_UINT) 0; + uint16 lock_pid; + unsigned char locktype = CVAL(inbuf,smb_vwv3); + BOOL large_file_format = (locktype & LOCKING_ANDX_LARGE_FILES); + char *data; + int i; + + data = smb_buf(inbuf) + ((large_file_format ? 20 : 10)*num_ulocks); + + /* + * 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) ..... + */ + + for(i = blr->lock_num - 1; i >= 0; i--) { + BOOL err; + + 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); + + /* + * We know err cannot be set as if it was the lock + * request would never have been queued. JRA. + */ + + do_unlock(fsp,conn,lock_pid,count,offset); + } + + generic_blocking_lock_error(blr, status); } /**************************************************************************** Return a lock fail error. *****************************************************************************/ -static void blocking_lock_reply_error(blocking_lock_record *blr, int eclass, int32 ecode) +static void blocking_lock_reply_error(blocking_lock_record *blr, NTSTATUS status) { - switch(blr->com_type) { - case SMBlock: - generic_blocking_lock_error(blr, eclass, ecode); - break; - case SMBlockread: - generic_blocking_lock_error(blr, eclass, ecode); - break; - case SMBlockingX: - reply_lockingX_error(blr, eclass, ecode); - break; - 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"); - } + switch(blr->com_type) { + case SMBlock: + case SMBlockread: + generic_blocking_lock_error(blr, status); + break; + case SMBlockingX: + reply_lockingX_error(blr, status); + break; + 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"); + } } /**************************************************************************** @@ -264,68 +257,68 @@ static void blocking_lock_reply_error(blocking_lock_record *blr, int eclass, int static BOOL process_lockread(blocking_lock_record *blr) { - char *outbuf = OutBuffer; - char *inbuf = blr->inbuf; - ssize_t nread = -1; - char *data, *p; - int outsize = 0; - SMB_OFF_T startpos; - size_t numtoread; - int eclass; - uint32 ecode; - connection_struct *conn = conn_find(SVAL(inbuf,smb_tid)); - files_struct *fsp = blr->fsp; - - numtoread = SVAL(inbuf,smb_vwv1); - startpos = IVAL(inbuf,smb_vwv2); - - numtoread = MIN(BUFFER_SIZE-outsize,numtoread); - data = smb_buf(outbuf) + 3; + char *outbuf = OutBuffer; + char *inbuf = blr->inbuf; + ssize_t nread = -1; + char *data, *p; + int outsize = 0; + SMB_OFF_T startpos; + size_t numtoread; + NTSTATUS status; + connection_struct *conn = conn_find(SVAL(inbuf,smb_tid)); + files_struct *fsp = blr->fsp; + + numtoread = SVAL(inbuf,smb_vwv1); + startpos = IVAL(inbuf,smb_vwv2); + + numtoread = MIN(BUFFER_SIZE-outsize,numtoread); + data = smb_buf(outbuf) + 3; - if(!do_lock( fsp, conn, SVAL(inbuf,smb_pid), (SMB_BIG_UINT)numtoread, (SMB_BIG_UINT)startpos, READ_LOCK, &eclass, &ecode)) { - if((errno != EACCES) && (errno != EAGAIN)) { - /* - * We have other than a "can't get lock" POSIX - * error. Send an error. - * Return True so we get dequeued. - */ - - generic_blocking_lock_error(blr, eclass, ecode); - return True; - } - - /* - * Still waiting for lock.... - */ - - DEBUG(10,("process_lockread: failed to get lock for file = %s. Still waiting....\n", - fsp->fsp_name)); - return False; - } - - nread = read_file(fsp,data,startpos,numtoread); - - if (nread < 0) { - generic_blocking_lock_error(blr,ERRDOS,ERRnoaccess); - return True; - } - - construct_reply_common(inbuf, outbuf); - outsize = set_message(outbuf,5,0,True); - - outsize += nread; - SSVAL(outbuf,smb_vwv0,nread); - SSVAL(outbuf,smb_vwv5,nread+3); - p = smb_buf(outbuf); - *p++ = 1; - SSVAL(p,0,nread); p += 2; - set_message_end(outbuf, p+nread); - - DEBUG(3, ( "process_lockread file = %s, fnum=%d num=%d nread=%d\n", - fsp->fsp_name, fsp->fnum, (int)numtoread, (int)nread ) ); - - send_blocking_reply(outbuf,outsize); - return True; + status = do_lock( fsp, conn, SVAL(inbuf,smb_pid), (SMB_BIG_UINT)numtoread, + (SMB_BIG_UINT)startpos, READ_LOCK); + if (status != NT_STATUS_NOPROBLEMO) { + if ((errno != EACCES) && (errno != EAGAIN)) { + /* + * We have other than a "can't get lock" POSIX + * error. Send an error. + * Return True so we get dequeued. + */ + generic_blocking_lock_error(blr, status); + return True; + } + + /* + * Still waiting for lock.... + */ + + DEBUG(10,("process_lockread: failed to get lock for file = %s. Still waiting....\n", + fsp->fsp_name)); + return False; + } + + nread = read_file(fsp,data,startpos,numtoread); + + if (nread < 0) { + generic_blocking_lock_error(blr,NT_STATUS_ACCESS_DENIED); + return True; + } + + construct_reply_common(inbuf, outbuf); + outsize = set_message(outbuf,5,0,True); + + outsize += nread; + SSVAL(outbuf,smb_vwv0,nread); + SSVAL(outbuf,smb_vwv5,nread+3); + p = smb_buf(outbuf); + *p++ = 1; + SSVAL(p,0,nread); p += 2; + set_message_end(outbuf, p+nread); + + DEBUG(3, ( "process_lockread file = %s, fnum=%d num=%d nread=%d\n", + fsp->fsp_name, fsp->fnum, (int)numtoread, (int)nread ) ); + + send_blocking_reply(outbuf,outsize); + return True; } /**************************************************************************** @@ -335,52 +328,50 @@ static BOOL process_lockread(blocking_lock_record *blr) static BOOL process_lock(blocking_lock_record *blr) { - char *outbuf = OutBuffer; - char *inbuf = blr->inbuf; - int outsize; - SMB_OFF_T count = 0, offset = 0; - int eclass; - uint32 ecode; - connection_struct *conn = conn_find(SVAL(inbuf,smb_tid)); - files_struct *fsp = blr->fsp; - - count = IVAL(inbuf,smb_vwv1); - offset = IVAL(inbuf,smb_vwv3); - - errno = 0; - if (!do_lock(fsp, conn, SVAL(inbuf,smb_pid), (SMB_BIG_UINT)count, (SMB_BIG_UINT)offset, WRITE_LOCK, &eclass, &ecode)) { - if((errno != EACCES) && (errno != EAGAIN)) { - - /* - * We have other than a "can't get lock" POSIX - * error. Send an error. - * Return True so we get dequeued. - */ - - blocking_lock_reply_error(blr, eclass, ecode); - return True; - } - - /* - * Still can't get the lock - keep waiting. - */ - - DEBUG(10,("process_lock: failed to get lock for file = %s. Still waiting....\n", - fsp->fsp_name)); - return False; - } - - /* - * Success - we got the lock. - */ - - DEBUG(3,("process_lock : file=%s fnum=%d offset=%.0f count=%.0f\n", - fsp->fsp_name, fsp->fnum, (double)offset, (double)count)); - - construct_reply_common(inbuf, outbuf); - outsize = set_message(outbuf,0,0,True); - send_blocking_reply(outbuf,outsize); - return True; + char *outbuf = OutBuffer; + char *inbuf = blr->inbuf; + int outsize; + SMB_OFF_T count = 0, offset = 0; + NTSTATUS status; + connection_struct *conn = conn_find(SVAL(inbuf,smb_tid)); + files_struct *fsp = blr->fsp; + + count = IVAL(inbuf,smb_vwv1); + offset = IVAL(inbuf,smb_vwv3); + + errno = 0; + status = do_lock(fsp, conn, SVAL(inbuf,smb_pid), (SMB_BIG_UINT)count, + (SMB_BIG_UINT)offset, WRITE_LOCK); + if (status != NT_STATUS_NOPROBLEMO) { + if((errno != EACCES) && (errno != EAGAIN)) { + /* + * We have other than a "can't get lock" POSIX + * error. Send an error. + * Return True so we get dequeued. + */ + + blocking_lock_reply_error(blr, status); + return True; + } + /* + * Still can't get the lock - keep waiting. + */ + DEBUG(10,("process_lock: failed to get lock for file = %s. Still waiting....\n", + fsp->fsp_name)); + return False; + } + + /* + * Success - we got the lock. + */ + + DEBUG(3,("process_lock : file=%s fnum=%d offset=%.0f count=%.0f\n", + fsp->fsp_name, fsp->fnum, (double)offset, (double)count)); + + construct_reply_common(inbuf, outbuf); + outsize = set_message(outbuf,0,0,True); + send_blocking_reply(outbuf,outsize); + return True; } /**************************************************************************** @@ -390,75 +381,72 @@ static BOOL process_lock(blocking_lock_record *blr) static BOOL process_lockingX(blocking_lock_record *blr) { - char *inbuf = blr->inbuf; - unsigned char locktype = CVAL(inbuf,smb_vwv3); - files_struct *fsp = blr->fsp; - connection_struct *conn = conn_find(SVAL(inbuf,smb_tid)); - uint16 num_ulocks = SVAL(inbuf,smb_vwv6); - uint16 num_locks = SVAL(inbuf,smb_vwv7); - SMB_BIG_UINT count = (SMB_BIG_UINT)0, offset = (SMB_BIG_UINT)0; - uint16 lock_pid; - BOOL large_file_format = (locktype & LOCKING_ANDX_LARGE_FILES); - char *data; - int eclass=0; - uint32 ecode=0; - - data = smb_buf(inbuf) + ((large_file_format ? 20 : 10)*num_ulocks); - - /* - * Data now points at the beginning of the list - * of smb_lkrng structs. - */ - - for(; blr->lock_num < num_locks; blr->lock_num++) { - BOOL err; - - 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); - - /* - * We know err cannot be set as if it was the lock - * request would never have been queued. JRA. - */ - errno = 0; - if(!do_lock(fsp,conn,count,lock_pid,offset, ((locktype & 1) ? READ_LOCK : WRITE_LOCK), - &eclass, &ecode)) - break; - } - - if(blr->lock_num == num_locks) { - - /* - * Success - we got all the locks. - */ - - 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; - - } else if((errno != EACCES) && (errno != EAGAIN)) { - - /* - * We have other than a "can't get lock" POSIX - * error. Free any locks we had and return an error. - * Return True so we get dequeued. - */ - - blocking_lock_reply_error(blr, eclass, ecode); - return True; - } - - /* - * Still can't get all the locks - keep waiting. - */ - - 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)); - - return False; + char *inbuf = blr->inbuf; + unsigned char locktype = CVAL(inbuf,smb_vwv3); + files_struct *fsp = blr->fsp; + connection_struct *conn = conn_find(SVAL(inbuf,smb_tid)); + uint16 num_ulocks = SVAL(inbuf,smb_vwv6); + uint16 num_locks = SVAL(inbuf,smb_vwv7); + SMB_BIG_UINT count = (SMB_BIG_UINT)0, offset = (SMB_BIG_UINT)0; + uint16 lock_pid; + BOOL large_file_format = (locktype & LOCKING_ANDX_LARGE_FILES); + char *data; + NTSTATUS status = 0; + + data = smb_buf(inbuf) + ((large_file_format ? 20 : 10)*num_ulocks); + + /* + * Data now points at the beginning of the list + * of smb_lkrng structs. + */ + + for(; blr->lock_num < num_locks; blr->lock_num++) { + BOOL err; + + 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); + + /* + * We know err cannot be set as if it was the lock + * request would never have been queued. JRA. + */ + errno = 0; + status = do_lock(fsp,conn,count,lock_pid,offset, + ((locktype & 1) ? READ_LOCK : WRITE_LOCK)); + if (status != NT_STATUS_NOPROBLEMO) break; + } + + if(blr->lock_num == num_locks) { + /* + * Success - we got all the locks. + */ + + 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; + } else if ((errno != EACCES) && (errno != EAGAIN)) { + /* + * We have other than a "can't get lock" POSIX + * error. Free any locks we had and return an error. + * Return True so we get dequeued. + */ + + blocking_lock_reply_error(blr, status); + return True; + } + + /* + * Still can't get all the locks - keep waiting. + */ + + 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)); + + return False; } /**************************************************************************** @@ -523,7 +511,7 @@ void remove_pending_lock_requests_by_mid(int mid) 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 )); - blocking_lock_reply_error(blr,0,NT_STATUS_CANCELLED); + blocking_lock_reply_error(blr,NT_STATUS_CANCELLED); free_blocking_lock_record((blocking_lock_record *)ubi_slRemNext( &blocking_lock_queue, prev)); blr = (blocking_lock_record *)(prev ? ubi_slNext(prev) : ubi_slFirst(&blocking_lock_queue)); continue; @@ -588,7 +576,7 @@ void process_blocking_lock_queue(time_t t) DEBUG(5,("process_blocking_lock_queue: pending lock fnum = %d for file %s timed out.\n", fsp->fnum, fsp->fsp_name )); - blocking_lock_reply_error(blr,ERRSRV,ERRaccess); + blocking_lock_reply_error(blr,NT_STATUS_ACCESS_DENIED); free_blocking_lock_record((blocking_lock_record *)ubi_slRemNext( &blocking_lock_queue, prev)); blr = (blocking_lock_record *)(prev ? ubi_slNext(prev) : ubi_slFirst(&blocking_lock_queue)); continue; @@ -600,7 +588,7 @@ void process_blocking_lock_queue(time_t t) /* * Remove the entry and return an error to the client. */ - blocking_lock_reply_error(blr,ERRSRV,ERRaccess); + blocking_lock_reply_error(blr,NT_STATUS_ACCESS_DENIED); free_blocking_lock_record((blocking_lock_record *)ubi_slRemNext( &blocking_lock_queue, prev)); blr = (blocking_lock_record *)(prev ? ubi_slNext(prev) : ubi_slFirst(&blocking_lock_queue)); continue; @@ -611,7 +599,7 @@ void process_blocking_lock_queue(time_t t) /* * Remove the entry and return an error to the client. */ - blocking_lock_reply_error(blr,ERRSRV,ERRaccess); + blocking_lock_reply_error(blr,NT_STATUS_ACCESS_DENIED); free_blocking_lock_record((blocking_lock_record *)ubi_slRemNext( &blocking_lock_queue, prev)); blr = (blocking_lock_record *)(prev ? ubi_slNext(prev) : ubi_slFirst(&blocking_lock_queue)); unbecome_user(); -- cgit From ee5f7237decfe446f4fdb08422beb2e6cb43af7f Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Mon, 27 Aug 2001 17:52:23 +0000 Subject: started converting NTSTATUS to be a structure on systems with gcc in order to make it type incompatible with BOOL so we catch errors sooner. This has already found a number of bugs (This used to be commit 1b778bc7d22efff3f90dc450eb12baa1241cf68f) --- source3/smbd/blocking.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'source3/smbd/blocking.c') diff --git a/source3/smbd/blocking.c b/source3/smbd/blocking.c index 697e1df194..1365985660 100644 --- a/source3/smbd/blocking.c +++ b/source3/smbd/blocking.c @@ -276,7 +276,7 @@ static BOOL process_lockread(blocking_lock_record *blr) status = do_lock( fsp, conn, SVAL(inbuf,smb_pid), (SMB_BIG_UINT)numtoread, (SMB_BIG_UINT)startpos, READ_LOCK); - if (status != NT_STATUS_NOPROBLEMO) { + if (NT_STATUS_V(status)) { if ((errno != EACCES) && (errno != EAGAIN)) { /* * We have other than a "can't get lock" POSIX @@ -342,7 +342,7 @@ static BOOL process_lock(blocking_lock_record *blr) errno = 0; status = do_lock(fsp, conn, SVAL(inbuf,smb_pid), (SMB_BIG_UINT)count, (SMB_BIG_UINT)offset, WRITE_LOCK); - if (status != NT_STATUS_NOPROBLEMO) { + if (NT_STATUS_IS_ERR(status)) { if((errno != EACCES) && (errno != EAGAIN)) { /* * We have other than a "can't get lock" POSIX @@ -391,7 +391,7 @@ static BOOL process_lockingX(blocking_lock_record *blr) uint16 lock_pid; BOOL large_file_format = (locktype & LOCKING_ANDX_LARGE_FILES); char *data; - NTSTATUS status = 0; + NTSTATUS status = NT_STATUS_OK; data = smb_buf(inbuf) + ((large_file_format ? 20 : 10)*num_ulocks); @@ -414,7 +414,7 @@ static BOOL process_lockingX(blocking_lock_record *blr) errno = 0; status = do_lock(fsp,conn,count,lock_pid,offset, ((locktype & 1) ? READ_LOCK : WRITE_LOCK)); - if (status != NT_STATUS_NOPROBLEMO) break; + if (NT_STATUS_IS_ERR(status)) break; } if(blr->lock_num == num_locks) { -- cgit From 3bd7e65cac84b6d0a22936addbd6e30617c84567 Mon Sep 17 00:00:00 2001 From: Simo Sorce Date: Thu, 30 Aug 2001 08:14:16 +0000 Subject: this was a stupid typo, thanks to Jochen Dolze (dolze@epcnet.de) for pointing out. (This used to be commit a554d5a99a03e6e8df7e946e5636f5ee80b21969) --- source3/smbd/blocking.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/smbd/blocking.c') diff --git a/source3/smbd/blocking.c b/source3/smbd/blocking.c index 1365985660..2008598104 100644 --- a/source3/smbd/blocking.c +++ b/source3/smbd/blocking.c @@ -412,7 +412,7 @@ static BOOL process_lockingX(blocking_lock_record *blr) * request would never have been queued. JRA. */ errno = 0; - status = do_lock(fsp,conn,count,lock_pid,offset, + status = do_lock(fsp,conn,lock_pid,count,offset, ((locktype & 1) ? READ_LOCK : WRITE_LOCK)); if (NT_STATUS_IS_ERR(status)) break; } -- cgit From 61b2794968faa35dc91edce17e9b91e5366c3514 Mon Sep 17 00:00:00 2001 From: Simo Sorce Date: Mon, 17 Sep 2001 11:25:41 +0000 Subject: move to SAFE_FREE() (This used to be commit a95943fde0ad89ae3f2deca2f7ba9cb5ab612b74) --- source3/smbd/blocking.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'source3/smbd/blocking.c') diff --git a/source3/smbd/blocking.c b/source3/smbd/blocking.c index 2008598104..cec1581254 100644 --- a/source3/smbd/blocking.c +++ b/source3/smbd/blocking.c @@ -46,8 +46,8 @@ static ubi_slList blocking_lock_queue = { NULL, (ubi_slNodePtr)&blocking_lock_qu static void free_blocking_lock_record(blocking_lock_record *blr) { - free(blr->inbuf); - free((char *)blr); + SAFE_FREE(blr->inbuf); + SAFE_FREE(blr); } /**************************************************************************** @@ -103,7 +103,7 @@ BOOL push_blocking_lock_request( char *inbuf, int length, int lock_timeout, int if((blr->inbuf = (char *)malloc(length)) == NULL) { DEBUG(0,("push_blocking_lock_request: Malloc fail (2)!\n" )); - free((char *)blr); + SAFE_FREE(blr); return False; } -- cgit From dc1fc3ee8ec2199bc73bb5d7ec711c6800f61d65 Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Tue, 2 Oct 2001 04:29:50 +0000 Subject: Removed 'extern int DEBUGLEVEL' as it is now in the smb.h header. (This used to be commit 2d0922b0eabfdc0aaf1d0797482fef47ed7fde8e) --- source3/smbd/blocking.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/smbd/blocking.c') diff --git a/source3/smbd/blocking.c b/source3/smbd/blocking.c index cec1581254..a398a4c2a1 100644 --- a/source3/smbd/blocking.c +++ b/source3/smbd/blocking.c @@ -20,7 +20,7 @@ */ #include "includes.h" -extern int DEBUGLEVEL; + extern char *OutBuffer; /**************************************************************************** -- cgit From c416ff851b4ecc7a44aee9d00d07dd481d8ae2a7 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 18 Oct 2001 20:15:12 +0000 Subject: Merge the become_XXX -> change_to_XXX fixes from 2.2.2 to HEAD. Ensure make_conection() can only be called as root. Jeremy. (This used to be commit 8d23a7441b4687458ee021bfe8880558506eddba) --- source3/smbd/blocking.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'source3/smbd/blocking.c') diff --git a/source3/smbd/blocking.c b/source3/smbd/blocking.c index a398a4c2a1..252ae6e0ea 100644 --- a/source3/smbd/blocking.c +++ b/source3/smbd/blocking.c @@ -582,7 +582,7 @@ void process_blocking_lock_queue(time_t t) continue; } - if(!become_user(conn,vuid)) { + if(!change_to_user(conn,vuid)) { DEBUG(0,("process_blocking_lock_queue: Unable to become user vuid=%d.\n", vuid )); /* @@ -594,7 +594,7 @@ void process_blocking_lock_queue(time_t t) continue; } - if(!become_service(conn,True)) { + if(!set_current_service(conn,True)) { DEBUG(0,("process_blocking_lock_queue: Unable to become service Error was %s.\n", strerror(errno) )); /* * Remove the entry and return an error to the client. @@ -602,7 +602,7 @@ void process_blocking_lock_queue(time_t t) blocking_lock_reply_error(blr,NT_STATUS_ACCESS_DENIED); free_blocking_lock_record((blocking_lock_record *)ubi_slRemNext( &blocking_lock_queue, prev)); blr = (blocking_lock_record *)(prev ? ubi_slNext(prev) : ubi_slFirst(&blocking_lock_queue)); - unbecome_user(); + change_to_root_user(); continue; } @@ -615,11 +615,11 @@ void process_blocking_lock_queue(time_t t) if(blocking_lock_record_process(blr)) { free_blocking_lock_record((blocking_lock_record *)ubi_slRemNext( &blocking_lock_queue, prev)); blr = (blocking_lock_record *)(prev ? ubi_slNext(prev) : ubi_slFirst(&blocking_lock_queue)); - unbecome_user(); + change_to_root_user(); continue; } - unbecome_user(); + change_to_root_user(); /* * Move to the next in the list. -- cgit From d876260d885ad991526544756609ea38e4867028 Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Mon, 5 Nov 2001 00:02:38 +0000 Subject: Don't put a \n on the end of the arg to exit_server() (This used to be commit dfb8566220c3e90ca2b757ea124f53aed103269e) --- source3/smbd/blocking.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source3/smbd/blocking.c') diff --git a/source3/smbd/blocking.c b/source3/smbd/blocking.c index 252ae6e0ea..0d2a99b3f0 100644 --- a/source3/smbd/blocking.c +++ b/source3/smbd/blocking.c @@ -134,7 +134,7 @@ static void send_blocking_reply(char *outbuf, int outsize) smb_setlen(outbuf,outsize - 4); if (!send_smb(smbd_server_fd(),outbuf)) - exit_server("send_blocking_reply: send_smb failed.\n"); + exit_server("send_blocking_reply: send_smb failed."); } /**************************************************************************** @@ -178,7 +178,7 @@ static void generic_blocking_lock_error(blocking_lock_record *blr, NTSTATUS stat ERROR_NT(status); if (!send_smb(smbd_server_fd(),outbuf)) - exit_server("generic_blocking_lock_error: send_smb failed.\n"); + exit_server("generic_blocking_lock_error: send_smb failed."); } /**************************************************************************** -- cgit From cd68afe31256ad60748b34f7318a180cfc2127cc Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Wed, 30 Jan 2002 06:08:46 +0000 Subject: Removed version number from file header. Changed "SMB/Netbios" to "SMB/CIFS" in file header. (This used to be commit 6a58c9bd06d0d7502a24bf5ce5a2faf0a146edfa) --- source3/smbd/blocking.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'source3/smbd/blocking.c') diff --git a/source3/smbd/blocking.c b/source3/smbd/blocking.c index 0d2a99b3f0..024e5b9f66 100644 --- a/source3/smbd/blocking.c +++ b/source3/smbd/blocking.c @@ -1,6 +1,5 @@ /* - Unix SMB/Netbios implementation. - Version 1.9. + Unix SMB/CIFS implementation. Blocking Locking functions Copyright (C) Jeremy Allison 1998 -- cgit From 0843c37abd0a1520fc3117f91fc6284d9475c87e Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sun, 10 Mar 2002 23:18:44 +0000 Subject: failed timed locks always give LOCK_CONFLICT not LOCK_NOT_GRANTED (This used to be commit ec71c1a66f9fd4b9cb4cad5a9b5b17e20de7aeb1) --- source3/smbd/blocking.c | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'source3/smbd/blocking.c') diff --git a/source3/smbd/blocking.c b/source3/smbd/blocking.c index 024e5b9f66..bc8c54caf7 100644 --- a/source3/smbd/blocking.c +++ b/source3/smbd/blocking.c @@ -175,6 +175,12 @@ static void generic_blocking_lock_error(blocking_lock_record *blr, NTSTATUS stat char *inbuf = blr->inbuf; construct_reply_common(inbuf, outbuf); + /* 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; + } + ERROR_NT(status); if (!send_smb(smbd_server_fd(),outbuf)) exit_server("generic_blocking_lock_error: send_smb failed."); -- cgit From 5e3b923124e82b1d19875746676df13cfdb0f918 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 13 Mar 2002 20:28:19 +0000 Subject: include/smb_macros.h: Don't round up an allocation if the size is zero. "One of these locks is not like the others... One of these locks is not quite the same" :-). When is a zero timeout lock not zero ? When it's being processed by Windows 2000 of course.. This code change, ugly though it is - completely fixes the foxpro/access multi-user file system database problems that people have been having. I used a *wonderful* test program donated by "Gerald Drouillard" which allowed me to completely reproduce this problem, and to finally determine the correct fix. This also explains why Windows 2000 is *so slow* when responding to the smbtorture lock tests. I *love* it when all these things come together and finally make sense :-). Jeremy. (This used to be commit 8aa9860ea2ea7f5aed4b6aa12794fffdfa81b0d0) --- source3/smbd/blocking.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'source3/smbd/blocking.c') diff --git a/source3/smbd/blocking.c b/source3/smbd/blocking.c index bc8c54caf7..d4a53d9a6d 100644 --- a/source3/smbd/blocking.c +++ b/source3/smbd/blocking.c @@ -279,7 +279,7 @@ static BOOL process_lockread(blocking_lock_record *blr) numtoread = MIN(BUFFER_SIZE-outsize,numtoread); data = smb_buf(outbuf) + 3; - status = do_lock( fsp, conn, SVAL(inbuf,smb_pid), (SMB_BIG_UINT)numtoread, + status = do_lock_spin( fsp, conn, SVAL(inbuf,smb_pid), (SMB_BIG_UINT)numtoread, (SMB_BIG_UINT)startpos, READ_LOCK); if (NT_STATUS_V(status)) { if ((errno != EACCES) && (errno != EAGAIN)) { @@ -345,7 +345,7 @@ static BOOL process_lock(blocking_lock_record *blr) offset = IVAL(inbuf,smb_vwv3); errno = 0; - status = do_lock(fsp, conn, SVAL(inbuf,smb_pid), (SMB_BIG_UINT)count, + status = do_lock_spin(fsp, conn, SVAL(inbuf,smb_pid), (SMB_BIG_UINT)count, (SMB_BIG_UINT)offset, WRITE_LOCK); if (NT_STATUS_IS_ERR(status)) { if((errno != EACCES) && (errno != EAGAIN)) { @@ -417,7 +417,7 @@ static BOOL process_lockingX(blocking_lock_record *blr) * request would never have been queued. JRA. */ errno = 0; - status = do_lock(fsp,conn,lock_pid,count,offset, + status = do_lock_spin(fsp,conn,lock_pid,count,offset, ((locktype & 1) ? READ_LOCK : WRITE_LOCK)); if (NT_STATUS_IS_ERR(status)) break; } -- cgit From 127e77e6e334fdc33086bffcbe00d340c0ba0097 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Sat, 17 Aug 2002 15:27:10 +0000 Subject: Sync 3.0 branch with head (This used to be commit 42615b945e2e48e53a21ea47f2e45407913a6a1e) --- source3/smbd/blocking.c | 23 +++++++++++++---------- 1 file changed, 13 insertions(+), 10 deletions(-) (limited to 'source3/smbd/blocking.c') diff --git a/source3/smbd/blocking.c b/source3/smbd/blocking.c index d4a53d9a6d..6623c6df64 100644 --- a/source3/smbd/blocking.c +++ b/source3/smbd/blocking.c @@ -282,9 +282,10 @@ static BOOL process_lockread(blocking_lock_record *blr) status = do_lock_spin( fsp, conn, SVAL(inbuf,smb_pid), (SMB_BIG_UINT)numtoread, (SMB_BIG_UINT)startpos, READ_LOCK); if (NT_STATUS_V(status)) { - if ((errno != EACCES) && (errno != EAGAIN)) { + 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" POSIX + * We have other than a "can't get lock" * error. Send an error. * Return True so we get dequeued. */ @@ -348,9 +349,10 @@ static BOOL process_lock(blocking_lock_record *blr) status = do_lock_spin(fsp, conn, SVAL(inbuf,smb_pid), (SMB_BIG_UINT)count, (SMB_BIG_UINT)offset, WRITE_LOCK); if (NT_STATUS_IS_ERR(status)) { - if((errno != EACCES) && (errno != EAGAIN)) { + 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" POSIX + * We have other than a "can't get lock" * error. Send an error. * Return True so we get dequeued. */ @@ -432,12 +434,13 @@ static BOOL process_lockingX(blocking_lock_record *blr) reply_lockingX_success(blr); return True; - } else if ((errno != EACCES) && (errno != EAGAIN)) { - /* - * We have other than a "can't get lock" POSIX - * error. Free any locks we had and return an error. - * Return True so we get dequeued. - */ + } else 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. + */ blocking_lock_reply_error(blr, status); return True; -- cgit From a834a73e341059be154426390304a42e4a011f72 Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Wed, 25 Sep 2002 15:19:00 +0000 Subject: sync'ing up for 3.0alpha20 release (This used to be commit 65e7b5273bb58802bf0c389b77f7fcae0a1f6139) --- source3/smbd/blocking.c | 34 +++++++++++++++++++++++++++------- 1 file changed, 27 insertions(+), 7 deletions(-) (limited to 'source3/smbd/blocking.c') diff --git a/source3/smbd/blocking.c b/source3/smbd/blocking.c index 6623c6df64..9d411711cb 100644 --- a/source3/smbd/blocking.c +++ b/source3/smbd/blocking.c @@ -531,13 +531,33 @@ file %s fnum = %d\n", blr->com_type, fsp->fsp_name, fsp->fnum )); } /**************************************************************************** - Return True if the blocking lock queue has entries. + Return the number of seconds to the next blocking locks timeout, or default_timeout *****************************************************************************/ - -BOOL blocking_locks_pending(void) +unsigned blocking_locks_timeout(unsigned default_timeout) { - blocking_lock_record *blr = (blocking_lock_record *)ubi_slFirst( &blocking_lock_queue ); - return (blr == NULL ? False : True); + unsigned timeout = default_timeout; + time_t t; + blocking_lock_record *blr = (blocking_lock_record *)ubi_slFirst(&blocking_lock_queue); + + /* note that we avoid the time() syscall if there are no blocking locks */ + if (!blr) { + return timeout; + } + + t = time(NULL); + + while (blr) { + if (timeout > (blr->expire_time - t)) { + timeout = blr->expire_time - t; + } + blr = (blocking_lock_record *)ubi_slNext(blr); + } + + if (timeout < 1) { + timeout = 1; + } + + return timeout; } /**************************************************************************** @@ -576,7 +596,7 @@ void process_blocking_lock_queue(time_t t) DEBUG(5,("process_blocking_lock_queue: examining pending lock fnum = %d for file %s\n", fsp->fnum, fsp->fsp_name )); - if((blr->expire_time != -1) && (blr->expire_time > t)) { + if((blr->expire_time != -1) && (blr->expire_time <= t)) { /* * Lock expired - throw away all previously * obtained locks and return lock error. @@ -584,7 +604,7 @@ void process_blocking_lock_queue(time_t t) DEBUG(5,("process_blocking_lock_queue: pending lock fnum = %d for file %s timed out.\n", fsp->fnum, fsp->fsp_name )); - blocking_lock_reply_error(blr,NT_STATUS_ACCESS_DENIED); + blocking_lock_reply_error(blr,NT_STATUS_FILE_LOCK_CONFLICT); free_blocking_lock_record((blocking_lock_record *)ubi_slRemNext( &blocking_lock_queue, prev)); blr = (blocking_lock_record *)(prev ? ubi_slNext(prev) : ubi_slFirst(&blocking_lock_queue)); continue; -- cgit From 6a019636b980857cf896f250841de757644ba9dd Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 3 Dec 2002 08:02:41 +0000 Subject: Fixed nasty bug where file writes with start offsets in the range 0x80000000 -> 0xFFFFFFFF would fail as they were being cast from IVAL (uint32) to SMB_OFF_T (off_t or off64_t, both *signed* types). The sign extension would cause the offset to be treated as negative. Thanks to Herb for helping me track this one down (IRIX is good for large file tests :-). Jeremy. PS. That horrid EXEXIST thing has broken configure..... (This used to be commit 2d14c442bc601a277458b69f05a763aa2a1ab3b7) --- source3/smbd/blocking.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) (limited to 'source3/smbd/blocking.c') diff --git a/source3/smbd/blocking.c b/source3/smbd/blocking.c index 9d411711cb..14239272c2 100644 --- a/source3/smbd/blocking.c +++ b/source3/smbd/blocking.c @@ -267,20 +267,20 @@ static BOOL process_lockread(blocking_lock_record *blr) ssize_t nread = -1; char *data, *p; int outsize = 0; - SMB_OFF_T startpos; + SMB_BIG_UINT startpos; size_t numtoread; NTSTATUS status; connection_struct *conn = conn_find(SVAL(inbuf,smb_tid)); files_struct *fsp = blr->fsp; numtoread = SVAL(inbuf,smb_vwv1); - startpos = IVAL(inbuf,smb_vwv2); + startpos = (SMB_BIG_UINT)IVAL(inbuf,smb_vwv2); numtoread = MIN(BUFFER_SIZE-outsize,numtoread); data = smb_buf(outbuf) + 3; status = do_lock_spin( fsp, conn, SVAL(inbuf,smb_pid), (SMB_BIG_UINT)numtoread, - (SMB_BIG_UINT)startpos, READ_LOCK); + startpos, READ_LOCK); if (NT_STATUS_V(status)) { if (!NT_STATUS_EQUAL(status,NT_STATUS_LOCK_NOT_GRANTED) && !NT_STATUS_EQUAL(status,NT_STATUS_FILE_LOCK_CONFLICT)) { @@ -337,17 +337,17 @@ static BOOL process_lock(blocking_lock_record *blr) char *outbuf = OutBuffer; char *inbuf = blr->inbuf; int outsize; - SMB_OFF_T count = 0, offset = 0; + SMB_BIG_UINT count = (SMB_BIG_UINT)0, offset = (SMB_BIG_UINT)0; NTSTATUS status; connection_struct *conn = conn_find(SVAL(inbuf,smb_tid)); files_struct *fsp = blr->fsp; - count = IVAL(inbuf,smb_vwv1); - offset = IVAL(inbuf,smb_vwv3); + count = IVAL_TO_SMB_OFF_T(inbuf,smb_vwv1); + offset = IVAL_TO_SMB_OFF_T(inbuf,smb_vwv3); errno = 0; - status = do_lock_spin(fsp, conn, SVAL(inbuf,smb_pid), (SMB_BIG_UINT)count, - (SMB_BIG_UINT)offset, WRITE_LOCK); + status = do_lock_spin(fsp, conn, SVAL(inbuf,smb_pid), count, + offset, WRITE_LOCK); if (NT_STATUS_IS_ERR(status)) { if (!NT_STATUS_EQUAL(status,NT_STATUS_LOCK_NOT_GRANTED) && !NT_STATUS_EQUAL(status,NT_STATUS_FILE_LOCK_CONFLICT)) { -- cgit From fb3e4b87973e9ad0c818e8d9dd60329c47f22afe Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 27 Feb 2003 01:04:34 +0000 Subject: Fix to allow blocking lock notification to be done rapidly (no wait for smb -> smb lock release). Adds new PENDING_LOCK type to lockdb (does not interfere with existing locks). Jeremy. (This used to be commit 766928bbba1e597c9c2b12458dd8d37e6080593e) --- source3/smbd/blocking.c | 78 ++++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 71 insertions(+), 7 deletions(-) (limited to 'source3/smbd/blocking.c') diff --git a/source3/smbd/blocking.c b/source3/smbd/blocking.c index 14239272c2..581ce43f91 100644 --- a/source3/smbd/blocking.c +++ b/source3/smbd/blocking.c @@ -1,7 +1,7 @@ /* Unix SMB/CIFS implementation. Blocking Locking functions - Copyright (C) Jeremy Allison 1998 + Copyright (C) Jeremy Allison 1998-2003 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 @@ -33,6 +33,9 @@ typedef struct { files_struct *fsp; time_t expire_time; int lock_num; + SMB_BIG_UINT offset; + SMB_BIG_UINT count; + uint16 lock_pid; char *inbuf; int length; } blocking_lock_record; @@ -77,13 +80,18 @@ static BOOL in_chained_smb(void) return (chain_size != 0); } +static void received_unlock_msg(int msg_type, pid_t src, void *buf, size_t len); + /**************************************************************************** Function to push a blocking lock request onto the lock queue. ****************************************************************************/ -BOOL push_blocking_lock_request( char *inbuf, int length, int lock_timeout, int lock_num) +BOOL push_blocking_lock_request( char *inbuf, int length, int lock_timeout, + int lock_num, uint16 lock_pid, SMB_BIG_UINT offset, SMB_BIG_UINT count) { + static BOOL set_lock_msg; blocking_lock_record *blr; + NTSTATUS status; if(in_chained_smb() ) { DEBUG(0,("push_blocking_lock_request: cannot queue a chained request (currently).\n")); @@ -110,11 +118,31 @@ BOOL push_blocking_lock_request( char *inbuf, int length, int lock_timeout, int blr->fsp = get_fsp_from_pkt(inbuf); blr->expire_time = (lock_timeout == -1) ? (time_t)-1 : time(NULL) + (time_t)lock_timeout; blr->lock_num = lock_num; + blr->lock_pid = lock_pid; + blr->offset = offset; + blr->count = count; memcpy(blr->inbuf, inbuf, length); blr->length = length; + /* Add a pending lock record for this. */ + status = brl_lock(blr->fsp->dev, blr->fsp->inode, blr->fsp->fnum, + lock_pid, sys_getpid(), blr->fsp->conn->cnum, + offset, count, + PENDING_LOCK); + + if (!NT_STATUS_IS_OK(status)) { + DEBUG(0,("push_blocking_lock_request: failed to add PENDING_LOCK record.\n")); + free_blocking_lock_record(blr); + return False; + } + ubi_slAddTail(&blocking_lock_queue, blr); + /* Ensure we'll receive messages when this is unlocked. */ + if (!set_lock_msg) { + message_register(MSG_SMB_UNLOCK, received_unlock_msg); + set_lock_msg = True; + } DEBUG(3,("push_blocking_lock_request: lock request length=%d blocked with expiry time %d (+%d) \ for fnum = %d, name = %s\n", length, (int)blr->expire_time, lock_timeout, @@ -493,6 +521,10 @@ void remove_pending_lock_requests_by_fid(files_struct *fsp) 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 )); + brl_unlock(blr->fsp->dev, blr->fsp->inode, blr->fsp->fnum, + blr->lock_pid, sys_getpid(), blr->fsp->conn->cnum, + blr->offset, blr->count, True); + free_blocking_lock_record((blocking_lock_record *)ubi_slRemNext( &blocking_lock_queue, prev)); blr = (blocking_lock_record *)(prev ? ubi_slNext(prev) : ubi_slFirst(&blocking_lock_queue)); continue; @@ -520,6 +552,9 @@ void remove_pending_lock_requests_by_mid(int mid) file %s fnum = %d\n", blr->com_type, fsp->fsp_name, fsp->fnum )); blocking_lock_reply_error(blr,NT_STATUS_CANCELLED); + brl_unlock(blr->fsp->dev, blr->fsp->inode, blr->fsp->fnum, + blr->lock_pid, sys_getpid(), blr->fsp->conn->cnum, + blr->offset, blr->count, True); free_blocking_lock_record((blocking_lock_record *)ubi_slRemNext( &blocking_lock_queue, prev)); blr = (blocking_lock_record *)(prev ? ubi_slNext(prev) : ubi_slFirst(&blocking_lock_queue)); continue; @@ -530,9 +565,20 @@ file %s fnum = %d\n", blr->com_type, fsp->fsp_name, fsp->fnum )); } } +/**************************************************************************** + Set a flag as an unlock request affects one of our pending locks. +*****************************************************************************/ + +static void received_unlock_msg(int msg_type, pid_t src, void *buf, size_t len) +{ + DEBUG(10,("received_unlock_msg\n")); + process_blocking_lock_queue(time(NULL)); +} + /**************************************************************************** Return the number of seconds to the next blocking locks timeout, or default_timeout *****************************************************************************/ + unsigned blocking_locks_timeout(unsigned default_timeout) { unsigned timeout = default_timeout; @@ -540,22 +586,21 @@ unsigned blocking_locks_timeout(unsigned default_timeout) blocking_lock_record *blr = (blocking_lock_record *)ubi_slFirst(&blocking_lock_queue); /* note that we avoid the time() syscall if there are no blocking locks */ - if (!blr) { + if (!blr) return timeout; - } t = time(NULL); while (blr) { - if (timeout > (blr->expire_time - t)) { + if ((blr->expire_time != (time_t)-1) && + (timeout > (blr->expire_time - t))) { timeout = blr->expire_time - t; } blr = (blocking_lock_record *)ubi_slNext(blr); } - if (timeout < 1) { + if (timeout < 1) timeout = 1; - } return timeout; } @@ -604,6 +649,10 @@ void process_blocking_lock_queue(time_t t) DEBUG(5,("process_blocking_lock_queue: pending lock fnum = %d for file %s timed out.\n", fsp->fnum, fsp->fsp_name )); + brl_unlock(fsp->dev, fsp->inode, fsp->fnum, + blr->lock_pid, sys_getpid(), conn->cnum, + blr->offset, blr->count, True); + blocking_lock_reply_error(blr,NT_STATUS_FILE_LOCK_CONFLICT); free_blocking_lock_record((blocking_lock_record *)ubi_slRemNext( &blocking_lock_queue, prev)); blr = (blocking_lock_record *)(prev ? ubi_slNext(prev) : ubi_slFirst(&blocking_lock_queue)); @@ -617,6 +666,11 @@ void process_blocking_lock_queue(time_t t) * Remove the entry and return an error to the client. */ blocking_lock_reply_error(blr,NT_STATUS_ACCESS_DENIED); + + brl_unlock(fsp->dev, fsp->inode, fsp->fnum, + blr->lock_pid, sys_getpid(), conn->cnum, + blr->offset, blr->count, True); + free_blocking_lock_record((blocking_lock_record *)ubi_slRemNext( &blocking_lock_queue, prev)); blr = (blocking_lock_record *)(prev ? ubi_slNext(prev) : ubi_slFirst(&blocking_lock_queue)); continue; @@ -628,6 +682,11 @@ void process_blocking_lock_queue(time_t t) * Remove the entry and return an error to the client. */ blocking_lock_reply_error(blr,NT_STATUS_ACCESS_DENIED); + + brl_unlock(fsp->dev, fsp->inode, fsp->fnum, + blr->lock_pid, sys_getpid(), conn->cnum, + blr->offset, blr->count, True); + free_blocking_lock_record((blocking_lock_record *)ubi_slRemNext( &blocking_lock_queue, prev)); blr = (blocking_lock_record *)(prev ? ubi_slNext(prev) : ubi_slFirst(&blocking_lock_queue)); change_to_root_user(); @@ -641,6 +700,11 @@ void process_blocking_lock_queue(time_t t) */ if(blocking_lock_record_process(blr)) { + + brl_unlock(fsp->dev, fsp->inode, fsp->fnum, + blr->lock_pid, sys_getpid(), conn->cnum, + blr->offset, blr->count, True); + free_blocking_lock_record((blocking_lock_record *)ubi_slRemNext( &blocking_lock_queue, prev)); blr = (blocking_lock_record *)(prev ? ubi_slNext(prev) : ubi_slFirst(&blocking_lock_queue)); change_to_root_user(); -- cgit From 34226f1bd4d90ffe0f324277b11bbc4f2b575740 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Fri, 4 Apr 2003 20:38:12 +0000 Subject: Fix for very subtle POSIX lock interaction race condition found by Herb. We need to unlock POSIX locks before notifying pending lock processes. Jeremy. (This used to be commit 6999eef51c3e597b3b2cd9cc26138acdfbb6a23a) --- source3/smbd/blocking.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'source3/smbd/blocking.c') diff --git a/source3/smbd/blocking.c b/source3/smbd/blocking.c index 581ce43f91..2802fbb151 100644 --- a/source3/smbd/blocking.c +++ b/source3/smbd/blocking.c @@ -523,7 +523,7 @@ file %s fnum = %d\n", blr->com_type, fsp->fsp_name, fsp->fnum )); brl_unlock(blr->fsp->dev, blr->fsp->inode, blr->fsp->fnum, blr->lock_pid, sys_getpid(), blr->fsp->conn->cnum, - blr->offset, blr->count, True); + blr->offset, blr->count, True, NULL, NULL); free_blocking_lock_record((blocking_lock_record *)ubi_slRemNext( &blocking_lock_queue, prev)); blr = (blocking_lock_record *)(prev ? ubi_slNext(prev) : ubi_slFirst(&blocking_lock_queue)); @@ -554,7 +554,7 @@ file %s fnum = %d\n", blr->com_type, fsp->fsp_name, fsp->fnum )); blocking_lock_reply_error(blr,NT_STATUS_CANCELLED); brl_unlock(blr->fsp->dev, blr->fsp->inode, blr->fsp->fnum, blr->lock_pid, sys_getpid(), blr->fsp->conn->cnum, - blr->offset, blr->count, True); + blr->offset, blr->count, True, NULL, NULL); free_blocking_lock_record((blocking_lock_record *)ubi_slRemNext( &blocking_lock_queue, prev)); blr = (blocking_lock_record *)(prev ? ubi_slNext(prev) : ubi_slFirst(&blocking_lock_queue)); continue; @@ -651,7 +651,7 @@ void process_blocking_lock_queue(time_t t) brl_unlock(fsp->dev, fsp->inode, fsp->fnum, blr->lock_pid, sys_getpid(), conn->cnum, - blr->offset, blr->count, True); + blr->offset, blr->count, True, NULL, NULL); blocking_lock_reply_error(blr,NT_STATUS_FILE_LOCK_CONFLICT); free_blocking_lock_record((blocking_lock_record *)ubi_slRemNext( &blocking_lock_queue, prev)); @@ -669,7 +669,7 @@ void process_blocking_lock_queue(time_t t) brl_unlock(fsp->dev, fsp->inode, fsp->fnum, blr->lock_pid, sys_getpid(), conn->cnum, - blr->offset, blr->count, True); + blr->offset, blr->count, True, NULL, NULL); free_blocking_lock_record((blocking_lock_record *)ubi_slRemNext( &blocking_lock_queue, prev)); blr = (blocking_lock_record *)(prev ? ubi_slNext(prev) : ubi_slFirst(&blocking_lock_queue)); @@ -685,7 +685,7 @@ void process_blocking_lock_queue(time_t t) brl_unlock(fsp->dev, fsp->inode, fsp->fnum, blr->lock_pid, sys_getpid(), conn->cnum, - blr->offset, blr->count, True); + blr->offset, blr->count, True, NULL, NULL); free_blocking_lock_record((blocking_lock_record *)ubi_slRemNext( &blocking_lock_queue, prev)); blr = (blocking_lock_record *)(prev ? ubi_slNext(prev) : ubi_slFirst(&blocking_lock_queue)); @@ -703,7 +703,7 @@ void process_blocking_lock_queue(time_t t) brl_unlock(fsp->dev, fsp->inode, fsp->fnum, blr->lock_pid, sys_getpid(), conn->cnum, - blr->offset, blr->count, True); + blr->offset, blr->count, True, NULL, NULL); free_blocking_lock_record((blocking_lock_record *)ubi_slRemNext( &blocking_lock_queue, prev)); blr = (blocking_lock_record *)(prev ? ubi_slNext(prev) : ubi_slFirst(&blocking_lock_queue)); -- cgit From 0c9433c03188a2d1b49318dd8535d10b7805ce42 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 24 Jul 2003 06:56:56 +0000 Subject: Ensure everywhere we defer an incoming SMB request (blocking lock queue, in oplock break state, change notify queue) we also push the MID onto the deferred signing queue. Tomorrow I will test this with valgrind and oplock tests. Jeremy. (This used to be commit 33a377f3726c85379ba5b962dd7c8ead337b892f) --- source3/smbd/blocking.c | 498 ++++++++++++++++++++++++------------------------ 1 file changed, 250 insertions(+), 248 deletions(-) (limited to 'source3/smbd/blocking.c') diff --git a/source3/smbd/blocking.c b/source3/smbd/blocking.c index 2802fbb151..fed3a51b88 100644 --- a/source3/smbd/blocking.c +++ b/source3/smbd/blocking.c @@ -28,16 +28,16 @@ extern char *OutBuffer; *****************************************************************************/ typedef struct { - ubi_slNode msg_next; - int com_type; - files_struct *fsp; - time_t expire_time; - int lock_num; - SMB_BIG_UINT offset; - SMB_BIG_UINT count; - uint16 lock_pid; - char *inbuf; - int length; + ubi_slNode msg_next; + int com_type; + files_struct *fsp; + time_t expire_time; + int lock_num; + SMB_BIG_UINT offset; + SMB_BIG_UINT count; + uint16 lock_pid; + char *inbuf; + int length; } blocking_lock_record; static ubi_slList blocking_lock_queue = { NULL, (ubi_slNodePtr)&blocking_lock_queue, 0}; @@ -48,8 +48,8 @@ static ubi_slList blocking_lock_queue = { NULL, (ubi_slNodePtr)&blocking_lock_qu static void free_blocking_lock_record(blocking_lock_record *blr) { - SAFE_FREE(blr->inbuf); - SAFE_FREE(blr); + SAFE_FREE(blr->inbuf); + SAFE_FREE(blr); } /**************************************************************************** @@ -58,17 +58,17 @@ static void free_blocking_lock_record(blocking_lock_record *blr) static files_struct *get_fsp_from_pkt(char *inbuf) { - switch(CVAL(inbuf,smb_com)) { - case SMBlock: - case SMBlockread: - return file_fsp(inbuf,smb_vwv0); - case SMBlockingX: - return file_fsp(inbuf,smb_vwv2); - default: - DEBUG(0,("get_fsp_from_pkt: PANIC - unknown type on blocking lock queue - exiting.!\n")); - exit_server("PANIC - unknown type on blocking lock queue"); - } - return NULL; /* Keep compiler happy. */ + switch(CVAL(inbuf,smb_com)) { + case SMBlock: + case SMBlockread: + return file_fsp(inbuf,smb_vwv0); + case SMBlockingX: + return file_fsp(inbuf,smb_vwv2); + default: + DEBUG(0,("get_fsp_from_pkt: PANIC - unknown type on blocking lock queue - exiting.!\n")); + exit_server("PANIC - unknown type on blocking lock queue"); + } + return NULL; /* Keep compiler happy. */ } /**************************************************************************** @@ -77,7 +77,7 @@ static files_struct *get_fsp_from_pkt(char *inbuf) static BOOL in_chained_smb(void) { - return (chain_size != 0); + return (chain_size != 0); } static void received_unlock_msg(int msg_type, pid_t src, void *buf, size_t len); @@ -89,66 +89,68 @@ static void received_unlock_msg(int msg_type, pid_t src, void *buf, size_t len); BOOL push_blocking_lock_request( char *inbuf, int length, int lock_timeout, int lock_num, uint16 lock_pid, SMB_BIG_UINT offset, SMB_BIG_UINT count) { - static BOOL set_lock_msg; - blocking_lock_record *blr; - 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. - */ - - if((blr = (blocking_lock_record *)malloc(sizeof(blocking_lock_record))) == NULL) { - DEBUG(0,("push_blocking_lock_request: Malloc fail !\n" )); - return False; - } - - if((blr->inbuf = (char *)malloc(length)) == NULL) { - DEBUG(0,("push_blocking_lock_request: Malloc fail (2)!\n" )); - SAFE_FREE(blr); - return False; - } - - blr->com_type = CVAL(inbuf,smb_com); - blr->fsp = get_fsp_from_pkt(inbuf); - blr->expire_time = (lock_timeout == -1) ? (time_t)-1 : time(NULL) + (time_t)lock_timeout; - blr->lock_num = lock_num; - blr->lock_pid = lock_pid; - blr->offset = offset; - blr->count = count; - memcpy(blr->inbuf, inbuf, length); - blr->length = length; - - /* Add a pending lock record for this. */ - status = brl_lock(blr->fsp->dev, blr->fsp->inode, blr->fsp->fnum, - lock_pid, sys_getpid(), blr->fsp->conn->cnum, - offset, count, - PENDING_LOCK); - - if (!NT_STATUS_IS_OK(status)) { - DEBUG(0,("push_blocking_lock_request: failed to add PENDING_LOCK record.\n")); - free_blocking_lock_record(blr); - return False; - } + static BOOL set_lock_msg; + blocking_lock_record *blr; + 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. + */ - ubi_slAddTail(&blocking_lock_queue, blr); + if((blr = (blocking_lock_record *)malloc(sizeof(blocking_lock_record))) == NULL) { + DEBUG(0,("push_blocking_lock_request: Malloc fail !\n" )); + return False; + } + + if((blr->inbuf = (char *)malloc(length)) == NULL) { + DEBUG(0,("push_blocking_lock_request: Malloc fail (2)!\n" )); + SAFE_FREE(blr); + return False; + } - /* Ensure we'll receive messages when this is unlocked. */ - if (!set_lock_msg) { - message_register(MSG_SMB_UNLOCK, received_unlock_msg); - set_lock_msg = True; - } + blr->com_type = CVAL(inbuf,smb_com); + blr->fsp = get_fsp_from_pkt(inbuf); + blr->expire_time = (lock_timeout == -1) ? (time_t)-1 : time(NULL) + (time_t)lock_timeout; + blr->lock_num = lock_num; + blr->lock_pid = lock_pid; + blr->offset = offset; + blr->count = count; + memcpy(blr->inbuf, inbuf, length); + blr->length = length; + + /* Add a pending lock record for this. */ + status = brl_lock(blr->fsp->dev, blr->fsp->inode, blr->fsp->fnum, + lock_pid, sys_getpid(), blr->fsp->conn->cnum, + offset, count, PENDING_LOCK); + + if (!NT_STATUS_IS_OK(status)) { + DEBUG(0,("push_blocking_lock_request: failed to add PENDING_LOCK record.\n")); + free_blocking_lock_record(blr); + return False; + } + + ubi_slAddTail(&blocking_lock_queue, blr); + + /* Ensure we'll receive messages when this is unlocked. */ + if (!set_lock_msg) { + message_register(MSG_SMB_UNLOCK, received_unlock_msg); + set_lock_msg = True; + } - DEBUG(3,("push_blocking_lock_request: lock request length=%d blocked with expiry time %d (+%d) \ + DEBUG(3,("push_blocking_lock_request: lock request length=%d blocked with expiry time %d (+%d) \ for fnum = %d, name = %s\n", length, (int)blr->expire_time, lock_timeout, - blr->fsp->fnum, blr->fsp->fsp_name )); + blr->fsp->fnum, blr->fsp->fsp_name )); - return True; + /* Push the MID of this packet on the signing queue. */ + srv_defer_sign_response(SVAL(inbuf,smb_mid)); + + return True; } /**************************************************************************** @@ -170,27 +172,27 @@ static void send_blocking_reply(char *outbuf, int outsize) static void reply_lockingX_success(blocking_lock_record *blr) { - char *outbuf = OutBuffer; - int bufsize = BUFFER_SIZE; - char *inbuf = blr->inbuf; - int outsize = 0; + char *outbuf = OutBuffer; + int bufsize = BUFFER_SIZE; + char *inbuf = blr->inbuf; + int outsize = 0; - construct_reply_common(inbuf, outbuf); - set_message(outbuf,2,0,True); + construct_reply_common(inbuf, outbuf); + set_message(outbuf,2,0,True); - /* - * 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. - */ + /* + * 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. + */ - outsize = chain_reply(inbuf,outbuf,blr->length,bufsize); + outsize = chain_reply(inbuf,outbuf,blr->length,bufsize); - outsize += chain_size; + outsize += chain_size; - send_blocking_reply(outbuf,outsize); + send_blocking_reply(outbuf,outsize); } /**************************************************************************** @@ -492,18 +494,18 @@ Waiting....\n", static BOOL blocking_lock_record_process(blocking_lock_record *blr) { - switch(blr->com_type) { - case SMBlock: - return process_lock(blr); - case SMBlockread: - return process_lockread(blr); - case SMBlockingX: - return process_lockingX(blr); - 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. */ + switch(blr->com_type) { + case SMBlock: + return process_lock(blr); + case SMBlockread: + return process_lockread(blr); + case SMBlockingX: + return process_lockingX(blr); + 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. */ } /**************************************************************************** @@ -512,27 +514,27 @@ static BOOL blocking_lock_record_process(blocking_lock_record *blr) void remove_pending_lock_requests_by_fid(files_struct *fsp) { - blocking_lock_record *blr = (blocking_lock_record *)ubi_slFirst( &blocking_lock_queue ); - blocking_lock_record *prev = NULL; + blocking_lock_record *blr = (blocking_lock_record *)ubi_slFirst( &blocking_lock_queue ); + blocking_lock_record *prev = NULL; - while(blr != NULL) { - if(blr->fsp->fnum == fsp->fnum) { + while(blr != NULL) { + if(blr->fsp->fnum == fsp->fnum) { - DEBUG(10,("remove_pending_lock_requests_by_fid - removing request type %d for \ + 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 )); - brl_unlock(blr->fsp->dev, blr->fsp->inode, blr->fsp->fnum, - blr->lock_pid, sys_getpid(), blr->fsp->conn->cnum, - blr->offset, blr->count, True, NULL, NULL); + brl_unlock(blr->fsp->dev, blr->fsp->inode, blr->fsp->fnum, + blr->lock_pid, sys_getpid(), blr->fsp->conn->cnum, + blr->offset, blr->count, True, NULL, NULL); - free_blocking_lock_record((blocking_lock_record *)ubi_slRemNext( &blocking_lock_queue, prev)); - blr = (blocking_lock_record *)(prev ? ubi_slNext(prev) : ubi_slFirst(&blocking_lock_queue)); - continue; - } + free_blocking_lock_record((blocking_lock_record *)ubi_slRemNext( &blocking_lock_queue, prev)); + blr = (blocking_lock_record *)(prev ? ubi_slNext(prev) : ubi_slFirst(&blocking_lock_queue)); + continue; + } - prev = blr; - blr = (blocking_lock_record *)ubi_slNext(blr); - } + prev = blr; + blr = (blocking_lock_record *)ubi_slNext(blr); + } } /**************************************************************************** @@ -541,28 +543,28 @@ file %s fnum = %d\n", blr->com_type, fsp->fsp_name, fsp->fnum )); void remove_pending_lock_requests_by_mid(int mid) { - blocking_lock_record *blr = (blocking_lock_record *)ubi_slFirst( &blocking_lock_queue ); - blocking_lock_record *prev = NULL; + blocking_lock_record *blr = (blocking_lock_record *)ubi_slFirst( &blocking_lock_queue ); + blocking_lock_record *prev = NULL; - while(blr != NULL) { - if(SVAL(blr->inbuf,smb_mid) == mid) { - files_struct *fsp = blr->fsp; + while(blr != NULL) { + if(SVAL(blr->inbuf,smb_mid) == mid) { + files_struct *fsp = blr->fsp; - DEBUG(10,("remove_pending_lock_requests_by_mid - removing request type %d for \ + 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 )); - blocking_lock_reply_error(blr,NT_STATUS_CANCELLED); - brl_unlock(blr->fsp->dev, blr->fsp->inode, blr->fsp->fnum, - blr->lock_pid, sys_getpid(), blr->fsp->conn->cnum, - blr->offset, blr->count, True, NULL, NULL); - free_blocking_lock_record((blocking_lock_record *)ubi_slRemNext( &blocking_lock_queue, prev)); - blr = (blocking_lock_record *)(prev ? ubi_slNext(prev) : ubi_slFirst(&blocking_lock_queue)); - continue; - } - - prev = blr; - blr = (blocking_lock_record *)ubi_slNext(blr); - } + blocking_lock_reply_error(blr,NT_STATUS_CANCELLED); + brl_unlock(blr->fsp->dev, blr->fsp->inode, blr->fsp->fnum, + blr->lock_pid, sys_getpid(), blr->fsp->conn->cnum, + blr->offset, blr->count, True, NULL, NULL); + free_blocking_lock_record((blocking_lock_record *)ubi_slRemNext( &blocking_lock_queue, prev)); + blr = (blocking_lock_record *)(prev ? ubi_slNext(prev) : ubi_slFirst(&blocking_lock_queue)); + continue; + } + + prev = blr; + blr = (blocking_lock_record *)ubi_slNext(blr); + } } /**************************************************************************** @@ -611,112 +613,112 @@ unsigned blocking_locks_timeout(unsigned default_timeout) void process_blocking_lock_queue(time_t t) { - blocking_lock_record *blr = (blocking_lock_record *)ubi_slFirst( &blocking_lock_queue ); - blocking_lock_record *prev = NULL; - - if(blr == NULL) - return; - - /* - * Go through the queue and see if we can get any of the locks. - */ - - while(blr != NULL) { - connection_struct *conn = NULL; - uint16 vuid; - files_struct *fsp = NULL; - - /* - * Ensure we don't have any old chain_fsp values - * sitting around.... - */ - chain_size = 0; - file_chain_reset(); - 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 )); - - if((blr->expire_time != -1) && (blr->expire_time <= t)) { - /* - * Lock expired - throw away all previously - * obtained locks and return lock error. - */ - DEBUG(5,("process_blocking_lock_queue: pending lock fnum = %d for file %s timed out.\n", - fsp->fnum, fsp->fsp_name )); - - brl_unlock(fsp->dev, fsp->inode, fsp->fnum, - blr->lock_pid, sys_getpid(), conn->cnum, - blr->offset, blr->count, True, NULL, NULL); - - blocking_lock_reply_error(blr,NT_STATUS_FILE_LOCK_CONFLICT); - free_blocking_lock_record((blocking_lock_record *)ubi_slRemNext( &blocking_lock_queue, prev)); - blr = (blocking_lock_record *)(prev ? ubi_slNext(prev) : ubi_slFirst(&blocking_lock_queue)); - continue; - } - - if(!change_to_user(conn,vuid)) { - DEBUG(0,("process_blocking_lock_queue: Unable to become user vuid=%d.\n", - vuid )); - /* - * Remove the entry and return an error to the client. - */ - blocking_lock_reply_error(blr,NT_STATUS_ACCESS_DENIED); - - brl_unlock(fsp->dev, fsp->inode, fsp->fnum, - blr->lock_pid, sys_getpid(), conn->cnum, - blr->offset, blr->count, True, NULL, NULL); - - free_blocking_lock_record((blocking_lock_record *)ubi_slRemNext( &blocking_lock_queue, prev)); - blr = (blocking_lock_record *)(prev ? ubi_slNext(prev) : ubi_slFirst(&blocking_lock_queue)); - continue; - } - - if(!set_current_service(conn,True)) { - DEBUG(0,("process_blocking_lock_queue: Unable to become service Error was %s.\n", strerror(errno) )); - /* - * Remove the entry and return an error to the client. - */ - blocking_lock_reply_error(blr,NT_STATUS_ACCESS_DENIED); - - brl_unlock(fsp->dev, fsp->inode, fsp->fnum, - blr->lock_pid, sys_getpid(), conn->cnum, - blr->offset, blr->count, True, NULL, NULL); - - free_blocking_lock_record((blocking_lock_record *)ubi_slRemNext( &blocking_lock_queue, prev)); - blr = (blocking_lock_record *)(prev ? ubi_slNext(prev) : ubi_slFirst(&blocking_lock_queue)); - change_to_root_user(); - continue; - } - - /* - * 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. - */ - - if(blocking_lock_record_process(blr)) { - - brl_unlock(fsp->dev, fsp->inode, fsp->fnum, - blr->lock_pid, sys_getpid(), conn->cnum, - blr->offset, blr->count, True, NULL, NULL); - - free_blocking_lock_record((blocking_lock_record *)ubi_slRemNext( &blocking_lock_queue, prev)); - blr = (blocking_lock_record *)(prev ? ubi_slNext(prev) : ubi_slFirst(&blocking_lock_queue)); - change_to_root_user(); - continue; - } - - change_to_root_user(); - - /* - * Move to the next in the list. - */ - prev = blr; - blr = (blocking_lock_record *)ubi_slNext(blr); - } + blocking_lock_record *blr = (blocking_lock_record *)ubi_slFirst( &blocking_lock_queue ); + blocking_lock_record *prev = NULL; + + if(blr == NULL) + return; + + /* + * Go through the queue and see if we can get any of the locks. + */ + + while(blr != NULL) { + connection_struct *conn = NULL; + uint16 vuid; + files_struct *fsp = NULL; + + /* + * Ensure we don't have any old chain_fsp values + * sitting around.... + */ + chain_size = 0; + file_chain_reset(); + 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 )); + + if((blr->expire_time != -1) && (blr->expire_time <= t)) { + /* + * Lock expired - throw away all previously + * obtained locks and return lock error. + */ + DEBUG(5,("process_blocking_lock_queue: pending lock fnum = %d for file %s timed out.\n", + fsp->fnum, fsp->fsp_name )); + + brl_unlock(fsp->dev, fsp->inode, fsp->fnum, + blr->lock_pid, sys_getpid(), conn->cnum, + blr->offset, blr->count, True, NULL, NULL); + + blocking_lock_reply_error(blr,NT_STATUS_FILE_LOCK_CONFLICT); + free_blocking_lock_record((blocking_lock_record *)ubi_slRemNext( &blocking_lock_queue, prev)); + blr = (blocking_lock_record *)(prev ? ubi_slNext(prev) : ubi_slFirst(&blocking_lock_queue)); + continue; + } + + if(!change_to_user(conn,vuid)) { + DEBUG(0,("process_blocking_lock_queue: Unable to become user vuid=%d.\n", + vuid )); + /* + * Remove the entry and return an error to the client. + */ + blocking_lock_reply_error(blr,NT_STATUS_ACCESS_DENIED); + + brl_unlock(fsp->dev, fsp->inode, fsp->fnum, + blr->lock_pid, sys_getpid(), conn->cnum, + blr->offset, blr->count, True, NULL, NULL); + + free_blocking_lock_record((blocking_lock_record *)ubi_slRemNext( &blocking_lock_queue, prev)); + blr = (blocking_lock_record *)(prev ? ubi_slNext(prev) : ubi_slFirst(&blocking_lock_queue)); + continue; + } + + if(!set_current_service(conn,True)) { + DEBUG(0,("process_blocking_lock_queue: Unable to become service Error was %s.\n", strerror(errno) )); + /* + * Remove the entry and return an error to the client. + */ + blocking_lock_reply_error(blr,NT_STATUS_ACCESS_DENIED); + + brl_unlock(fsp->dev, fsp->inode, fsp->fnum, + blr->lock_pid, sys_getpid(), conn->cnum, + blr->offset, blr->count, True, NULL, NULL); + + free_blocking_lock_record((blocking_lock_record *)ubi_slRemNext( &blocking_lock_queue, prev)); + blr = (blocking_lock_record *)(prev ? ubi_slNext(prev) : ubi_slFirst(&blocking_lock_queue)); + change_to_root_user(); + continue; + } + + /* + * 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. + */ + + if(blocking_lock_record_process(blr)) { + + brl_unlock(fsp->dev, fsp->inode, fsp->fnum, + blr->lock_pid, sys_getpid(), conn->cnum, + blr->offset, blr->count, True, NULL, NULL); + + free_blocking_lock_record((blocking_lock_record *)ubi_slRemNext( &blocking_lock_queue, prev)); + blr = (blocking_lock_record *)(prev ? ubi_slNext(prev) : ubi_slFirst(&blocking_lock_queue)); + change_to_root_user(); + continue; + } + + change_to_root_user(); + + /* + * Move to the next in the list. + */ + prev = blr; + blr = (blocking_lock_record *)ubi_slNext(blr); + } } -- cgit From 110abf10d208769bf6bcfc0604874cb1bed0406a Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 7 Aug 2003 02:59:52 +0000 Subject: Turns out I had my packet sequences wrong for oplock break code. I was storing the mid of the oplock break - I should have been storing the mid from the open. There are thus 2 types of deferred packet sequence returns - ones that increment the sequence number (returns from oplock causing opens) and ones that don't (change notify returns etc). Running with signing forced on does lead to some interesting tests :-). Jeremy. (This used to be commit 85907f02cec566502d9e4adabbd414020a26064d) --- source3/smbd/blocking.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/smbd/blocking.c') diff --git a/source3/smbd/blocking.c b/source3/smbd/blocking.c index fed3a51b88..8fa2a6494e 100644 --- a/source3/smbd/blocking.c +++ b/source3/smbd/blocking.c @@ -148,7 +148,7 @@ for fnum = %d, name = %s\n", length, (int)blr->expire_time, lock_timeout, blr->fsp->fnum, blr->fsp->fsp_name )); /* Push the MID of this packet on the signing queue. */ - srv_defer_sign_response(SVAL(inbuf,smb_mid)); + srv_defer_sign_response(SVAL(inbuf,smb_mid), True); return True; } -- cgit From 22c024157129e287a6e4bb4bc7232144c36d9604 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 9 Oct 2003 01:46:01 +0000 Subject: Changes to allow Samba3 to pass the Samba4 RAW-READ tests. Jeremy. (This used to be commit e7565dbba696adbb0fd8cca6b86a1a7e5a655f2e) --- source3/smbd/blocking.c | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) (limited to 'source3/smbd/blocking.c') diff --git a/source3/smbd/blocking.c b/source3/smbd/blocking.c index 8fa2a6494e..5c6ddbc6b7 100644 --- a/source3/smbd/blocking.c +++ b/source3/smbd/blocking.c @@ -91,6 +91,7 @@ BOOL push_blocking_lock_request( char *inbuf, int length, int lock_timeout, { static BOOL set_lock_msg; blocking_lock_record *blr; + BOOL my_lock_ctx = False; NTSTATUS status; if(in_chained_smb() ) { @@ -127,7 +128,7 @@ BOOL push_blocking_lock_request( char *inbuf, int length, int lock_timeout, /* Add a pending lock record for this. */ status = brl_lock(blr->fsp->dev, blr->fsp->inode, blr->fsp->fnum, lock_pid, sys_getpid(), blr->fsp->conn->cnum, - offset, count, PENDING_LOCK); + offset, count, PENDING_LOCK, &my_lock_ctx); if (!NT_STATUS_IS_OK(status)) { DEBUG(0,("push_blocking_lock_request: failed to add PENDING_LOCK record.\n")); @@ -302,6 +303,7 @@ static BOOL process_lockread(blocking_lock_record *blr) NTSTATUS status; connection_struct *conn = conn_find(SVAL(inbuf,smb_tid)); files_struct *fsp = blr->fsp; + BOOL my_lock_ctx = False; numtoread = SVAL(inbuf,smb_vwv1); startpos = (SMB_BIG_UINT)IVAL(inbuf,smb_vwv2); @@ -309,8 +311,7 @@ static BOOL process_lockread(blocking_lock_record *blr) numtoread = MIN(BUFFER_SIZE-outsize,numtoread); data = smb_buf(outbuf) + 3; - status = do_lock_spin( fsp, conn, SVAL(inbuf,smb_pid), (SMB_BIG_UINT)numtoread, - startpos, READ_LOCK); + status = do_lock_spin( fsp, conn, SVAL(inbuf,smb_pid), (SMB_BIG_UINT)numtoread, startpos, READ_LOCK, &my_lock_ctx); if (NT_STATUS_V(status)) { if (!NT_STATUS_EQUAL(status,NT_STATUS_LOCK_NOT_GRANTED) && !NT_STATUS_EQUAL(status,NT_STATUS_FILE_LOCK_CONFLICT)) { @@ -371,13 +372,13 @@ static BOOL process_lock(blocking_lock_record *blr) NTSTATUS status; connection_struct *conn = conn_find(SVAL(inbuf,smb_tid)); files_struct *fsp = blr->fsp; + BOOL my_lock_ctx = False; count = IVAL_TO_SMB_OFF_T(inbuf,smb_vwv1); offset = IVAL_TO_SMB_OFF_T(inbuf,smb_vwv3); errno = 0; - status = do_lock_spin(fsp, conn, SVAL(inbuf,smb_pid), count, - offset, WRITE_LOCK); + status = do_lock_spin(fsp, conn, SVAL(inbuf,smb_pid), count, offset, WRITE_LOCK, &my_lock_ctx); if (NT_STATUS_IS_ERR(status)) { if (!NT_STATUS_EQUAL(status,NT_STATUS_LOCK_NOT_GRANTED) && !NT_STATUS_EQUAL(status,NT_STATUS_FILE_LOCK_CONFLICT)) { @@ -428,6 +429,7 @@ static BOOL process_lockingX(blocking_lock_record *blr) uint16 lock_pid; BOOL large_file_format = (locktype & LOCKING_ANDX_LARGE_FILES); char *data; + BOOL my_lock_ctx = False; NTSTATUS status = NT_STATUS_OK; data = smb_buf(inbuf) + ((large_file_format ? 20 : 10)*num_ulocks); @@ -450,7 +452,7 @@ static BOOL process_lockingX(blocking_lock_record *blr) */ errno = 0; status = do_lock_spin(fsp,conn,lock_pid,count,offset, - ((locktype & 1) ? READ_LOCK : WRITE_LOCK)); + ((locktype & 1) ? READ_LOCK : WRITE_LOCK), &my_lock_ctx); if (NT_STATUS_IS_ERR(status)) break; } -- cgit From 6af214dbb0bf9505483fd225b097ad695eed9361 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Fri, 10 Oct 2003 02:02:05 +0000 Subject: Ensure cancelling a blocking lock returns the correct error message. Testing with Samba4 RAW-MUX code. Jeremy. (This used to be commit 533847c95d475921b0421ae113f52c44979939d2) --- source3/smbd/blocking.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/smbd/blocking.c') diff --git a/source3/smbd/blocking.c b/source3/smbd/blocking.c index 5c6ddbc6b7..f43790bfe0 100644 --- a/source3/smbd/blocking.c +++ b/source3/smbd/blocking.c @@ -555,7 +555,7 @@ void remove_pending_lock_requests_by_mid(int mid) 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 )); - blocking_lock_reply_error(blr,NT_STATUS_CANCELLED); + blocking_lock_reply_error(blr,NT_STATUS_FILE_LOCK_CONFLICT); brl_unlock(blr->fsp->dev, blr->fsp->inode, blr->fsp->fnum, blr->lock_pid, sys_getpid(), blr->fsp->conn->cnum, blr->offset, blr->count, True, NULL, NULL); -- cgit From f589164ed94d79161d0798296c325b81c5eadbc7 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 21 Oct 2003 21:19:00 +0000 Subject: Patch from Stefan Metzmacher to fix signing problems when reverse connecting back to a client for printer notify. Jeremy. (This used to be commit 06aa434c3fdb139e3f3143d19413556945cbcd4f) --- source3/smbd/blocking.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/smbd/blocking.c') diff --git a/source3/smbd/blocking.c b/source3/smbd/blocking.c index f43790bfe0..c0512d5539 100644 --- a/source3/smbd/blocking.c +++ b/source3/smbd/blocking.c @@ -149,7 +149,7 @@ for fnum = %d, name = %s\n", length, (int)blr->expire_time, lock_timeout, blr->fsp->fnum, blr->fsp->fsp_name )); /* Push the MID of this packet on the signing queue. */ - srv_defer_sign_response(SVAL(inbuf,smb_mid), True); + srv_defer_sign_response(SVAL(inbuf,smb_mid)); return True; } -- cgit From 2acd0848663f28afedff9b11b738e048f5ead2cc Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 15 Jun 2004 18:36:45 +0000 Subject: r1154: Change default setting for case sensitivity to "auto". If set to auto then is the client supports it (current clients supported are Samba and CIFSVFS - detected by the negprot strings "Samba", "POSIX 2" and a bare "NT LM 0.12" string) then the setting of the per packet flag smb_flag FLAG_CASELESS_PATHNAMES is taken into account per packet. This allows the linux CIFS client to use Samba in a case sensitive manner. Additional command in smbclient "case_sensitive", toggles the flag in subsequent packets. Docs to follow. Jeremy. (This used to be commit cf84c0fe1a061acc0313f7db124b8f947cdf623d) --- source3/smbd/blocking.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/smbd/blocking.c') diff --git a/source3/smbd/blocking.c b/source3/smbd/blocking.c index c0512d5539..3983a4cbdf 100644 --- a/source3/smbd/blocking.c +++ b/source3/smbd/blocking.c @@ -680,7 +680,7 @@ void process_blocking_lock_queue(time_t t) continue; } - if(!set_current_service(conn,True)) { + if(!set_current_service(conn,SVAL(blr->inbuf,smb_flg),True)) { DEBUG(0,("process_blocking_lock_queue: Unable to become service Error was %s.\n", strerror(errno) )); /* * Remove the entry and return an error to the client. -- cgit From 4e02b70863f6dac8cf7995010af12d94a372749c Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Fri, 20 Aug 2004 23:39:29 +0000 Subject: r1976: Simplify, use standard dlist interface. Jeremy. (This used to be commit 776c28133dfa29320608829f15da2f1056454e4c) --- source3/smbd/blocking.c | 73 ++++++++++++++++--------------------------------- 1 file changed, 24 insertions(+), 49 deletions(-) (limited to 'source3/smbd/blocking.c') diff --git a/source3/smbd/blocking.c b/source3/smbd/blocking.c index 3983a4cbdf..b4feef459b 100644 --- a/source3/smbd/blocking.c +++ b/source3/smbd/blocking.c @@ -27,8 +27,9 @@ extern char *OutBuffer; notify. It consists of the requesting SMB and the expiry time. *****************************************************************************/ -typedef struct { - ubi_slNode msg_next; +typedef struct _blocking_lock_record { + struct _blocking_lock_record *next; + struct _blocking_lock_record *prev; int com_type; files_struct *fsp; time_t expire_time; @@ -40,7 +41,7 @@ typedef struct { int length; } blocking_lock_record; -static ubi_slList blocking_lock_queue = { NULL, (ubi_slNodePtr)&blocking_lock_queue, 0}; +static blocking_lock_record *blocking_lock_queue; /**************************************************************************** Destructor for the above structure. @@ -90,7 +91,7 @@ BOOL push_blocking_lock_request( char *inbuf, int length, int lock_timeout, int lock_num, uint16 lock_pid, SMB_BIG_UINT offset, SMB_BIG_UINT count) { static BOOL set_lock_msg; - blocking_lock_record *blr; + blocking_lock_record *blr, *tmp; BOOL my_lock_ctx = False; NTSTATUS status; @@ -136,7 +137,7 @@ BOOL push_blocking_lock_request( char *inbuf, int length, int lock_timeout, return False; } - ubi_slAddTail(&blocking_lock_queue, blr); + DLIST_ADD_END(blocking_lock_queue, blr, tmp); /* Ensure we'll receive messages when this is unlocked. */ if (!set_lock_msg) { @@ -516,10 +517,10 @@ static BOOL blocking_lock_record_process(blocking_lock_record *blr) void remove_pending_lock_requests_by_fid(files_struct *fsp) { - blocking_lock_record *blr = (blocking_lock_record *)ubi_slFirst( &blocking_lock_queue ); - blocking_lock_record *prev = NULL; + blocking_lock_record *blr, *next = NULL; - while(blr != NULL) { + for(blr = blocking_lock_queue; blr; blr = next) { + next = blr->next; if(blr->fsp->fnum == fsp->fnum) { DEBUG(10,("remove_pending_lock_requests_by_fid - removing request type %d for \ @@ -529,13 +530,8 @@ file %s fnum = %d\n", blr->com_type, fsp->fsp_name, fsp->fnum )); blr->lock_pid, sys_getpid(), blr->fsp->conn->cnum, blr->offset, blr->count, True, NULL, NULL); - free_blocking_lock_record((blocking_lock_record *)ubi_slRemNext( &blocking_lock_queue, prev)); - blr = (blocking_lock_record *)(prev ? ubi_slNext(prev) : ubi_slFirst(&blocking_lock_queue)); - continue; + free_blocking_lock_record(blr); } - - prev = blr; - blr = (blocking_lock_record *)ubi_slNext(blr); } } @@ -545,10 +541,10 @@ file %s fnum = %d\n", blr->com_type, fsp->fsp_name, fsp->fnum )); void remove_pending_lock_requests_by_mid(int mid) { - blocking_lock_record *blr = (blocking_lock_record *)ubi_slFirst( &blocking_lock_queue ); - blocking_lock_record *prev = NULL; + blocking_lock_record *blr, *next = NULL; - while(blr != NULL) { + for(blr = blocking_lock_queue; blr; blr = next) { + next = blr->next; if(SVAL(blr->inbuf,smb_mid) == mid) { files_struct *fsp = blr->fsp; @@ -559,13 +555,8 @@ file %s fnum = %d\n", blr->com_type, fsp->fsp_name, fsp->fnum )); brl_unlock(blr->fsp->dev, blr->fsp->inode, blr->fsp->fnum, blr->lock_pid, sys_getpid(), blr->fsp->conn->cnum, blr->offset, blr->count, True, NULL, NULL); - free_blocking_lock_record((blocking_lock_record *)ubi_slRemNext( &blocking_lock_queue, prev)); - blr = (blocking_lock_record *)(prev ? ubi_slNext(prev) : ubi_slFirst(&blocking_lock_queue)); - continue; + free_blocking_lock_record(blr); } - - prev = blr; - blr = (blocking_lock_record *)ubi_slNext(blr); } } @@ -587,7 +578,7 @@ unsigned blocking_locks_timeout(unsigned default_timeout) { unsigned timeout = default_timeout; time_t t; - blocking_lock_record *blr = (blocking_lock_record *)ubi_slFirst(&blocking_lock_queue); + blocking_lock_record *blr = blocking_lock_queue; /* note that we avoid the time() syscall if there are no blocking locks */ if (!blr) @@ -595,12 +586,11 @@ unsigned blocking_locks_timeout(unsigned default_timeout) t = time(NULL); - while (blr) { + for (; blr; blr = blr->next) { if ((blr->expire_time != (time_t)-1) && (timeout > (blr->expire_time - t))) { timeout = blr->expire_time - t; } - blr = (blocking_lock_record *)ubi_slNext(blr); } if (timeout < 1) @@ -615,21 +605,19 @@ unsigned blocking_locks_timeout(unsigned default_timeout) void process_blocking_lock_queue(time_t t) { - blocking_lock_record *blr = (blocking_lock_record *)ubi_slFirst( &blocking_lock_queue ); - blocking_lock_record *prev = NULL; - - if(blr == NULL) - return; + blocking_lock_record *blr, *next = NULL; /* * Go through the queue and see if we can get any of the locks. */ - while(blr != NULL) { + for (blr = blocking_lock_queue; blr; blr = next) { connection_struct *conn = NULL; uint16 vuid; files_struct *fsp = NULL; + next = blr->next; + /* * Ensure we don't have any old chain_fsp values * sitting around.... @@ -658,8 +646,7 @@ void process_blocking_lock_queue(time_t t) blr->offset, blr->count, True, NULL, NULL); blocking_lock_reply_error(blr,NT_STATUS_FILE_LOCK_CONFLICT); - free_blocking_lock_record((blocking_lock_record *)ubi_slRemNext( &blocking_lock_queue, prev)); - blr = (blocking_lock_record *)(prev ? ubi_slNext(prev) : ubi_slFirst(&blocking_lock_queue)); + free_blocking_lock_record(blr); continue; } @@ -675,8 +662,7 @@ void process_blocking_lock_queue(time_t t) blr->lock_pid, sys_getpid(), conn->cnum, blr->offset, blr->count, True, NULL, NULL); - free_blocking_lock_record((blocking_lock_record *)ubi_slRemNext( &blocking_lock_queue, prev)); - blr = (blocking_lock_record *)(prev ? ubi_slNext(prev) : ubi_slFirst(&blocking_lock_queue)); + free_blocking_lock_record(blr); continue; } @@ -691,8 +677,7 @@ void process_blocking_lock_queue(time_t t) blr->lock_pid, sys_getpid(), conn->cnum, blr->offset, blr->count, True, NULL, NULL); - free_blocking_lock_record((blocking_lock_record *)ubi_slRemNext( &blocking_lock_queue, prev)); - blr = (blocking_lock_record *)(prev ? ubi_slNext(prev) : ubi_slFirst(&blocking_lock_queue)); + free_blocking_lock_record(blr); change_to_root_user(); continue; } @@ -709,18 +694,8 @@ void process_blocking_lock_queue(time_t t) blr->lock_pid, sys_getpid(), conn->cnum, blr->offset, blr->count, True, NULL, NULL); - free_blocking_lock_record((blocking_lock_record *)ubi_slRemNext( &blocking_lock_queue, prev)); - blr = (blocking_lock_record *)(prev ? ubi_slNext(prev) : ubi_slFirst(&blocking_lock_queue)); - change_to_root_user(); - continue; + free_blocking_lock_record(blr); } - change_to_root_user(); - - /* - * Move to the next in the list. - */ - prev = blr; - blr = (blocking_lock_record *)ubi_slNext(blr); } } -- cgit From d792569de6123562f929a3e18ce670d6296c98d5 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Fri, 20 Aug 2004 23:46:18 +0000 Subject: r1978: Roll it back until I do it right.... :-). Jeremy. (This used to be commit f16aa99f8c2f8a31f82e2aedfe3ea6a7276db504) --- source3/smbd/blocking.c | 73 +++++++++++++++++++++++++++++++++---------------- 1 file changed, 49 insertions(+), 24 deletions(-) (limited to 'source3/smbd/blocking.c') diff --git a/source3/smbd/blocking.c b/source3/smbd/blocking.c index b4feef459b..3983a4cbdf 100644 --- a/source3/smbd/blocking.c +++ b/source3/smbd/blocking.c @@ -27,9 +27,8 @@ extern char *OutBuffer; notify. It consists of the requesting SMB and the expiry time. *****************************************************************************/ -typedef struct _blocking_lock_record { - struct _blocking_lock_record *next; - struct _blocking_lock_record *prev; +typedef struct { + ubi_slNode msg_next; int com_type; files_struct *fsp; time_t expire_time; @@ -41,7 +40,7 @@ typedef struct _blocking_lock_record { int length; } blocking_lock_record; -static blocking_lock_record *blocking_lock_queue; +static ubi_slList blocking_lock_queue = { NULL, (ubi_slNodePtr)&blocking_lock_queue, 0}; /**************************************************************************** Destructor for the above structure. @@ -91,7 +90,7 @@ BOOL push_blocking_lock_request( char *inbuf, int length, int lock_timeout, int lock_num, uint16 lock_pid, SMB_BIG_UINT offset, SMB_BIG_UINT count) { static BOOL set_lock_msg; - blocking_lock_record *blr, *tmp; + blocking_lock_record *blr; BOOL my_lock_ctx = False; NTSTATUS status; @@ -137,7 +136,7 @@ BOOL push_blocking_lock_request( char *inbuf, int length, int lock_timeout, return False; } - DLIST_ADD_END(blocking_lock_queue, blr, tmp); + ubi_slAddTail(&blocking_lock_queue, blr); /* Ensure we'll receive messages when this is unlocked. */ if (!set_lock_msg) { @@ -517,10 +516,10 @@ static BOOL blocking_lock_record_process(blocking_lock_record *blr) void remove_pending_lock_requests_by_fid(files_struct *fsp) { - blocking_lock_record *blr, *next = NULL; + blocking_lock_record *blr = (blocking_lock_record *)ubi_slFirst( &blocking_lock_queue ); + blocking_lock_record *prev = NULL; - for(blr = blocking_lock_queue; blr; blr = next) { - next = blr->next; + while(blr != NULL) { if(blr->fsp->fnum == fsp->fnum) { DEBUG(10,("remove_pending_lock_requests_by_fid - removing request type %d for \ @@ -530,8 +529,13 @@ file %s fnum = %d\n", blr->com_type, fsp->fsp_name, fsp->fnum )); blr->lock_pid, sys_getpid(), blr->fsp->conn->cnum, blr->offset, blr->count, True, NULL, NULL); - free_blocking_lock_record(blr); + free_blocking_lock_record((blocking_lock_record *)ubi_slRemNext( &blocking_lock_queue, prev)); + blr = (blocking_lock_record *)(prev ? ubi_slNext(prev) : ubi_slFirst(&blocking_lock_queue)); + continue; } + + prev = blr; + blr = (blocking_lock_record *)ubi_slNext(blr); } } @@ -541,10 +545,10 @@ file %s fnum = %d\n", blr->com_type, fsp->fsp_name, fsp->fnum )); void remove_pending_lock_requests_by_mid(int mid) { - blocking_lock_record *blr, *next = NULL; + blocking_lock_record *blr = (blocking_lock_record *)ubi_slFirst( &blocking_lock_queue ); + blocking_lock_record *prev = NULL; - for(blr = blocking_lock_queue; blr; blr = next) { - next = blr->next; + while(blr != NULL) { if(SVAL(blr->inbuf,smb_mid) == mid) { files_struct *fsp = blr->fsp; @@ -555,8 +559,13 @@ file %s fnum = %d\n", blr->com_type, fsp->fsp_name, fsp->fnum )); brl_unlock(blr->fsp->dev, blr->fsp->inode, blr->fsp->fnum, blr->lock_pid, sys_getpid(), blr->fsp->conn->cnum, blr->offset, blr->count, True, NULL, NULL); - free_blocking_lock_record(blr); + free_blocking_lock_record((blocking_lock_record *)ubi_slRemNext( &blocking_lock_queue, prev)); + blr = (blocking_lock_record *)(prev ? ubi_slNext(prev) : ubi_slFirst(&blocking_lock_queue)); + continue; } + + prev = blr; + blr = (blocking_lock_record *)ubi_slNext(blr); } } @@ -578,7 +587,7 @@ unsigned blocking_locks_timeout(unsigned default_timeout) { unsigned timeout = default_timeout; time_t t; - blocking_lock_record *blr = blocking_lock_queue; + blocking_lock_record *blr = (blocking_lock_record *)ubi_slFirst(&blocking_lock_queue); /* note that we avoid the time() syscall if there are no blocking locks */ if (!blr) @@ -586,11 +595,12 @@ unsigned blocking_locks_timeout(unsigned default_timeout) t = time(NULL); - for (; blr; blr = blr->next) { + while (blr) { if ((blr->expire_time != (time_t)-1) && (timeout > (blr->expire_time - t))) { timeout = blr->expire_time - t; } + blr = (blocking_lock_record *)ubi_slNext(blr); } if (timeout < 1) @@ -605,19 +615,21 @@ unsigned blocking_locks_timeout(unsigned default_timeout) void process_blocking_lock_queue(time_t t) { - blocking_lock_record *blr, *next = NULL; + blocking_lock_record *blr = (blocking_lock_record *)ubi_slFirst( &blocking_lock_queue ); + blocking_lock_record *prev = NULL; + + if(blr == NULL) + return; /* * Go through the queue and see if we can get any of the locks. */ - for (blr = blocking_lock_queue; blr; blr = next) { + while(blr != NULL) { connection_struct *conn = NULL; uint16 vuid; files_struct *fsp = NULL; - next = blr->next; - /* * Ensure we don't have any old chain_fsp values * sitting around.... @@ -646,7 +658,8 @@ void process_blocking_lock_queue(time_t t) blr->offset, blr->count, True, NULL, NULL); blocking_lock_reply_error(blr,NT_STATUS_FILE_LOCK_CONFLICT); - free_blocking_lock_record(blr); + free_blocking_lock_record((blocking_lock_record *)ubi_slRemNext( &blocking_lock_queue, prev)); + blr = (blocking_lock_record *)(prev ? ubi_slNext(prev) : ubi_slFirst(&blocking_lock_queue)); continue; } @@ -662,7 +675,8 @@ void process_blocking_lock_queue(time_t t) blr->lock_pid, sys_getpid(), conn->cnum, blr->offset, blr->count, True, NULL, NULL); - free_blocking_lock_record(blr); + free_blocking_lock_record((blocking_lock_record *)ubi_slRemNext( &blocking_lock_queue, prev)); + blr = (blocking_lock_record *)(prev ? ubi_slNext(prev) : ubi_slFirst(&blocking_lock_queue)); continue; } @@ -677,7 +691,8 @@ void process_blocking_lock_queue(time_t t) blr->lock_pid, sys_getpid(), conn->cnum, blr->offset, blr->count, True, NULL, NULL); - free_blocking_lock_record(blr); + free_blocking_lock_record((blocking_lock_record *)ubi_slRemNext( &blocking_lock_queue, prev)); + blr = (blocking_lock_record *)(prev ? ubi_slNext(prev) : ubi_slFirst(&blocking_lock_queue)); change_to_root_user(); continue; } @@ -694,8 +709,18 @@ void process_blocking_lock_queue(time_t t) blr->lock_pid, sys_getpid(), conn->cnum, blr->offset, blr->count, True, NULL, NULL); - free_blocking_lock_record(blr); + free_blocking_lock_record((blocking_lock_record *)ubi_slRemNext( &blocking_lock_queue, prev)); + blr = (blocking_lock_record *)(prev ? ubi_slNext(prev) : ubi_slFirst(&blocking_lock_queue)); + change_to_root_user(); + continue; } + change_to_root_user(); + + /* + * Move to the next in the list. + */ + prev = blr; + blr = (blocking_lock_record *)ubi_slNext(blr); } } -- cgit From 2ea1c9de9fe30a8c1929f7cc8c907f6242ea7fd0 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Sat, 21 Aug 2004 00:43:21 +0000 Subject: r1980: Re-apply (remember to remove entry from list on delete this time :-). Jeremy. (This used to be commit 275a0010f487a06b3bc86f82e45d08c821a51b0e) --- source3/smbd/blocking.c | 74 +++++++++++++++++-------------------------------- 1 file changed, 25 insertions(+), 49 deletions(-) (limited to 'source3/smbd/blocking.c') diff --git a/source3/smbd/blocking.c b/source3/smbd/blocking.c index 3983a4cbdf..e143999a78 100644 --- a/source3/smbd/blocking.c +++ b/source3/smbd/blocking.c @@ -27,8 +27,9 @@ extern char *OutBuffer; notify. It consists of the requesting SMB and the expiry time. *****************************************************************************/ -typedef struct { - ubi_slNode msg_next; +typedef struct _blocking_lock_record { + struct _blocking_lock_record *next; + struct _blocking_lock_record *prev; int com_type; files_struct *fsp; time_t expire_time; @@ -40,7 +41,7 @@ typedef struct { int length; } blocking_lock_record; -static ubi_slList blocking_lock_queue = { NULL, (ubi_slNodePtr)&blocking_lock_queue, 0}; +static blocking_lock_record *blocking_lock_queue; /**************************************************************************** Destructor for the above structure. @@ -48,6 +49,7 @@ static ubi_slList blocking_lock_queue = { NULL, (ubi_slNodePtr)&blocking_lock_qu static void free_blocking_lock_record(blocking_lock_record *blr) { + DLIST_REMOVE(blocking_lock_queue, blr); SAFE_FREE(blr->inbuf); SAFE_FREE(blr); } @@ -90,7 +92,7 @@ BOOL push_blocking_lock_request( char *inbuf, int length, int lock_timeout, int lock_num, uint16 lock_pid, SMB_BIG_UINT offset, SMB_BIG_UINT count) { static BOOL set_lock_msg; - blocking_lock_record *blr; + blocking_lock_record *blr, *tmp; BOOL my_lock_ctx = False; NTSTATUS status; @@ -136,7 +138,7 @@ BOOL push_blocking_lock_request( char *inbuf, int length, int lock_timeout, return False; } - ubi_slAddTail(&blocking_lock_queue, blr); + DLIST_ADD_END(blocking_lock_queue, blr, tmp); /* Ensure we'll receive messages when this is unlocked. */ if (!set_lock_msg) { @@ -516,10 +518,10 @@ static BOOL blocking_lock_record_process(blocking_lock_record *blr) void remove_pending_lock_requests_by_fid(files_struct *fsp) { - blocking_lock_record *blr = (blocking_lock_record *)ubi_slFirst( &blocking_lock_queue ); - blocking_lock_record *prev = NULL; + blocking_lock_record *blr, *next = NULL; - while(blr != NULL) { + for(blr = blocking_lock_queue; blr; blr = next) { + next = blr->next; if(blr->fsp->fnum == fsp->fnum) { DEBUG(10,("remove_pending_lock_requests_by_fid - removing request type %d for \ @@ -529,13 +531,8 @@ file %s fnum = %d\n", blr->com_type, fsp->fsp_name, fsp->fnum )); blr->lock_pid, sys_getpid(), blr->fsp->conn->cnum, blr->offset, blr->count, True, NULL, NULL); - free_blocking_lock_record((blocking_lock_record *)ubi_slRemNext( &blocking_lock_queue, prev)); - blr = (blocking_lock_record *)(prev ? ubi_slNext(prev) : ubi_slFirst(&blocking_lock_queue)); - continue; + free_blocking_lock_record(blr); } - - prev = blr; - blr = (blocking_lock_record *)ubi_slNext(blr); } } @@ -545,10 +542,10 @@ file %s fnum = %d\n", blr->com_type, fsp->fsp_name, fsp->fnum )); void remove_pending_lock_requests_by_mid(int mid) { - blocking_lock_record *blr = (blocking_lock_record *)ubi_slFirst( &blocking_lock_queue ); - blocking_lock_record *prev = NULL; + blocking_lock_record *blr, *next = NULL; - while(blr != NULL) { + for(blr = blocking_lock_queue; blr; blr = next) { + next = blr->next; if(SVAL(blr->inbuf,smb_mid) == mid) { files_struct *fsp = blr->fsp; @@ -559,13 +556,8 @@ file %s fnum = %d\n", blr->com_type, fsp->fsp_name, fsp->fnum )); brl_unlock(blr->fsp->dev, blr->fsp->inode, blr->fsp->fnum, blr->lock_pid, sys_getpid(), blr->fsp->conn->cnum, blr->offset, blr->count, True, NULL, NULL); - free_blocking_lock_record((blocking_lock_record *)ubi_slRemNext( &blocking_lock_queue, prev)); - blr = (blocking_lock_record *)(prev ? ubi_slNext(prev) : ubi_slFirst(&blocking_lock_queue)); - continue; + free_blocking_lock_record(blr); } - - prev = blr; - blr = (blocking_lock_record *)ubi_slNext(blr); } } @@ -587,7 +579,7 @@ unsigned blocking_locks_timeout(unsigned default_timeout) { unsigned timeout = default_timeout; time_t t; - blocking_lock_record *blr = (blocking_lock_record *)ubi_slFirst(&blocking_lock_queue); + blocking_lock_record *blr = blocking_lock_queue; /* note that we avoid the time() syscall if there are no blocking locks */ if (!blr) @@ -595,12 +587,11 @@ unsigned blocking_locks_timeout(unsigned default_timeout) t = time(NULL); - while (blr) { + for (; blr; blr = blr->next) { if ((blr->expire_time != (time_t)-1) && (timeout > (blr->expire_time - t))) { timeout = blr->expire_time - t; } - blr = (blocking_lock_record *)ubi_slNext(blr); } if (timeout < 1) @@ -615,21 +606,19 @@ unsigned blocking_locks_timeout(unsigned default_timeout) void process_blocking_lock_queue(time_t t) { - blocking_lock_record *blr = (blocking_lock_record *)ubi_slFirst( &blocking_lock_queue ); - blocking_lock_record *prev = NULL; - - if(blr == NULL) - return; + blocking_lock_record *blr, *next = NULL; /* * Go through the queue and see if we can get any of the locks. */ - while(blr != NULL) { + for (blr = blocking_lock_queue; blr; blr = next) { connection_struct *conn = NULL; uint16 vuid; files_struct *fsp = NULL; + next = blr->next; + /* * Ensure we don't have any old chain_fsp values * sitting around.... @@ -658,8 +647,7 @@ void process_blocking_lock_queue(time_t t) blr->offset, blr->count, True, NULL, NULL); blocking_lock_reply_error(blr,NT_STATUS_FILE_LOCK_CONFLICT); - free_blocking_lock_record((blocking_lock_record *)ubi_slRemNext( &blocking_lock_queue, prev)); - blr = (blocking_lock_record *)(prev ? ubi_slNext(prev) : ubi_slFirst(&blocking_lock_queue)); + free_blocking_lock_record(blr); continue; } @@ -675,8 +663,7 @@ void process_blocking_lock_queue(time_t t) blr->lock_pid, sys_getpid(), conn->cnum, blr->offset, blr->count, True, NULL, NULL); - free_blocking_lock_record((blocking_lock_record *)ubi_slRemNext( &blocking_lock_queue, prev)); - blr = (blocking_lock_record *)(prev ? ubi_slNext(prev) : ubi_slFirst(&blocking_lock_queue)); + free_blocking_lock_record(blr); continue; } @@ -691,8 +678,7 @@ void process_blocking_lock_queue(time_t t) blr->lock_pid, sys_getpid(), conn->cnum, blr->offset, blr->count, True, NULL, NULL); - free_blocking_lock_record((blocking_lock_record *)ubi_slRemNext( &blocking_lock_queue, prev)); - blr = (blocking_lock_record *)(prev ? ubi_slNext(prev) : ubi_slFirst(&blocking_lock_queue)); + free_blocking_lock_record(blr); change_to_root_user(); continue; } @@ -709,18 +695,8 @@ void process_blocking_lock_queue(time_t t) blr->lock_pid, sys_getpid(), conn->cnum, blr->offset, blr->count, True, NULL, NULL); - free_blocking_lock_record((blocking_lock_record *)ubi_slRemNext( &blocking_lock_queue, prev)); - blr = (blocking_lock_record *)(prev ? ubi_slNext(prev) : ubi_slFirst(&blocking_lock_queue)); - change_to_root_user(); - continue; + free_blocking_lock_record(blr); } - change_to_root_user(); - - /* - * Move to the next in the list. - */ - prev = blr; - blr = (blocking_lock_record *)ubi_slNext(blr); } } -- cgit From acf9d61421faa6c0055d57fdee7db300dc5431aa Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 7 Dec 2004 18:25:53 +0000 Subject: r4088: Get medieval on our ass about malloc.... :-). Take control of all our allocation functions so we can funnel through some well known functions. Should help greatly with malloc checking. HEAD patch to follow. Jeremy. (This used to be commit 620f2e608f70ba92f032720c031283d295c5c06a) --- source3/smbd/blocking.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source3/smbd/blocking.c') diff --git a/source3/smbd/blocking.c b/source3/smbd/blocking.c index e143999a78..0e71174a2e 100644 --- a/source3/smbd/blocking.c +++ b/source3/smbd/blocking.c @@ -106,12 +106,12 @@ BOOL push_blocking_lock_request( char *inbuf, int length, int lock_timeout, * the expiration time here. */ - if((blr = (blocking_lock_record *)malloc(sizeof(blocking_lock_record))) == NULL) { + if((blr = SMB_MALLOC_P(blocking_lock_record)) == NULL) { DEBUG(0,("push_blocking_lock_request: Malloc fail !\n" )); return False; } - if((blr->inbuf = (char *)malloc(length)) == NULL) { + if((blr->inbuf = (char *)SMB_MALLOC(length)) == NULL) { DEBUG(0,("push_blocking_lock_request: Malloc fail (2)!\n" )); SAFE_FREE(blr); return False; -- cgit From f2f55d703d0dd549a83809d3e5cc5151569b48d6 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Mon, 27 Jun 2005 22:53:56 +0000 Subject: r7963: Add aio support to 3.0. Jeremy. (This used to be commit 1de27da47051af08790317f5b48b02719d6b9934) --- source3/smbd/blocking.c | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) (limited to 'source3/smbd/blocking.c') diff --git a/source3/smbd/blocking.c b/source3/smbd/blocking.c index 0e71174a2e..72d021d4e6 100644 --- a/source3/smbd/blocking.c +++ b/source3/smbd/blocking.c @@ -20,8 +20,6 @@ #include "includes.h" -extern char *OutBuffer; - /**************************************************************************** This is the structure to queue to implement blocking locks. notify. It consists of the requesting SMB and the expiry time. @@ -175,7 +173,7 @@ static void send_blocking_reply(char *outbuf, int outsize) static void reply_lockingX_success(blocking_lock_record *blr) { - char *outbuf = OutBuffer; + char *outbuf = get_OutBuffer(); int bufsize = BUFFER_SIZE; char *inbuf = blr->inbuf; int outsize = 0; @@ -204,7 +202,7 @@ static void reply_lockingX_success(blocking_lock_record *blr) static void generic_blocking_lock_error(blocking_lock_record *blr, NTSTATUS status) { - char *outbuf = OutBuffer; + char *outbuf = get_OutBuffer(); char *inbuf = blr->inbuf; construct_reply_common(inbuf, outbuf); @@ -295,7 +293,7 @@ static void blocking_lock_reply_error(blocking_lock_record *blr, NTSTATUS status static BOOL process_lockread(blocking_lock_record *blr) { - char *outbuf = OutBuffer; + char *outbuf = get_OutBuffer(); char *inbuf = blr->inbuf; ssize_t nread = -1; char *data, *p; @@ -367,7 +365,7 @@ static BOOL process_lockread(blocking_lock_record *blr) static BOOL process_lock(blocking_lock_record *blr) { - char *outbuf = OutBuffer; + char *outbuf = get_OutBuffer(); char *inbuf = blr->inbuf; int outsize; SMB_BIG_UINT count = (SMB_BIG_UINT)0, offset = (SMB_BIG_UINT)0; -- cgit From 54abd2aa66069e6baf7769c496f46d9dba18db39 Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Fri, 30 Sep 2005 17:13:37 +0000 Subject: r10656: BIG merge from trunk. Features not copied over * \PIPE\unixinfo * winbindd's {group,alias}membership new functions * winbindd's lookupsids() functionality * swat (trunk changes to be reverted as per discussion with Deryck) (This used to be commit 939c3cb5d78e3a2236209b296aa8aba8bdce32d3) --- source3/smbd/blocking.c | 24 +++++++++++++----------- 1 file changed, 13 insertions(+), 11 deletions(-) (limited to 'source3/smbd/blocking.c') diff --git a/source3/smbd/blocking.c b/source3/smbd/blocking.c index 72d021d4e6..805e45f6ea 100644 --- a/source3/smbd/blocking.c +++ b/source3/smbd/blocking.c @@ -80,7 +80,8 @@ static BOOL in_chained_smb(void) return (chain_size != 0); } -static void received_unlock_msg(int msg_type, pid_t src, void *buf, size_t len); +static void received_unlock_msg(int msg_type, struct process_id src, + void *buf, size_t len); /**************************************************************************** Function to push a blocking lock request onto the lock queue. @@ -127,7 +128,7 @@ BOOL push_blocking_lock_request( char *inbuf, int length, int lock_timeout, /* Add a pending lock record for this. */ status = brl_lock(blr->fsp->dev, blr->fsp->inode, blr->fsp->fnum, - lock_pid, sys_getpid(), blr->fsp->conn->cnum, + lock_pid, procid_self(), blr->fsp->conn->cnum, offset, count, PENDING_LOCK, &my_lock_ctx); if (!NT_STATUS_IS_OK(status)) { @@ -351,8 +352,8 @@ static BOOL process_lockread(blocking_lock_record *blr) SSVAL(p,0,nread); p += 2; set_message_end(outbuf, p+nread); - DEBUG(3, ( "process_lockread file = %s, fnum=%d num=%d nread=%d\n", - fsp->fsp_name, fsp->fnum, (int)numtoread, (int)nread ) ); + DEBUG(3, ( "process_lockread file = %s, fnum=%d num=%lu nread=%ld\n", + fsp->fsp_name, fsp->fnum, (unsigned long)numtoread, (long)nread ) ); send_blocking_reply(outbuf,outsize); return True; @@ -526,7 +527,7 @@ void remove_pending_lock_requests_by_fid(files_struct *fsp) file %s fnum = %d\n", blr->com_type, fsp->fsp_name, fsp->fnum )); brl_unlock(blr->fsp->dev, blr->fsp->inode, blr->fsp->fnum, - blr->lock_pid, sys_getpid(), blr->fsp->conn->cnum, + blr->lock_pid, procid_self(), blr->fsp->conn->cnum, blr->offset, blr->count, True, NULL, NULL); free_blocking_lock_record(blr); @@ -552,7 +553,7 @@ file %s fnum = %d\n", blr->com_type, fsp->fsp_name, fsp->fnum )); blocking_lock_reply_error(blr,NT_STATUS_FILE_LOCK_CONFLICT); brl_unlock(blr->fsp->dev, blr->fsp->inode, blr->fsp->fnum, - blr->lock_pid, sys_getpid(), blr->fsp->conn->cnum, + blr->lock_pid, procid_self(), blr->fsp->conn->cnum, blr->offset, blr->count, True, NULL, NULL); free_blocking_lock_record(blr); } @@ -563,7 +564,8 @@ file %s fnum = %d\n", blr->com_type, fsp->fsp_name, fsp->fnum )); Set a flag as an unlock request affects one of our pending locks. *****************************************************************************/ -static void received_unlock_msg(int msg_type, pid_t src, void *buf, size_t len) +static void received_unlock_msg(int msg_type, struct process_id src, + void *buf, size_t len) { DEBUG(10,("received_unlock_msg\n")); process_blocking_lock_queue(time(NULL)); @@ -641,7 +643,7 @@ void process_blocking_lock_queue(time_t t) fsp->fnum, fsp->fsp_name )); brl_unlock(fsp->dev, fsp->inode, fsp->fnum, - blr->lock_pid, sys_getpid(), conn->cnum, + blr->lock_pid, procid_self(), conn->cnum, blr->offset, blr->count, True, NULL, NULL); blocking_lock_reply_error(blr,NT_STATUS_FILE_LOCK_CONFLICT); @@ -658,7 +660,7 @@ void process_blocking_lock_queue(time_t t) blocking_lock_reply_error(blr,NT_STATUS_ACCESS_DENIED); brl_unlock(fsp->dev, fsp->inode, fsp->fnum, - blr->lock_pid, sys_getpid(), conn->cnum, + blr->lock_pid, procid_self(), conn->cnum, blr->offset, blr->count, True, NULL, NULL); free_blocking_lock_record(blr); @@ -673,7 +675,7 @@ void process_blocking_lock_queue(time_t t) blocking_lock_reply_error(blr,NT_STATUS_ACCESS_DENIED); brl_unlock(fsp->dev, fsp->inode, fsp->fnum, - blr->lock_pid, sys_getpid(), conn->cnum, + blr->lock_pid, procid_self(), conn->cnum, blr->offset, blr->count, True, NULL, NULL); free_blocking_lock_record(blr); @@ -690,7 +692,7 @@ void process_blocking_lock_queue(time_t t) if(blocking_lock_record_process(blr)) { brl_unlock(fsp->dev, fsp->inode, fsp->fnum, - blr->lock_pid, sys_getpid(), conn->cnum, + blr->lock_pid, procid_self(), conn->cnum, blr->offset, blr->count, True, NULL, NULL); free_blocking_lock_record(blr); -- cgit From 22dbd67708f1651a2341d70ce576fac360affccf Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Mon, 10 Apr 2006 15:33:04 +0000 Subject: r15018: Merge Volker's ipc/trans2/nttrans changes over into 3.0. Also merge the new POSIX lock code - this is not enabled unless -DDEVELOPER is defined. This doesn't yet map onto underlying system POSIX locks. Updates vfs to allow lock queries. Jeremy. (This used to be commit 08e52ead03304ff04229e1bfe544ff40e2564fc7) --- source3/smbd/blocking.c | 277 +++++++++++++++++++++++++++++++++++++----------- 1 file changed, 214 insertions(+), 63 deletions(-) (limited to 'source3/smbd/blocking.c') diff --git a/source3/smbd/blocking.c b/source3/smbd/blocking.c index 805e45f6ea..6b47d0466b 100644 --- a/source3/smbd/blocking.c +++ b/source3/smbd/blocking.c @@ -35,6 +35,8 @@ typedef struct _blocking_lock_record { SMB_BIG_UINT offset; SMB_BIG_UINT count; uint16 lock_pid; + enum brl_flavour lock_flav; + enum brl_type lock_type; char *inbuf; int length; } blocking_lock_record; @@ -52,25 +54,6 @@ static void free_blocking_lock_record(blocking_lock_record *blr) SAFE_FREE(blr); } -/**************************************************************************** - Get the files_struct given a particular queued SMB. -*****************************************************************************/ - -static files_struct *get_fsp_from_pkt(char *inbuf) -{ - switch(CVAL(inbuf,smb_com)) { - case SMBlock: - case SMBlockread: - return file_fsp(inbuf,smb_vwv0); - case SMBlockingX: - return file_fsp(inbuf,smb_vwv2); - default: - DEBUG(0,("get_fsp_from_pkt: PANIC - unknown type on blocking lock queue - exiting.!\n")); - exit_server("PANIC - unknown type on blocking lock queue"); - } - return NULL; /* Keep compiler happy. */ -} - /**************************************************************************** Determine if this is a secondary element of a chained SMB. **************************************************************************/ @@ -87,12 +70,19 @@ static void received_unlock_msg(int msg_type, struct process_id src, Function to push a blocking lock request onto the lock queue. ****************************************************************************/ -BOOL push_blocking_lock_request( char *inbuf, int length, int lock_timeout, - int lock_num, uint16 lock_pid, SMB_BIG_UINT offset, SMB_BIG_UINT count) +BOOL push_blocking_lock_request( char *inbuf, int length, + files_struct *fsp, + int lock_timeout, + int lock_num, + uint16 lock_pid, + enum brl_type lock_type, + enum brl_flavour lock_flav, + SMB_BIG_UINT offset, SMB_BIG_UINT count) { static BOOL set_lock_msg; blocking_lock_record *blr, *tmp; BOOL my_lock_ctx = False; + struct byte_range_lock *br_lck = NULL; NTSTATUS status; if(in_chained_smb() ) { @@ -110,6 +100,9 @@ BOOL push_blocking_lock_request( char *inbuf, int length, int lock_timeout, return False; } + blr->next = NULL; + blr->prev = NULL; + if((blr->inbuf = (char *)SMB_MALLOC(length)) == NULL) { DEBUG(0,("push_blocking_lock_request: Malloc fail (2)!\n" )); SAFE_FREE(blr); @@ -117,19 +110,33 @@ BOOL push_blocking_lock_request( char *inbuf, int length, int lock_timeout, } blr->com_type = CVAL(inbuf,smb_com); - blr->fsp = get_fsp_from_pkt(inbuf); + blr->fsp = fsp; blr->expire_time = (lock_timeout == -1) ? (time_t)-1 : time(NULL) + (time_t)lock_timeout; blr->lock_num = lock_num; blr->lock_pid = lock_pid; + blr->lock_flav = lock_flav; + blr->lock_type = lock_type; blr->offset = offset; blr->count = count; memcpy(blr->inbuf, inbuf, length); blr->length = length; + br_lck = brl_get_locks(NULL, blr->fsp); + if (!br_lck) { + free_blocking_lock_record(blr); + return False; + } + /* Add a pending lock record for this. */ - status = brl_lock(blr->fsp->dev, blr->fsp->inode, blr->fsp->fnum, - lock_pid, procid_self(), blr->fsp->conn->cnum, - offset, count, PENDING_LOCK, &my_lock_ctx); + status = brl_lock(br_lck, + lock_pid, + procid_self(), + offset, + count, + PENDING_LOCK, + blr->lock_flav, + &my_lock_ctx); + TALLOC_FREE(br_lck); if (!NT_STATUS_IS_OK(status)) { DEBUG(0,("push_blocking_lock_request: failed to add PENDING_LOCK record.\n")); @@ -227,7 +234,6 @@ static void reply_lockingX_error(blocking_lock_record *blr, NTSTATUS status) { char *inbuf = blr->inbuf; files_struct *fsp = blr->fsp; - connection_struct *conn = conn_find(SVAL(inbuf,smb_tid)); uint16 num_ulocks = SVAL(inbuf,smb_vwv6); SMB_BIG_UINT count = (SMB_BIG_UINT)0, offset = (SMB_BIG_UINT) 0; uint16 lock_pid; @@ -261,7 +267,11 @@ static void reply_lockingX_error(blocking_lock_record *blr, NTSTATUS status) * request would never have been queued. JRA. */ - do_unlock(fsp,conn,lock_pid,count,offset); + do_unlock(fsp, + lock_pid, + count, + offset, + WINDOWS_LOCK); } generic_blocking_lock_error(blr, status); @@ -274,19 +284,41 @@ static void reply_lockingX_error(blocking_lock_record *blr, NTSTATUS status) static void blocking_lock_reply_error(blocking_lock_record *blr, NTSTATUS status) { switch(blr->com_type) { +#if 0 + /* We no longer push blocking lock requests for anything but lockingX and trans2. */ case SMBlock: case SMBlockread: generic_blocking_lock_error(blr, status); break; +#endif case SMBlockingX: reply_lockingX_error(blr, status); break; + case SMBtrans2: + case SMBtranss2: + { + char *outbuf = get_OutBuffer(); + 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); + if (!send_smb(smbd_server_fd(),outbuf)) { + exit_server("blocking_lock_reply_error: send_smb failed."); + } + break; + } 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"); } } +#if 0 +/* We no longer push blocking lock requests for anything but lockingX and trans2. */ + /**************************************************************************** Attempt to finish off getting all pending blocking locks for a lockread call. Returns True if we want to be removed from the list. @@ -302,7 +334,6 @@ static BOOL process_lockread(blocking_lock_record *blr) SMB_BIG_UINT startpos; size_t numtoread; NTSTATUS status; - connection_struct *conn = conn_find(SVAL(inbuf,smb_tid)); files_struct *fsp = blr->fsp; BOOL my_lock_ctx = False; @@ -312,7 +343,14 @@ static BOOL process_lockread(blocking_lock_record *blr) numtoread = MIN(BUFFER_SIZE-outsize,numtoread); data = smb_buf(outbuf) + 3; - status = do_lock_spin( fsp, conn, SVAL(inbuf,smb_pid), (SMB_BIG_UINT)numtoread, startpos, READ_LOCK, &my_lock_ctx); + status = do_lock_spin(fsp, + SVAL(inbuf,smb_pid), + (SMB_BIG_UINT)numtoread, + startpos, + READ_LOCK, + WINDOWS_LOCK, + &my_lock_ctx); + if (NT_STATUS_V(status)) { if (!NT_STATUS_EQUAL(status,NT_STATUS_LOCK_NOT_GRANTED) && !NT_STATUS_EQUAL(status,NT_STATUS_FILE_LOCK_CONFLICT)) { @@ -371,7 +409,6 @@ static BOOL process_lock(blocking_lock_record *blr) int outsize; SMB_BIG_UINT count = (SMB_BIG_UINT)0, offset = (SMB_BIG_UINT)0; NTSTATUS status; - connection_struct *conn = conn_find(SVAL(inbuf,smb_tid)); files_struct *fsp = blr->fsp; BOOL my_lock_ctx = False; @@ -379,7 +416,14 @@ static BOOL process_lock(blocking_lock_record *blr) offset = IVAL_TO_SMB_OFF_T(inbuf,smb_vwv3); errno = 0; - status = do_lock_spin(fsp, conn, SVAL(inbuf,smb_pid), count, offset, WRITE_LOCK, &my_lock_ctx); + status = do_lock_spin(fsp, + SVAL(inbuf,smb_pid), + count, + offset, + WRITE_LOCK, + WINDOWS_LOCK, + &my_lock_ctx); + if (NT_STATUS_IS_ERR(status)) { if (!NT_STATUS_EQUAL(status,NT_STATUS_LOCK_NOT_GRANTED) && !NT_STATUS_EQUAL(status,NT_STATUS_FILE_LOCK_CONFLICT)) { @@ -412,6 +456,7 @@ static BOOL process_lock(blocking_lock_record *blr) send_blocking_reply(outbuf,outsize); return True; } +#endif /**************************************************************************** Attempt to finish off getting all pending blocking locks for a lockingX call. @@ -423,7 +468,6 @@ static BOOL process_lockingX(blocking_lock_record *blr) char *inbuf = blr->inbuf; unsigned char locktype = CVAL(inbuf,smb_vwv3); files_struct *fsp = blr->fsp; - connection_struct *conn = conn_find(SVAL(inbuf,smb_tid)); uint16 num_ulocks = SVAL(inbuf,smb_vwv6); uint16 num_locks = SVAL(inbuf,smb_vwv7); SMB_BIG_UINT count = (SMB_BIG_UINT)0, offset = (SMB_BIG_UINT)0; @@ -452,9 +496,17 @@ static BOOL process_lockingX(blocking_lock_record *blr) * request would never have been queued. JRA. */ errno = 0; - status = do_lock_spin(fsp,conn,lock_pid,count,offset, - ((locktype & 1) ? READ_LOCK : WRITE_LOCK), &my_lock_ctx); - if (NT_STATUS_IS_ERR(status)) break; + status = do_lock_spin(fsp, + lock_pid, + count, + offset, + ((locktype & 1) ? READ_LOCK : WRITE_LOCK), + WINDOWS_LOCK, + &my_lock_ctx); + + if (NT_STATUS_IS_ERR(status)) { + break; + } } if(blr->lock_num == num_locks) { @@ -490,6 +542,51 @@ Waiting....\n", return False; } +/**************************************************************************** + Attempt to get the posix lock request from a SMBtrans2 call. + Returns True if we want to be removed from the list. +*****************************************************************************/ + +static BOOL process_trans2(blocking_lock_record *blr) +{ + extern int max_send; + char *inbuf = blr->inbuf; + char *outbuf; + BOOL my_lock_ctx = False; + char params[2]; + NTSTATUS status; + + status = do_lock(blr->fsp, + blr->lock_pid, + blr->count, + blr->offset, + blr->lock_type, + blr->lock_flav, + &my_lock_ctx); + + 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. */ + outbuf = get_OutBuffer(); + construct_reply_common(inbuf, outbuf); + SCVAL(outbuf,smb_com,SMBtrans2); + SSVAL(params,0,0); + send_trans2_replies(outbuf, max_send, params, 2, NULL, 0); + return True; +} + + /**************************************************************************** Process a blocking lock SMB. Returns True if we want to be removed from the list. @@ -498,12 +595,18 @@ Waiting....\n", static BOOL blocking_lock_record_process(blocking_lock_record *blr) { switch(blr->com_type) { +#if 0 + /* We no longer push blocking lock requests for anything but lockingX and trans2. */ case SMBlock: return process_lock(blr); case SMBlockread: return process_lockread(blr); +#endif case SMBlockingX: return process_lockingX(blr); + case SMBtrans2: + case SMBtranss2: + return process_trans2(blr); 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"); @@ -522,13 +625,21 @@ void remove_pending_lock_requests_by_fid(files_struct *fsp) for(blr = blocking_lock_queue; blr; blr = next) { next = blr->next; if(blr->fsp->fnum == fsp->fnum) { + struct byte_range_lock *br_lck = brl_get_locks(NULL, fsp); - DEBUG(10,("remove_pending_lock_requests_by_fid - removing request type %d for \ + 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 )); - brl_unlock(blr->fsp->dev, blr->fsp->inode, blr->fsp->fnum, - blr->lock_pid, procid_self(), blr->fsp->conn->cnum, - blr->offset, blr->count, True, NULL, NULL); + brl_remove_pending_lock(br_lck, + blr->lock_pid, + procid_self(), + blr->offset, + blr->count, + blr->lock_flav); + TALLOC_FREE(br_lck); + + } free_blocking_lock_record(blr); } @@ -547,14 +658,22 @@ void remove_pending_lock_requests_by_mid(int mid) next = blr->next; if(SVAL(blr->inbuf,smb_mid) == mid) { files_struct *fsp = blr->fsp; + struct byte_range_lock *br_lck = brl_get_locks(NULL, fsp); - DEBUG(10,("remove_pending_lock_requests_by_mid - removing request type %d for \ + 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_remove_pending_lock(br_lck, + blr->lock_pid, + procid_self(), + blr->offset, + blr->count, + blr->lock_flav); + TALLOC_FREE(br_lck); + } + blocking_lock_reply_error(blr,NT_STATUS_FILE_LOCK_CONFLICT); - brl_unlock(blr->fsp->dev, blr->fsp->inode, blr->fsp->fnum, - blr->lock_pid, procid_self(), blr->fsp->conn->cnum, - blr->offset, blr->count, True, NULL, NULL); free_blocking_lock_record(blr); } } @@ -635,16 +754,25 @@ void process_blocking_lock_queue(time_t t) fsp->fnum, fsp->fsp_name )); if((blr->expire_time != -1) && (blr->expire_time <= t)) { + struct byte_range_lock *br_lck = brl_get_locks(NULL, fsp); + /* * Lock expired - throw away all previously * obtained locks and return lock error. */ - DEBUG(5,("process_blocking_lock_queue: pending lock fnum = %d for file %s timed out.\n", - fsp->fnum, fsp->fsp_name )); - brl_unlock(fsp->dev, fsp->inode, fsp->fnum, - blr->lock_pid, procid_self(), conn->cnum, - blr->offset, blr->count, True, NULL, NULL); + if (br_lck) { + DEBUG(5,("process_blocking_lock_queue: pending lock fnum = %d for file %s timed out.\n", + fsp->fnum, fsp->fsp_name )); + + brl_remove_pending_lock(br_lck, + blr->lock_pid, + procid_self(), + blr->offset, + blr->count, + blr->lock_flav); + TALLOC_FREE(br_lck); + } blocking_lock_reply_error(blr,NT_STATUS_FILE_LOCK_CONFLICT); free_blocking_lock_record(blr); @@ -652,32 +780,48 @@ void process_blocking_lock_queue(time_t t) } if(!change_to_user(conn,vuid)) { - DEBUG(0,("process_blocking_lock_queue: Unable to become user vuid=%d.\n", - vuid )); + struct byte_range_lock *br_lck = brl_get_locks(NULL, fsp); + /* * Remove the entry and return an error to the client. */ - blocking_lock_reply_error(blr,NT_STATUS_ACCESS_DENIED); - brl_unlock(fsp->dev, fsp->inode, fsp->fnum, - blr->lock_pid, procid_self(), conn->cnum, - blr->offset, blr->count, True, NULL, NULL); + if (br_lck) { + brl_remove_pending_lock(br_lck, + blr->lock_pid, + procid_self(), + blr->offset, + blr->count, + blr->lock_flav); + TALLOC_FREE(br_lck); + } + DEBUG(0,("process_blocking_lock_queue: Unable to become user vuid=%d.\n", + vuid )); + blocking_lock_reply_error(blr,NT_STATUS_ACCESS_DENIED); free_blocking_lock_record(blr); continue; } if(!set_current_service(conn,SVAL(blr->inbuf,smb_flg),True)) { - DEBUG(0,("process_blocking_lock_queue: Unable to become service Error was %s.\n", strerror(errno) )); + struct byte_range_lock *br_lck = brl_get_locks(NULL, fsp); + /* * Remove the entry and return an error to the client. */ - blocking_lock_reply_error(blr,NT_STATUS_ACCESS_DENIED); - brl_unlock(fsp->dev, fsp->inode, fsp->fnum, - blr->lock_pid, procid_self(), conn->cnum, - blr->offset, blr->count, True, NULL, NULL); + if (br_lck) { + brl_remove_pending_lock(br_lck, + blr->lock_pid, + procid_self(), + blr->offset, + blr->count, + blr->lock_flav); + TALLOC_FREE(br_lck); + } + DEBUG(0,("process_blocking_lock_queue: Unable to become service Error was %s.\n", strerror(errno) )); + blocking_lock_reply_error(blr,NT_STATUS_ACCESS_DENIED); free_blocking_lock_record(blr); change_to_root_user(); continue; @@ -690,10 +834,17 @@ void process_blocking_lock_queue(time_t t) */ if(blocking_lock_record_process(blr)) { - - brl_unlock(fsp->dev, fsp->inode, fsp->fnum, - blr->lock_pid, procid_self(), conn->cnum, - blr->offset, blr->count, True, NULL, NULL); + struct byte_range_lock *br_lck = brl_get_locks(NULL, fsp); + + if (br_lck) { + brl_remove_pending_lock(br_lck, + blr->lock_pid, + procid_self(), + blr->offset, + blr->count, + blr->lock_flav); + TALLOC_FREE(br_lck); + } free_blocking_lock_record(blr); } -- cgit From 713eaf1d67d9ef967fb4526113e2a3ba3dd5e229 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 13 Apr 2006 22:22:54 +0000 Subject: r15083: Using talloc with destructors is nice and all, but in this case it's in a performace critical path and it *hurts* us. Go back to plain malloc/free with an explicit destructor call. Jeremy. (This used to be commit 1c99aed563c29e1b3d70939878af747a0660bfec) --- source3/smbd/blocking.c | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) (limited to 'source3/smbd/blocking.c') diff --git a/source3/smbd/blocking.c b/source3/smbd/blocking.c index 6b47d0466b..a8db498ef5 100644 --- a/source3/smbd/blocking.c +++ b/source3/smbd/blocking.c @@ -121,7 +121,7 @@ BOOL push_blocking_lock_request( char *inbuf, int length, memcpy(blr->inbuf, inbuf, length); blr->length = length; - br_lck = brl_get_locks(NULL, blr->fsp); + br_lck = brl_get_locks(blr->fsp); if (!br_lck) { free_blocking_lock_record(blr); return False; @@ -136,7 +136,7 @@ BOOL push_blocking_lock_request( char *inbuf, int length, PENDING_LOCK, blr->lock_flav, &my_lock_ctx); - TALLOC_FREE(br_lck); + byte_range_lock_destructor(br_lck); if (!NT_STATUS_IS_OK(status)) { DEBUG(0,("push_blocking_lock_request: failed to add PENDING_LOCK record.\n")); @@ -625,7 +625,7 @@ void remove_pending_lock_requests_by_fid(files_struct *fsp) for(blr = blocking_lock_queue; blr; blr = next) { next = blr->next; if(blr->fsp->fnum == fsp->fnum) { - struct byte_range_lock *br_lck = brl_get_locks(NULL, fsp); + struct byte_range_lock *br_lck = brl_get_locks(fsp); if (br_lck) { DEBUG(10,("remove_pending_lock_requests_by_fid - removing request type %d for \ @@ -637,7 +637,7 @@ file %s fnum = %d\n", blr->com_type, fsp->fsp_name, fsp->fnum )); blr->offset, blr->count, blr->lock_flav); - TALLOC_FREE(br_lck); + byte_range_lock_destructor(br_lck); } @@ -658,7 +658,7 @@ void remove_pending_lock_requests_by_mid(int mid) next = blr->next; if(SVAL(blr->inbuf,smb_mid) == mid) { files_struct *fsp = blr->fsp; - struct byte_range_lock *br_lck = brl_get_locks(NULL, fsp); + struct byte_range_lock *br_lck = brl_get_locks(fsp); if (br_lck) { DEBUG(10,("remove_pending_lock_requests_by_mid - removing request type %d for \ @@ -670,7 +670,7 @@ file %s fnum = %d\n", blr->com_type, fsp->fsp_name, fsp->fnum )); blr->offset, blr->count, blr->lock_flav); - TALLOC_FREE(br_lck); + byte_range_lock_destructor(br_lck); } blocking_lock_reply_error(blr,NT_STATUS_FILE_LOCK_CONFLICT); @@ -754,7 +754,7 @@ void process_blocking_lock_queue(time_t t) fsp->fnum, fsp->fsp_name )); if((blr->expire_time != -1) && (blr->expire_time <= t)) { - struct byte_range_lock *br_lck = brl_get_locks(NULL, fsp); + struct byte_range_lock *br_lck = brl_get_locks(fsp); /* * Lock expired - throw away all previously @@ -771,7 +771,7 @@ void process_blocking_lock_queue(time_t t) blr->offset, blr->count, blr->lock_flav); - TALLOC_FREE(br_lck); + byte_range_lock_destructor(br_lck); } blocking_lock_reply_error(blr,NT_STATUS_FILE_LOCK_CONFLICT); @@ -780,7 +780,7 @@ void process_blocking_lock_queue(time_t t) } if(!change_to_user(conn,vuid)) { - struct byte_range_lock *br_lck = brl_get_locks(NULL, fsp); + struct byte_range_lock *br_lck = brl_get_locks(fsp); /* * Remove the entry and return an error to the client. @@ -793,7 +793,7 @@ void process_blocking_lock_queue(time_t t) blr->offset, blr->count, blr->lock_flav); - TALLOC_FREE(br_lck); + byte_range_lock_destructor(br_lck); } DEBUG(0,("process_blocking_lock_queue: Unable to become user vuid=%d.\n", @@ -804,7 +804,7 @@ void process_blocking_lock_queue(time_t t) } if(!set_current_service(conn,SVAL(blr->inbuf,smb_flg),True)) { - struct byte_range_lock *br_lck = brl_get_locks(NULL, fsp); + struct byte_range_lock *br_lck = brl_get_locks(fsp); /* * Remove the entry and return an error to the client. @@ -817,7 +817,7 @@ void process_blocking_lock_queue(time_t t) blr->offset, blr->count, blr->lock_flav); - TALLOC_FREE(br_lck); + byte_range_lock_destructor(br_lck); } DEBUG(0,("process_blocking_lock_queue: Unable to become service Error was %s.\n", strerror(errno) )); @@ -834,7 +834,7 @@ void process_blocking_lock_queue(time_t t) */ if(blocking_lock_record_process(blr)) { - struct byte_range_lock *br_lck = brl_get_locks(NULL, fsp); + struct byte_range_lock *br_lck = brl_get_locks(fsp); if (br_lck) { brl_remove_pending_lock(br_lck, @@ -843,7 +843,7 @@ void process_blocking_lock_queue(time_t t) blr->offset, blr->count, blr->lock_flav); - TALLOC_FREE(br_lck); + byte_range_lock_destructor(br_lck); } free_blocking_lock_record(blr); -- cgit From fbdcf2663b56007a438ac4f0d8d82436b1bfe688 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 11 Jul 2006 18:01:26 +0000 Subject: r16945: Sync trunk -> 3.0 for 3.0.24 code. Still need to do the upper layer directories but this is what everyone is waiting for.... Jeremy. (This used to be commit 9dafb7f48ca3e7af956b0a7d1720c2546fc4cfb8) --- source3/smbd/blocking.c | 40 ++++++++++++++++++++-------------------- 1 file changed, 20 insertions(+), 20 deletions(-) (limited to 'source3/smbd/blocking.c') diff --git a/source3/smbd/blocking.c b/source3/smbd/blocking.c index a8db498ef5..04ab01eb66 100644 --- a/source3/smbd/blocking.c +++ b/source3/smbd/blocking.c @@ -34,7 +34,7 @@ typedef struct _blocking_lock_record { int lock_num; SMB_BIG_UINT offset; SMB_BIG_UINT count; - uint16 lock_pid; + uint32 lock_pid; enum brl_flavour lock_flav; enum brl_type lock_type; char *inbuf; @@ -74,7 +74,7 @@ BOOL push_blocking_lock_request( char *inbuf, int length, files_struct *fsp, int lock_timeout, int lock_num, - uint16 lock_pid, + uint32 lock_pid, enum brl_type lock_type, enum brl_flavour lock_flav, SMB_BIG_UINT offset, SMB_BIG_UINT count) @@ -121,7 +121,7 @@ BOOL push_blocking_lock_request( char *inbuf, int length, memcpy(blr->inbuf, inbuf, length); blr->length = length; - br_lck = brl_get_locks(blr->fsp); + br_lck = brl_get_locks(NULL, blr->fsp); if (!br_lck) { free_blocking_lock_record(blr); return False; @@ -136,7 +136,7 @@ BOOL push_blocking_lock_request( char *inbuf, int length, PENDING_LOCK, blr->lock_flav, &my_lock_ctx); - byte_range_lock_destructor(br_lck); + TALLOC_FREE(br_lck); if (!NT_STATUS_IS_OK(status)) { DEBUG(0,("push_blocking_lock_request: failed to add PENDING_LOCK record.\n")); @@ -236,7 +236,7 @@ static void reply_lockingX_error(blocking_lock_record *blr, NTSTATUS status) files_struct *fsp = blr->fsp; uint16 num_ulocks = SVAL(inbuf,smb_vwv6); SMB_BIG_UINT count = (SMB_BIG_UINT)0, offset = (SMB_BIG_UINT) 0; - uint16 lock_pid; + uint32 lock_pid; unsigned char locktype = CVAL(inbuf,smb_vwv3); BOOL large_file_format = (locktype & LOCKING_ANDX_LARGE_FILES); char *data; @@ -344,7 +344,7 @@ static BOOL process_lockread(blocking_lock_record *blr) data = smb_buf(outbuf) + 3; status = do_lock_spin(fsp, - SVAL(inbuf,smb_pid), + (uint32)SVAL(inbuf,smb_pid), (SMB_BIG_UINT)numtoread, startpos, READ_LOCK, @@ -417,7 +417,7 @@ static BOOL process_lock(blocking_lock_record *blr) errno = 0; status = do_lock_spin(fsp, - SVAL(inbuf,smb_pid), + (uint32)SVAL(inbuf,smb_pid), count, offset, WRITE_LOCK, @@ -471,7 +471,7 @@ static BOOL process_lockingX(blocking_lock_record *blr) uint16 num_ulocks = SVAL(inbuf,smb_vwv6); uint16 num_locks = SVAL(inbuf,smb_vwv7); SMB_BIG_UINT count = (SMB_BIG_UINT)0, offset = (SMB_BIG_UINT)0; - uint16 lock_pid; + uint32 lock_pid; BOOL large_file_format = (locktype & LOCKING_ANDX_LARGE_FILES); char *data; BOOL my_lock_ctx = False; @@ -625,7 +625,7 @@ void remove_pending_lock_requests_by_fid(files_struct *fsp) for(blr = blocking_lock_queue; blr; blr = next) { next = blr->next; if(blr->fsp->fnum == fsp->fnum) { - struct byte_range_lock *br_lck = brl_get_locks(fsp); + struct byte_range_lock *br_lck = brl_get_locks(NULL, fsp); if (br_lck) { DEBUG(10,("remove_pending_lock_requests_by_fid - removing request type %d for \ @@ -637,7 +637,7 @@ file %s fnum = %d\n", blr->com_type, fsp->fsp_name, fsp->fnum )); blr->offset, blr->count, blr->lock_flav); - byte_range_lock_destructor(br_lck); + TALLOC_FREE(br_lck); } @@ -658,7 +658,7 @@ void remove_pending_lock_requests_by_mid(int mid) next = blr->next; if(SVAL(blr->inbuf,smb_mid) == mid) { files_struct *fsp = blr->fsp; - struct byte_range_lock *br_lck = brl_get_locks(fsp); + struct byte_range_lock *br_lck = brl_get_locks(NULL, fsp); if (br_lck) { DEBUG(10,("remove_pending_lock_requests_by_mid - removing request type %d for \ @@ -670,7 +670,7 @@ file %s fnum = %d\n", blr->com_type, fsp->fsp_name, fsp->fnum )); blr->offset, blr->count, blr->lock_flav); - byte_range_lock_destructor(br_lck); + TALLOC_FREE(br_lck); } blocking_lock_reply_error(blr,NT_STATUS_FILE_LOCK_CONFLICT); @@ -754,7 +754,7 @@ void process_blocking_lock_queue(time_t t) fsp->fnum, fsp->fsp_name )); if((blr->expire_time != -1) && (blr->expire_time <= t)) { - struct byte_range_lock *br_lck = brl_get_locks(fsp); + struct byte_range_lock *br_lck = brl_get_locks(NULL, fsp); /* * Lock expired - throw away all previously @@ -771,7 +771,7 @@ void process_blocking_lock_queue(time_t t) blr->offset, blr->count, blr->lock_flav); - byte_range_lock_destructor(br_lck); + TALLOC_FREE(br_lck); } blocking_lock_reply_error(blr,NT_STATUS_FILE_LOCK_CONFLICT); @@ -780,7 +780,7 @@ void process_blocking_lock_queue(time_t t) } if(!change_to_user(conn,vuid)) { - struct byte_range_lock *br_lck = brl_get_locks(fsp); + struct byte_range_lock *br_lck = brl_get_locks(NULL, fsp); /* * Remove the entry and return an error to the client. @@ -793,7 +793,7 @@ void process_blocking_lock_queue(time_t t) blr->offset, blr->count, blr->lock_flav); - byte_range_lock_destructor(br_lck); + TALLOC_FREE(br_lck); } DEBUG(0,("process_blocking_lock_queue: Unable to become user vuid=%d.\n", @@ -804,7 +804,7 @@ void process_blocking_lock_queue(time_t t) } if(!set_current_service(conn,SVAL(blr->inbuf,smb_flg),True)) { - struct byte_range_lock *br_lck = brl_get_locks(fsp); + struct byte_range_lock *br_lck = brl_get_locks(NULL, fsp); /* * Remove the entry and return an error to the client. @@ -817,7 +817,7 @@ void process_blocking_lock_queue(time_t t) blr->offset, blr->count, blr->lock_flav); - byte_range_lock_destructor(br_lck); + TALLOC_FREE(br_lck); } DEBUG(0,("process_blocking_lock_queue: Unable to become service Error was %s.\n", strerror(errno) )); @@ -834,7 +834,7 @@ void process_blocking_lock_queue(time_t t) */ if(blocking_lock_record_process(blr)) { - struct byte_range_lock *br_lck = brl_get_locks(fsp); + struct byte_range_lock *br_lck = brl_get_locks(NULL, fsp); if (br_lck) { brl_remove_pending_lock(br_lck, @@ -843,7 +843,7 @@ void process_blocking_lock_queue(time_t t) blr->offset, blr->count, blr->lock_flav); - byte_range_lock_destructor(br_lck); + TALLOC_FREE(br_lck); } free_blocking_lock_record(blr); -- cgit From e1da1fcf12164f50f3462c90f0bb785d18c59b0b Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Mon, 17 Jul 2006 21:09:02 +0000 Subject: r17098: Samba3 now cleanly passes Samba4 RAW-LOCK torture test. Phew - that was painful :-). But what it means is that we now implement lock cancels and I can add lock cancels into POSIX lock handling which will fix the fast/slow system call issue with cifsfs ! Jeremy. (This used to be commit f1a9cf075b87c76c032d19da0168424c90f6cb3c) --- source3/smbd/blocking.c | 204 +++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 166 insertions(+), 38 deletions(-) (limited to 'source3/smbd/blocking.c') diff --git a/source3/smbd/blocking.c b/source3/smbd/blocking.c index 04ab01eb66..941e87d3ad 100644 --- a/source3/smbd/blocking.c +++ b/source3/smbd/blocking.c @@ -19,6 +19,8 @@ */ #include "includes.h" +#undef DBGC_CLASS +#define DBGC_CLASS DBGC_LOCKING /**************************************************************************** This is the structure to queue to implement blocking locks. @@ -41,15 +43,18 @@ typedef struct _blocking_lock_record { int length; } blocking_lock_record; +/* dlink list we store pending lock records on. */ static blocking_lock_record *blocking_lock_queue; +/* dlink list we move cancelled lock records onto. */ +static blocking_lock_record *blocking_lock_cancelled_queue; + /**************************************************************************** Destructor for the above structure. ****************************************************************************/ static void free_blocking_lock_record(blocking_lock_record *blr) { - DLIST_REMOVE(blocking_lock_queue, blr); SAFE_FREE(blr->inbuf); SAFE_FREE(blr); } @@ -81,7 +86,6 @@ BOOL push_blocking_lock_request( char *inbuf, int length, { static BOOL set_lock_msg; blocking_lock_record *blr, *tmp; - BOOL my_lock_ctx = False; struct byte_range_lock *br_lck = NULL; NTSTATUS status; @@ -123,6 +127,7 @@ BOOL push_blocking_lock_request( char *inbuf, int length, br_lck = brl_get_locks(NULL, blr->fsp); if (!br_lck) { + DLIST_REMOVE(blocking_lock_queue, blr); free_blocking_lock_record(blr); return False; } @@ -135,11 +140,12 @@ BOOL push_blocking_lock_request( char *inbuf, int length, count, PENDING_LOCK, blr->lock_flav, - &my_lock_ctx); + lock_timeout); TALLOC_FREE(br_lck); if (!NT_STATUS_IS_OK(status)) { DEBUG(0,("push_blocking_lock_request: failed to add PENDING_LOCK record.\n")); + DLIST_REMOVE(blocking_lock_queue, blr); free_blocking_lock_record(blr); return False; } @@ -220,9 +226,24 @@ static void generic_blocking_lock_error(blocking_lock_record *blr, NTSTATUS stat status = NT_STATUS_FILE_LOCK_CONFLICT; } + if (NT_STATUS_EQUAL(status, NT_STATUS_FILE_LOCK_CONFLICT)) { + /* Store the last lock error. */ + files_struct *fsp = blr->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; + } + ERROR_NT(status); - if (!send_smb(smbd_server_fd(),outbuf)) + if (!send_smb(smbd_server_fd(),outbuf)) { exit_server("generic_blocking_lock_error: send_smb failed."); + } } /**************************************************************************** @@ -335,7 +356,6 @@ static BOOL process_lockread(blocking_lock_record *blr) size_t numtoread; NTSTATUS status; files_struct *fsp = blr->fsp; - BOOL my_lock_ctx = False; numtoread = SVAL(inbuf,smb_vwv1); startpos = (SMB_BIG_UINT)IVAL(inbuf,smb_vwv2); @@ -343,13 +363,13 @@ static BOOL process_lockread(blocking_lock_record *blr) numtoread = MIN(BUFFER_SIZE-outsize,numtoread); data = smb_buf(outbuf) + 3; - status = do_lock_spin(fsp, - (uint32)SVAL(inbuf,smb_pid), - (SMB_BIG_UINT)numtoread, - startpos, - READ_LOCK, - WINDOWS_LOCK, - &my_lock_ctx); + status = do_lock(fsp, + (uint32)SVAL(inbuf,smb_pid), + (SMB_BIG_UINT)numtoread, + startpos, + READ_LOCK, + WINDOWS_LOCK, + (int32)-1); if (NT_STATUS_V(status)) { if (!NT_STATUS_EQUAL(status,NT_STATUS_LOCK_NOT_GRANTED) && @@ -410,19 +430,18 @@ static BOOL process_lock(blocking_lock_record *blr) SMB_BIG_UINT count = (SMB_BIG_UINT)0, offset = (SMB_BIG_UINT)0; NTSTATUS status; files_struct *fsp = blr->fsp; - BOOL my_lock_ctx = False; count = IVAL_TO_SMB_OFF_T(inbuf,smb_vwv1); offset = IVAL_TO_SMB_OFF_T(inbuf,smb_vwv3); errno = 0; - status = do_lock_spin(fsp, - (uint32)SVAL(inbuf,smb_pid), - count, - offset, - WRITE_LOCK, - WINDOWS_LOCK, - &my_lock_ctx); + status = do_lock(fsp, + (uint32)SVAL(inbuf,smb_pid), + count, + offset, + WRITE_LOCK, + WINDOWS_LOCK, + (int32)-1); if (NT_STATUS_IS_ERR(status)) { if (!NT_STATUS_EQUAL(status,NT_STATUS_LOCK_NOT_GRANTED) && @@ -474,7 +493,6 @@ static BOOL process_lockingX(blocking_lock_record *blr) uint32 lock_pid; BOOL large_file_format = (locktype & LOCKING_ANDX_LARGE_FILES); char *data; - BOOL my_lock_ctx = False; NTSTATUS status = NT_STATUS_OK; data = smb_buf(inbuf) + ((large_file_format ? 20 : 10)*num_ulocks); @@ -496,13 +514,14 @@ static BOOL process_lockingX(blocking_lock_record *blr) * request would never have been queued. JRA. */ errno = 0; - status = do_lock_spin(fsp, + status = do_lock(fsp, lock_pid, count, offset, - ((locktype & 1) ? READ_LOCK : WRITE_LOCK), + ((locktype & LOCKING_ANDX_SHARED_LOCK) ? + READ_LOCK : WRITE_LOCK), WINDOWS_LOCK, - &my_lock_ctx); + (int32)-1); if (NT_STATUS_IS_ERR(status)) { break; @@ -552,7 +571,6 @@ static BOOL process_trans2(blocking_lock_record *blr) extern int max_send; char *inbuf = blr->inbuf; char *outbuf; - BOOL my_lock_ctx = False; char params[2]; NTSTATUS status; @@ -562,7 +580,7 @@ static BOOL process_trans2(blocking_lock_record *blr) blr->offset, blr->lock_type, blr->lock_flav, - &my_lock_ctx); + (int32)-1); if (!NT_STATUS_IS_OK(status)) { if (ERROR_WAS_LOCK_DENIED(status)) { @@ -615,33 +633,41 @@ static BOOL blocking_lock_record_process(blocking_lock_record *blr) } /**************************************************************************** - Delete entries by fnum from the blocking lock pending queue. + Cancel entries by fnum from the blocking lock pending queue. *****************************************************************************/ -void remove_pending_lock_requests_by_fid(files_struct *fsp) +void cancel_pending_lock_requests_by_fid(files_struct *fsp, struct byte_range_lock *br_lck) { blocking_lock_record *blr, *next = NULL; for(blr = blocking_lock_queue; blr; blr = next) { next = blr->next; if(blr->fsp->fnum == fsp->fnum) { - struct byte_range_lock *br_lck = brl_get_locks(NULL, fsp); + unsigned char locktype = 0; + + if (blr->com_type == SMBlockingX) { + locktype = CVAL(blr->inbuf,smb_vwv3); + } 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 )); - brl_remove_pending_lock(br_lck, + brl_lock_cancel(br_lck, blr->lock_pid, procid_self(), blr->offset, blr->count, blr->lock_flav); - TALLOC_FREE(br_lck); + blocking_lock_cancel(fsp, + blr->lock_pid, + blr->offset, + blr->count, + blr->lock_flav, + locktype, + NT_STATUS_RANGE_NOT_LOCKED); } - - free_blocking_lock_record(blr); } } } @@ -664,7 +690,7 @@ void remove_pending_lock_requests_by_mid(int mid) 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_remove_pending_lock(br_lck, + brl_lock_cancel(br_lck, blr->lock_pid, procid_self(), blr->offset, @@ -674,6 +700,7 @@ file %s fnum = %d\n", blr->com_type, fsp->fsp_name, fsp->fnum )); } blocking_lock_reply_error(blr,NT_STATUS_FILE_LOCK_CONFLICT); + DLIST_REMOVE(blocking_lock_queue, blr); free_blocking_lock_record(blr); } } @@ -765,7 +792,7 @@ void process_blocking_lock_queue(time_t t) DEBUG(5,("process_blocking_lock_queue: pending lock fnum = %d for file %s timed out.\n", fsp->fnum, fsp->fsp_name )); - brl_remove_pending_lock(br_lck, + brl_lock_cancel(br_lck, blr->lock_pid, procid_self(), blr->offset, @@ -775,6 +802,7 @@ void process_blocking_lock_queue(time_t t) } blocking_lock_reply_error(blr,NT_STATUS_FILE_LOCK_CONFLICT); + DLIST_REMOVE(blocking_lock_queue, blr); free_blocking_lock_record(blr); continue; } @@ -787,7 +815,7 @@ void process_blocking_lock_queue(time_t t) */ if (br_lck) { - brl_remove_pending_lock(br_lck, + brl_lock_cancel(br_lck, blr->lock_pid, procid_self(), blr->offset, @@ -799,6 +827,7 @@ void process_blocking_lock_queue(time_t t) DEBUG(0,("process_blocking_lock_queue: Unable to become user vuid=%d.\n", vuid )); blocking_lock_reply_error(blr,NT_STATUS_ACCESS_DENIED); + DLIST_REMOVE(blocking_lock_queue, blr); free_blocking_lock_record(blr); continue; } @@ -811,7 +840,7 @@ void process_blocking_lock_queue(time_t t) */ if (br_lck) { - brl_remove_pending_lock(br_lck, + brl_lock_cancel(br_lck, blr->lock_pid, procid_self(), blr->offset, @@ -822,6 +851,7 @@ void process_blocking_lock_queue(time_t t) DEBUG(0,("process_blocking_lock_queue: Unable to become service Error was %s.\n", strerror(errno) )); blocking_lock_reply_error(blr,NT_STATUS_ACCESS_DENIED); + DLIST_REMOVE(blocking_lock_queue, blr); free_blocking_lock_record(blr); change_to_root_user(); continue; @@ -837,7 +867,7 @@ void process_blocking_lock_queue(time_t t) struct byte_range_lock *br_lck = brl_get_locks(NULL, fsp); if (br_lck) { - brl_remove_pending_lock(br_lck, + brl_lock_cancel(br_lck, blr->lock_pid, procid_self(), blr->offset, @@ -846,8 +876,106 @@ void process_blocking_lock_queue(time_t t) TALLOC_FREE(br_lck); } + DLIST_REMOVE(blocking_lock_queue, blr); free_blocking_lock_record(blr); } change_to_root_user(); } } + +/**************************************************************************** + Handle a cancel message. Lock already moved onto the cancel queue. +*****************************************************************************/ + +#define MSG_BLOCKING_LOCK_CANCEL_SIZE (sizeof(blocking_lock_record *) + sizeof(NTSTATUS)) + +static void process_blocking_lock_cancel_message(int msg_type, struct process_id src, + void *buf, size_t len) +{ + NTSTATUS err; + const char *msg = (const char *)buf; + blocking_lock_record *blr; + + if (buf == NULL) { + smb_panic("process_blocking_lock_cancel_message: null msg\n"); + } + + if (len != MSG_BLOCKING_LOCK_CANCEL_SIZE) { + DEBUG(0, ("process_blocking_lock_cancel_message: " + "Got invalid msg len %d\n", (int)len)); + smb_panic("process_blocking_lock_cancel_message: bad msg\n"); + } + + 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); + free_blocking_lock_record(blr); +} + +/**************************************************************************** + Send ourselves a blocking lock cancelled message. Handled asynchronously above. +*****************************************************************************/ + +BOOL blocking_lock_cancel(files_struct *fsp, + uint32 lock_pid, + SMB_BIG_UINT offset, + SMB_BIG_UINT count, + enum brl_flavour lock_flav, + unsigned char locktype, + NTSTATUS err) +{ + static BOOL initialized; + char msg[MSG_BLOCKING_LOCK_CANCEL_SIZE]; + blocking_lock_record *blr; + + if (!initialized) { + /* Register our message. */ + message_register(MSG_SMB_BLOCKING_LOCK_CANCEL, + process_blocking_lock_cancel_message); + + 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)); + + /* Don't need to be root here as we're only ever + sending to ourselves. */ + + message_send_pid(pid_to_procid(sys_getpid()), + MSG_SMB_BLOCKING_LOCK_CANCEL, + &msg, sizeof(msg), True); + + return True; +} -- cgit From b737f26764cce935d9482335ece11c71a96720f4 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 18 Jul 2006 01:05:51 +0000 Subject: r17105: Fix the race Volker found - we had a non-locked region between detecting a pending lock was needed and when we added the blocking lock record. Make sure that we hold the lock over all this period. Removed the old code for doing blocking locks on SMB requests that never block (the old SMBlock and friends). Discovered something interesting about the strange NT_STATUS_FILE_LOCK_CONFLICT return. If we asked for a lock with zero timeout, and we got an error of NT_STATUS_FILE_LOCK_CONFLICT, treat it as though it was a blocking lock with a timeout of 150 - 300ms. This only happens when timeout is sent as zero and can be seen quite clearly in ethereal. This is the real replacement for old do_lock_spin() code. Re-worked the blocking lock select timeout to correctly use milliseconds instead of the old second level resolution (far too coarse for this work). Jeremy. (This used to be commit b81d6d1ae95a3d3e449dde629884b565eac289d9) --- source3/smbd/blocking.c | 261 ++++++++++++------------------------------------ 1 file changed, 64 insertions(+), 197 deletions(-) (limited to 'source3/smbd/blocking.c') diff --git a/source3/smbd/blocking.c b/source3/smbd/blocking.c index 941e87d3ad..a0b93f5032 100644 --- a/source3/smbd/blocking.c +++ b/source3/smbd/blocking.c @@ -32,7 +32,7 @@ typedef struct _blocking_lock_record { struct _blocking_lock_record *prev; int com_type; files_struct *fsp; - time_t expire_time; + struct timeval expire_time; int lock_num; SMB_BIG_UINT offset; SMB_BIG_UINT count; @@ -75,7 +75,8 @@ static void received_unlock_msg(int msg_type, struct process_id src, Function to push a blocking lock request onto the lock queue. ****************************************************************************/ -BOOL push_blocking_lock_request( char *inbuf, int length, +BOOL push_blocking_lock_request( struct byte_range_lock *br_lck, + char *inbuf, int length, files_struct *fsp, int lock_timeout, int lock_num, @@ -86,7 +87,6 @@ BOOL push_blocking_lock_request( char *inbuf, int length, { static BOOL set_lock_msg; blocking_lock_record *blr, *tmp; - struct byte_range_lock *br_lck = NULL; NTSTATUS status; if(in_chained_smb() ) { @@ -115,7 +115,13 @@ BOOL push_blocking_lock_request( char *inbuf, int length, blr->com_type = CVAL(inbuf,smb_com); blr->fsp = fsp; - blr->expire_time = (lock_timeout == -1) ? (time_t)-1 : time(NULL) + (time_t)lock_timeout; + 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); + } blr->lock_num = lock_num; blr->lock_pid = lock_pid; blr->lock_flav = lock_flav; @@ -125,13 +131,6 @@ BOOL push_blocking_lock_request( char *inbuf, int length, memcpy(blr->inbuf, inbuf, length); blr->length = length; - br_lck = brl_get_locks(NULL, blr->fsp); - if (!br_lck) { - DLIST_REMOVE(blocking_lock_queue, blr); - free_blocking_lock_record(blr); - return False; - } - /* Add a pending lock record for this. */ status = brl_lock(br_lck, lock_pid, @@ -140,8 +139,7 @@ BOOL push_blocking_lock_request( char *inbuf, int length, count, PENDING_LOCK, blr->lock_flav, - lock_timeout); - TALLOC_FREE(br_lck); + lock_timeout ? True : False); /* blocking_lock. */ if (!NT_STATUS_IS_OK(status)) { DEBUG(0,("push_blocking_lock_request: failed to add PENDING_LOCK record.\n")); @@ -158,8 +156,10 @@ BOOL push_blocking_lock_request( char *inbuf, int length, set_lock_msg = True; } - DEBUG(3,("push_blocking_lock_request: lock request length=%d blocked with expiry time %d (+%d) \ -for fnum = %d, name = %s\n", length, (int)blr->expire_time, lock_timeout, + DEBUG(3,("push_blocking_lock_request: lock request length=%d blocked with " + "expiry time (%u sec. %u usec) (+%d msec) for fnum = %d, name = %s\n", + length, (unsigned int)blr->expire_time.tv_sec, + (unsigned int)blr->expire_time.tv_usec, lock_timeout, blr->fsp->fnum, blr->fsp->fsp_name )); /* Push the MID of this packet on the signing queue. */ @@ -305,13 +305,6 @@ static void reply_lockingX_error(blocking_lock_record *blr, NTSTATUS status) static void blocking_lock_reply_error(blocking_lock_record *blr, NTSTATUS status) { switch(blr->com_type) { -#if 0 - /* We no longer push blocking lock requests for anything but lockingX and trans2. */ - case SMBlock: - case SMBlockread: - generic_blocking_lock_error(blr, status); - break; -#endif case SMBlockingX: reply_lockingX_error(blr, status); break; @@ -337,146 +330,6 @@ static void blocking_lock_reply_error(blocking_lock_record *blr, NTSTATUS status } } -#if 0 -/* We no longer push blocking lock requests for anything but lockingX and trans2. */ - -/**************************************************************************** - Attempt to finish off getting all pending blocking locks for a lockread call. - Returns True if we want to be removed from the list. -*****************************************************************************/ - -static BOOL process_lockread(blocking_lock_record *blr) -{ - char *outbuf = get_OutBuffer(); - char *inbuf = blr->inbuf; - ssize_t nread = -1; - char *data, *p; - int outsize = 0; - SMB_BIG_UINT startpos; - size_t numtoread; - NTSTATUS status; - files_struct *fsp = blr->fsp; - - numtoread = SVAL(inbuf,smb_vwv1); - startpos = (SMB_BIG_UINT)IVAL(inbuf,smb_vwv2); - - numtoread = MIN(BUFFER_SIZE-outsize,numtoread); - data = smb_buf(outbuf) + 3; - - status = do_lock(fsp, - (uint32)SVAL(inbuf,smb_pid), - (SMB_BIG_UINT)numtoread, - startpos, - READ_LOCK, - WINDOWS_LOCK, - (int32)-1); - - if (NT_STATUS_V(status)) { - 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. Send an error. - * Return True so we get dequeued. - */ - generic_blocking_lock_error(blr, status); - return True; - } - - /* - * Still waiting for lock.... - */ - - DEBUG(10,("process_lockread: failed to get lock for file = %s. Still waiting....\n", - fsp->fsp_name)); - return False; - } - - nread = read_file(fsp,data,startpos,numtoread); - - if (nread < 0) { - generic_blocking_lock_error(blr,NT_STATUS_ACCESS_DENIED); - return True; - } - - construct_reply_common(inbuf, outbuf); - outsize = set_message(outbuf,5,0,True); - - outsize += nread; - SSVAL(outbuf,smb_vwv0,nread); - SSVAL(outbuf,smb_vwv5,nread+3); - p = smb_buf(outbuf); - *p++ = 1; - SSVAL(p,0,nread); p += 2; - set_message_end(outbuf, p+nread); - - DEBUG(3, ( "process_lockread file = %s, fnum=%d num=%lu nread=%ld\n", - fsp->fsp_name, fsp->fnum, (unsigned long)numtoread, (long)nread ) ); - - send_blocking_reply(outbuf,outsize); - return True; -} - -/**************************************************************************** - Attempt to finish off getting all pending blocking locks for a lock call. - Returns True if we want to be removed from the list. -*****************************************************************************/ - -static BOOL process_lock(blocking_lock_record *blr) -{ - char *outbuf = get_OutBuffer(); - char *inbuf = blr->inbuf; - int outsize; - SMB_BIG_UINT count = (SMB_BIG_UINT)0, offset = (SMB_BIG_UINT)0; - NTSTATUS status; - files_struct *fsp = blr->fsp; - - count = IVAL_TO_SMB_OFF_T(inbuf,smb_vwv1); - offset = IVAL_TO_SMB_OFF_T(inbuf,smb_vwv3); - - errno = 0; - status = do_lock(fsp, - (uint32)SVAL(inbuf,smb_pid), - count, - offset, - WRITE_LOCK, - WINDOWS_LOCK, - (int32)-1); - - if (NT_STATUS_IS_ERR(status)) { - 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. Send an error. - * Return True so we get dequeued. - */ - - blocking_lock_reply_error(blr, status); - return True; - } - /* - * Still can't get the lock - keep waiting. - */ - DEBUG(10,("process_lock: failed to get lock for file = %s. Still waiting....\n", - fsp->fsp_name)); - return False; - } - - /* - * Success - we got the lock. - */ - - DEBUG(3,("process_lock : file=%s fnum=%d offset=%.0f count=%.0f\n", - fsp->fsp_name, fsp->fnum, (double)offset, (double)count)); - - construct_reply_common(inbuf, outbuf); - outsize = set_message(outbuf,0,0,True); - send_blocking_reply(outbuf,outsize); - return True; -} -#endif - /**************************************************************************** Attempt to finish off getting all pending blocking locks for a lockingX call. Returns True if we want to be removed from the list. @@ -501,8 +354,9 @@ static BOOL process_lockingX(blocking_lock_record *blr) * Data now points at the beginning of the list * of smb_lkrng structs. */ - + for(; blr->lock_num < num_locks; blr->lock_num++) { + struct byte_range_lock *br_lck = NULL; BOOL err; lock_pid = get_lock_pid( data, blr->lock_num, large_file_format); @@ -514,14 +368,17 @@ static BOOL process_lockingX(blocking_lock_record *blr) * request would never have been queued. JRA. */ errno = 0; - status = do_lock(fsp, + br_lck = do_lock(fsp, lock_pid, count, offset, ((locktype & LOCKING_ANDX_SHARED_LOCK) ? READ_LOCK : WRITE_LOCK), WINDOWS_LOCK, - (int32)-1); + True, + &status); + + TALLOC_FREE(br_lck); if (NT_STATUS_IS_ERR(status)) { break; @@ -573,14 +430,15 @@ static BOOL process_trans2(blocking_lock_record *blr) char *outbuf; char params[2]; NTSTATUS status; - - status = do_lock(blr->fsp, - blr->lock_pid, - blr->count, - blr->offset, - blr->lock_type, - blr->lock_flav, - (int32)-1); + struct byte_range_lock *br_lck = do_lock(blr->fsp, + blr->lock_pid, + blr->count, + blr->offset, + blr->lock_type, + blr->lock_flav, + True, + &status); + TALLOC_FREE(br_lck); if (!NT_STATUS_IS_OK(status)) { if (ERROR_WAS_LOCK_DENIED(status)) { @@ -613,13 +471,6 @@ static BOOL process_trans2(blocking_lock_record *blr) static BOOL blocking_lock_record_process(blocking_lock_record *blr) { switch(blr->com_type) { -#if 0 - /* We no longer push blocking lock requests for anything but lockingX and trans2. */ - case SMBlock: - return process_lock(blr); - case SMBlockread: - return process_lockread(blr); -#endif case SMBlockingX: return process_lockingX(blr); case SMBtrans2: @@ -714,44 +565,60 @@ static void received_unlock_msg(int msg_type, struct process_id src, void *buf, size_t len) { DEBUG(10,("received_unlock_msg\n")); - process_blocking_lock_queue(time(NULL)); + process_blocking_lock_queue(); } /**************************************************************************** - Return the number of seconds to the next blocking locks timeout, or default_timeout + Return the number of milliseconds to the next blocking locks timeout, or default_timeout *****************************************************************************/ -unsigned blocking_locks_timeout(unsigned default_timeout) +unsigned int blocking_locks_timeout_ms(unsigned int default_timeout_ms) { - unsigned timeout = default_timeout; - time_t t; + unsigned int timeout_ms = default_timeout_ms; + struct timeval tv_curr; + SMB_BIG_INT min_tv_dif_us = 0x7FFFFFFF; /* A large +ve number. */ blocking_lock_record *blr = blocking_lock_queue; - /* note that we avoid the time() syscall if there are no blocking locks */ - if (!blr) - return timeout; + /* note that we avoid the GetTimeOfDay() syscall if there are no blocking locks */ + if (!blr) { + return timeout_ms; + } - t = time(NULL); + tv_curr = timeval_current(); for (; blr; blr = blr->next) { - if ((blr->expire_time != (time_t)-1) && - (timeout > (blr->expire_time - t))) { - timeout = blr->expire_time - t; + SMB_BIG_INT tv_dif_us; + + if (timeval_is_zero(&blr->expire_time)) { + continue; /* Never timeout. */ } + + tv_dif_us = usec_time_diff(&blr->expire_time, &tv_curr); + min_tv_dif_us = MIN(min_tv_dif_us, tv_dif_us); + } + + if (min_tv_dif_us < 0) { + min_tv_dif_us = 0; + } + + timeout_ms = (unsigned int)(min_tv_dif_us / (SMB_BIG_INT)1000); + + if (timeout_ms < 1) { + timeout_ms = 1; } - if (timeout < 1) - timeout = 1; + DEBUG(10,("blocking_locks_timeout_ms: returning %u\n", timeout_ms)); - return timeout; + return timeout_ms; } /**************************************************************************** Process the blocking lock queue. Note that this is only called as root. *****************************************************************************/ -void process_blocking_lock_queue(time_t t) +void process_blocking_lock_queue(void) { + struct timeval tv_curr = timeval_current(); blocking_lock_record *blr, *next = NULL; /* @@ -780,7 +647,7 @@ void process_blocking_lock_queue(time_t t) DEBUG(5,("process_blocking_lock_queue: examining pending lock fnum = %d for file %s\n", fsp->fnum, fsp->fsp_name )); - if((blr->expire_time != -1) && (blr->expire_time <= t)) { + if (!timeval_is_zero(&blr->expire_time) && timeval_compare(&blr->expire_time, &tv_curr) <= 0) { struct byte_range_lock *br_lck = brl_get_locks(NULL, fsp); /* -- cgit From a093a76dc14303fd1c42fb2c0b87faf3748815e4 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Fri, 28 Jul 2006 22:42:39 +0000 Subject: r17293: After the results from the cluster tests in Germany, fix the messaging code to call the efficient calls : save_re_uid() set_effective_uid(0); messaging_op restore_re_uid(); instead of using heavyweight become_root()/unbecome_root() pairs around all messaging code. Fixup the messaging code to ensure sec_init() is called (only once) so that non-root processes still work when sending messages. This is a lighter weight solution to become_root()/unbecome_root() (which swaps all the supplemental groups) and should be more efficient. I will migrate all server code over to using this (a similar technique should be used in the passdb backend where needed). Jeremy. (This used to be commit 4ace291278d9a44f5c577bdd3b282c1231e543df) --- source3/smbd/blocking.c | 3 --- 1 file changed, 3 deletions(-) (limited to 'source3/smbd/blocking.c') diff --git a/source3/smbd/blocking.c b/source3/smbd/blocking.c index a0b93f5032..ed57c9f621 100644 --- a/source3/smbd/blocking.c +++ b/source3/smbd/blocking.c @@ -837,9 +837,6 @@ BOOL blocking_lock_cancel(files_struct *fsp, memcpy(msg, &blr, sizeof(blr)); memcpy(&msg[sizeof(blr)], &err, sizeof(NTSTATUS)); - /* Don't need to be root here as we're only ever - sending to ourselves. */ - message_send_pid(pid_to_procid(sys_getpid()), MSG_SMB_BLOCKING_LOCK_CANCEL, &msg, sizeof(msg), True); -- cgit From 2c6030415e0b1f421ea6e85fe6ffe7389ee7a941 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Sat, 29 Jul 2006 19:14:24 +0000 Subject: r17314: Optimisation for POSIX locking. If we're downgrading a POSIX lock (applying a read-lock) and we overlap pending read locks then send them an unlock message, we may have allowed them to proceed. Jeremy. (This used to be commit a7a0b6ba50f4cf7c5a0a29809fdff9e1266a29e7) --- source3/smbd/blocking.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/smbd/blocking.c') diff --git a/source3/smbd/blocking.c b/source3/smbd/blocking.c index ed57c9f621..0304a6559f 100644 --- a/source3/smbd/blocking.c +++ b/source3/smbd/blocking.c @@ -137,7 +137,7 @@ BOOL push_blocking_lock_request( struct byte_range_lock *br_lck, procid_self(), offset, count, - PENDING_LOCK, + lock_type == READ_LOCK ? PENDING_READ_LOCK : PENDING_WRITE_LOCK, blr->lock_flav, lock_timeout ? True : False); /* blocking_lock. */ -- cgit From 6fd4813ece5e03c92334acfa7e168cd7d0248919 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Mon, 14 Aug 2006 16:53:14 +0000 Subject: r17541: When returning a trans2 request, if the "max data bytes returned" is less than the amount we want to send, return what we can and set STATUS_BUFFER_OVERFLOW (doserror ERRDOS,ERRbufferoverflow). Required by OS/2 to handle EA's that are too large. It's hard to test this in Samba4 smbtorture as the max data bytes returned is hard coded at 0xffff (as it is in the Samba3 client libraries also). I used a custom version of Samba4 smbtorture to test this out. Might add a "max data bytes" param to make this testable in the build farm. Confirmed by "Guenter Kukkukk (sambaos2)" and Andreas Taegener that this fixes the issue. Jeremy. (This used to be commit ff2f1202b76991a404dae8df17c36f8135c8dc51) --- source3/smbd/blocking.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'source3/smbd/blocking.c') diff --git a/source3/smbd/blocking.c b/source3/smbd/blocking.c index 0304a6559f..2f89759ffd 100644 --- a/source3/smbd/blocking.c +++ b/source3/smbd/blocking.c @@ -458,7 +458,8 @@ static BOOL process_trans2(blocking_lock_record *blr) construct_reply_common(inbuf, outbuf); SCVAL(outbuf,smb_com,SMBtrans2); SSVAL(params,0,0); - send_trans2_replies(outbuf, max_send, params, 2, NULL, 0); + /* Fake up max_data_bytes here - we know it fits. */ + send_trans2_replies(outbuf, max_send, params, 2, NULL, 0, 0xffff); return True; } -- cgit From 258a465e20e007a30043220367d17ecfc87b4f90 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Mon, 18 Sep 2006 07:52:16 +0000 Subject: r18605: sync dlinklist.h with samba4, that means DLIST_ADD_END() and DLIST_DEMOTE() now take the type of the tmp pointer not the tmp pointer itself anymore. metze (This used to be commit 2f58645b7094e81dff3734f11aa183ea2ab53d2d) --- source3/smbd/blocking.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source3/smbd/blocking.c') diff --git a/source3/smbd/blocking.c b/source3/smbd/blocking.c index 2f89759ffd..f489a8e96b 100644 --- a/source3/smbd/blocking.c +++ b/source3/smbd/blocking.c @@ -86,7 +86,7 @@ BOOL push_blocking_lock_request( struct byte_range_lock *br_lck, SMB_BIG_UINT offset, SMB_BIG_UINT count) { static BOOL set_lock_msg; - blocking_lock_record *blr, *tmp; + blocking_lock_record *blr; NTSTATUS status; if(in_chained_smb() ) { @@ -148,7 +148,7 @@ BOOL push_blocking_lock_request( struct byte_range_lock *br_lck, return False; } - DLIST_ADD_END(blocking_lock_queue, blr, tmp); + DLIST_ADD_END(blocking_lock_queue, blr, blocking_lock_record *); /* Ensure we'll receive messages when this is unlocked. */ if (!set_lock_msg) { -- cgit From 791f48f167de339c8ae371e5c80706511fd10018 Mon Sep 17 00:00:00 2001 From: Herb Lewis Date: Tue, 12 Dec 2006 17:38:42 +0000 Subject: r20124: clean up nested extern declaration warnings (This used to be commit ac3eb7813e33b9a2e78c9158433f7ed62c3b62bb) --- source3/smbd/blocking.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'source3/smbd/blocking.c') diff --git a/source3/smbd/blocking.c b/source3/smbd/blocking.c index f489a8e96b..aeb2bd6b6b 100644 --- a/source3/smbd/blocking.c +++ b/source3/smbd/blocking.c @@ -22,6 +22,8 @@ #undef DBGC_CLASS #define DBGC_CLASS DBGC_LOCKING +extern int max_send; + /**************************************************************************** This is the structure to queue to implement blocking locks. notify. It consists of the requesting SMB and the expiry time. @@ -425,7 +427,6 @@ Waiting....\n", static BOOL process_trans2(blocking_lock_record *blr) { - extern int max_send; char *inbuf = blr->inbuf; char *outbuf; char params[2]; -- cgit From 5bb49b08f3d79ef9ee17dbbd64ce90dc438d96df Mon Sep 17 00:00:00 2001 From: James Peach Date: Mon, 18 Dec 2006 04:25:21 +0000 Subject: r20237: Replace exit_server with exit_server_cleanly where appropriate. All send_smb failures should be clean exits. All times when we exit as a matter of policy should also be clean exits. (This used to be commit d6382092e72120a3c89ffe81975e8898d454bf06) --- source3/smbd/blocking.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'source3/smbd/blocking.c') diff --git a/source3/smbd/blocking.c b/source3/smbd/blocking.c index aeb2bd6b6b..7a71fc67e5 100644 --- a/source3/smbd/blocking.c +++ b/source3/smbd/blocking.c @@ -180,7 +180,7 @@ static void send_blocking_reply(char *outbuf, int outsize) smb_setlen(outbuf,outsize - 4); if (!send_smb(smbd_server_fd(),outbuf)) - exit_server("send_blocking_reply: send_smb failed."); + exit_server_cleanly("send_blocking_reply: send_smb failed."); } /**************************************************************************** @@ -244,7 +244,7 @@ static void generic_blocking_lock_error(blocking_lock_record *blr, NTSTATUS stat ERROR_NT(status); if (!send_smb(smbd_server_fd(),outbuf)) { - exit_server("generic_blocking_lock_error: send_smb failed."); + exit_server_cleanly("generic_blocking_lock_error: send_smb failed."); } } @@ -322,7 +322,7 @@ static void blocking_lock_reply_error(blocking_lock_record *blr, NTSTATUS status SCVAL(outbuf,smb_com,SMBtrans2); ERROR_NT(status); if (!send_smb(smbd_server_fd(),outbuf)) { - exit_server("blocking_lock_reply_error: send_smb failed."); + exit_server_cleanly("blocking_lock_reply_error: send_smb failed."); } break; } -- cgit From deaf4131b99951cfcc599b96e35af680202ce609 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 30 Jan 2007 20:49:37 +0000 Subject: r21062: Should fix the build plus make all refactored functions return NTSTATUS. Jeremy. (This used to be commit 1f3c2b2abca6f1b3b59b73df038832e14106ff76) --- source3/smbd/blocking.c | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) (limited to 'source3/smbd/blocking.c') diff --git a/source3/smbd/blocking.c b/source3/smbd/blocking.c index 7a71fc67e5..e0478fa762 100644 --- a/source3/smbd/blocking.c +++ b/source3/smbd/blocking.c @@ -559,6 +559,23 @@ file %s fnum = %d\n", blr->com_type, fsp->fsp_name, fsp->fnum )); } } +/**************************************************************************** + Is this mid a blocking lock request on the queue ? +*****************************************************************************/ + +BOOL blocking_lock_was_deferred(int mid) +{ + 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; +} + /**************************************************************************** Set a flag as an unlock request affects one of our pending locks. *****************************************************************************/ -- cgit From caf8c6a76be051559ffcfe97084edca43e0a3cee Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Tue, 30 Jan 2007 22:22:06 +0000 Subject: r21064: The core of this patch is void message_register(int msg_type, void (*fn)(int msg_type, struct process_id pid, - void *buf, size_t len)) + void *buf, size_t len, + void *private_data), + void *private_data) { struct dispatch_fns *dfn; So this adds a (so far unused) private pointer that is passed from message_register to the message handler. A prerequisite to implement a tiny samba4-API compatible wrapper around our messaging system. That itself is necessary for the Samba4 notify system. Yes, I know, I could import the whole Samba4 messaging system, but I want to do it step by step and I think getting notify in is more important in this step. Volker (This used to be commit c8ae60ed65dcce9660ee39c75488f2838cf9a28b) --- source3/smbd/blocking.c | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) (limited to 'source3/smbd/blocking.c') diff --git a/source3/smbd/blocking.c b/source3/smbd/blocking.c index e0478fa762..70b2d30aab 100644 --- a/source3/smbd/blocking.c +++ b/source3/smbd/blocking.c @@ -71,7 +71,8 @@ static BOOL in_chained_smb(void) } static void received_unlock_msg(int msg_type, struct process_id src, - void *buf, size_t len); + void *buf, size_t len, + void *private_data); /**************************************************************************** Function to push a blocking lock request onto the lock queue. @@ -154,7 +155,8 @@ BOOL push_blocking_lock_request( struct byte_range_lock *br_lck, /* Ensure we'll receive messages when this is unlocked. */ if (!set_lock_msg) { - message_register(MSG_SMB_UNLOCK, received_unlock_msg); + message_register(MSG_SMB_UNLOCK, received_unlock_msg, + NULL); set_lock_msg = True; } @@ -581,7 +583,8 @@ BOOL blocking_lock_was_deferred(int mid) *****************************************************************************/ static void received_unlock_msg(int msg_type, struct process_id src, - void *buf, size_t len) + void *buf, size_t len, + void *private_data) { DEBUG(10,("received_unlock_msg\n")); process_blocking_lock_queue(); @@ -775,8 +778,10 @@ void process_blocking_lock_queue(void) #define MSG_BLOCKING_LOCK_CANCEL_SIZE (sizeof(blocking_lock_record *) + sizeof(NTSTATUS)) -static void process_blocking_lock_cancel_message(int msg_type, struct process_id src, - void *buf, size_t len) +static void process_blocking_lock_cancel_message(int msg_type, + struct process_id src, + void *buf, size_t len, + void *private_data) { NTSTATUS err; const char *msg = (const char *)buf; @@ -822,7 +827,8 @@ BOOL blocking_lock_cancel(files_struct *fsp, if (!initialized) { /* Register our message. */ message_register(MSG_SMB_BLOCKING_LOCK_CANCEL, - process_blocking_lock_cancel_message); + process_blocking_lock_cancel_message, + NULL); initialized = True; } -- cgit From 496dbdf4350ffc5f53c9f8f734d2c29b312ff11b Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Mon, 19 Mar 2007 21:52:27 +0000 Subject: r21879: Move process_blocking_lock_queue to a timed event. The idea is that we have blocking.c:brl_timeout as a timed event that is present whenever we do have a blocking lock pending. It fires brl_timeout_fn() which calls process_blocking_lock_queue(). Whenever we make changes to blocking_lock_queue, we trigger a recalc_brl_timeout() which sets a new brl_timout event if necessary. This makes the call to blocking_locks_timeout_ms() in setup_select_timeout() unnecessary, this is implicitly done in event_add_to_select_args() from the timed events. Volker (This used to be commit 7e31b8ce21de803ac1f8967967393341a3f44ac3) --- source3/smbd/blocking.c | 116 +++++++++++++++++++++++++++++------------------- 1 file changed, 71 insertions(+), 45 deletions(-) (limited to 'source3/smbd/blocking.c') diff --git a/source3/smbd/blocking.c b/source3/smbd/blocking.c index 70b2d30aab..101f16bb9d 100644 --- a/source3/smbd/blocking.c +++ b/source3/smbd/blocking.c @@ -51,6 +51,9 @@ static blocking_lock_record *blocking_lock_queue; /* dlink list we move cancelled lock records onto. */ static blocking_lock_record *blocking_lock_cancelled_queue; +/* The event that makes us process our blocking lock queue */ +static struct timed_event *brl_timeout; + /**************************************************************************** Destructor for the above structure. ****************************************************************************/ @@ -73,6 +76,63 @@ static BOOL in_chained_smb(void) static void received_unlock_msg(int msg_type, struct process_id src, void *buf, size_t len, void *private_data); +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. +****************************************************************************/ + +static BOOL recalc_brl_timeout(void) +{ + 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)) { + 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; +} + /**************************************************************************** Function to push a blocking lock request onto the lock queue. @@ -152,6 +212,7 @@ BOOL push_blocking_lock_request( struct byte_range_lock *br_lck, } DLIST_ADD_END(blocking_lock_queue, blr, blocking_lock_record *); + recalc_brl_timeout(); /* Ensure we'll receive messages when this is unlocked. */ if (!set_lock_msg) { @@ -590,58 +651,15 @@ static void received_unlock_msg(int msg_type, struct process_id src, process_blocking_lock_queue(); } -/**************************************************************************** - Return the number of milliseconds to the next blocking locks timeout, or default_timeout -*****************************************************************************/ - -unsigned int blocking_locks_timeout_ms(unsigned int default_timeout_ms) -{ - unsigned int timeout_ms = default_timeout_ms; - struct timeval tv_curr; - SMB_BIG_INT min_tv_dif_us = 0x7FFFFFFF; /* A large +ve number. */ - blocking_lock_record *blr = blocking_lock_queue; - - /* note that we avoid the GetTimeOfDay() syscall if there are no blocking locks */ - if (!blr) { - return timeout_ms; - } - - tv_curr = timeval_current(); - - for (; blr; blr = blr->next) { - SMB_BIG_INT tv_dif_us; - - if (timeval_is_zero(&blr->expire_time)) { - continue; /* Never timeout. */ - } - - tv_dif_us = usec_time_diff(&blr->expire_time, &tv_curr); - min_tv_dif_us = MIN(min_tv_dif_us, tv_dif_us); - } - - if (min_tv_dif_us < 0) { - min_tv_dif_us = 0; - } - - timeout_ms = (unsigned int)(min_tv_dif_us / (SMB_BIG_INT)1000); - - if (timeout_ms < 1) { - timeout_ms = 1; - } - - DEBUG(10,("blocking_locks_timeout_ms: returning %u\n", timeout_ms)); - - return timeout_ms; -} - /**************************************************************************** Process the blocking lock queue. Note that this is only called as root. *****************************************************************************/ -void process_blocking_lock_queue(void) +static void process_blocking_lock_queue(void) { struct timeval tv_curr = timeval_current(); blocking_lock_record *blr, *next = NULL; + BOOL recalc_timeout = False; /* * Go through the queue and see if we can get any of the locks. @@ -693,6 +711,7 @@ void process_blocking_lock_queue(void) blocking_lock_reply_error(blr,NT_STATUS_FILE_LOCK_CONFLICT); DLIST_REMOVE(blocking_lock_queue, blr); free_blocking_lock_record(blr); + recalc_timeout = True; continue; } @@ -718,6 +737,7 @@ void process_blocking_lock_queue(void) blocking_lock_reply_error(blr,NT_STATUS_ACCESS_DENIED); DLIST_REMOVE(blocking_lock_queue, blr); free_blocking_lock_record(blr); + recalc_timeout = True; continue; } @@ -742,6 +762,7 @@ void process_blocking_lock_queue(void) blocking_lock_reply_error(blr,NT_STATUS_ACCESS_DENIED); DLIST_REMOVE(blocking_lock_queue, blr); free_blocking_lock_record(blr); + recalc_timeout = True; change_to_root_user(); continue; } @@ -767,9 +788,14 @@ void process_blocking_lock_queue(void) DLIST_REMOVE(blocking_lock_queue, blr); free_blocking_lock_record(blr); + recalc_timeout = True; } change_to_root_user(); } + + if (recalc_timeout) { + recalc_brl_timeout(); + } } /**************************************************************************** -- cgit From dc90cd89a7fef3b0a744ef1873193cf2c9d75cad Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 19 Apr 2007 20:50:49 +0000 Subject: r22389: Start preparing for multiple encryption contexts in the server. Allow server to reflect back to calling client the encryption context that was sent. Jeremy. (This used to be commit b49e90335d1e589916b5ab4992e3c4a2d221ca7e) --- source3/smbd/blocking.c | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) (limited to 'source3/smbd/blocking.c') diff --git a/source3/smbd/blocking.c b/source3/smbd/blocking.c index 101f16bb9d..58953bac11 100644 --- a/source3/smbd/blocking.c +++ b/source3/smbd/blocking.c @@ -237,13 +237,15 @@ BOOL push_blocking_lock_request( struct byte_range_lock *br_lck, Return a smd with a given size. *****************************************************************************/ -static void send_blocking_reply(char *outbuf, int outsize) +static void send_blocking_reply(char *outbuf, int outsize, const char *inbuf) { - if(outsize > 4) - smb_setlen(outbuf,outsize - 4); + if(outsize > 4) { + smb_setlen(outbuf,outsize - 4, inbuf); + } - if (!send_smb(smbd_server_fd(),outbuf)) + if (!send_smb(smbd_server_fd(),outbuf)) { exit_server_cleanly("send_blocking_reply: send_smb failed."); + } } /**************************************************************************** @@ -272,7 +274,7 @@ static void reply_lockingX_success(blocking_lock_record *blr) outsize += chain_size; - send_blocking_reply(outbuf,outsize); + send_blocking_reply(outbuf,outsize,inbuf); } /**************************************************************************** -- cgit From 0829e1ad1c3646efecf50729f493b9ee72ef0517 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 19 Apr 2007 22:40:32 +0000 Subject: r22391: Looks bigger than it is. Make "inbuf" available to all callers of smb_setlen (via set_message() calls). This will allow the server to reflect back the correct encryption context. Jeremy. (This used to be commit 2d80a96120a5fe2fe726f00746d36d85044c4bdb) --- source3/smbd/blocking.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'source3/smbd/blocking.c') diff --git a/source3/smbd/blocking.c b/source3/smbd/blocking.c index 58953bac11..d0caa29597 100644 --- a/source3/smbd/blocking.c +++ b/source3/smbd/blocking.c @@ -240,7 +240,7 @@ BOOL push_blocking_lock_request( struct byte_range_lock *br_lck, static void send_blocking_reply(char *outbuf, int outsize, const char *inbuf) { if(outsize > 4) { - smb_setlen(outbuf,outsize - 4, inbuf); + smb_setlen(inbuf, outbuf,outsize - 4); } if (!send_smb(smbd_server_fd(),outbuf)) { @@ -260,7 +260,7 @@ static void reply_lockingX_success(blocking_lock_record *blr) int outsize = 0; construct_reply_common(inbuf, outbuf); - set_message(outbuf,2,0,True); + set_message(inbuf,outbuf,2,0,True); /* * As this message is a lockingX call we must handle @@ -525,7 +525,7 @@ static BOOL process_trans2(blocking_lock_record *blr) SCVAL(outbuf,smb_com,SMBtrans2); SSVAL(params,0,0); /* Fake up max_data_bytes here - we know it fits. */ - send_trans2_replies(outbuf, max_send, params, 2, NULL, 0, 0xffff); + send_trans2_replies(inbuf, outbuf, max_send, params, 2, NULL, 0, 0xffff); return True; } -- cgit From e6383f47629368d9dd4e803f17566a24e9d7359e Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Mon, 7 May 2007 09:35:35 +0000 Subject: r22736: Start to merge the low-hanging fruit from the now 7000-line cluster patch. This changes "struct process_id" to "struct server_id", keeping both is just too much hassle. No functional change (I hope ;-)) Volker (This used to be commit 0ad4b1226c9d91b72136310d3bbb640d2c5d67b8) --- source3/smbd/blocking.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'source3/smbd/blocking.c') diff --git a/source3/smbd/blocking.c b/source3/smbd/blocking.c index d0caa29597..7fe9f0c3c7 100644 --- a/source3/smbd/blocking.c +++ b/source3/smbd/blocking.c @@ -73,7 +73,7 @@ static BOOL in_chained_smb(void) return (chain_size != 0); } -static void received_unlock_msg(int msg_type, struct process_id src, +static void received_unlock_msg(int msg_type, struct server_id src, void *buf, size_t len, void *private_data); static void process_blocking_lock_queue(void); @@ -645,7 +645,7 @@ BOOL blocking_lock_was_deferred(int mid) Set a flag as an unlock request affects one of our pending locks. *****************************************************************************/ -static void received_unlock_msg(int msg_type, struct process_id src, +static void received_unlock_msg(int msg_type, struct server_id src, void *buf, size_t len, void *private_data) { @@ -807,7 +807,7 @@ static void process_blocking_lock_queue(void) #define MSG_BLOCKING_LOCK_CANCEL_SIZE (sizeof(blocking_lock_record *) + sizeof(NTSTATUS)) static void process_blocking_lock_cancel_message(int msg_type, - struct process_id src, + struct server_id src, void *buf, size_t len, void *private_data) { -- cgit From b92064fcfd804b861e2f5125078812d83b9120a6 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Mon, 14 May 2007 13:01:28 +0000 Subject: r22846: Chunk one to replace message_send_pid with messaging_send: Deep inside locking/locking.c we have to send retry messages to timed lock holders. The majority of this patch passes a "struct messaging_context" down there. No functional change, survives make test. (This used to be commit bbb508414683eeddd2ee0d2d36fe620118180bbb) --- source3/smbd/blocking.c | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) (limited to 'source3/smbd/blocking.c') diff --git a/source3/smbd/blocking.c b/source3/smbd/blocking.c index 7fe9f0c3c7..ab2b0949bd 100644 --- a/source3/smbd/blocking.c +++ b/source3/smbd/blocking.c @@ -195,7 +195,7 @@ BOOL push_blocking_lock_request( struct byte_range_lock *br_lck, blr->length = length; /* Add a pending lock record for this. */ - status = brl_lock(br_lck, + status = brl_lock(smbd_messaging_context(), br_lck, lock_pid, procid_self(), offset, @@ -355,7 +355,8 @@ static void reply_lockingX_error(blocking_lock_record *blr, NTSTATUS status) * request would never have been queued. JRA. */ - do_unlock(fsp, + do_unlock(smbd_messaging_context(), + fsp, lock_pid, count, offset, @@ -435,7 +436,8 @@ static BOOL process_lockingX(blocking_lock_record *blr) * request would never have been queued. JRA. */ errno = 0; - br_lck = do_lock(fsp, + br_lck = do_lock(smbd_messaging_context(), + fsp, lock_pid, count, offset, @@ -496,7 +498,8 @@ static BOOL process_trans2(blocking_lock_record *blr) char *outbuf; char params[2]; NTSTATUS status; - struct byte_range_lock *br_lck = do_lock(blr->fsp, + struct byte_range_lock *br_lck = do_lock(smbd_messaging_context(), + blr->fsp, blr->lock_pid, blr->count, blr->offset, -- cgit From fad7dd8a60e6637598b17fa89ec92d98db51fffe Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Mon, 14 May 2007 20:31:28 +0000 Subject: r22868: Replace some message_send_pid calls with messaging_send_pid calls. More tomorrow. (This used to be commit 74fa57ca5d7fa8eace72bbe948a08a0bca3cc4ca) --- source3/smbd/blocking.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'source3/smbd/blocking.c') diff --git a/source3/smbd/blocking.c b/source3/smbd/blocking.c index ab2b0949bd..ae7b861f2b 100644 --- a/source3/smbd/blocking.c +++ b/source3/smbd/blocking.c @@ -893,9 +893,9 @@ BOOL blocking_lock_cancel(files_struct *fsp, memcpy(msg, &blr, sizeof(blr)); memcpy(&msg[sizeof(blr)], &err, sizeof(NTSTATUS)); - message_send_pid(pid_to_procid(sys_getpid()), - MSG_SMB_BLOCKING_LOCK_CANCEL, - &msg, sizeof(msg), True); + messaging_send_buf(smbd_messaging_context(), procid_self(), + MSG_SMB_BLOCKING_LOCK_CANCEL, + (uint8 *)&msg, sizeof(msg)); return True; } -- cgit From 01a7017d7b0e0cbc3b0923c43b7fe3f0b01aac0b Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Sat, 19 May 2007 20:57:12 +0000 Subject: r23014: For all branches, ensure that if we're blocked on a POSIX lock we know nothing about that we retry the lock every 10 seconds instead of waiting for the standard select timeout. This is how we used to (and are supposed to) work. Jeremy. (This used to be commit fa18fc25a50cf13c687ae88e7e5e2dda1120e017) --- source3/smbd/blocking.c | 25 +++++++++++++++++++++---- 1 file changed, 21 insertions(+), 4 deletions(-) (limited to 'source3/smbd/blocking.c') diff --git a/source3/smbd/blocking.c b/source3/smbd/blocking.c index ae7b861f2b..43b2633b9a 100644 --- a/source3/smbd/blocking.c +++ b/source3/smbd/blocking.c @@ -39,6 +39,7 @@ typedef struct _blocking_lock_record { SMB_BIG_UINT offset; SMB_BIG_UINT count; uint32 lock_pid; + uint32 blocking_pid; /* PID that blocks us. */ enum brl_flavour lock_flav; enum brl_type lock_type; char *inbuf; @@ -108,6 +109,16 @@ static BOOL recalc_brl_timeout(void) for (brl = blocking_lock_queue; brl; brl = brl->next) { if (timeval_is_zero(&brl->expire_time)) { + /* + * 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); + } + continue; } @@ -146,7 +157,9 @@ BOOL push_blocking_lock_request( struct byte_range_lock *br_lck, uint32 lock_pid, enum brl_type lock_type, enum brl_flavour lock_flav, - SMB_BIG_UINT offset, SMB_BIG_UINT count) + SMB_BIG_UINT offset, + SMB_BIG_UINT count, + uint32 blocking_pid) { static BOOL set_lock_msg; blocking_lock_record *blr; @@ -187,6 +200,7 @@ BOOL push_blocking_lock_request( struct byte_range_lock *br_lck, } blr->lock_num = lock_num; blr->lock_pid = lock_pid; + blr->blocking_pid = blocking_pid; blr->lock_flav = lock_flav; blr->lock_type = lock_type; blr->offset = offset; @@ -202,7 +216,8 @@ BOOL push_blocking_lock_request( struct byte_range_lock *br_lck, count, lock_type == READ_LOCK ? PENDING_READ_LOCK : PENDING_WRITE_LOCK, blr->lock_flav, - lock_timeout ? True : False); /* blocking_lock. */ + lock_timeout ? True : False, /* blocking_lock. */ + NULL); if (!NT_STATUS_IS_OK(status)) { DEBUG(0,("push_blocking_lock_request: failed to add PENDING_LOCK record.\n")); @@ -445,7 +460,8 @@ static BOOL process_lockingX(blocking_lock_record *blr) READ_LOCK : WRITE_LOCK), WINDOWS_LOCK, True, - &status); + &status, + &blr->blocking_pid); TALLOC_FREE(br_lck); @@ -506,7 +522,8 @@ static BOOL process_trans2(blocking_lock_record *blr) blr->lock_type, blr->lock_flav, True, - &status); + &status, + &blr->blocking_pid); TALLOC_FREE(br_lck); if (!NT_STATUS_IS_OK(status)) { -- cgit From 4d5f58c2b945e7a2263ba42749f73c7ba72ab3c7 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Sat, 19 May 2007 21:53:28 +0000 Subject: r23015: Make message_(de)register static to messages.c (This used to be commit a8082a3c7c3d1e68c27fc3bf42f3d44402cc6f9f) --- source3/smbd/blocking.c | 43 ++++++++++++++++++++++++------------------- 1 file changed, 24 insertions(+), 19 deletions(-) (limited to 'source3/smbd/blocking.c') diff --git a/source3/smbd/blocking.c b/source3/smbd/blocking.c index 43b2633b9a..6a892b477d 100644 --- a/source3/smbd/blocking.c +++ b/source3/smbd/blocking.c @@ -74,9 +74,11 @@ static BOOL in_chained_smb(void) return (chain_size != 0); } -static void received_unlock_msg(int msg_type, struct server_id src, - void *buf, size_t len, - void *private_data); +static void received_unlock_msg(struct messaging_context *msg, + void *private_data, + uint32_t msg_type, + struct server_id server_id, + DATA_BLOB *data); static void process_blocking_lock_queue(void); static void brl_timeout_fn(struct event_context *event_ctx, @@ -231,8 +233,8 @@ BOOL push_blocking_lock_request( struct byte_range_lock *br_lck, /* Ensure we'll receive messages when this is unlocked. */ if (!set_lock_msg) { - message_register(MSG_SMB_UNLOCK, received_unlock_msg, - NULL); + messaging_register(smbd_messaging_context(), NULL, + MSG_SMB_UNLOCK, received_unlock_msg); set_lock_msg = True; } @@ -665,9 +667,11 @@ BOOL blocking_lock_was_deferred(int mid) Set a flag as an unlock request affects one of our pending locks. *****************************************************************************/ -static void received_unlock_msg(int msg_type, struct server_id src, - void *buf, size_t len, - void *private_data) +static void received_unlock_msg(struct messaging_context *msg, + void *private_data, + uint32_t msg_type, + struct server_id server_id, + DATA_BLOB *data) { DEBUG(10,("received_unlock_msg\n")); process_blocking_lock_queue(); @@ -826,22 +830,23 @@ static void process_blocking_lock_queue(void) #define MSG_BLOCKING_LOCK_CANCEL_SIZE (sizeof(blocking_lock_record *) + sizeof(NTSTATUS)) -static void process_blocking_lock_cancel_message(int msg_type, - struct server_id src, - void *buf, size_t len, - void *private_data) +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) { NTSTATUS err; - const char *msg = (const char *)buf; + const char *msg = (const char *)data->data; blocking_lock_record *blr; - if (buf == NULL) { + if (data->data == NULL) { smb_panic("process_blocking_lock_cancel_message: null msg\n"); } - if (len != MSG_BLOCKING_LOCK_CANCEL_SIZE) { + if (data->length != MSG_BLOCKING_LOCK_CANCEL_SIZE) { DEBUG(0, ("process_blocking_lock_cancel_message: " - "Got invalid msg len %d\n", (int)len)); + "Got invalid msg len %d\n", (int)data->length)); smb_panic("process_blocking_lock_cancel_message: bad msg\n"); } @@ -874,9 +879,9 @@ BOOL blocking_lock_cancel(files_struct *fsp, if (!initialized) { /* Register our message. */ - message_register(MSG_SMB_BLOCKING_LOCK_CANCEL, - process_blocking_lock_cancel_message, - NULL); + messaging_register(smbd_messaging_context(), NULL, + MSG_SMB_BLOCKING_LOCK_CANCEL, + process_blocking_lock_cancel_message); initialized = True; } -- cgit From b1ce226af8b61ad7e3c37860a59c6715012e738b Mon Sep 17 00:00:00 2001 From: James Peach Date: Fri, 15 Jun 2007 21:58:49 +0000 Subject: r23510: Tidy calls to smb_panic by removing trailing newlines. Print the failed expression in SMB_ASSERT. (This used to be commit 171dc060e2a576d724eed1ca65636bdafffd7713) --- source3/smbd/blocking.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source3/smbd/blocking.c') diff --git a/source3/smbd/blocking.c b/source3/smbd/blocking.c index 6a892b477d..924b99b113 100644 --- a/source3/smbd/blocking.c +++ b/source3/smbd/blocking.c @@ -841,13 +841,13 @@ static void process_blocking_lock_cancel_message(struct messaging_context *ctx, blocking_lock_record *blr; if (data->data == NULL) { - smb_panic("process_blocking_lock_cancel_message: null msg\n"); + smb_panic("process_blocking_lock_cancel_message: null msg"); } if (data->length != MSG_BLOCKING_LOCK_CANCEL_SIZE) { DEBUG(0, ("process_blocking_lock_cancel_message: " "Got invalid msg len %d\n", (int)data->length)); - smb_panic("process_blocking_lock_cancel_message: bad msg\n"); + smb_panic("process_blocking_lock_cancel_message: bad msg"); } memcpy(&blr, msg, sizeof(blr)); -- cgit From d824b98f80ba186030cbb70b3a1e5daf80469ecd Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Mon, 9 Jul 2007 19:25:36 +0000 Subject: r23779: Change from v2 or later to v3 or later. Jeremy. (This used to be commit 407e6e695b8366369b7c76af1ff76869b45347b3) --- source3/smbd/blocking.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/smbd/blocking.c') diff --git a/source3/smbd/blocking.c b/source3/smbd/blocking.c index 924b99b113..7fafdcf887 100644 --- a/source3/smbd/blocking.c +++ b/source3/smbd/blocking.c @@ -5,7 +5,7 @@ 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 + the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, -- cgit From 5e54558c6dea67b56bbfaba5698f3a434d3dffb6 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Tue, 10 Jul 2007 00:52:41 +0000 Subject: r23784: use the GPLv3 boilerplate as recommended by the FSF and the license text (This used to be commit b0132e94fc5fef936aa766fb99a306b3628e9f07) --- source3/smbd/blocking.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'source3/smbd/blocking.c') diff --git a/source3/smbd/blocking.c b/source3/smbd/blocking.c index 7fafdcf887..ed1977e3be 100644 --- a/source3/smbd/blocking.c +++ b/source3/smbd/blocking.c @@ -14,8 +14,7 @@ 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 02139, USA. + along with this program. If not, see . */ #include "includes.h" -- cgit From cc6a41017c577742af73b4bc60993d8d415ea580 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Mon, 23 Jul 2007 09:36:09 +0000 Subject: r23997: Check in the infrastructure for getting rid of the global InBuffer/OutBuffer The complete history of this patch can be found under http://www.samba.org/~vlendec/inbuf-checkin/. Jeremy, Jerry: If possible I would like to see this in 3.2.0. I'm only checking into 3_2 at the moment, as it currently will slow down operations for all non-converted (i.e. all at this moment) operations, as it will copy the talloc'ed inbuf over the global InBuffer. It will need quite a bit of effort to convert everything necessary for the normal operations an XP box does. I have patches for negprot, session setup, tcon_and_X, open_and_X, close. More to come, but I would appreciate some help here. Volker (This used to be commit 5594af2b208c860d3f4b453af6a649d9e4295d1c) --- source3/smbd/blocking.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/smbd/blocking.c') diff --git a/source3/smbd/blocking.c b/source3/smbd/blocking.c index ed1977e3be..09d16337cd 100644 --- a/source3/smbd/blocking.c +++ b/source3/smbd/blocking.c @@ -286,7 +286,7 @@ static void reply_lockingX_success(blocking_lock_record *blr) * that here and must set up the chain info manually. */ - outsize = chain_reply(inbuf,outbuf,blr->length,bufsize); + outsize = chain_reply(inbuf,&outbuf,blr->length,bufsize); outsize += chain_size; -- cgit From c1ca4c298bfdba42fc7db9d83514edd33893e7e7 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Sun, 29 Jul 2007 16:40:45 +0000 Subject: r24070: Apply some const (This used to be commit e6d592dcb8ff9f986b531435d0d03df20880880b) --- source3/smbd/blocking.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/smbd/blocking.c') diff --git a/source3/smbd/blocking.c b/source3/smbd/blocking.c index 09d16337cd..c6e174ae22 100644 --- a/source3/smbd/blocking.c +++ b/source3/smbd/blocking.c @@ -151,7 +151,7 @@ static BOOL recalc_brl_timeout(void) ****************************************************************************/ BOOL push_blocking_lock_request( struct byte_range_lock *br_lck, - char *inbuf, int length, + const char *inbuf, int length, files_struct *fsp, int lock_timeout, int lock_num, -- cgit From 9f3062d8a7abd904cf75da58553bdd34bc106e56 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Fri, 3 Aug 2007 14:33:38 +0000 Subject: r24160: process_trans2 in smbd/blocking.c used send_trans2_replies. Fake a struct smb_request here. Volker (This used to be commit f712d1c92bee024a165b5facabdac1e2c866d9b1) --- source3/smbd/blocking.c | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) (limited to 'source3/smbd/blocking.c') diff --git a/source3/smbd/blocking.c b/source3/smbd/blocking.c index c6e174ae22..1a0a988ea7 100644 --- a/source3/smbd/blocking.c +++ b/source3/smbd/blocking.c @@ -511,8 +511,7 @@ Waiting....\n", static BOOL process_trans2(blocking_lock_record *blr) { - char *inbuf = blr->inbuf; - char *outbuf; + struct smb_request *req; char params[2]; NTSTATUS status; struct byte_range_lock *br_lck = do_lock(smbd_messaging_context(), @@ -541,12 +540,18 @@ static BOOL process_trans2(blocking_lock_record *blr) } /* We finally got the lock, return success. */ - outbuf = get_OutBuffer(); - construct_reply_common(inbuf, outbuf); - SCVAL(outbuf,smb_com,SMBtrans2); + + if (!(req = talloc(tmp_talloc_ctx(), struct smb_request))) { + blocking_lock_reply_error(blr, NT_STATUS_NO_MEMORY); + return True; + } + + init_smb_request(req, (uint8 *)blr->inbuf); + + SCVAL(req->inbuf, smb_com, SMBtrans2); SSVAL(params,0,0); /* Fake up max_data_bytes here - we know it fits. */ - send_trans2_replies(inbuf, outbuf, max_send, params, 2, NULL, 0, 0xffff); + send_trans2_replies_new(req, params, 2, NULL, 0, 0xffff); return True; } -- cgit From c7a425f30fc0fa5f1e32ae30f631849c81786057 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Fri, 3 Aug 2007 16:06:44 +0000 Subject: r24163: Remove the send_trans2_replies_new wrapper This changes send_trans2_replies to not depend on large buffers anymore and finishes the trans2 conversion. (This used to be commit b1d133e4ffa8c9b8219ba6e7b83e23ca4bdd1616) --- source3/smbd/blocking.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/smbd/blocking.c') diff --git a/source3/smbd/blocking.c b/source3/smbd/blocking.c index 1a0a988ea7..0b24fc8257 100644 --- a/source3/smbd/blocking.c +++ b/source3/smbd/blocking.c @@ -551,7 +551,7 @@ static BOOL process_trans2(blocking_lock_record *blr) SCVAL(req->inbuf, smb_com, SMBtrans2); SSVAL(params,0,0); /* Fake up max_data_bytes here - we know it fits. */ - send_trans2_replies_new(req, params, 2, NULL, 0, 0xffff); + send_trans2_replies(req, params, 2, NULL, 0, 0xffff); return True; } -- cgit From ae89ba48ec548f28d38a0a35bc3884181946f1b8 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Tue, 14 Aug 2007 10:06:33 +0000 Subject: r24404: Remove get_OutBuffer usage from blocking.c (This used to be commit cb8fab5663db2cb408e1b85a7287d3670b09d503) --- source3/smbd/blocking.c | 41 ++++++++++++++--------------------------- 1 file changed, 14 insertions(+), 27 deletions(-) (limited to 'source3/smbd/blocking.c') diff --git a/source3/smbd/blocking.c b/source3/smbd/blocking.c index 0b24fc8257..8bdc992910 100644 --- a/source3/smbd/blocking.c +++ b/source3/smbd/blocking.c @@ -249,34 +249,20 @@ BOOL push_blocking_lock_request( struct byte_range_lock *br_lck, return True; } -/**************************************************************************** - Return a smd with a given size. -*****************************************************************************/ - -static void send_blocking_reply(char *outbuf, int outsize, const char *inbuf) -{ - if(outsize > 4) { - smb_setlen(inbuf, outbuf,outsize - 4); - } - - if (!send_smb(smbd_server_fd(),outbuf)) { - exit_server_cleanly("send_blocking_reply: send_smb failed."); - } -} - /**************************************************************************** Return a lockingX success SMB. *****************************************************************************/ static void reply_lockingX_success(blocking_lock_record *blr) { - char *outbuf = get_OutBuffer(); - int bufsize = BUFFER_SIZE; - char *inbuf = blr->inbuf; - int outsize = 0; + struct smb_request *req; - construct_reply_common(inbuf, outbuf); - set_message(inbuf,outbuf,2,0,True); + if (!(req = talloc(tmp_talloc_ctx(), struct smb_request))) { + smb_panic("Could not allocate smb_request"); + } + + init_smb_request(req, (uint8 *)blr->inbuf); + reply_outbuf(req, 2, 0); /* * As this message is a lockingX call we must handle @@ -286,11 +272,11 @@ static void reply_lockingX_success(blocking_lock_record *blr) * that here and must set up the chain info manually. */ - outsize = chain_reply(inbuf,&outbuf,blr->length,bufsize); - - outsize += chain_size; + chain_reply_new(req); - send_blocking_reply(outbuf,outsize,inbuf); + if (!send_smb(smbd_server_fd(),(char *)req->outbuf)) { + exit_server_cleanly("send_blocking_reply: send_smb failed."); + } } /**************************************************************************** @@ -299,8 +285,9 @@ static void reply_lockingX_success(blocking_lock_record *blr) static void generic_blocking_lock_error(blocking_lock_record *blr, NTSTATUS status) { - char *outbuf = get_OutBuffer(); + char outbuf[smb_size]; char *inbuf = blr->inbuf; + construct_reply_common(inbuf, outbuf); /* whenever a timeout is given w2k maps LOCK_NOT_GRANTED to @@ -395,7 +382,7 @@ static void blocking_lock_reply_error(blocking_lock_record *blr, NTSTATUS status case SMBtrans2: case SMBtranss2: { - char *outbuf = get_OutBuffer(); + char outbuf[smb_size]; char *inbuf = blr->inbuf; construct_reply_common(inbuf, outbuf); /* construct_reply_common has done us the favor to pre-fill the -- cgit From b578db69e91a088f158c1cd78a71d00045fc1da6 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Mon, 27 Aug 2007 12:04:09 +0000 Subject: r24702: Remove the old API pointers (This used to be commit 17df313db42199e26d7d2044f6a1d845aacd1a90) --- source3/smbd/blocking.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'source3/smbd/blocking.c') diff --git a/source3/smbd/blocking.c b/source3/smbd/blocking.c index 8bdc992910..86cf315930 100644 --- a/source3/smbd/blocking.c +++ b/source3/smbd/blocking.c @@ -21,8 +21,6 @@ #undef DBGC_CLASS #define DBGC_CLASS DBGC_LOCKING -extern int max_send; - /**************************************************************************** This is the structure to queue to implement blocking locks. notify. It consists of the requesting SMB and the expiry time. @@ -272,7 +270,7 @@ static void reply_lockingX_success(blocking_lock_record *blr) * that here and must set up the chain info manually. */ - chain_reply_new(req); + chain_reply(req); if (!send_smb(smbd_server_fd(),(char *)req->outbuf)) { exit_server_cleanly("send_blocking_reply: send_smb failed."); -- cgit From d76e724b1029f840c947859ba5354fa171a2b383 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 29 Aug 2007 20:49:09 +0000 Subject: r24791: Fix logic error in timeout of blocking lock processing found by Ronnie. If a lock timeout expires, we must check we can get the lock before responding with failure. Volker is writing a torture test. Jeremy. (This used to be commit 45380f356b99d575645873b05af17c504b091dc8) --- source3/smbd/blocking.c | 51 ++++++++++++++++++++++++++++--------------------- 1 file changed, 29 insertions(+), 22 deletions(-) (limited to 'source3/smbd/blocking.c') diff --git a/source3/smbd/blocking.c b/source3/smbd/blocking.c index 86cf315930..3bf6e0f99a 100644 --- a/source3/smbd/blocking.c +++ b/source3/smbd/blocking.c @@ -702,18 +702,14 @@ static void process_blocking_lock_queue(void) DEBUG(5,("process_blocking_lock_queue: examining pending lock fnum = %d for file %s\n", fsp->fnum, fsp->fsp_name )); - if (!timeval_is_zero(&blr->expire_time) && timeval_compare(&blr->expire_time, &tv_curr) <= 0) { + if(!change_to_user(conn,vuid)) { struct byte_range_lock *br_lck = brl_get_locks(NULL, fsp); /* - * Lock expired - throw away all previously - * obtained locks and return lock error. + * Remove the entry and return an error to the client. */ if (br_lck) { - DEBUG(5,("process_blocking_lock_queue: pending lock fnum = %d for file %s timed out.\n", - fsp->fnum, fsp->fsp_name )); - brl_lock_cancel(br_lck, blr->lock_pid, procid_self(), @@ -723,14 +719,16 @@ static void process_blocking_lock_queue(void) TALLOC_FREE(br_lck); } - blocking_lock_reply_error(blr,NT_STATUS_FILE_LOCK_CONFLICT); + DEBUG(0,("process_blocking_lock_queue: Unable to become user vuid=%d.\n", + vuid )); + blocking_lock_reply_error(blr,NT_STATUS_ACCESS_DENIED); DLIST_REMOVE(blocking_lock_queue, blr); free_blocking_lock_record(blr); recalc_timeout = True; continue; } - if(!change_to_user(conn,vuid)) { + if(!set_current_service(conn,SVAL(blr->inbuf,smb_flg),True)) { struct byte_range_lock *br_lck = brl_get_locks(NULL, fsp); /* @@ -747,21 +745,23 @@ static void process_blocking_lock_queue(void) TALLOC_FREE(br_lck); } - DEBUG(0,("process_blocking_lock_queue: Unable to become user vuid=%d.\n", - vuid )); + DEBUG(0,("process_blocking_lock_queue: Unable to become service Error was %s.\n", strerror(errno) )); blocking_lock_reply_error(blr,NT_STATUS_ACCESS_DENIED); DLIST_REMOVE(blocking_lock_queue, blr); free_blocking_lock_record(blr); recalc_timeout = True; + change_to_root_user(); continue; } - if(!set_current_service(conn,SVAL(blr->inbuf,smb_flg),True)) { - struct byte_range_lock *br_lck = brl_get_locks(NULL, fsp); + /* + * 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. + */ - /* - * Remove the entry and return an error to the client. - */ + if(blocking_lock_record_process(blr)) { + struct byte_range_lock *br_lck = brl_get_locks(NULL, fsp); if (br_lck) { brl_lock_cancel(br_lck, @@ -773,8 +773,6 @@ static void process_blocking_lock_queue(void) TALLOC_FREE(br_lck); } - DEBUG(0,("process_blocking_lock_queue: Unable to become service Error was %s.\n", strerror(errno) )); - blocking_lock_reply_error(blr,NT_STATUS_ACCESS_DENIED); DLIST_REMOVE(blocking_lock_queue, blr); free_blocking_lock_record(blr); recalc_timeout = True; @@ -782,16 +780,25 @@ static void process_blocking_lock_queue(void) continue; } + change_to_root_user(); + /* - * 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. + * We couldn't get the locks for this record on the list. + * If the time has expired, return a lock error. */ - if(blocking_lock_record_process(blr)) { + if (!timeval_is_zero(&blr->expire_time) && timeval_compare(&blr->expire_time, &tv_curr) <= 0) { struct byte_range_lock *br_lck = brl_get_locks(NULL, fsp); + /* + * Lock expired - throw away all previously + * obtained locks and return lock error. + */ + if (br_lck) { + DEBUG(5,("process_blocking_lock_queue: pending lock fnum = %d for file %s timed out.\n", + fsp->fnum, fsp->fsp_name )); + brl_lock_cancel(br_lck, blr->lock_pid, procid_self(), @@ -801,11 +808,11 @@ static void process_blocking_lock_queue(void) TALLOC_FREE(br_lck); } + blocking_lock_reply_error(blr,NT_STATUS_FILE_LOCK_CONFLICT); DLIST_REMOVE(blocking_lock_queue, blr); free_blocking_lock_record(blr); recalc_timeout = True; } - change_to_root_user(); } if (recalc_timeout) { -- cgit From 929e1d99209e20a9c2c95c8bdfc8eaa37b2c2291 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Thu, 30 Aug 2007 19:48:31 +0000 Subject: r24809: Consolidate the use of temporary talloc contexts. This adds the two functions talloc_stackframe() and talloc_tos(). * When a new talloc stackframe is allocated with talloc_stackframe(), then * the TALLOC_CTX returned with talloc_tos() is reset to that new * frame. Whenever that stack frame is TALLOC_FREE()'ed, then the reverse * happens: The previous talloc_tos() is restored. * * This API is designed to be robust in the sense that if someone forgets to * TALLOC_FREE() a stackframe, then the next outer one correctly cleans up and * resets the talloc_tos(). The original motivation for this patch was to get rid of the sid_string_static & friends buffers. Explicitly passing talloc context everywhere clutters code too much for my taste, so an implicit talloc_tos() is introduced here. Many of these static buffers are replaced by a single static pointer. The intended use would thus be that low-level functions can rather freely push stuff to talloc_tos, the upper layers clean up by freeing the stackframe. The more of these stackframes are used and correctly freed the more exact the memory cleanup happens. This patch removes the main_loop_talloc_ctx, tmp_talloc_ctx and lp_talloc_ctx (did I forget any?) So, never do a tmp_ctx = talloc_init("foo"); anymore, instead, use tmp_ctx = talloc_stackframe() :-) Volker (This used to be commit 6585ea2cb7f417e14540495b9c7380fe9c8c717b) --- source3/smbd/blocking.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source3/smbd/blocking.c') diff --git a/source3/smbd/blocking.c b/source3/smbd/blocking.c index 3bf6e0f99a..ef70829f74 100644 --- a/source3/smbd/blocking.c +++ b/source3/smbd/blocking.c @@ -255,7 +255,7 @@ static void reply_lockingX_success(blocking_lock_record *blr) { struct smb_request *req; - if (!(req = talloc(tmp_talloc_ctx(), struct smb_request))) { + if (!(req = talloc(talloc_tos(), struct smb_request))) { smb_panic("Could not allocate smb_request"); } @@ -526,7 +526,7 @@ static BOOL process_trans2(blocking_lock_record *blr) /* We finally got the lock, return success. */ - if (!(req = talloc(tmp_talloc_ctx(), struct smb_request))) { + if (!(req = talloc(talloc_tos(), struct smb_request))) { blocking_lock_reply_error(blr, NT_STATUS_NO_MEMORY); return True; } -- cgit From 30191d1a5704ad2b158386b511558972d539ce47 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 18 Oct 2007 17:40:25 -0700 Subject: RIP BOOL. Convert BOOL -> bool. I found a few interesting bugs in various places whilst doing this (places that assumed BOOL == int). I also need to fix the Samba4 pidl generation (next checkin). Jeremy. (This used to be commit f35a266b3cbb3e5fa6a86be60f34fe340a3ca71f) --- source3/smbd/blocking.c | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) (limited to 'source3/smbd/blocking.c') diff --git a/source3/smbd/blocking.c b/source3/smbd/blocking.c index ef70829f74..66a61449a1 100644 --- a/source3/smbd/blocking.c +++ b/source3/smbd/blocking.c @@ -66,7 +66,7 @@ static void free_blocking_lock_record(blocking_lock_record *blr) Determine if this is a secondary element of a chained SMB. **************************************************************************/ -static BOOL in_chained_smb(void) +static bool in_chained_smb(void) { return (chain_size != 0); } @@ -97,7 +97,7 @@ static void brl_timeout_fn(struct event_context *event_ctx, next processing. ****************************************************************************/ -static BOOL recalc_brl_timeout(void) +static bool recalc_brl_timeout(void) { blocking_lock_record *brl; struct timeval next_timeout; @@ -148,7 +148,7 @@ static BOOL recalc_brl_timeout(void) Function to push a blocking lock request onto the lock queue. ****************************************************************************/ -BOOL push_blocking_lock_request( struct byte_range_lock *br_lck, +bool push_blocking_lock_request( struct byte_range_lock *br_lck, const char *inbuf, int length, files_struct *fsp, int lock_timeout, @@ -160,7 +160,7 @@ BOOL push_blocking_lock_request( struct byte_range_lock *br_lck, SMB_BIG_UINT count, uint32 blocking_pid) { - static BOOL set_lock_msg; + static bool set_lock_msg; blocking_lock_record *blr; NTSTATUS status; @@ -327,7 +327,7 @@ static void reply_lockingX_error(blocking_lock_record *blr, NTSTATUS status) SMB_BIG_UINT count = (SMB_BIG_UINT)0, offset = (SMB_BIG_UINT) 0; uint32 lock_pid; unsigned char locktype = CVAL(inbuf,smb_vwv3); - BOOL large_file_format = (locktype & LOCKING_ANDX_LARGE_FILES); + bool large_file_format = (locktype & LOCKING_ANDX_LARGE_FILES); char *data; int i; @@ -345,7 +345,7 @@ static void reply_lockingX_error(blocking_lock_record *blr, NTSTATUS status) */ for(i = blr->lock_num - 1; i >= 0; i--) { - BOOL err; + bool err; lock_pid = get_lock_pid( data, i, large_file_format); count = get_lock_count( data, i, large_file_format); @@ -404,7 +404,7 @@ static void blocking_lock_reply_error(blocking_lock_record *blr, NTSTATUS status Returns True if we want to be removed from the list. *****************************************************************************/ -static BOOL process_lockingX(blocking_lock_record *blr) +static bool process_lockingX(blocking_lock_record *blr) { char *inbuf = blr->inbuf; unsigned char locktype = CVAL(inbuf,smb_vwv3); @@ -413,7 +413,7 @@ static BOOL process_lockingX(blocking_lock_record *blr) uint16 num_locks = SVAL(inbuf,smb_vwv7); SMB_BIG_UINT count = (SMB_BIG_UINT)0, offset = (SMB_BIG_UINT)0; uint32 lock_pid; - BOOL large_file_format = (locktype & LOCKING_ANDX_LARGE_FILES); + bool large_file_format = (locktype & LOCKING_ANDX_LARGE_FILES); char *data; NTSTATUS status = NT_STATUS_OK; @@ -426,7 +426,7 @@ static BOOL process_lockingX(blocking_lock_record *blr) for(; blr->lock_num < num_locks; blr->lock_num++) { struct byte_range_lock *br_lck = NULL; - BOOL err; + bool err; lock_pid = get_lock_pid( data, blr->lock_num, large_file_format); count = get_lock_count( data, blr->lock_num, large_file_format); @@ -494,7 +494,7 @@ Waiting....\n", Returns True if we want to be removed from the list. *****************************************************************************/ -static BOOL process_trans2(blocking_lock_record *blr) +static bool process_trans2(blocking_lock_record *blr) { struct smb_request *req; char params[2]; @@ -546,7 +546,7 @@ static BOOL process_trans2(blocking_lock_record *blr) Returns True if we want to be removed from the list. *****************************************************************************/ -static BOOL blocking_lock_record_process(blocking_lock_record *blr) +static bool blocking_lock_record_process(blocking_lock_record *blr) { switch(blr->com_type) { case SMBlockingX: @@ -639,7 +639,7 @@ file %s fnum = %d\n", blr->com_type, fsp->fsp_name, fsp->fnum )); Is this mid a blocking lock request on the queue ? *****************************************************************************/ -BOOL blocking_lock_was_deferred(int mid) +bool blocking_lock_was_deferred(int mid) { blocking_lock_record *blr, *next = NULL; @@ -674,7 +674,7 @@ static void process_blocking_lock_queue(void) { struct timeval tv_curr = timeval_current(); blocking_lock_record *blr, *next = NULL; - BOOL recalc_timeout = False; + bool recalc_timeout = False; /* * Go through the queue and see if we can get any of the locks. @@ -861,7 +861,7 @@ static void process_blocking_lock_cancel_message(struct messaging_context *ctx, Send ourselves a blocking lock cancelled message. Handled asynchronously above. *****************************************************************************/ -BOOL blocking_lock_cancel(files_struct *fsp, +bool blocking_lock_cancel(files_struct *fsp, uint32 lock_pid, SMB_BIG_UINT offset, SMB_BIG_UINT count, @@ -869,7 +869,7 @@ BOOL blocking_lock_cancel(files_struct *fsp, unsigned char locktype, NTSTATUS err) { - static BOOL initialized; + static bool initialized; char msg[MSG_BLOCKING_LOCK_CANCEL_SIZE]; blocking_lock_record *blr; -- cgit From c3250149e12338fac5093991b385ad2807c92d1f Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 30 Oct 2007 16:22:24 -0700 Subject: Add new parameter, "min receivefile size" (by default set to zero). If non-zero, writeX calls greater than this value will be left in the socket buffer for later handling with recvfile (or userspace equivalent). Definition of recvfile for your system is left as an exercise for the reader (I'm working on getting splice working :-). Jeremy. (This used to be commit 11c03b75ddbcb6e36b231bb40a1773d1c550621c) --- source3/smbd/blocking.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source3/smbd/blocking.c') diff --git a/source3/smbd/blocking.c b/source3/smbd/blocking.c index 66a61449a1..0078bb7d13 100644 --- a/source3/smbd/blocking.c +++ b/source3/smbd/blocking.c @@ -259,7 +259,7 @@ static void reply_lockingX_success(blocking_lock_record *blr) smb_panic("Could not allocate smb_request"); } - init_smb_request(req, (uint8 *)blr->inbuf); + init_smb_request(req, (uint8 *)blr->inbuf, 0); reply_outbuf(req, 2, 0); /* @@ -531,7 +531,7 @@ static bool process_trans2(blocking_lock_record *blr) return True; } - init_smb_request(req, (uint8 *)blr->inbuf); + init_smb_request(req, (uint8 *)blr->inbuf, 0); SCVAL(req->inbuf, smb_com, SMBtrans2); SSVAL(params,0,0); -- cgit From 9254bb4ef1c3c3a52ea8e935edb0e7a86ec3ea7a Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Fri, 4 Jan 2008 12:56:23 -0800 Subject: Refactor the crypto code after a very helpful conversation with Volker. Mostly making sure we have data on the incoming packet type, not stored in the smb header. Jeremy. (This used to be commit c4e5a505043965eec77b5bb9bc60957e8f3b97c8) --- source3/smbd/blocking.c | 34 +++++++++++++++++++++------------- 1 file changed, 21 insertions(+), 13 deletions(-) (limited to 'source3/smbd/blocking.c') diff --git a/source3/smbd/blocking.c b/source3/smbd/blocking.c index 0078bb7d13..c56f635dde 100644 --- a/source3/smbd/blocking.c +++ b/source3/smbd/blocking.c @@ -41,6 +41,7 @@ typedef struct _blocking_lock_record { enum brl_type lock_type; char *inbuf; int length; + bool encrypted; } blocking_lock_record; /* dlink list we store pending lock records on. */ @@ -149,7 +150,7 @@ static bool recalc_brl_timeout(void) ****************************************************************************/ bool push_blocking_lock_request( struct byte_range_lock *br_lck, - const char *inbuf, int length, + const struct smb_request *req, files_struct *fsp, int lock_timeout, int lock_num, @@ -161,6 +162,7 @@ bool push_blocking_lock_request( struct byte_range_lock *br_lck, uint32 blocking_pid) { static bool set_lock_msg; + size_t length = smb_len(req->inbuf)+4; blocking_lock_record *blr; NTSTATUS status; @@ -188,7 +190,7 @@ bool push_blocking_lock_request( struct byte_range_lock *br_lck, return False; } - blr->com_type = CVAL(inbuf,smb_com); + blr->com_type = CVAL(req->inbuf,smb_com); blr->fsp = fsp; if (lock_timeout == -1) { blr->expire_time.tv_sec = 0; @@ -204,8 +206,9 @@ bool push_blocking_lock_request( struct byte_range_lock *br_lck, blr->lock_type = lock_type; blr->offset = offset; blr->count = count; - memcpy(blr->inbuf, inbuf, length); + memcpy(blr->inbuf, req->inbuf, length); blr->length = length; + blr->encrypted = req->encrypted; /* Add a pending lock record for this. */ status = brl_lock(smbd_messaging_context(), br_lck, @@ -242,7 +245,7 @@ bool push_blocking_lock_request( struct byte_range_lock *br_lck, blr->fsp->fnum, blr->fsp->fsp_name )); /* Push the MID of this packet on the signing queue. */ - srv_defer_sign_response(SVAL(inbuf,smb_mid)); + srv_defer_sign_response(SVAL(req->inbuf,smb_mid)); return True; } @@ -259,7 +262,7 @@ static void reply_lockingX_success(blocking_lock_record *blr) smb_panic("Could not allocate smb_request"); } - init_smb_request(req, (uint8 *)blr->inbuf, 0); + init_smb_request(req, (uint8 *)blr->inbuf, 0, blr->encrypted); reply_outbuf(req, 2, 0); /* @@ -272,8 +275,10 @@ static void reply_lockingX_success(blocking_lock_record *blr) chain_reply(req); - if (!send_smb(smbd_server_fd(),(char *)req->outbuf)) { - exit_server_cleanly("send_blocking_reply: send_smb failed."); + 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."); } } @@ -309,8 +314,9 @@ static void generic_blocking_lock_error(blocking_lock_record *blr, NTSTATUS stat } ERROR_NT(status); - if (!send_smb(smbd_server_fd(),outbuf)) { - exit_server_cleanly("generic_blocking_lock_error: send_smb failed."); + if (!srv_send_smb(smbd_server_fd(),outbuf, + IS_CONN_ENCRYPTED(blr->fsp->conn))) { + exit_server_cleanly("generic_blocking_lock_error: srv_send_smb failed."); } } @@ -388,8 +394,10 @@ static void blocking_lock_reply_error(blocking_lock_record *blr, NTSTATUS status */ SCVAL(outbuf,smb_com,SMBtrans2); ERROR_NT(status); - if (!send_smb(smbd_server_fd(),outbuf)) { - exit_server_cleanly("blocking_lock_reply_error: send_smb failed."); + 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."); } break; } @@ -531,12 +539,12 @@ static bool process_trans2(blocking_lock_record *blr) return True; } - init_smb_request(req, (uint8 *)blr->inbuf, 0); + init_smb_request(req, (uint8 *)blr->inbuf, 0, blr->encrypted); SCVAL(req->inbuf, smb_com, SMBtrans2); SSVAL(params,0,0); /* Fake up max_data_bytes here - we know it fits. */ - send_trans2_replies(req, params, 2, NULL, 0, 0xffff); + send_trans2_replies(blr->fsp->conn, req, params, 2, NULL, 0, 0xffff); return True; } -- cgit From 6503c7338e2c46bf3c660759c078ff51835a40e9 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Fri, 4 Jan 2008 13:59:26 -0800 Subject: Fix interesting bug found with make valgrindtest. When cancelling a lock due to file closure make sure we null out the fsp pointer so it isn't dangling. This is an old bug (not related to the new changes). Jeremy. (This used to be commit b5ee972b0c04b4d119573d95ac458a3b6be30c5c) --- source3/smbd/blocking.c | 24 ++++++++++++++---------- 1 file changed, 14 insertions(+), 10 deletions(-) (limited to 'source3/smbd/blocking.c') diff --git a/source3/smbd/blocking.c b/source3/smbd/blocking.c index c56f635dde..41963166f7 100644 --- a/source3/smbd/blocking.c +++ b/source3/smbd/blocking.c @@ -303,19 +303,20 @@ static void generic_blocking_lock_error(blocking_lock_record *blr, NTSTATUS stat /* Store the last lock error. */ files_struct *fsp = blr->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; + 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; + } } ERROR_NT(status); - if (!srv_send_smb(smbd_server_fd(),outbuf, - IS_CONN_ENCRYPTED(blr->fsp->conn))) { + if (!srv_send_smb(smbd_server_fd(),outbuf, blr->encrypted)) { exit_server_cleanly("generic_blocking_lock_error: srv_send_smb failed."); } } @@ -605,6 +606,9 @@ file %s fnum = %d\n", blr->com_type, fsp->fsp_name, fsp->fnum )); locktype, NT_STATUS_RANGE_NOT_LOCKED); } + /* We're closing the file fsp here, so ensure + * we don't have a dangling pointer. */ + blr->fsp = NULL; } } } -- cgit From 4a413e4bd177402a1697cffac43d35e94cc55102 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Sat, 5 Jan 2008 01:17:33 -0800 Subject: Fix %d / size_t printf arg missmatch. Jeremy. (This used to be commit 3e3205309b75edf7d29633525adfdceb5f8856eb) --- source3/smbd/blocking.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source3/smbd/blocking.c') diff --git a/source3/smbd/blocking.c b/source3/smbd/blocking.c index 41963166f7..4e0d5289f8 100644 --- a/source3/smbd/blocking.c +++ b/source3/smbd/blocking.c @@ -238,9 +238,9 @@ bool push_blocking_lock_request( struct byte_range_lock *br_lck, set_lock_msg = True; } - DEBUG(3,("push_blocking_lock_request: lock request length=%d blocked with " + DEBUG(3,("push_blocking_lock_request: lock request length=%u blocked with " "expiry time (%u sec. %u usec) (+%d msec) for fnum = %d, name = %s\n", - length, (unsigned int)blr->expire_time.tv_sec, + (unsigned int)length, (unsigned int)blr->expire_time.tv_sec, (unsigned int)blr->expire_time.tv_usec, lock_timeout, blr->fsp->fnum, blr->fsp->fsp_name )); -- cgit From 5ddb2abf7611a93960056075ea56f992329c3678 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Sun, 6 Jan 2008 16:15:45 +0100 Subject: Some more talloc_tos() (This used to be commit 444e35e7df1f13fc285183da8fb41b30ad99a3fa) --- source3/smbd/blocking.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'source3/smbd/blocking.c') diff --git a/source3/smbd/blocking.c b/source3/smbd/blocking.c index 4e0d5289f8..479361a8c1 100644 --- a/source3/smbd/blocking.c +++ b/source3/smbd/blocking.c @@ -625,7 +625,7 @@ void remove_pending_lock_requests_by_mid(int mid) next = blr->next; if(SVAL(blr->inbuf,smb_mid) == mid) { files_struct *fsp = blr->fsp; - struct byte_range_lock *br_lck = brl_get_locks(NULL, fsp); + struct byte_range_lock *br_lck = brl_get_locks(talloc_tos(), fsp); if (br_lck) { DEBUG(10,("remove_pending_lock_requests_by_mid - removing request type %d for \ @@ -715,7 +715,7 @@ static void process_blocking_lock_queue(void) fsp->fnum, fsp->fsp_name )); if(!change_to_user(conn,vuid)) { - struct byte_range_lock *br_lck = brl_get_locks(NULL, fsp); + struct byte_range_lock *br_lck = brl_get_locks(talloc_tos(), fsp); /* * Remove the entry and return an error to the client. @@ -741,7 +741,7 @@ static void process_blocking_lock_queue(void) } if(!set_current_service(conn,SVAL(blr->inbuf,smb_flg),True)) { - struct byte_range_lock *br_lck = brl_get_locks(NULL, fsp); + struct byte_range_lock *br_lck = brl_get_locks(talloc_tos(), fsp); /* * Remove the entry and return an error to the client. @@ -773,7 +773,7 @@ static void process_blocking_lock_queue(void) */ if(blocking_lock_record_process(blr)) { - struct byte_range_lock *br_lck = brl_get_locks(NULL, fsp); + struct byte_range_lock *br_lck = brl_get_locks(talloc_tos(), fsp); if (br_lck) { brl_lock_cancel(br_lck, @@ -800,7 +800,7 @@ static void process_blocking_lock_queue(void) */ if (!timeval_is_zero(&blr->expire_time) && timeval_compare(&blr->expire_time, &tv_curr) <= 0) { - struct byte_range_lock *br_lck = brl_get_locks(NULL, fsp); + struct byte_range_lock *br_lck = brl_get_locks(talloc_tos(), fsp); /* * Lock expired - throw away all previously -- cgit