[SCM] Samba Shared Repository - branch v3-6-test updated

Jeremy Allison jra at samba.org
Tue Oct 19 15:47:02 MDT 2010


The branch, v3-6-test has been updated
       via  f91c4b0 Add deadtime detection for SMB2. Correctly update lastused timestamp across all active tcons. Should fix dfree cache not updating bug.
       via  bdd78af Add SMB2 paths to smbd/conn.c. Except for conn_idle_all(), to be cleaned up next. (cherry picked from commit dd9317d8790bc7f32a4af1014c70ca55779933aa)
       via  a786890 Copyright/whitespace/comment cleanup in preparation for adding SMB2 paths. (cherry picked from commit 437f9436d51314e2bf55708d4f964189c493779a)
       via  3856dfc Move tcons.num_open from smb1 to sconn->num_tcons_open as this is needed for SMB2 also.
      from  1fec543 This is typo fix patch for smbcacls.1.xml .

http://gitweb.samba.org/?p=samba.git;a=shortlog;h=v3-6-test


- Log -----------------------------------------------------------------
commit f91c4b00dc7f139af6cedc6eae0738d29b28fe23
Author: Jeremy Allison <jra at samba.org>
Date:   Tue Oct 19 11:11:56 2010 -0700

    Add deadtime detection for SMB2. Correctly update lastused timestamp across all active tcons. Should fix dfree cache not updating bug.

commit bdd78af6c5fce2cbec880dc391df9274ae8707ba
Author: Jeremy Allison <jra at samba.org>
Date:   Tue Oct 19 10:12:42 2010 -0700

    Add SMB2 paths to smbd/conn.c. Except for conn_idle_all(), to be cleaned up next.
    (cherry picked from commit dd9317d8790bc7f32a4af1014c70ca55779933aa)

commit a78689056569e4f4b3c6b49527995a8961ee7c2e
Author: Jeremy Allison <jra at samba.org>
Date:   Tue Oct 19 10:04:27 2010 -0700

    Copyright/whitespace/comment cleanup in preparation for adding SMB2 paths.
    (cherry picked from commit 437f9436d51314e2bf55708d4f964189c493779a)

commit 3856dfccce4241b8872bb6092b6edfc7a5f26f31
Author: Jeremy Allison <jra at samba.org>
Date:   Tue Oct 19 13:25:51 2010 -0700

    Move tcons.num_open from smb1 to sconn->num_tcons_open as this is needed for SMB2 also.

-----------------------------------------------------------------------

Summary of changes:
 source3/smbd/conn.c      |  289 ++++++++++++++++++++++++++++++++++------------
 source3/smbd/globals.h   |   14 ++-
 source3/smbd/msdfs.c     |    2 +-
 source3/smbd/process.c   |   13 +--
 source3/smbd/smb2_tcon.c |    3 +
 5 files changed, 231 insertions(+), 90 deletions(-)


Changeset truncated at 500 lines:

diff --git a/source3/smbd/conn.c b/source3/smbd/conn.c
index fffb5bf..710c182 100644
--- a/source3/smbd/conn.c
+++ b/source3/smbd/conn.c
@@ -1,19 +1,20 @@
-/* 
+/*
    Unix SMB/CIFS implementation.
    Manage connections_struct structures
    Copyright (C) Andrew Tridgell 1998
    Copyright (C) Alexander Bokovoy 2002
-   
+   Copyright (C) Jeremy Allison 2010
+
    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 3 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, see <http://www.gnu.org/licenses/>.
 */
@@ -25,40 +26,60 @@
  * maximum size of the bitmap is the largest positive integer, but you will hit
  * the "max connections" limit, looong before that.
  */
+
 #define BITMAP_BLOCK_SZ 128
 
 /****************************************************************************
-init the conn structures
+ Init the conn structures.
 ****************************************************************************/
+
 void conn_init(struct smbd_server_connection *sconn)
 {
 	sconn->smb1.tcons.Connections = NULL;
-	sconn->smb1.tcons.num_open = 0;
 	sconn->smb1.tcons.bmap = bitmap_talloc(sconn, BITMAP_BLOCK_SZ);
 }
 
 /****************************************************************************
-return the number of open connections
+ Return the number of open connections.
 ****************************************************************************/
+
 int conn_num_open(struct smbd_server_connection *sconn)
 {
-	return sconn->smb1.tcons.num_open;
+	return sconn->num_tcons_open;
 }
 
-
 /****************************************************************************
-check if a snum is in use
+ Check if a snum is in use.
 ****************************************************************************/
+
 bool conn_snum_used(int snum)
 {
 	struct smbd_server_connection *sconn = smbd_server_conn;
-	connection_struct *conn;
-	for (conn=sconn->smb1.tcons.Connections;conn;conn=conn->next) {
-		if (conn->params->service == snum) {
-			return(True);
+
+	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) {
+				if (ptcon->compat_conn &&
+						ptcon->compat_conn->params &&
+						(ptcon->compat_conn->params->service = snum)) {
+					return true;
+				}
+			}
+		}
+	} else {
+		/* SMB1 */
+		connection_struct *conn;
+		for (conn=sconn->smb1.tcons.Connections;conn;conn=conn->next) {
+			if (conn->params->service == snum) {
+				return true;
+			}
 		}
 	}
-	return(False);
+	return false;
 }
 
 /****************************************************************************
@@ -67,16 +88,31 @@ bool conn_snum_used(int snum)
 
 connection_struct *conn_find(struct smbd_server_connection *sconn,unsigned cnum)
 {
-	int count=0;
-	connection_struct *conn;
-
-	for (conn=sconn->smb1.tcons.Connections;conn;conn=conn->next,count++) {
-		if (conn->cnum == cnum) {
-			if (count > 10) {
-				DLIST_PROMOTE(sconn->smb1.tcons.Connections,
-					      conn);
+	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) {
+				if (ptcon->compat_conn &&
+						ptcon->compat_conn->cnum == cnum) {
+					return ptcon->compat_conn;
+				}
+			}
+		}
+	} else {
+		/* SMB1 */
+		int count=0;
+		connection_struct *conn;
+		for (conn=sconn->smb1.tcons.Connections;conn;conn=conn->next,count++) {
+			if (conn->cnum == cnum) {
+				if (count > 10) {
+					DLIST_PROMOTE(sconn->smb1.tcons.Connections,
+						conn);
+				}
+				return conn;
 			}
-			return conn;
 		}
 	}
 
@@ -84,10 +120,11 @@ connection_struct *conn_find(struct smbd_server_connection *sconn,unsigned cnum)
 }
 
 /****************************************************************************
-  find first available connection slot, starting from a random position.
-The randomisation stops problems with the server dieing and clients
-thinking the server is still available.
+ Find first available connection slot, starting from a random position.
+ The randomisation stops problems with the server dieing and clients
+ thinking the server is still available.
 ****************************************************************************/
+
 connection_struct *conn_new(struct smbd_server_connection *sconn)
 {
 	connection_struct *conn;
@@ -95,6 +132,7 @@ connection_struct *conn_new(struct smbd_server_connection *sconn)
         int find_offset = 1;
 
 	if (sconn->using_smb2) {
+		/* SMB2 */
 		if (!(conn=TALLOC_ZERO_P(NULL, connection_struct)) ||
 		    !(conn->params = TALLOC_P(conn, struct share_params))) {
 			DEBUG(0,("TALLOC_ZERO() failed!\n"));
@@ -105,9 +143,10 @@ connection_struct *conn_new(struct smbd_server_connection *sconn)
 		return conn;
 	}
 
+	/* SMB1 */
 find_again:
 	i = bitmap_find(sconn->smb1.tcons.bmap, find_offset);
-	
+
 	if (i == -1) {
                 /* Expand the connections bitmap. */
                 int             oldsz = sconn->smb1.tcons.bmap->n;
@@ -161,11 +200,11 @@ find_again:
 
 	bitmap_set(sconn->smb1.tcons.bmap, i);
 
-	sconn->smb1.tcons.num_open++;
+	sconn->num_tcons_open++;
 
 	string_set(&conn->connectpath,"");
 	string_set(&conn->origpath,"");
-	
+
 	DLIST_ADD(sconn->smb1.tcons.Connections, conn);
 
 	return conn;
@@ -173,28 +212,27 @@ find_again:
 
 /****************************************************************************
  Close all conn structures.
-return true if any were closed
+ Return true if any were closed.
 ****************************************************************************/
+
 bool conn_close_all(struct smbd_server_connection *sconn)
 {
+	bool ret = false;
 	if (sconn->using_smb2) {
 		/* SMB2 */
-		if (sconn->smb2.sessions.list &&
-				sconn->smb2.sessions.list->tcons.list) {
+		struct smbd_smb2_session *sess;
+		for (sess = sconn->smb2.sessions.list; sess; sess = sess->next) {
 			struct smbd_smb2_tcon *tcon, *tc_next;
 
-			for (tcon = sconn->smb2.sessions.list->tcons.list;
-					tcon; tcon = tc_next) {
+			for (tcon = sess->tcons.list; tcon; tcon = tc_next) {
 				tc_next = tcon->next;
 				TALLOC_FREE(tcon);
+				ret = true;
 			}
-			return true;
 		}
-		return false;
 	} else {
 		/* SMB1 */
 		connection_struct *conn, *next;
-		bool ret = false;
 
 		for (conn=sconn->smb1.tcons.Connections;conn;conn=next) {
 			next=conn->next;
@@ -202,7 +240,41 @@ bool conn_close_all(struct smbd_server_connection *sconn)
 			close_cnum(conn, conn->vuid);
 			ret = true;
 		}
-		return ret;
+	}
+	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;
+			}
+		}
 	}
 }
 
@@ -210,31 +282,55 @@ bool conn_close_all(struct smbd_server_connection *sconn)
  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)
-		deadtime = DEFAULT_SMBD_TIMEOUT;
+	conn_lastused_update(sconn, t);
 
-	for (conn=sconn->smb1.tcons.Connections;conn;conn=conn->next) {
-
-		time_t age = t - conn->lastused;
+	if (deadtime <= 0) {
+		deadtime = DEFAULT_SMBD_TIMEOUT;
+	}
 
-		/* Update if connection wasn't idle. */
-		if (conn->lastused != conn->lastused_count) {
-			conn->lastused = t;
-			conn->lastused_count = 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) {
+				time_t age;
+				connection_struct *conn = ptcon->compat_conn;
+
+				if (conn == NULL) {
+					continue;
+				}
+
+				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;
 
-		/* close dirptrs on connections that are idle */
-		if (age > DPTR_IDLE_TIMEOUT) {
-			dptr_idlecnum(conn);
-		}
+			/* 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;
+			if (conn->num_files_open > 0 || age < deadtime) {
+				return false;
+			}
 		}
 	}
 
@@ -243,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;
 }
 
 /****************************************************************************
@@ -257,11 +353,29 @@ void conn_clear_vuid_caches(struct smbd_server_connection *sconn,uint16_t vuid)
 {
 	connection_struct *conn;
 
-	for (conn=sconn->smb1.tcons.Connections;conn;conn=conn->next) {
-		if (conn->vuid == vuid) {
-			conn->vuid = UID_FIELD_INVALID;
+	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) {
+				if (ptcon->compat_conn) {
+					if (ptcon->compat_conn->vuid == vuid) {
+						ptcon->compat_conn->vuid = UID_FIELD_INVALID;
+					}
+					conn_clear_vuid_cache(ptcon->compat_conn, vuid);
+				}
+			}
+		}
+	} else {
+		/* SMB1 */
+		for (conn=sconn->smb1.tcons.Connections;conn;conn=conn->next) {
+			if (conn->vuid == vuid) {
+				conn->vuid = UID_FIELD_INVALID;
+			}
+			conn_clear_vuid_cache(conn, vuid);
 		}
-		conn_clear_vuid_cache(conn, vuid);
 	}
 }
 
@@ -295,7 +409,7 @@ static void conn_free_internal(connection_struct *conn)
 	free_namearray(conn->hide_list);
 	free_namearray(conn->veto_oplock_list);
 	free_namearray(conn->aio_write_behind_list);
-	
+
 	string_free(&conn->connectpath);
 	string_free(&conn->origpath);
 
@@ -315,10 +429,12 @@ void conn_free(connection_struct *conn)
 	}
 
 	if (conn->sconn->using_smb2) {
+		/* SMB2 */
 		conn_free_internal(conn);
 		return;
 	}
 
+	/* SMB1 */
 	DLIST_REMOVE(conn->sconn->smb1.tcons.Connections, conn);
 
 	if (conn->sconn->smb1.tcons.bmap != NULL) {
@@ -329,18 +445,19 @@ void conn_free(connection_struct *conn)
 		bitmap_clear(conn->sconn->smb1.tcons.bmap, conn->cnum);
 	}
 
-	SMB_ASSERT(conn->sconn->smb1.tcons.num_open > 0);
-	conn->sconn->smb1.tcons.num_open--;
+	SMB_ASSERT(conn->sconn->num_tcons_open > 0);
+	conn->sconn->num_tcons_open--;
 
 	conn_free_internal(conn);
 }
- 
+
 /****************************************************************************
-receive a smbcontrol message to forcibly unmount a share
-the message contains just a share name and all instances of that
-share are unmounted
-the special sharename '*' forces unmount of all shares
+ Receive a smbcontrol message to forcibly unmount a share.
+ The message contains just a share name and all instances of that
+ share are unmounted.
+ The special sharename '*' forces unmount of all shares.
 ****************************************************************************/
+
 void msg_force_tdis(struct messaging_context *msg,
 		    void *private_data,
 		    uint32_t msg_type,
@@ -359,12 +476,32 @@ void msg_force_tdis(struct messaging_context *msg,
 		return;
 	}
 
-	for (conn=sconn->smb1.tcons.Connections;conn;conn=next) {
-		next=conn->next;
-		if (strequal(lp_servicename(SNUM(conn)), sharename)) {
-			DEBUG(1,("Forcing close of share %s cnum=%d\n",
-				 sharename, conn->cnum));
-			close_cnum(conn, (uint16)-1);
+	if (sconn->using_smb2) {
+		/* SMB2 */
+		struct smbd_smb2_session *sess;
+		for (sess = sconn->smb2.sessions.list; sess; sess = sess->next) {
+			struct smbd_smb2_tcon *tcon, *tc_next;
+
+			for (tcon = sess->tcons.list; tcon; tcon = tc_next) {
+				tc_next = tcon->next;
+				if (tcon->compat_conn &&
+						strequal(lp_servicename(SNUM(tcon->compat_conn)),
+								sharename)) {
+					DEBUG(1,("Forcing close of share %s cnum=%d\n",
+						sharename, tcon->compat_conn->cnum));
+					TALLOC_FREE(tcon);
+				}
+			}
+		}
+	} else {
+		/* SMB1 */
+		for (conn=sconn->smb1.tcons.Connections;conn;conn=next) {
+			next=conn->next;
+			if (strequal(lp_servicename(SNUM(conn)), sharename)) {
+				DEBUG(1,("Forcing close of share %s cnum=%d\n",
+					sharename, conn->cnum));
+				close_cnum(conn, (uint16)-1);
+			}
 		}
 	}
 }
diff --git a/source3/smbd/globals.h b/source3/smbd/globals.h
index 1a7c513..83f8e7f 100644
--- a/source3/smbd/globals.h
+++ b/source3/smbd/globals.h
@@ -461,6 +461,19 @@ struct smbd_server_connection {
 		bool got_session;
 	} nbt;
 	bool using_smb2;
+	int trans_num;
+
+	struct files_struct *files;
+	struct bitmap *file_bmap;
+	int real_max_open_files;
+	int files_used;
+	struct fsp_singleton_cache fsp_fi_cache;
+	unsigned long file_gen_counter;
+	int first_file;
+
+	/* number of open connections (tcons) */
+	int num_tcons_open;
+
 	struct {


-- 
Samba Shared Repository


More information about the samba-cvs mailing list