mirror of
https://github.com/samba-team/samba.git
synced 2024-12-24 21:34:56 +03:00
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 commit is contained in:
parent
e1dd03ecda
commit
193cb53824
@ -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 :
|
||||
|
@ -104,6 +104,8 @@ void close_file(files_struct *fsp, BOOL normal_close)
|
||||
int token;
|
||||
connection_struct *conn = fsp->conn;
|
||||
|
||||
remove_pending_lock_requests_by_fid(fsp);
|
||||
|
||||
close_filestruct(fsp);
|
||||
|
||||
#if USE_READ_PREDICTION
|
||||
@ -142,8 +144,6 @@ void close_file(files_struct *fsp, BOOL normal_close)
|
||||
string_free(&fsp->fsp_name);
|
||||
}
|
||||
|
||||
remove_pending_lock_requests_by_fid(fsp);
|
||||
|
||||
file_free(fsp);
|
||||
}
|
||||
|
||||
|
@ -28,6 +28,7 @@ extern int Client;
|
||||
extern int oplock_sock;
|
||||
extern int smb_read_error;
|
||||
extern int global_oplock_break;
|
||||
extern int chain_size;
|
||||
extern BOOL case_sensitive;
|
||||
extern BOOL case_preserve;
|
||||
extern BOOL short_case_preserve;
|
||||
@ -1029,7 +1030,7 @@ void remove_pending_change_notify_requests_by_fid(files_struct *fsp)
|
||||
change_notify_buf *prev = NULL;
|
||||
|
||||
while(cnbp != NULL) {
|
||||
if(cnbp->fsp == fsp) {
|
||||
if(cnbp->fsp->fnum == fsp->fnum) {
|
||||
free((char *)ubi_slRemNext( &change_notify_queue, prev));
|
||||
cnbp = (change_notify_buf *)(prev ? ubi_slNext(prev) : ubi_slFirst(&change_notify_queue));
|
||||
continue;
|
||||
@ -1089,6 +1090,13 @@ void process_pending_change_notify_queue(time_t t)
|
||||
uint16 vuid = (lp_security() == SEC_SHARE) ? UID_FIELD_INVALID :
|
||||
SVAL(cnbp->request_buf,smb_uid);
|
||||
|
||||
/*
|
||||
* Ensure we don't have any old chain_fsp values
|
||||
* sitting around....
|
||||
*/
|
||||
chain_size = 0;
|
||||
file_chain_reset();
|
||||
|
||||
if(!become_user(conn,vuid)) {
|
||||
DEBUG(0,("process_pending_change_notify_queue: Unable to become user vuid=%d.\n",
|
||||
vuid ));
|
||||
|
Loading…
Reference in New Issue
Block a user