diff options
Diffstat (limited to 'fs/cifs/connect.c')
-rw-r--r-- | fs/cifs/connect.c | 77 |
1 files changed, 24 insertions, 53 deletions
diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c index ec0ea4a43bdb..88c84a38bccb 100644 --- a/fs/cifs/connect.c +++ b/fs/cifs/connect.c | |||
@@ -400,7 +400,9 @@ incomplete_rcv: | |||
400 | cFYI(1, "call to reconnect done"); | 400 | cFYI(1, "call to reconnect done"); |
401 | csocket = server->ssocket; | 401 | csocket = server->ssocket; |
402 | continue; | 402 | continue; |
403 | } else if ((length == -ERESTARTSYS) || (length == -EAGAIN)) { | 403 | } else if (length == -ERESTARTSYS || |
404 | length == -EAGAIN || | ||
405 | length == -EINTR) { | ||
404 | msleep(1); /* minimum sleep to prevent looping | 406 | msleep(1); /* minimum sleep to prevent looping |
405 | allowing socket to clear and app threads to set | 407 | allowing socket to clear and app threads to set |
406 | tcpStatus CifsNeedReconnect if server hung */ | 408 | tcpStatus CifsNeedReconnect if server hung */ |
@@ -414,18 +416,6 @@ incomplete_rcv: | |||
414 | } else | 416 | } else |
415 | continue; | 417 | continue; |
416 | } else if (length <= 0) { | 418 | } else if (length <= 0) { |
417 | if (server->tcpStatus == CifsNew) { | ||
418 | cFYI(1, "tcp session abend after SMBnegprot"); | ||
419 | /* some servers kill the TCP session rather than | ||
420 | returning an SMB negprot error, in which | ||
421 | case reconnecting here is not going to help, | ||
422 | and so simply return error to mount */ | ||
423 | break; | ||
424 | } | ||
425 | if (!try_to_freeze() && (length == -EINTR)) { | ||
426 | cFYI(1, "cifsd thread killed"); | ||
427 | break; | ||
428 | } | ||
429 | cFYI(1, "Reconnect after unexpected peek error %d", | 419 | cFYI(1, "Reconnect after unexpected peek error %d", |
430 | length); | 420 | length); |
431 | cifs_reconnect(server); | 421 | cifs_reconnect(server); |
@@ -466,27 +456,19 @@ incomplete_rcv: | |||
466 | an error on SMB negprot response */ | 456 | an error on SMB negprot response */ |
467 | cFYI(1, "Negative RFC1002 Session Response Error 0x%x)", | 457 | cFYI(1, "Negative RFC1002 Session Response Error 0x%x)", |
468 | pdu_length); | 458 | pdu_length); |
469 | if (server->tcpStatus == CifsNew) { | 459 | /* give server a second to clean up */ |
470 | /* if nack on negprot (rather than | 460 | msleep(1000); |
471 | ret of smb negprot error) reconnecting | 461 | /* always try 445 first on reconnect since we get NACK |
472 | not going to help, ret error to mount */ | 462 | * on some if we ever connected to port 139 (the NACK |
473 | break; | 463 | * is since we do not begin with RFC1001 session |
474 | } else { | 464 | * initialize frame) |
475 | /* give server a second to | 465 | */ |
476 | clean up before reconnect attempt */ | 466 | cifs_set_port((struct sockaddr *) |
477 | msleep(1000); | 467 | &server->addr.sockAddr, CIFS_PORT); |
478 | /* always try 445 first on reconnect | 468 | cifs_reconnect(server); |
479 | since we get NACK on some if we ever | 469 | csocket = server->ssocket; |
480 | connected to port 139 (the NACK is | 470 | wake_up(&server->response_q); |
481 | since we do not begin with RFC1001 | 471 | continue; |
482 | session initialize frame) */ | ||
483 | server->addr.sockAddr.sin_port = | ||
484 | htons(CIFS_PORT); | ||
485 | cifs_reconnect(server); | ||
486 | csocket = server->ssocket; | ||
487 | wake_up(&server->response_q); | ||
488 | continue; | ||
489 | } | ||
490 | } else if (temp != (char) 0) { | 472 | } else if (temp != (char) 0) { |
491 | cERROR(1, "Unknown RFC 1002 frame"); | 473 | cERROR(1, "Unknown RFC 1002 frame"); |
492 | cifs_dump_mem(" Received Data: ", (char *)smb_buffer, | 474 | cifs_dump_mem(" Received Data: ", (char *)smb_buffer, |
@@ -522,8 +504,7 @@ incomplete_rcv: | |||
522 | total_read += length) { | 504 | total_read += length) { |
523 | length = kernel_recvmsg(csocket, &smb_msg, &iov, 1, | 505 | length = kernel_recvmsg(csocket, &smb_msg, &iov, 1, |
524 | pdu_length - total_read, 0); | 506 | pdu_length - total_read, 0); |
525 | if ((server->tcpStatus == CifsExiting) || | 507 | if (server->tcpStatus == CifsExiting) { |
526 | (length == -EINTR)) { | ||
527 | /* then will exit */ | 508 | /* then will exit */ |
528 | reconnect = 2; | 509 | reconnect = 2; |
529 | break; | 510 | break; |
@@ -534,8 +515,9 @@ incomplete_rcv: | |||
534 | /* Now we will reread sock */ | 515 | /* Now we will reread sock */ |
535 | reconnect = 1; | 516 | reconnect = 1; |
536 | break; | 517 | break; |
537 | } else if ((length == -ERESTARTSYS) || | 518 | } else if (length == -ERESTARTSYS || |
538 | (length == -EAGAIN)) { | 519 | length == -EAGAIN || |
520 | length == -EINTR) { | ||
539 | msleep(1); /* minimum sleep to prevent looping, | 521 | msleep(1); /* minimum sleep to prevent looping, |
540 | allowing socket to clear and app | 522 | allowing socket to clear and app |
541 | threads to set tcpStatus | 523 | threads to set tcpStatus |
@@ -1708,7 +1690,6 @@ cifs_put_smb_ses(struct cifsSesInfo *ses) | |||
1708 | CIFSSMBLogoff(xid, ses); | 1690 | CIFSSMBLogoff(xid, ses); |
1709 | _FreeXid(xid); | 1691 | _FreeXid(xid); |
1710 | } | 1692 | } |
1711 | cifs_crypto_shash_release(server); | ||
1712 | sesInfoFree(ses); | 1693 | sesInfoFree(ses); |
1713 | cifs_put_tcp_session(server); | 1694 | cifs_put_tcp_session(server); |
1714 | } | 1695 | } |
@@ -1725,9 +1706,6 @@ cifs_get_smb_ses(struct TCP_Server_Info *server, struct smb_vol *volume_info) | |||
1725 | if (ses) { | 1706 | if (ses) { |
1726 | cFYI(1, "Existing smb sess found (status=%d)", ses->status); | 1707 | cFYI(1, "Existing smb sess found (status=%d)", ses->status); |
1727 | 1708 | ||
1728 | /* existing SMB ses has a server reference already */ | ||
1729 | cifs_put_tcp_session(server); | ||
1730 | |||
1731 | mutex_lock(&ses->session_mutex); | 1709 | mutex_lock(&ses->session_mutex); |
1732 | rc = cifs_negotiate_protocol(xid, ses); | 1710 | rc = cifs_negotiate_protocol(xid, ses); |
1733 | if (rc) { | 1711 | if (rc) { |
@@ -1750,6 +1728,9 @@ cifs_get_smb_ses(struct TCP_Server_Info *server, struct smb_vol *volume_info) | |||
1750 | } | 1728 | } |
1751 | } | 1729 | } |
1752 | mutex_unlock(&ses->session_mutex); | 1730 | mutex_unlock(&ses->session_mutex); |
1731 | |||
1732 | /* existing SMB ses has a server reference already */ | ||
1733 | cifs_put_tcp_session(server); | ||
1753 | FreeXid(xid); | 1734 | FreeXid(xid); |
1754 | return ses; | 1735 | return ses; |
1755 | } | 1736 | } |
@@ -1788,23 +1769,13 @@ cifs_get_smb_ses(struct TCP_Server_Info *server, struct smb_vol *volume_info) | |||
1788 | ses->linux_uid = volume_info->linux_uid; | 1769 | ses->linux_uid = volume_info->linux_uid; |
1789 | ses->overrideSecFlg = volume_info->secFlg; | 1770 | ses->overrideSecFlg = volume_info->secFlg; |
1790 | 1771 | ||
1791 | rc = cifs_crypto_shash_allocate(server); | ||
1792 | if (rc) { | ||
1793 | cERROR(1, "could not setup hash structures rc %d", rc); | ||
1794 | goto get_ses_fail; | ||
1795 | } | ||
1796 | server->tilen = 0; | ||
1797 | server->tiblob = NULL; | ||
1798 | |||
1799 | mutex_lock(&ses->session_mutex); | 1772 | mutex_lock(&ses->session_mutex); |
1800 | rc = cifs_negotiate_protocol(xid, ses); | 1773 | rc = cifs_negotiate_protocol(xid, ses); |
1801 | if (!rc) | 1774 | if (!rc) |
1802 | rc = cifs_setup_session(xid, ses, volume_info->local_nls); | 1775 | rc = cifs_setup_session(xid, ses, volume_info->local_nls); |
1803 | mutex_unlock(&ses->session_mutex); | 1776 | mutex_unlock(&ses->session_mutex); |
1804 | if (rc) { | 1777 | if (rc) |
1805 | cifs_crypto_shash_release(ses->server); | ||
1806 | goto get_ses_fail; | 1778 | goto get_ses_fail; |
1807 | } | ||
1808 | 1779 | ||
1809 | /* success, put it on the list */ | 1780 | /* success, put it on the list */ |
1810 | write_lock(&cifs_tcp_ses_lock); | 1781 | write_lock(&cifs_tcp_ses_lock); |