aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/cifs/connect.c73
1 files changed, 36 insertions, 37 deletions
diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c
index eca86256709b..65e760b9428f 100644
--- a/fs/cifs/connect.c
+++ b/fs/cifs/connect.c
@@ -1381,18 +1381,44 @@ cifs_parse_mount_options(char *options, const char *devname,
1381 return 0; 1381 return 0;
1382} 1382}
1383 1383
1384static bool
1385match_address(struct TCP_Server_Info *server, struct sockaddr *addr)
1386{
1387 struct sockaddr_in *addr4 = (struct sockaddr_in *)addr;
1388 struct sockaddr_in6 *addr6 = (struct sockaddr_in6 *)addr;
1389
1390 switch (addr->sa_family) {
1391 case AF_INET:
1392 if (addr4->sin_addr.s_addr !=
1393 server->addr.sockAddr.sin_addr.s_addr)
1394 return false;
1395 if (addr4->sin_port &&
1396 addr4->sin_port != server->addr.sockAddr.sin_port)
1397 return false;
1398 break;
1399 case AF_INET6:
1400 if (!ipv6_addr_equal(&addr6->sin6_addr,
1401 &server->addr.sockAddr6.sin6_addr))
1402 return false;
1403 if (addr6->sin6_scope_id !=
1404 server->addr.sockAddr6.sin6_scope_id)
1405 return false;
1406 if (addr6->sin6_port &&
1407 addr6->sin6_port != server->addr.sockAddr6.sin6_port)
1408 return false;
1409 break;
1410 }
1411
1412 return true;
1413}
1414
1384static struct TCP_Server_Info * 1415static struct TCP_Server_Info *
1385cifs_find_tcp_session(struct sockaddr_storage *addr) 1416cifs_find_tcp_session(struct sockaddr *addr)
1386{ 1417{
1387 struct list_head *tmp;
1388 struct TCP_Server_Info *server; 1418 struct TCP_Server_Info *server;
1389 struct sockaddr_in *addr4 = (struct sockaddr_in *) addr;
1390 struct sockaddr_in6 *addr6 = (struct sockaddr_in6 *) addr;
1391 1419
1392 write_lock(&cifs_tcp_ses_lock); 1420 write_lock(&cifs_tcp_ses_lock);
1393 list_for_each(tmp, &cifs_tcp_ses_list) { 1421 list_for_each_entry(server, &cifs_tcp_ses_list, tcp_ses_list) {
1394 server = list_entry(tmp, struct TCP_Server_Info,
1395 tcp_ses_list);
1396 /* 1422 /*
1397 * the demux thread can exit on its own while still in CifsNew 1423 * the demux thread can exit on its own while still in CifsNew
1398 * so don't accept any sockets in that state. Since the 1424 * so don't accept any sockets in that state. Since the
@@ -1402,35 +1428,8 @@ cifs_find_tcp_session(struct sockaddr_storage *addr)
1402 if (server->tcpStatus == CifsNew) 1428 if (server->tcpStatus == CifsNew)
1403 continue; 1429 continue;
1404 1430
1405 switch (addr->ss_family) { 1431 if (!match_address(server, addr))
1406 case AF_INET: 1432 continue;
1407 if (addr4->sin_addr.s_addr ==
1408 server->addr.sockAddr.sin_addr.s_addr) {
1409 /* user overrode default port? */
1410 if (addr4->sin_port) {
1411 if (addr4->sin_port !=
1412 server->addr.sockAddr.sin_port)
1413 continue;
1414 }
1415 break;
1416 } else
1417 continue;
1418
1419 case AF_INET6:
1420 if (ipv6_addr_equal(&addr6->sin6_addr,
1421 &server->addr.sockAddr6.sin6_addr) &&
1422 (addr6->sin6_scope_id ==
1423 server->addr.sockAddr6.sin6_scope_id)) {
1424 /* user overrode default port? */
1425 if (addr6->sin6_port) {
1426 if (addr6->sin6_port !=
1427 server->addr.sockAddr6.sin6_port)
1428 continue;
1429 }
1430 break;
1431 } else
1432 continue;
1433 }
1434 1433
1435 ++server->srv_count; 1434 ++server->srv_count;
1436 write_unlock(&cifs_tcp_ses_lock); 1435 write_unlock(&cifs_tcp_ses_lock);
@@ -1502,7 +1501,7 @@ cifs_get_tcp_session(struct smb_vol *volume_info)
1502 } 1501 }
1503 1502
1504 /* see if we already have a matching tcp_ses */ 1503 /* see if we already have a matching tcp_ses */
1505 tcp_ses = cifs_find_tcp_session(&addr); 1504 tcp_ses = cifs_find_tcp_session((struct sockaddr *)&addr);
1506 if (tcp_ses) 1505 if (tcp_ses)
1507 return tcp_ses; 1506 return tcp_ses;
1508 1507