summaryrefslogtreecommitdiffstats
path: root/fs/cifs/smb2ops.c
diff options
context:
space:
mode:
authorTakashi Iwai <tiwai@suse.de>2019-02-08 08:20:32 -0500
committerTakashi Iwai <tiwai@suse.de>2019-02-08 08:20:32 -0500
commitd02cac152c97dffcb0cdd91e09b54fd6e2cca63d (patch)
tree68e4c6bd842703009f3edbf8f0e0e9326e4b2fad /fs/cifs/smb2ops.c
parent36e4617c01153757cde9e5fcd375a75a8f8425c3 (diff)
parenta50e32694fbcdbf55875095258b9398e2eabd71f (diff)
Merge tag 'asoc-v5.1' of https://git.kernel.org/pub/scm/linux/kernel/git/broonie/sound into for-next
ASoC: Updates for v5.1 Lots and lots of new drivers so far, a highlight being the MediaTek BTCVSD which is a driver for a Bluetooth radio chip - the first such driver we've had upstream. Hopefully we will soon also see a baseband with an upstream driver! - Support for only powering up channels that are actively being used. - Quite a few improvements to simplify the generic card drivers, especially the merge of the SCU cards into the main generic drivers. - Lots of fixes for probing on Intel systems, trying to rationalize things to look more standard from a framework point of view. - New drivers for Asahi Kasei Microdevices AK4497, Cirrus Logic CS4341, Google ChromeOS embedded controllers, Ingenic JZ4725B, MediaTek BTCVSD, MT8183 and MT6358, NXP MICFIL, Rockchip RK3328, Spreadtrum DMA controllers, Qualcomm WCD9335, Xilinx S/PDIF and PCM formatters.
Diffstat (limited to 'fs/cifs/smb2ops.c')
-rw-r--r--fs/cifs/smb2ops.c68
1 files changed, 47 insertions, 21 deletions
diff --git a/fs/cifs/smb2ops.c b/fs/cifs/smb2ops.c
index cf7eb891804f..153238fc4fa9 100644
--- a/fs/cifs/smb2ops.c
+++ b/fs/cifs/smb2ops.c
@@ -34,6 +34,7 @@
34#include "cifs_ioctl.h" 34#include "cifs_ioctl.h"
35#include "smbdirect.h" 35#include "smbdirect.h"
36 36
37/* Change credits for different ops and return the total number of credits */
37static int 38static int
38change_conf(struct TCP_Server_Info *server) 39change_conf(struct TCP_Server_Info *server)
39{ 40{
@@ -41,17 +42,15 @@ change_conf(struct TCP_Server_Info *server)
41 server->oplock_credits = server->echo_credits = 0; 42 server->oplock_credits = server->echo_credits = 0;
42 switch (server->credits) { 43 switch (server->credits) {
43 case 0: 44 case 0:
44 return -1; 45 return 0;
45 case 1: 46 case 1:
46 server->echoes = false; 47 server->echoes = false;
47 server->oplocks = false; 48 server->oplocks = false;
48 cifs_dbg(VFS, "disabling echoes and oplocks\n");
49 break; 49 break;
50 case 2: 50 case 2:
51 server->echoes = true; 51 server->echoes = true;
52 server->oplocks = false; 52 server->oplocks = false;
53 server->echo_credits = 1; 53 server->echo_credits = 1;
54 cifs_dbg(FYI, "disabling oplocks\n");
55 break; 54 break;
56 default: 55 default:
57 server->echoes = true; 56 server->echoes = true;
@@ -64,14 +63,15 @@ change_conf(struct TCP_Server_Info *server)
64 server->echo_credits = 1; 63 server->echo_credits = 1;
65 } 64 }
66 server->credits -= server->echo_credits + server->oplock_credits; 65 server->credits -= server->echo_credits + server->oplock_credits;
67 return 0; 66 return server->credits + server->echo_credits + server->oplock_credits;
68} 67}
69 68
70static void 69static void
71smb2_add_credits(struct TCP_Server_Info *server, const unsigned int add, 70smb2_add_credits(struct TCP_Server_Info *server, const unsigned int add,
72 const int optype) 71 const int optype)
73{ 72{
74 int *val, rc = 0; 73 int *val, rc = -1;
74
75 spin_lock(&server->req_lock); 75 spin_lock(&server->req_lock);
76 val = server->ops->get_credits_field(server, optype); 76 val = server->ops->get_credits_field(server, optype);
77 77
@@ -101,8 +101,26 @@ smb2_add_credits(struct TCP_Server_Info *server, const unsigned int add,
101 } 101 }
102 spin_unlock(&server->req_lock); 102 spin_unlock(&server->req_lock);
103 wake_up(&server->request_q); 103 wake_up(&server->request_q);
104 if (rc) 104
105 cifs_reconnect(server); 105 if (server->tcpStatus == CifsNeedReconnect)
106 return;
107
108 switch (rc) {
109 case -1:
110 /* change_conf hasn't been executed */
111 break;
112 case 0:
113 cifs_dbg(VFS, "Possible client or server bug - zero credits\n");
114 break;
115 case 1:
116 cifs_dbg(VFS, "disabling echoes and oplocks\n");
117 break;
118 case 2:
119 cifs_dbg(FYI, "disabling oplocks\n");
120 break;
121 default:
122 cifs_dbg(FYI, "add %u credits total=%d\n", add, rc);
123 }
106} 124}
107 125
108static void 126static void
@@ -136,7 +154,11 @@ smb2_get_credits(struct mid_q_entry *mid)
136{ 154{
137 struct smb2_sync_hdr *shdr = (struct smb2_sync_hdr *)mid->resp_buf; 155 struct smb2_sync_hdr *shdr = (struct smb2_sync_hdr *)mid->resp_buf;
138 156
139 return le16_to_cpu(shdr->CreditRequest); 157 if (mid->mid_state == MID_RESPONSE_RECEIVED
158 || mid->mid_state == MID_RESPONSE_MALFORMED)
159 return le16_to_cpu(shdr->CreditRequest);
160
161 return 0;
140} 162}
141 163
142static int 164static int
@@ -165,14 +187,14 @@ smb2_wait_mtu_credits(struct TCP_Server_Info *server, unsigned int size,
165 187
166 scredits = server->credits; 188 scredits = server->credits;
167 /* can deadlock with reopen */ 189 /* can deadlock with reopen */
168 if (scredits == 1) { 190 if (scredits <= 8) {
169 *num = SMB2_MAX_BUFFER_SIZE; 191 *num = SMB2_MAX_BUFFER_SIZE;
170 *credits = 0; 192 *credits = 0;
171 break; 193 break;
172 } 194 }
173 195
174 /* leave one credit for a possible reopen */ 196 /* leave some credits for reopen and other ops */
175 scredits--; 197 scredits -= 8;
176 *num = min_t(unsigned int, size, 198 *num = min_t(unsigned int, size,
177 scredits * SMB2_MAX_BUFFER_SIZE); 199 scredits * SMB2_MAX_BUFFER_SIZE);
178 200
@@ -3189,11 +3211,23 @@ handle_read_data(struct TCP_Server_Info *server, struct mid_q_entry *mid,
3189 server->ops->is_status_pending(buf, server, 0)) 3211 server->ops->is_status_pending(buf, server, 0))
3190 return -1; 3212 return -1;
3191 3213
3192 rdata->result = server->ops->map_error(buf, false); 3214 /* set up first two iov to get credits */
3215 rdata->iov[0].iov_base = buf;
3216 rdata->iov[0].iov_len = 4;
3217 rdata->iov[1].iov_base = buf + 4;
3218 rdata->iov[1].iov_len =
3219 min_t(unsigned int, buf_len, server->vals->read_rsp_size) - 4;
3220 cifs_dbg(FYI, "0: iov_base=%p iov_len=%zu\n",
3221 rdata->iov[0].iov_base, rdata->iov[0].iov_len);
3222 cifs_dbg(FYI, "1: iov_base=%p iov_len=%zu\n",
3223 rdata->iov[1].iov_base, rdata->iov[1].iov_len);
3224
3225 rdata->result = server->ops->map_error(buf, true);
3193 if (rdata->result != 0) { 3226 if (rdata->result != 0) {
3194 cifs_dbg(FYI, "%s: server returned error %d\n", 3227 cifs_dbg(FYI, "%s: server returned error %d\n",
3195 __func__, rdata->result); 3228 __func__, rdata->result);
3196 dequeue_mid(mid, rdata->result); 3229 /* normal error on read response */
3230 dequeue_mid(mid, false);
3197 return 0; 3231 return 0;
3198 } 3232 }
3199 3233
@@ -3266,14 +3300,6 @@ handle_read_data(struct TCP_Server_Info *server, struct mid_q_entry *mid,
3266 return 0; 3300 return 0;
3267 } 3301 }
3268 3302
3269 /* set up first iov for signature check */
3270 rdata->iov[0].iov_base = buf;
3271 rdata->iov[0].iov_len = 4;
3272 rdata->iov[1].iov_base = buf + 4;
3273 rdata->iov[1].iov_len = server->vals->read_rsp_size - 4;
3274 cifs_dbg(FYI, "0: iov_base=%p iov_len=%zu\n",
3275 rdata->iov[0].iov_base, server->vals->read_rsp_size);
3276
3277 length = rdata->copy_into_pages(server, rdata, &iter); 3303 length = rdata->copy_into_pages(server, rdata, &iter);
3278 3304
3279 kfree(bvec); 3305 kfree(bvec);