[CIFS] add hostname field to TCP_Server_Info struct

...and populate it with the hostname portion of the UNC string.

Signed-off-by: Jeff Layton <jlayton@redhat.com>
Signed-off-by: Steve French <sfrench@us.ibm.com>
diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c
index 58c509e..98ec57f 100644
--- a/fs/cifs/connect.c
+++ b/fs/cifs/connect.c
@@ -752,6 +752,7 @@
 	}
 	write_unlock(&GlobalSMBSeslock);
 
+	kfree(server->hostname);
 	kfree(server);
 	if (length  > 0)
 		mempool_resize(cifs_req_poolp, length + cifs_min_rcv,
@@ -760,6 +761,34 @@
 	return 0;
 }
 
+/* extract the host portion of the UNC string */
+static char *
+extract_hostname(const char *unc)
+{
+	const char *src;
+	char *dst, *delim;
+	unsigned int len;
+
+	/* skip double chars at beginning of string */
+	/* BB: check validity of these bytes? */
+	src = unc + 2;
+
+	/* delimiter between hostname and sharename is always '\\' now */
+	delim = strchr(src, '\\');
+	if (!delim)
+		return ERR_PTR(-EINVAL);
+
+	len = delim - src;
+	dst = kmalloc((len + 1), GFP_KERNEL);
+	if (dst == NULL)
+		return ERR_PTR(-ENOMEM);
+
+	memcpy(dst, src, len);
+	dst[len] = '\0';
+
+	return dst;
+}
+
 static int
 cifs_parse_mount_options(char *options, const char *devname,
 			 struct smb_vol *vol)
@@ -1900,6 +1929,12 @@
 			/* BB Add code for ipv6 case too */
 			srvTcp->ssocket = csocket;
 			srvTcp->protocolType = IPV4;
+			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);
@@ -1914,6 +1949,7 @@
 				cERROR(1, ("error %d create cifsd thread", rc));
 				srvTcp->tsk = NULL;
 				sock_release(csocket);
+				kfree(srvTcp->hostname);
 				goto out;
 			}
 			wait_for_completion(&cifsd_complete);