diff options
-rw-r--r-- | source/include/local.h | 3 | ||||
-rw-r--r-- | source/include/proto.h | 1 | ||||
-rw-r--r-- | source/smbd/blocking.c | 10 | ||||
-rw-r--r-- | source/smbd/process.c | 62 |
4 files changed, 52 insertions, 24 deletions
diff --git a/source/include/local.h b/source/include/local.h index cdff63aa8e5..7a444a8b247 100644 --- a/source/include/local.h +++ b/source/include/local.h @@ -129,7 +129,8 @@ #define SMBD_RELOAD_CHECK (180) #define IDLE_CLOSED_TIMEOUT (60) #define DPTR_IDLE_TIMEOUT (120) -#define SMBD_SELECT_LOOP (60) +#define SMBD_SELECT_TIMEOUT (60) +#define SMBD_SELECT_TIMEOUT_WITH_PENDING_LOCKS (10) #define NMBD_SELECT_LOOP (10) #define BROWSE_INTERVAL (60) #define REGISTRATION_INTERVAL (10*60) diff --git a/source/include/proto.h b/source/include/proto.h index 1f4f522ac77..f357a5b1926 100644 --- a/source/include/proto.h +++ b/source/include/proto.h @@ -2261,6 +2261,7 @@ void rpcclient_init(void); BOOL push_blocking_lock_request( char *inbuf, int length, int lock_timeout, int lock_num); void remove_pending_lock_requests_by_fid(files_struct *fsp); void remove_pending_lock_requests_by_mid(int mid); +BOOL blocking_locks_pending(void); void process_blocking_lock_queue(time_t t); /*The following definitions come from smbd/chgpasswd.c */ diff --git a/source/smbd/blocking.c b/source/smbd/blocking.c index b82ad88e94c..19d73a74f9a 100644 --- a/source/smbd/blocking.c +++ b/source/smbd/blocking.c @@ -522,6 +522,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. *****************************************************************************/ diff --git a/source/smbd/process.c b/source/smbd/process.c index 1e263249f38..f4ff2e86dab 100644 --- a/source/smbd/process.c +++ b/source/smbd/process.c @@ -740,21 +740,16 @@ int chain_reply(char *inbuf,char *outbuf,int size,int bufsize) Process any timeout housekeeping. Return False if the caler should exit. ****************************************************************************/ -static BOOL timeout_processing(int *counter, int deadtime, - int *last_keepalive, int *service_load_counter) +static BOOL timeout_processing(int deadtime) { extern int Client; - + static time_t last_smb_conf_reload_time = 0; + static time_t last_keepalive_sent_time = 0; + static time_t last_idle_closed_check = 0; time_t t; BOOL allidle = True; extern int keepalive; - if (*counter > 365 * 3600) /* big number of seconds. */ - { - *counter = 0; - *service_load_counter = 0; - } - if (smb_read_error == READ_EOF) { DEBUG(3,("end of file from client\n")); @@ -770,16 +765,24 @@ static BOOL timeout_processing(int *counter, int deadtime, t = time(NULL); + if(last_smb_conf_reload_time == 0) + last_smb_conf_reload_time = t; + + if(last_keepalive_sent_time == 0) + last_keepalive_sent_time = t; + + if(last_idle_closed_check == 0) + last_idle_closed_check = t; + /* become root again if waiting */ unbecome_user(); /* check for smb.conf reload */ - if (*counter >= *service_load_counter + SMBD_RELOAD_CHECK) + if (t >= last_smb_conf_reload_time + SMBD_RELOAD_CHECK) { - *service_load_counter = *counter; - /* reload services, if files have changed. */ reload_services(True); + last_smb_conf_reload_time = t; } /* @@ -792,6 +795,7 @@ static BOOL timeout_processing(int *counter, int deadtime, DEBUG(0,("Reloading services after SIGHUP\n")); reload_services(False); reload_after_sighup = False; + last_smb_conf_reload_time = t; /* * Use this as an excuse to print some stats. */ @@ -799,13 +803,15 @@ static BOOL timeout_processing(int *counter, int deadtime, } /* automatic timeout if all connections are closed */ - if (conn_num_open()==0 && *counter >= IDLE_CLOSED_TIMEOUT) + if (conn_num_open()==0 && (t - last_idle_closed_check) >= IDLE_CLOSED_TIMEOUT) { DEBUG( 2, ( "Closing idle connection\n" ) ); return False; } + else + last_idle_closed_check = t; - if (keepalive && (*counter-*last_keepalive)>keepalive) + if (keepalive && (t - last_keepalive_sent_time)>keepalive) { struct cli_state *cli = server_client(); if (!send_keepalive(Client)) { @@ -816,7 +822,7 @@ static BOOL timeout_processing(int *counter, int deadtime, connected */ if (cli && cli->initialised) send_keepalive(cli->fd); - *last_keepalive = *counter; + last_keepalive_sent_time = t; } /* check for connection timeouts */ @@ -895,9 +901,6 @@ machine %s in domain %s.\n", global_myname, global_myworkgroup )); void smbd_process(void) { extern int smb_echo_count; - int counter = SMBD_SELECT_LOOP; - int service_load_counter = 0; - int last_keepalive=0; InBuffer = (char *)malloc(BUFFER_SIZE + SAFETY_MARGIN); OutBuffer = (char *)malloc(BUFFER_SIZE + SAFETY_MARGIN); @@ -928,6 +931,7 @@ void smbd_process(void) { int deadtime = lp_deadtime()*60; BOOL got_smb = False; + int select_timeout = SMBD_SELECT_TIMEOUT*1000; if (deadtime <= 0) deadtime = DEFAULT_SMBD_TIMEOUT; @@ -939,11 +943,16 @@ void smbd_process(void) errno = 0; - while(!receive_message_or_smb(InBuffer,BUFFER_SIZE,SMBD_SELECT_LOOP*1000,&got_smb)) + while(!receive_message_or_smb(InBuffer,BUFFER_SIZE,select_timeout,&got_smb)) { - if(!timeout_processing(&counter, deadtime, &last_keepalive, &service_load_counter)) + if(!timeout_processing(deadtime)) return; - counter += SMBD_SELECT_LOOP; + /* + * Increase the select timeout back to SMBD_SELECT_TIMEOUT if we + * have removed any blocking locks. JRA. + */ + select_timeout = blocking_locks_pending() ? SMBD_SELECT_TIMEOUT_WITH_PENDING_LOCKS*1000 : + SMBD_SELECT_TIMEOUT*1000; } if(got_smb) { @@ -961,9 +970,16 @@ void smbd_process(void) process_smb(InBuffer, OutBuffer); if(smb_echo_count != num_echos) { - if(!timeout_processing(&counter, deadtime, &last_keepalive, &service_load_counter)) + if(!timeout_processing(deadtime)) return; - counter += SMBD_SELECT_LOOP; + + /* + * Lower the select timeout to SMBD_SELECT_TIMEOUT_WITH_PENDING_LOCKS if we + * now have any blocking locks pending. JRA. + */ + + select_timeout = blocking_locks_pending() ? SMBD_SELECT_TIMEOUT_WITH_PENDING_LOCKS*1000 : + SMBD_SELECT_TIMEOUT*1000; } } else |