@@ -538,6 +538,7 @@ struct smb_vol {
char *username;
char *password;
char *domainname;
+ char *server_hostname;
char *UNC;
char *iocharset; /* local code page for mapping to and from Unicode */
char source_rfc1001_name[RFC1001_NAME_LEN_WITH_NULL]; /* clnt nb name */
@@ -1101,7 +1101,6 @@ static void clean_demultiplex_info(struct TCP_Server_Info *server)
*/
}
- kfree(server->hostname);
kfree(server);
length = atomic_dec_return(&tcpSesAllocCount);
@@ -1653,6 +1652,11 @@ cifs_parse_devname(const char *devname, struct smb_vol *vol)
if (!pos)
return -EINVAL;
+ /* record the server hostname */
+ vol->server_hostname = kstrndup(devname + 2, pos - devname - 2, GFP_KERNEL);
+ if (!vol->server_hostname)
+ return -ENOMEM;
+
/* skip past delimiter */
++pos;
@@ -2510,6 +2514,12 @@ cifs_parse_mount_options(const char *mountdata, const char *devname,
goto cifs_parse_mount_err;
}
#endif
+
+ if (!vol->server_hostname) {
+ cifs_dbg(VFS, "CIFS mount error: Unable to parse server name in device string!\n");
+ goto cifs_parse_mount_err;
+ }
+
if (!vol->UNC) {
cifs_dbg(VFS, "CIFS mount error: No usable UNC path provided in device string!\n");
goto cifs_parse_mount_err;
@@ -2712,6 +2722,9 @@ static int match_server(struct TCP_Server_Info *server, struct smb_vol *vol)
if (!net_eq(cifs_net_ns(server), current->nsproxy->net_ns))
return 0;
+ if (strcasecmp(server->hostname, vol->server_hostname))
+ return 0;
+
if (!match_address(server, addr,
(struct sockaddr *)&vol->srcaddr))
return 0;
@@ -2796,6 +2809,7 @@ cifs_put_tcp_session(struct TCP_Server_Info *server, int from_reconnect)
kfree(server->session_key.response);
server->session_key.response = NULL;
server->session_key.len = 0;
+ kfree(server->hostname);
task = xchg(&server->tsk, NULL);
if (task)
@@ -2821,14 +2835,15 @@ cifs_get_tcp_session(struct smb_vol *volume_info)
goto out_err;
}
+ tcp_ses->hostname = kstrdup(volume_info->server_hostname, GFP_KERNEL);
+ if (!tcp_ses->hostname) {
+ rc = -ENOMEM;
+ goto out_err;
+ }
+
tcp_ses->ops = volume_info->ops;
tcp_ses->vals = volume_info->vals;
cifs_set_net_ns(tcp_ses, get_net(current->nsproxy->net_ns));
- tcp_ses->hostname = extract_hostname(volume_info->UNC);
- if (IS_ERR(tcp_ses->hostname)) {
- rc = PTR_ERR(tcp_ses->hostname);
- goto out_err_crypto_release;
- }
tcp_ses->noblockcnt = volume_info->rootfs;
tcp_ses->noblocksnd = volume_info->noblocksnd || volume_info->rootfs;
@@ -2942,8 +2957,7 @@ cifs_get_tcp_session(struct smb_vol *volume_info)
out_err:
if (tcp_ses) {
- if (!IS_ERR(tcp_ses->hostname))
- kfree(tcp_ses->hostname);
+ kfree(tcp_ses->hostname);
if (tcp_ses->ssocket)
sock_release(tcp_ses->ssocket);
kfree(tcp_ses);
@@ -4272,6 +4286,7 @@ cifs_cleanup_volume_info_contents(struct smb_vol *volume_info)
kfree(volume_info->username);
kzfree(volume_info->password);
kfree(volume_info->UNC);
+ kfree(volume_info->server_hostname);
kfree(volume_info->domainname);
kfree(volume_info->iocharset);
kfree(volume_info->prepath);
@@ -4541,6 +4556,12 @@ static int update_vol_info(const struct dfs_cache_tgt_iterator *tgt_it,
kfree(vol->UNC);
vol->UNC = new_unc;
+ if (fake_vol->server_hostname) {
+ kfree(vol->server_hostname);
+ vol->server_hostname = fake_vol->server_hostname;
+ fake_vol->server_hostname = NULL;
+ }
+
if (fake_vol->prepath) {
kfree(vol->prepath);
vol->prepath = fake_vol->prepath;
@@ -5342,6 +5363,7 @@ cifs_construct_tcon(struct cifs_sb_info *cifs_sb, kuid_t fsuid)
vol_info->linux_uid = fsuid;
vol_info->cred_uid = fsuid;
vol_info->UNC = master_tcon->treeName;
+ vol_info->server_hostname = master_tcon->ses->server->hostname;
vol_info->retry = master_tcon->retry;
vol_info->nocase = master_tcon->nocase;
vol_info->nohandlecache = master_tcon->nohandlecache;