diff options
Diffstat (limited to 'fs/cifs/connect.c')
| -rw-r--r-- | fs/cifs/connect.c | 28 |
1 files changed, 25 insertions, 3 deletions
diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c index f66529679ca2..8463c940e0e5 100644 --- a/fs/cifs/connect.c +++ b/fs/cifs/connect.c | |||
| @@ -433,9 +433,10 @@ static void reconn_inval_dfs_target(struct TCP_Server_Info *server, | |||
| 433 | kfree(server->hostname); | 433 | kfree(server->hostname); |
| 434 | 434 | ||
| 435 | server->hostname = extract_hostname(name); | 435 | server->hostname = extract_hostname(name); |
| 436 | if (!server->hostname) { | 436 | if (IS_ERR(server->hostname)) { |
| 437 | cifs_dbg(FYI, "%s: failed to extract hostname from target: %d\n", | 437 | cifs_dbg(FYI, |
| 438 | __func__, -ENOMEM); | 438 | "%s: failed to extract hostname from target: %ld\n", |
| 439 | __func__, PTR_ERR(server->hostname)); | ||
| 439 | } | 440 | } |
| 440 | } | 441 | } |
| 441 | 442 | ||
| @@ -719,6 +720,21 @@ server_unresponsive(struct TCP_Server_Info *server) | |||
| 719 | return false; | 720 | return false; |
| 720 | } | 721 | } |
| 721 | 722 | ||
| 723 | static inline bool | ||
| 724 | zero_credits(struct TCP_Server_Info *server) | ||
| 725 | { | ||
| 726 | int val; | ||
| 727 | |||
| 728 | spin_lock(&server->req_lock); | ||
| 729 | val = server->credits + server->echo_credits + server->oplock_credits; | ||
| 730 | if (server->in_flight == 0 && val == 0) { | ||
| 731 | spin_unlock(&server->req_lock); | ||
| 732 | return true; | ||
| 733 | } | ||
| 734 | spin_unlock(&server->req_lock); | ||
| 735 | return false; | ||
| 736 | } | ||
| 737 | |||
| 722 | static int | 738 | static int |
| 723 | cifs_readv_from_socket(struct TCP_Server_Info *server, struct msghdr *smb_msg) | 739 | cifs_readv_from_socket(struct TCP_Server_Info *server, struct msghdr *smb_msg) |
| 724 | { | 740 | { |
| @@ -731,6 +747,12 @@ cifs_readv_from_socket(struct TCP_Server_Info *server, struct msghdr *smb_msg) | |||
| 731 | for (total_read = 0; msg_data_left(smb_msg); total_read += length) { | 747 | for (total_read = 0; msg_data_left(smb_msg); total_read += length) { |
| 732 | try_to_freeze(); | 748 | try_to_freeze(); |
| 733 | 749 | ||
| 750 | /* reconnect if no credits and no requests in flight */ | ||
| 751 | if (zero_credits(server)) { | ||
| 752 | cifs_reconnect(server); | ||
| 753 | return -ECONNABORTED; | ||
| 754 | } | ||
| 755 | |||
| 734 | if (server_unresponsive(server)) | 756 | if (server_unresponsive(server)) |
| 735 | return -ECONNABORTED; | 757 | return -ECONNABORTED; |
| 736 | if (cifs_rdma_enabled(server) && server->smbd_conn) | 758 | if (cifs_rdma_enabled(server) && server->smbd_conn) |
