Fix bug #7744 - "dfree cache time" doesn't work.
authorJeremy Allison <jra@samba.org>
Wed, 20 Oct 2010 20:58:15 +0000 (13:58 -0700)
committerKarolin Seeger <kseeger@samba.org>
Thu, 11 Nov 2010 11:12:31 +0000 (12:12 +0100)
There is a bug in processing the dfree cache time, which is associated with the
smbd idle timer. The idle timer call conn_idle_all(), which updates the
conn->lastused timestamp. The dfree cache time code in smbd/dfree.c depends on
conn->lastused being up to date to refresh the cached dfree value.

Unfortunately the conn_idle_all() returns early if any of the connection
structs is not idle, never updating any further conn->lastused timestamps. If
(as is common due to an IPC$ connection) there are more than one used
connection struct, then the conn->lastused timestamps after the IPC$ connection
in the connection list will never be updated.

Ensure we always update conn->lastused for all connections when calling
conn_idle_all().

Jeremy.

source3/smbd/conn.c

index 959fcd7754de3f6de6bc432c34b5c663135592da..37c2311be8724fed3b6fc14d32513f840019a064 100644 (file)
@@ -197,6 +197,7 @@ bool conn_idle_all(struct smbd_server_connection *sconn,time_t t)
        int deadtime = lp_deadtime()*60;
        pipes_struct *plist = NULL;
        connection_struct *conn;
+       bool ret = true;
 
        if (deadtime <= 0)
                deadtime = DEFAULT_SMBD_TIMEOUT;
@@ -209,6 +210,7 @@ bool conn_idle_all(struct smbd_server_connection *sconn,time_t t)
                if (conn->lastused != conn->lastused_count) {
                        conn->lastused = t;
                        conn->lastused_count = t;
+                       age = 0;
                }
 
                /* close dirptrs on connections that are idle */
@@ -217,7 +219,7 @@ bool conn_idle_all(struct smbd_server_connection *sconn,time_t t)
                }
 
                if (conn->num_files_open > 0 || age < deadtime) {
-                       return False;
+                       ret = false;
                }
        }
 
@@ -229,11 +231,12 @@ bool conn_idle_all(struct smbd_server_connection *sconn,time_t t)
        for (plist = get_first_internal_pipe(); plist;
             plist = get_next_internal_pipe(plist)) {
                if (num_pipe_handles(plist->pipe_handles) != 0) {
-                       return False;
+                       ret = false;
+                       break;
                }
        }
        
-       return True;
+       return ret;
 }
 
 /****************************************************************************