[linux-cifs-client] [PATCH 2/6] cifs: move allocation of new TCP_Server_Info into separate function

Jeff Layton jlayton at redhat.com
Sun Nov 30 13:57:21 GMT 2008


Clean up cifs_mount a bit by moving the code that creates new TCP
sessions into a separate function. Have that function search for an
existing socket and then create a new one if one isn't found.

Also reorganize the initializion of TCP_Server_Info a bit to prepare
for cleanup of the socket connection code.

Signed-off-by: Jeff Layton <jlayton at redhat.com>
---
 fs/cifs/connect.c |  199 +++++++++++++++++++++++++++++------------------------
 1 files changed, 110 insertions(+), 89 deletions(-)

diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c
index f61d620..812fe38 100644
--- a/fs/cifs/connect.c
+++ b/fs/cifs/connect.c
@@ -1417,6 +1417,111 @@ cifs_put_tcp_session(struct TCP_Server_Info *server)
 		force_sig(SIGKILL, task);
 }
 
+static struct TCP_Server_Info *
+cifs_get_tcp_session(struct smb_vol *volume_info, struct sockaddr *addr)
+{
+	struct TCP_Server_Info *srvTcp;
+	struct sockaddr_in *sin_server = (struct sockaddr_in *) addr;
+	struct sockaddr_in6 *sin_server6 = (struct sockaddr_in6 *) addr;
+	int rc;
+
+	srvTcp = cifs_find_tcp_session(addr);
+	if (srvTcp)
+		return srvTcp;
+
+	srvTcp = kzalloc(sizeof(struct TCP_Server_Info), GFP_KERNEL);
+	if (!srvTcp) {
+		rc = -ENOMEM;
+		goto out_err;
+	}
+
+	srvTcp->noblocksnd = volume_info->noblocksnd;
+	srvTcp->noautotune = volume_info->noautotune;
+
+	srvTcp->hostname = extract_hostname(volume_info->UNC);
+	if (IS_ERR(srvTcp->hostname)) {
+		rc = PTR_ERR(srvTcp->hostname);
+		goto out_err;
+	}
+
+	atomic_set(&srvTcp->inFlight, 0);
+	init_waitqueue_head(&srvTcp->response_q);
+	init_waitqueue_head(&srvTcp->request_q);
+	INIT_LIST_HEAD(&srvTcp->pending_mid_q);
+	mutex_init(&srvTcp->tcpMutex);
+	memcpy(srvTcp->workstation_RFC1001_name,
+		volume_info->source_rfc1001_name,
+		RFC1001_NAME_LEN_WITH_NULL);
+	memcpy(srvTcp->server_RFC1001_name,
+		volume_info->target_rfc1001_name,
+		RFC1001_NAME_LEN_WITH_NULL);
+	srvTcp->sequence_number = 0;
+	INIT_LIST_HEAD(&srvTcp->tcp_ses_list);
+	INIT_LIST_HEAD(&srvTcp->smb_ses_list);
+
+	/* at this point we are the only ones with the pointer
+	to the struct since the kernel thread not created yet
+	no need to spinlock this init of tcpStatus or refcnt */
+	srvTcp->tcpStatus = CifsNew;
+	++srvTcp->srv_count;
+
+	if (addr->sa_family == AF_INET6) {
+		cFYI(1, ("attempting ipv6 connect"));
+		/* BB should we allow ipv6 on port 139? */
+		/* other OS never observed in Wild doing 139 with v6 */
+		memcpy(&srvTcp->addr.sockAddr6, sin_server6,
+			sizeof(struct sockaddr_in6));
+		sin_server6->sin6_port = htons(volume_info->port);
+		rc = ipv6_connect(sin_server6, &srvTcp->ssocket,
+				volume_info->noblocksnd);
+	} else {
+		memcpy(&srvTcp->addr.sockAddr, sin_server,
+			sizeof(struct sockaddr_in));
+		sin_server->sin_port = htons(volume_info->port);
+		rc = ipv4_connect(sin_server, &srvTcp->ssocket,
+			  volume_info->source_rfc1001_name,
+			  volume_info->target_rfc1001_name,
+			  volume_info->noblocksnd,
+			  volume_info->noautotune);
+	}
+	if (rc < 0) {
+		cERROR(1, ("Error connecting to socket. "
+			   "Aborting operation"));
+		goto out_err;
+	}
+
+	/*
+	 * since we're in a cifs function already, we know that
+	 * this will succeed. No need for try_module_get().
+	 */
+	__module_get(THIS_MODULE);
+	srvTcp->tsk = kthread_run((void *)(void *)cifs_demultiplex_thread,
+				  srvTcp, "cifsd");
+	if (IS_ERR(srvTcp->tsk)) {
+		rc = PTR_ERR(srvTcp->tsk);
+		cERROR(1, ("error %d create cifsd thread", rc));
+		module_put(THIS_MODULE);
+		goto out_err;
+	}
+
+	/* thread spawned, put it on the list */
+	write_lock(&cifs_tcp_ses_lock);
+	list_add(&srvTcp->tcp_ses_list, &cifs_tcp_ses_list);
+	write_unlock(&cifs_tcp_ses_lock);
+
+	return srvTcp;
+
+out_err:
+	if (srvTcp) {
+		kfree(srvTcp->hostname);
+		if (srvTcp->ssocket)
+			sock_release(srvTcp->ssocket);
+		kfree(srvTcp);
+	}
+	return ERR_PTR(rc);
+}
+
+
 static struct cifsSesInfo *
 cifs_find_smb_ses(struct TCP_Server_Info *server, char *username)
 {
@@ -2043,7 +2148,6 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb,
 {
 	int rc = 0;
 	int xid;
-	struct socket *csocket = NULL;
 	struct sockaddr addr;
 	struct sockaddr_in *sin_server = (struct sockaddr_in *) &addr;
 	struct sockaddr_in6 *sin_server6 = (struct sockaddr_in6 *) &addr;
@@ -2128,94 +2232,11 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb,
 		}
 	}
 
-	srvTcp = cifs_find_tcp_session(&addr);
-	if (!srvTcp) { /* create socket */
-		if (addr.sa_family == AF_INET6) {
-			cFYI(1, ("attempting ipv6 connect"));
-			/* BB should we allow ipv6 on port 139? */
-			/* other OS never observed in Wild doing 139 with v6 */
-			sin_server6->sin6_port = htons(volume_info.port);
-			rc = ipv6_connect(sin_server6, &csocket,
-					volume_info.noblocksnd);
-		} else {
-			sin_server->sin_port = htons(volume_info.port);
-			rc = ipv4_connect(sin_server, &csocket,
-				  volume_info.source_rfc1001_name,
-				  volume_info.target_rfc1001_name,
-				  volume_info.noblocksnd,
-				  volume_info.noautotune);
-		}
-		if (rc < 0) {
-			cERROR(1, ("Error connecting to socket. "
-				   "Aborting operation"));
-			if (csocket != NULL)
-				sock_release(csocket);
-			goto out;
-		}
-
-		srvTcp = kzalloc(sizeof(struct TCP_Server_Info), GFP_KERNEL);
-		if (!srvTcp) {
-			rc = -ENOMEM;
-			sock_release(csocket);
-			goto out;
-		} else {
-			srvTcp->noblocksnd = volume_info.noblocksnd;
-			srvTcp->noautotune = volume_info.noautotune;
-			if (addr.sa_family == AF_INET6)
-				memcpy(&srvTcp->addr.sockAddr6, sin_server6,
-					sizeof(struct sockaddr_in6));
-			else
-				memcpy(&srvTcp->addr.sockAddr, sin_server,
-					sizeof(struct sockaddr_in));
-			atomic_set(&srvTcp->inFlight, 0);
-			/* BB Add code for ipv6 case too */
-			srvTcp->ssocket = csocket;
-			srvTcp->hostname = extract_hostname(volume_info.UNC);
-			if (IS_ERR(srvTcp->hostname)) {
-				rc = PTR_ERR(srvTcp->hostname);
-				sock_release(csocket);
-				goto out;
-			}
-			init_waitqueue_head(&srvTcp->response_q);
-			init_waitqueue_head(&srvTcp->request_q);
-			INIT_LIST_HEAD(&srvTcp->pending_mid_q);
-			/* at this point we are the only ones with the pointer
-			to the struct since the kernel thread not created yet
-			so no need to spinlock this init of tcpStatus */
-			srvTcp->tcpStatus = CifsNew;
-			mutex_init(&srvTcp->tcpMutex);
-
-			/*
-			 * since we're in a cifs function already, we know that
-			 * this will succeed. No need for try_module_get().
-			 */
-			__module_get(THIS_MODULE);
-			srvTcp->tsk = kthread_run((void *)(void *)cifs_demultiplex_thread, srvTcp, "cifsd");
-			if (IS_ERR(srvTcp->tsk)) {
-				rc = PTR_ERR(srvTcp->tsk);
-				cERROR(1, ("error %d create cifsd thread", rc));
-				module_put(THIS_MODULE);
-				srvTcp->tsk = NULL;
-				sock_release(csocket);
-				kfree(srvTcp->hostname);
-				goto out;
-			}
-			rc = 0;
-			memcpy(srvTcp->workstation_RFC1001_name,
-				volume_info.source_rfc1001_name,
-				RFC1001_NAME_LEN_WITH_NULL);
-			memcpy(srvTcp->server_RFC1001_name,
-				volume_info.target_rfc1001_name,
-				RFC1001_NAME_LEN_WITH_NULL);
-			srvTcp->sequence_number = 0;
-			INIT_LIST_HEAD(&srvTcp->tcp_ses_list);
-			INIT_LIST_HEAD(&srvTcp->smb_ses_list);
-			++srvTcp->srv_count;
-			write_lock(&cifs_tcp_ses_lock);
-			list_add(&srvTcp->tcp_ses_list,
-				 &cifs_tcp_ses_list);
-			write_unlock(&cifs_tcp_ses_lock);
-		}
+	/* get a reference to a tcp session */
+	srvTcp = cifs_get_tcp_session(&volume_info, &addr);
+	if (IS_ERR(srvTcp)) {
+		rc = PTR_ERR(srvTcp);
+		goto out;
 	}
 
 	pSesInfo = cifs_find_smb_ses(srvTcp, volume_info.username);
-- 
1.5.5.1



More information about the linux-cifs-client mailing list