summaryrefslogtreecommitdiffstats
path: root/fs/cifs
diff options
context:
space:
mode:
authorJeff Layton <jlayton@redhat.com>2007-11-16 23:22:06 +0100
committerSteve French <sfrench@us.ibm.com>2007-11-16 23:22:06 +0100
commitc359cf3c61c6ea9f4f461a8bd22023a15d75d9b5 (patch)
tree24abf7b5a77af5007ee9bdf30592775df4e66035 /fs/cifs
parent[CIFS] clean up error handling in cifs_mount (diff)
downloadlinux-c359cf3c61c6ea9f4f461a8bd22023a15d75d9b5.tar.xz
linux-c359cf3c61c6ea9f4f461a8bd22023a15d75d9b5.zip
[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>
Diffstat (limited to 'fs/cifs')
-rw-r--r--fs/cifs/cifsglob.h1
-rw-r--r--fs/cifs/connect.c36
2 files changed, 37 insertions, 0 deletions
diff --git a/fs/cifs/cifsglob.h b/fs/cifs/cifsglob.h
index 4ff8179df7ec..3525082f5e58 100644
--- a/fs/cifs/cifsglob.h
+++ b/fs/cifs/cifsglob.h
@@ -139,6 +139,7 @@ struct TCP_Server_Info {
/* 15 character server name + 0x20 16th byte indicating type = srv */
char server_RFC1001_name[SERVER_NAME_LEN_WITH_NULL];
char unicode_server_Name[SERVER_NAME_LEN_WITH_NULL * 2];
+ char *hostname; /* hostname portion of UNC string */
struct socket *ssocket;
union {
struct sockaddr_in sockAddr;
diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c
index 58c509e6ac6a..98ec57ff4d98 100644
--- a/fs/cifs/connect.c
+++ b/fs/cifs/connect.c
@@ -752,6 +752,7 @@ multi_t2_fnd:
}
write_unlock(&GlobalSMBSeslock);
+ kfree(server->hostname);
kfree(server);
if (length > 0)
mempool_resize(cifs_req_poolp, length + cifs_min_rcv,
@@ -760,6 +761,34 @@ multi_t2_fnd:
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 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb,
/* 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 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb,
cERROR(1, ("error %d create cifsd thread", rc));
srvTcp->tsk = NULL;
sock_release(csocket);
+ kfree(srvTcp->hostname);
goto out;
}
wait_for_completion(&cifsd_complete);