aboutsummaryrefslogtreecommitdiffstats
path: root/fs/cifs/transport.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/cifs/transport.c')
-rw-r--r--fs/cifs/transport.c331
1 files changed, 255 insertions, 76 deletions
diff --git a/fs/cifs/transport.c b/fs/cifs/transport.c
index 0046c219833d..981ea0d8b9cd 100644
--- a/fs/cifs/transport.c
+++ b/fs/cifs/transport.c
@@ -49,7 +49,8 @@ AllocMidQEntry(struct smb_hdr *smb_buffer, struct cifsSesInfo *ses)
49 return NULL; 49 return NULL;
50 } 50 }
51 51
52 temp = (struct mid_q_entry *) mempool_alloc(cifs_mid_poolp,SLAB_KERNEL | SLAB_NOFS); 52 temp = (struct mid_q_entry *) mempool_alloc(cifs_mid_poolp,
53 SLAB_KERNEL | SLAB_NOFS);
53 if (temp == NULL) 54 if (temp == NULL)
54 return temp; 55 return temp;
55 else { 56 else {
@@ -58,7 +59,9 @@ AllocMidQEntry(struct smb_hdr *smb_buffer, struct cifsSesInfo *ses)
58 temp->pid = current->pid; 59 temp->pid = current->pid;
59 temp->command = smb_buffer->Command; 60 temp->command = smb_buffer->Command;
60 cFYI(1, ("For smb_command %d", temp->command)); 61 cFYI(1, ("For smb_command %d", temp->command));
61 do_gettimeofday(&temp->when_sent); 62 /* do_gettimeofday(&temp->when_sent);*/ /* easier to use jiffies */
63 /* when mid allocated can be before when sent */
64 temp->when_alloc = jiffies;
62 temp->ses = ses; 65 temp->ses = ses;
63 temp->tsk = current; 66 temp->tsk = current;
64 } 67 }
@@ -74,6 +77,9 @@ AllocMidQEntry(struct smb_hdr *smb_buffer, struct cifsSesInfo *ses)
74static void 77static void
75DeleteMidQEntry(struct mid_q_entry *midEntry) 78DeleteMidQEntry(struct mid_q_entry *midEntry)
76{ 79{
80#ifdef CONFIG_CIFS_STATS2
81 unsigned long now;
82#endif
77 spin_lock(&GlobalMid_Lock); 83 spin_lock(&GlobalMid_Lock);
78 midEntry->midState = MID_FREE; 84 midEntry->midState = MID_FREE;
79 list_del(&midEntry->qhead); 85 list_del(&midEntry->qhead);
@@ -83,6 +89,22 @@ DeleteMidQEntry(struct mid_q_entry *midEntry)
83 cifs_buf_release(midEntry->resp_buf); 89 cifs_buf_release(midEntry->resp_buf);
84 else 90 else
85 cifs_small_buf_release(midEntry->resp_buf); 91 cifs_small_buf_release(midEntry->resp_buf);
92#ifdef CONFIG_CIFS_STATS2
93 now = jiffies;
94 /* commands taking longer than one second are indications that
95 something is wrong, unless it is quite a slow link or server */
96 if((now - midEntry->when_alloc) > HZ) {
97 if((cifsFYI & CIFS_TIMER) &&
98 (midEntry->command != SMB_COM_LOCKING_ANDX)) {
99 printk(KERN_DEBUG " CIFS slow rsp: cmd %d mid %d",
100 midEntry->command, midEntry->mid);
101 printk(" A: 0x%lx S: 0x%lx R: 0x%lx\n",
102 now - midEntry->when_alloc,
103 now - midEntry->when_sent,
104 now - midEntry->when_received);
105 }
106 }
107#endif
86 mempool_free(midEntry, cifs_mid_poolp); 108 mempool_free(midEntry, cifs_mid_poolp);
87} 109}
88 110
@@ -146,32 +168,37 @@ smb_send(struct socket *ssocket, struct smb_hdr *smb_buffer,
146 Flags2 is converted in SendReceive */ 168 Flags2 is converted in SendReceive */
147 169
148 smb_buffer->smb_buf_length = cpu_to_be32(smb_buffer->smb_buf_length); 170 smb_buffer->smb_buf_length = cpu_to_be32(smb_buffer->smb_buf_length);
149 cFYI(1, ("Sending smb of length %d ", smb_buf_length)); 171 cFYI(1, ("Sending smb of length %d", smb_buf_length));
150 dump_smb(smb_buffer, len); 172 dump_smb(smb_buffer, len);
151 173
152 while (len > 0) { 174 while (len > 0) {
153 rc = kernel_sendmsg(ssocket, &smb_msg, &iov, 1, len); 175 rc = kernel_sendmsg(ssocket, &smb_msg, &iov, 1, len);
154 if ((rc == -ENOSPC) || (rc == -EAGAIN)) { 176 if ((rc == -ENOSPC) || (rc == -EAGAIN)) {
155 i++; 177 i++;
156 if(i > 60) { 178 /* smaller timeout here than send2 since smaller size */
179 /* Although it may not be required, this also is smaller
180 oplock break time */
181 if(i > 12) {
157 cERROR(1, 182 cERROR(1,
158 ("sends on sock %p stuck for 30 seconds", 183 ("sends on sock %p stuck for 7 seconds",
159 ssocket)); 184 ssocket));
160 rc = -EAGAIN; 185 rc = -EAGAIN;
161 break; 186 break;
162 } 187 }
163 msleep(500); 188 msleep(1 << i);
164 continue; 189 continue;
165 } 190 }
166 if (rc < 0) 191 if (rc < 0)
167 break; 192 break;
193 else
194 i = 0; /* reset i after each successful send */
168 iov.iov_base += rc; 195 iov.iov_base += rc;
169 iov.iov_len -= rc; 196 iov.iov_len -= rc;
170 len -= rc; 197 len -= rc;
171 } 198 }
172 199
173 if (rc < 0) { 200 if (rc < 0) {
174 cERROR(1,("Error %d sending data on socket to server.", rc)); 201 cERROR(1,("Error %d sending data on socket to server", rc));
175 } else { 202 } else {
176 rc = 0; 203 rc = 0;
177 } 204 }
@@ -179,26 +206,21 @@ smb_send(struct socket *ssocket, struct smb_hdr *smb_buffer,
179 return rc; 206 return rc;
180} 207}
181 208
182#ifdef CIFS_EXPERIMENTAL 209#ifdef CONFIG_CIFS_EXPERIMENTAL
183/* BB finish off this function, adding support for writing set of pages as iovec */ 210static int
184/* and also adding support for operations that need to parse the response smb */ 211smb_send2(struct socket *ssocket, struct kvec *iov, int n_vec,
185 212 struct sockaddr *sin)
186int
187smb_sendv(struct socket *ssocket, struct smb_hdr *smb_buffer,
188 unsigned int smb_buf_length, struct kvec * write_vector
189 /* page list */, struct sockaddr *sin)
190{ 213{
191 int rc = 0; 214 int rc = 0;
192 int i = 0; 215 int i = 0;
193 struct msghdr smb_msg; 216 struct msghdr smb_msg;
194 number_of_pages += 1; /* account for SMB header */ 217 struct smb_hdr *smb_buffer = iov[0].iov_base;
195 struct kvec * piov = kmalloc(number_of_pages * sizeof(struct kvec)); 218 unsigned int len = iov[0].iov_len;
196 unsigned len = smb_buf_length + 4; 219 unsigned int total_len;
197 220 int first_vec = 0;
221
198 if(ssocket == NULL) 222 if(ssocket == NULL)
199 return -ENOTSOCK; /* BB eventually add reconnect code here */ 223 return -ENOTSOCK; /* BB eventually add reconnect code here */
200 iov.iov_base = smb_buffer;
201 iov.iov_len = len;
202 224
203 smb_msg.msg_name = sin; 225 smb_msg.msg_name = sin;
204 smb_msg.msg_namelen = sizeof (struct sockaddr); 226 smb_msg.msg_namelen = sizeof (struct sockaddr);
@@ -211,49 +233,80 @@ smb_sendv(struct socket *ssocket, struct smb_hdr *smb_buffer,
211 cifssmb.c and RFC1001 len is converted to bigendian in smb_send 233 cifssmb.c and RFC1001 len is converted to bigendian in smb_send
212 Flags2 is converted in SendReceive */ 234 Flags2 is converted in SendReceive */
213 235
236
237 total_len = 0;
238 for (i = 0; i < n_vec; i++)
239 total_len += iov[i].iov_len;
240
214 smb_buffer->smb_buf_length = cpu_to_be32(smb_buffer->smb_buf_length); 241 smb_buffer->smb_buf_length = cpu_to_be32(smb_buffer->smb_buf_length);
215 cFYI(1, ("Sending smb of length %d ", smb_buf_length)); 242 cFYI(1, ("Sending smb: total_len %d", total_len));
216 dump_smb(smb_buffer, len); 243 dump_smb(smb_buffer, len);
217 244
218 while (len > 0) { 245 while (total_len) {
219 rc = kernel_sendmsg(ssocket, &smb_msg, &iov, number_of_pages, 246 rc = kernel_sendmsg(ssocket, &smb_msg, &iov[first_vec],
220 len); 247 n_vec - first_vec, total_len);
221 if ((rc == -ENOSPC) || (rc == -EAGAIN)) { 248 if ((rc == -ENOSPC) || (rc == -EAGAIN)) {
222 i++; 249 i++;
223 if(i > 60) { 250 if(i >= 14) {
224 cERROR(1, 251 cERROR(1,
225 ("sends on sock %p stuck for 30 seconds", 252 ("sends on sock %p stuck for 15 seconds",
226 ssocket)); 253 ssocket));
227 rc = -EAGAIN; 254 rc = -EAGAIN;
228 break; 255 break;
229 } 256 }
230 msleep(500); 257 msleep(1 << i);
231 continue; 258 continue;
232 } 259 }
233 if (rc < 0) 260 if (rc < 0)
234 break; 261 break;
235 iov.iov_base += rc; 262
236 iov.iov_len -= rc; 263 if (rc >= total_len) {
237 len -= rc; 264 WARN_ON(rc > total_len);
265 break;
266 }
267 if(rc == 0) {
268 /* should never happen, letting socket clear before
269 retrying is our only obvious option here */
270 cERROR(1,("tcp sent no data"));
271 msleep(500);
272 continue;
273 }
274 total_len -= rc;
275 /* the line below resets i */
276 for (i = first_vec; i < n_vec; i++) {
277 if (iov[i].iov_len) {
278 if (rc > iov[i].iov_len) {
279 rc -= iov[i].iov_len;
280 iov[i].iov_len = 0;
281 } else {
282 iov[i].iov_base += rc;
283 iov[i].iov_len -= rc;
284 first_vec = i;
285 break;
286 }
287 }
288 }
289 i = 0; /* in case we get ENOSPC on the next send */
238 } 290 }
239 291
240 if (rc < 0) { 292 if (rc < 0) {
241 cERROR(1,("Error %d sending data on socket to server.", rc)); 293 cERROR(1,("Error %d sending data on socket to server", rc));
242 } else { 294 } else
243 rc = 0; 295 rc = 0;
244 }
245 296
246 return rc; 297 return rc;
247} 298}
248 299
249
250int 300int
251CIFSSendRcv(const unsigned int xid, struct cifsSesInfo *ses, 301SendReceive2(const unsigned int xid, struct cifsSesInfo *ses,
252 struct smb_hdr *in_buf, struct kvec * write_vector /* page list */, int *pbytes_returned, const int long_op) 302 struct kvec *iov, int n_vec, int *pbytes_returned,
303 const int long_op)
253{ 304{
254 int rc = 0; 305 int rc = 0;
255 unsigned long timeout = 15 * HZ; 306 unsigned int receive_len;
256 struct mid_q_entry *midQ = NULL; 307 unsigned long timeout;
308 struct mid_q_entry *midQ;
309 struct smb_hdr *in_buf = iov[0].iov_base;
257 310
258 if (ses == NULL) { 311 if (ses == NULL) {
259 cERROR(1,("Null smb session")); 312 cERROR(1,("Null smb session"));
@@ -263,14 +316,8 @@ CIFSSendRcv(const unsigned int xid, struct cifsSesInfo *ses,
263 cERROR(1,("Null tcp session")); 316 cERROR(1,("Null tcp session"));
264 return -EIO; 317 return -EIO;
265 } 318 }
266 if(pbytes_returned == NULL)
267 return -EIO;
268 else
269 *pbytes_returned = 0;
270 319
271 320 if(ses->server->tcpStatus == CifsExiting)
272
273 if(ses->server->tcpStatus == CIFS_EXITING)
274 return -ENOENT; 321 return -ENOENT;
275 322
276 /* Ensure that we do not send more than 50 overlapping requests 323 /* Ensure that we do not send more than 50 overlapping requests
@@ -282,11 +329,18 @@ CIFSSendRcv(const unsigned int xid, struct cifsSesInfo *ses,
282 } else { 329 } else {
283 spin_lock(&GlobalMid_Lock); 330 spin_lock(&GlobalMid_Lock);
284 while(1) { 331 while(1) {
285 if(atomic_read(&ses->server->inFlight) >= cifs_max_pending){ 332 if(atomic_read(&ses->server->inFlight) >=
333 cifs_max_pending){
286 spin_unlock(&GlobalMid_Lock); 334 spin_unlock(&GlobalMid_Lock);
335#ifdef CONFIG_CIFS_STATS2
336 atomic_inc(&ses->server->num_waiters);
337#endif
287 wait_event(ses->server->request_q, 338 wait_event(ses->server->request_q,
288 atomic_read(&ses->server->inFlight) 339 atomic_read(&ses->server->inFlight)
289 < cifs_max_pending); 340 < cifs_max_pending);
341#ifdef CONFIG_CIFS_STATS2
342 atomic_dec(&ses->server->num_waiters);
343#endif
290 spin_lock(&GlobalMid_Lock); 344 spin_lock(&GlobalMid_Lock);
291 } else { 345 } else {
292 if(ses->server->tcpStatus == CifsExiting) { 346 if(ses->server->tcpStatus == CifsExiting) {
@@ -314,17 +368,17 @@ CIFSSendRcv(const unsigned int xid, struct cifsSesInfo *ses,
314 368
315 if (ses->server->tcpStatus == CifsExiting) { 369 if (ses->server->tcpStatus == CifsExiting) {
316 rc = -ENOENT; 370 rc = -ENOENT;
317 goto cifs_out_label; 371 goto out_unlock2;
318 } else if (ses->server->tcpStatus == CifsNeedReconnect) { 372 } else if (ses->server->tcpStatus == CifsNeedReconnect) {
319 cFYI(1,("tcp session dead - return to caller to retry")); 373 cFYI(1,("tcp session dead - return to caller to retry"));
320 rc = -EAGAIN; 374 rc = -EAGAIN;
321 goto cifs_out_label; 375 goto out_unlock2;
322 } else if (ses->status != CifsGood) { 376 } else if (ses->status != CifsGood) {
323 /* check if SMB session is bad because we are setting it up */ 377 /* check if SMB session is bad because we are setting it up */
324 if((in_buf->Command != SMB_COM_SESSION_SETUP_ANDX) && 378 if((in_buf->Command != SMB_COM_SESSION_SETUP_ANDX) &&
325 (in_buf->Command != SMB_COM_NEGOTIATE)) { 379 (in_buf->Command != SMB_COM_NEGOTIATE)) {
326 rc = -EAGAIN; 380 rc = -EAGAIN;
327 goto cifs_out_label; 381 goto out_unlock2;
328 } /* else ok - we are setting up session */ 382 } /* else ok - we are setting up session */
329 } 383 }
330 midQ = AllocMidQEntry(in_buf, ses); 384 midQ = AllocMidQEntry(in_buf, ses);
@@ -338,51 +392,162 @@ CIFSSendRcv(const unsigned int xid, struct cifsSesInfo *ses,
338 return -ENOMEM; 392 return -ENOMEM;
339 } 393 }
340 394
341 if (in_buf->smb_buf_length > CIFSMaxBufSize + MAX_CIFS_HDR_SIZE - 4) { 395/* BB FIXME */
342 up(&ses->server->tcpSem); 396/* rc = cifs_sign_smb2(iov, n_vec, ses->server, &midQ->sequence_number); */
343 cERROR(1, 397
344 ("Illegal length, greater than maximum frame, %d ", 398 midQ->midState = MID_REQUEST_SUBMITTED;
345 in_buf->smb_buf_length)); 399#ifdef CONFIG_CIFS_STATS2
400 atomic_inc(&ses->server->inSend);
401#endif
402 rc = smb_send2(ses->server->ssocket, iov, n_vec,
403 (struct sockaddr *) &(ses->server->addr.sockAddr));
404#ifdef CONFIG_CIFS_STATS2
405 atomic_dec(&ses->server->inSend);
406 midQ->when_sent = jiffies;
407#endif
408 if(rc < 0) {
346 DeleteMidQEntry(midQ); 409 DeleteMidQEntry(midQ);
410 up(&ses->server->tcpSem);
347 /* If not lock req, update # of requests on wire to server */ 411 /* If not lock req, update # of requests on wire to server */
348 if(long_op < 3) { 412 if(long_op < 3) {
349 atomic_dec(&ses->server->inFlight); 413 atomic_dec(&ses->server->inFlight);
350 wake_up(&ses->server->request_q); 414 wake_up(&ses->server->request_q);
351 } 415 }
352 return -EIO; 416 return rc;
417 } else
418 up(&ses->server->tcpSem);
419 if (long_op == -1)
420 goto cifs_no_response_exit2;
421 else if (long_op == 2) /* writes past end of file can take loong time */
422 timeout = 180 * HZ;
423 else if (long_op == 1)
424 timeout = 45 * HZ; /* should be greater than
425 servers oplock break timeout (about 43 seconds) */
426 else if (long_op > 2) {
427 timeout = MAX_SCHEDULE_TIMEOUT;
428 } else
429 timeout = 15 * HZ;
430 /* wait for 15 seconds or until woken up due to response arriving or
431 due to last connection to this server being unmounted */
432 if (signal_pending(current)) {
433 /* if signal pending do not hold up user for full smb timeout
434 but we still give response a change to complete */
435 timeout = 2 * HZ;
436 }
437
438 /* No user interrupts in wait - wreaks havoc with performance */
439 if(timeout != MAX_SCHEDULE_TIMEOUT) {
440 timeout += jiffies;
441 wait_event(ses->server->response_q,
442 (!(midQ->midState & MID_REQUEST_SUBMITTED)) ||
443 time_after(jiffies, timeout) ||
444 ((ses->server->tcpStatus != CifsGood) &&
445 (ses->server->tcpStatus != CifsNew)));
446 } else {
447 wait_event(ses->server->response_q,
448 (!(midQ->midState & MID_REQUEST_SUBMITTED)) ||
449 ((ses->server->tcpStatus != CifsGood) &&
450 (ses->server->tcpStatus != CifsNew)));
353 } 451 }
354 452
355 /* BB can we sign efficiently in this path? */ 453 spin_lock(&GlobalMid_Lock);
356 rc = cifs_sign_smb(in_buf, ses->server, &midQ->sequence_number); 454 if (midQ->resp_buf) {
455 spin_unlock(&GlobalMid_Lock);
456 receive_len = midQ->resp_buf->smb_buf_length;
457 } else {
458 cERROR(1,("No response to cmd %d mid %d",
459 midQ->command, midQ->mid));
460 if(midQ->midState == MID_REQUEST_SUBMITTED) {
461 if(ses->server->tcpStatus == CifsExiting)
462 rc = -EHOSTDOWN;
463 else {
464 ses->server->tcpStatus = CifsNeedReconnect;
465 midQ->midState = MID_RETRY_NEEDED;
466 }
467 }
357 468
358 midQ->midState = MID_REQUEST_SUBMITTED; 469 if (rc != -EHOSTDOWN) {
359/* rc = smb_sendv(ses->server->ssocket, in_buf, in_buf->smb_buf_length, 470 if(midQ->midState == MID_RETRY_NEEDED) {
360 piovec, 471 rc = -EAGAIN;
361 (struct sockaddr *) &(ses->server->addr.sockAddr));*/ 472 cFYI(1,("marking request for retry"));
362 if(rc < 0) { 473 } else {
474 rc = -EIO;
475 }
476 }
477 spin_unlock(&GlobalMid_Lock);
363 DeleteMidQEntry(midQ); 478 DeleteMidQEntry(midQ);
364 up(&ses->server->tcpSem);
365 /* If not lock req, update # of requests on wire to server */ 479 /* If not lock req, update # of requests on wire to server */
366 if(long_op < 3) { 480 if(long_op < 3) {
367 atomic_dec(&ses->server->inFlight); 481 atomic_dec(&ses->server->inFlight);
368 wake_up(&ses->server->request_q); 482 wake_up(&ses->server->request_q);
369 } 483 }
370 return rc; 484 return rc;
371 } else 485 }
372 up(&ses->server->tcpSem); 486
373cifs_out_label: 487 if (receive_len > CIFSMaxBufSize + MAX_CIFS_HDR_SIZE) {
374 if(midQ) 488 cERROR(1, ("Frame too large received. Length: %d Xid: %d",
375 DeleteMidQEntry(midQ); 489 receive_len, xid));
376 490 rc = -EIO;
491 } else { /* rcvd frame is ok */
492
493 if (midQ->resp_buf &&
494 (midQ->midState == MID_RESPONSE_RECEIVED)) {
495 in_buf->smb_buf_length = receive_len;
496 /* BB verify that length would not overrun small buf */
497 memcpy((char *)in_buf + 4,
498 (char *)midQ->resp_buf + 4,
499 receive_len);
500
501 dump_smb(in_buf, 80);
502 /* convert the length into a more usable form */
503 if((receive_len > 24) &&
504 (ses->server->secMode & (SECMODE_SIGN_REQUIRED |
505 SECMODE_SIGN_ENABLED))) {
506 rc = cifs_verify_signature(in_buf,
507 ses->server->mac_signing_key,
508 midQ->sequence_number+1);
509 if(rc) {
510 cERROR(1,("Unexpected SMB signature"));
511 /* BB FIXME add code to kill session */
512 }
513 }
514
515 *pbytes_returned = in_buf->smb_buf_length;
516
517 /* BB special case reconnect tid and uid here? */
518 rc = map_smb_to_linux_error(in_buf);
519
520 /* convert ByteCount if necessary */
521 if (receive_len >=
522 sizeof (struct smb_hdr) -
523 4 /* do not count RFC1001 header */ +
524 (2 * in_buf->WordCount) + 2 /* bcc */ )
525 BCC(in_buf) = le16_to_cpu(BCC(in_buf));
526 } else {
527 rc = -EIO;
528 cFYI(1,("Bad MID state?"));
529 }
530 }
531cifs_no_response_exit2:
532 DeleteMidQEntry(midQ);
533
377 if(long_op < 3) { 534 if(long_op < 3) {
378 atomic_dec(&ses->server->inFlight); 535 atomic_dec(&ses->server->inFlight);
379 wake_up(&ses->server->request_q); 536 wake_up(&ses->server->request_q);
380 } 537 }
381 538
382 return rc; 539 return rc;
383}
384 540
541out_unlock2:
542 up(&ses->server->tcpSem);
543 /* If not lock req, update # of requests on wire to server */
544 if(long_op < 3) {
545 atomic_dec(&ses->server->inFlight);
546 wake_up(&ses->server->request_q);
547 }
385 548
549 return rc;
550}
386#endif /* CIFS_EXPERIMENTAL */ 551#endif /* CIFS_EXPERIMENTAL */
387 552
388int 553int
@@ -419,9 +584,15 @@ SendReceive(const unsigned int xid, struct cifsSesInfo *ses,
419 if(atomic_read(&ses->server->inFlight) >= 584 if(atomic_read(&ses->server->inFlight) >=
420 cifs_max_pending){ 585 cifs_max_pending){
421 spin_unlock(&GlobalMid_Lock); 586 spin_unlock(&GlobalMid_Lock);
587#ifdef CONFIG_CIFS_STATS2
588 atomic_inc(&ses->server->num_waiters);
589#endif
422 wait_event(ses->server->request_q, 590 wait_event(ses->server->request_q,
423 atomic_read(&ses->server->inFlight) 591 atomic_read(&ses->server->inFlight)
424 < cifs_max_pending); 592 < cifs_max_pending);
593#ifdef CONFIG_CIFS_STATS2
594 atomic_dec(&ses->server->num_waiters);
595#endif
425 spin_lock(&GlobalMid_Lock); 596 spin_lock(&GlobalMid_Lock);
426 } else { 597 } else {
427 if(ses->server->tcpStatus == CifsExiting) { 598 if(ses->server->tcpStatus == CifsExiting) {
@@ -490,8 +661,15 @@ SendReceive(const unsigned int xid, struct cifsSesInfo *ses,
490 rc = cifs_sign_smb(in_buf, ses->server, &midQ->sequence_number); 661 rc = cifs_sign_smb(in_buf, ses->server, &midQ->sequence_number);
491 662
492 midQ->midState = MID_REQUEST_SUBMITTED; 663 midQ->midState = MID_REQUEST_SUBMITTED;
664#ifdef CONFIG_CIFS_STATS2
665 atomic_inc(&ses->server->inSend);
666#endif
493 rc = smb_send(ses->server->ssocket, in_buf, in_buf->smb_buf_length, 667 rc = smb_send(ses->server->ssocket, in_buf, in_buf->smb_buf_length,
494 (struct sockaddr *) &(ses->server->addr.sockAddr)); 668 (struct sockaddr *) &(ses->server->addr.sockAddr));
669#ifdef CONFIG_CIFS_STATS2
670 atomic_dec(&ses->server->inSend);
671 midQ->when_sent = jiffies;
672#endif
495 if(rc < 0) { 673 if(rc < 0) {
496 DeleteMidQEntry(midQ); 674 DeleteMidQEntry(midQ);
497 up(&ses->server->tcpSem); 675 up(&ses->server->tcpSem);
@@ -506,7 +684,7 @@ SendReceive(const unsigned int xid, struct cifsSesInfo *ses,
506 if (long_op == -1) 684 if (long_op == -1)
507 goto cifs_no_response_exit; 685 goto cifs_no_response_exit;
508 else if (long_op == 2) /* writes past end of file can take loong time */ 686 else if (long_op == 2) /* writes past end of file can take loong time */
509 timeout = 300 * HZ; 687 timeout = 180 * HZ;
510 else if (long_op == 1) 688 else if (long_op == 1)
511 timeout = 45 * HZ; /* should be greater than 689 timeout = 45 * HZ; /* should be greater than
512 servers oplock break timeout (about 43 seconds) */ 690 servers oplock break timeout (about 43 seconds) */
@@ -540,9 +718,10 @@ SendReceive(const unsigned int xid, struct cifsSesInfo *ses,
540 spin_lock(&GlobalMid_Lock); 718 spin_lock(&GlobalMid_Lock);
541 if (midQ->resp_buf) { 719 if (midQ->resp_buf) {
542 spin_unlock(&GlobalMid_Lock); 720 spin_unlock(&GlobalMid_Lock);
543 receive_len = be32_to_cpu(*(__be32 *)midQ->resp_buf); 721 receive_len = midQ->resp_buf->smb_buf_length;
544 } else { 722 } else {
545 cERROR(1,("No response buffer")); 723 cERROR(1,("No response for cmd %d mid %d",
724 midQ->command, midQ->mid));
546 if(midQ->midState == MID_REQUEST_SUBMITTED) { 725 if(midQ->midState == MID_REQUEST_SUBMITTED) {
547 if(ses->server->tcpStatus == CifsExiting) 726 if(ses->server->tcpStatus == CifsExiting)
548 rc = -EHOSTDOWN; 727 rc = -EHOSTDOWN;
@@ -610,7 +789,7 @@ SendReceive(const unsigned int xid, struct cifsSesInfo *ses,
610 BCC(out_buf) = le16_to_cpu(BCC(out_buf)); 789 BCC(out_buf) = le16_to_cpu(BCC(out_buf));
611 } else { 790 } else {
612 rc = -EIO; 791 rc = -EIO;
613 cFYI(1,("Bad MID state? ")); 792 cERROR(1,("Bad MID state? "));
614 } 793 }
615 } 794 }
616cifs_no_response_exit: 795cifs_no_response_exit: