From: Jeremy Allison Date: Tue, 19 Oct 2010 18:11:56 +0000 (-0700) Subject: Add deadtime detection for SMB2. Correctly update lastused timestamp across all activ... X-Git-Url: http://git.samba.org/?p=abartlet%2Fsamba.git%2F.git;a=commitdiff_plain;h=e7d0f478ee529500461f80f2fd51987c9255d345 Add deadtime detection for SMB2. Correctly update lastused timestamp across all active tcons. Should fix dfree cache not updating bug. --- diff --git a/source3/smbd/conn.c b/source3/smbd/conn.c index e8f14fd9189..8de8ce2e11a 100644 --- a/source3/smbd/conn.c +++ b/source3/smbd/conn.c @@ -244,35 +244,93 @@ bool conn_close_all(struct smbd_server_connection *sconn) return ret; } +/**************************************************************************** + Update last used timestamps. +****************************************************************************/ + +static void conn_lastused_update(struct smbd_server_connection *sconn,time_t t) +{ + if (sconn->using_smb2) { + /* SMB2 */ + struct smbd_smb2_session *sess; + for (sess = sconn->smb2.sessions.list; sess; sess = sess->next) { + struct smbd_smb2_tcon *ptcon; + + for (ptcon = sess->tcons.list; ptcon; ptcon = ptcon->next) { + connection_struct *conn = ptcon->compat_conn; + /* Update if connection wasn't idle. */ + if (conn && conn->lastused != conn->lastused_count) { + conn->lastused = t; + conn->lastused_count = t; + } + } + } + } else { + /* SMB1 */ + connection_struct *conn; + for (conn=sconn->smb1.tcons.Connections;conn;conn=conn->next) { + /* Update if connection wasn't idle. */ + if (conn->lastused != conn->lastused_count) { + conn->lastused = t; + conn->lastused_count = t; + } + } + } +} + /**************************************************************************** Idle inactive connections. ****************************************************************************/ -bool conn_idle_all(struct smbd_server_connection *sconn,time_t t) +bool conn_idle_all(struct smbd_server_connection *sconn, time_t t) { int deadtime = lp_deadtime()*60; - connection_struct *conn; - if (deadtime <= 0) + conn_lastused_update(sconn, t); + + if (deadtime <= 0) { deadtime = DEFAULT_SMBD_TIMEOUT; + } - for (conn=sconn->smb1.tcons.Connections;conn;conn=conn->next) { + if (sconn->using_smb2) { + /* SMB2 */ + struct smbd_smb2_session *sess; + for (sess = sconn->smb2.sessions.list; sess; sess = sess->next) { + struct smbd_smb2_tcon *ptcon; - time_t age = t - conn->lastused; + for (ptcon = sess->tcons.list; ptcon; ptcon = ptcon->next) { + time_t age; + connection_struct *conn = ptcon->compat_conn; - /* Update if connection wasn't idle. */ - if (conn->lastused != conn->lastused_count) { - conn->lastused = t; - conn->lastused_count = t; - } + if (conn == NULL) { + continue; + } - /* close dirptrs on connections that are idle */ - if (age > DPTR_IDLE_TIMEOUT) { - dptr_idlecnum(conn); + age = t - conn->lastused; + /* close dirptrs on connections that are idle */ + if (age > DPTR_IDLE_TIMEOUT) { + dptr_idlecnum(conn); + } + + if (conn->num_files_open > 0 || age < deadtime) { + return false; + } + } } + } else { + /* SMB1 */ + connection_struct *conn; + for (conn=sconn->smb1.tcons.Connections;conn;conn=conn->next) { + time_t age = t - conn->lastused; - if (conn->num_files_open > 0 || age < deadtime) { - return False; + /* close dirptrs on connections that are idle */ + if (age > DPTR_IDLE_TIMEOUT) { + dptr_idlecnum(conn); + } + + if (conn->num_files_open > 0 || age < deadtime) { + return false; + } } } @@ -281,10 +339,10 @@ bool conn_idle_all(struct smbd_server_connection *sconn,time_t t) * idle with a handle open. */ if (check_open_pipes()) { - return False; + return false; } - return True; + return true; } /**************************************************************************** diff --git a/source3/smbd/process.c b/source3/smbd/process.c index ff2b8fc67d5..f2aa23e3e09 100644 --- a/source3/smbd/process.c +++ b/source3/smbd/process.c @@ -2467,21 +2467,9 @@ static bool deadtime_fn(const struct timeval *now, void *private_data) struct smbd_server_connection *sconn = (struct smbd_server_connection *)private_data; - if (sconn->using_smb2) { - /* TODO: implement real idle check */ - if (sconn->smb2.sessions.list) { - return true; - } - DEBUG( 2, ( "Closing idle SMB2 connection\n" ) ); - messaging_send(sconn->msg_ctx, - messaging_server_id(sconn->msg_ctx), - MSG_SHUTDOWN, &data_blob_null); - return false; - } - if ((conn_num_open(sconn) == 0) || (conn_idle_all(sconn, now->tv_sec))) { - DEBUG( 2, ( "Closing idle SMB1 connection\n" ) ); + DEBUG( 2, ( "Closing idle connection\n" ) ); messaging_send(sconn->msg_ctx, messaging_server_id(sconn->msg_ctx), MSG_SHUTDOWN, &data_blob_null);