1/* 2 * fs/cifs/transport.c 3 * 4 * Copyright (C) International Business Machines Corp., 2002,2005 5 * Author(s): Steve French (sfrench@us.ibm.com) 6 * Jeremy Allison (jra@samba.org) 2006. 7 * 8 * This library is free software; you can redistribute it and/or modify 9 * it under the terms of the GNU Lesser General Public License as published 10 * by the Free Software Foundation; either version 2.1 of the License, or 11 * (at your option) any later version. 12 * 13 * This library is distributed in the hope that it will be useful, 14 * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See 16 * the GNU Lesser General Public License for more details. 17 * 18 * You should have received a copy of the GNU Lesser General Public License 19 * along with this library; if not, write to the Free Software 20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 21 */ 22 23#include <linux/fs.h> 24#include <linux/list.h> 25#include <linux/wait.h> 26#include <linux/net.h> 27#include <linux/delay.h> 28#include <asm/uaccess.h> 29#include <asm/processor.h> 30#include <linux/mempool.h> 31#include "cifspdu.h" 32#include "cifsglob.h" 33#include "cifsproto.h" 34#include "cifs_debug.h" 35 36extern mempool_t *cifs_mid_poolp; 37extern struct kmem_cache *cifs_oplock_cachep; 38 39static struct mid_q_entry * 40AllocMidQEntry(const struct smb_hdr *smb_buffer, struct cifsSesInfo *ses) 41{ 42 struct mid_q_entry *temp; 43 44 if (ses == NULL) { 45 cERROR(1, ("Null session passed in to AllocMidQEntry")); 46 return NULL; 47 } 48 if (ses->server == NULL) { 49 cERROR(1, ("Null TCP session in AllocMidQEntry")); 50 return NULL; 51 } 52 53 temp = (struct mid_q_entry *) mempool_alloc(cifs_mid_poolp, 54 GFP_KERNEL | GFP_NOFS); 55 if (temp == NULL) 56 return temp; 57 else { 58 memset(temp, 0, sizeof (struct mid_q_entry)); 59 temp->mid = smb_buffer->Mid; /* always LE */ 60 temp->pid = current->pid; 61 temp->command = smb_buffer->Command; 62 cFYI(1, ("For smb_command %d", temp->command)); 63 /* do_gettimeofday(&temp->when_sent);*/ /* easier to use jiffies */ 64 /* when mid allocated can be before when sent */ 65 temp->when_alloc = jiffies; 66 temp->ses = ses; 67 temp->tsk = current; 68 } 69 70 spin_lock(&GlobalMid_Lock); 71 list_add_tail(&temp->qhead, &ses->server->pending_mid_q); 72 atomic_inc(&midCount); 73 temp->midState = MID_REQUEST_ALLOCATED; 74 spin_unlock(&GlobalMid_Lock); 75 return temp; 76} 77 78static void 79DeleteMidQEntry(struct mid_q_entry *midEntry) 80{ 81#ifdef CONFIG_CIFS_STATS2 82 unsigned long now; 83#endif 84 spin_lock(&GlobalMid_Lock); 85 midEntry->midState = MID_FREE; 86 list_del(&midEntry->qhead); 87 atomic_dec(&midCount); 88 spin_unlock(&GlobalMid_Lock); 89 if(midEntry->largeBuf) 90 cifs_buf_release(midEntry->resp_buf); 91 else 92 cifs_small_buf_release(midEntry->resp_buf); 93#ifdef CONFIG_CIFS_STATS2 94 now = jiffies; 95 /* commands taking longer than one second are indications that 96 something is wrong, unless it is quite a slow link or server */ 97 if((now - midEntry->when_alloc) > HZ) { 98 if((cifsFYI & CIFS_TIMER) && 99 (midEntry->command != SMB_COM_LOCKING_ANDX)) { 100 printk(KERN_DEBUG " CIFS slow rsp: cmd %d mid %d", 101 midEntry->command, midEntry->mid); 102 printk(" A: 0x%lx S: 0x%lx R: 0x%lx\n", 103 now - midEntry->when_alloc, 104 now - midEntry->when_sent, 105 now - midEntry->when_received); 106 } 107 } 108#endif 109 mempool_free(midEntry, cifs_mid_poolp); 110} 111 112struct oplock_q_entry * 113AllocOplockQEntry(struct inode * pinode, __u16 fid, struct cifsTconInfo * tcon) 114{ 115 struct oplock_q_entry *temp; 116 if ((pinode== NULL) || (tcon == NULL)) { 117 cERROR(1, ("Null parms passed to AllocOplockQEntry")); 118 return NULL; 119 } 120 temp = (struct oplock_q_entry *) kmem_cache_alloc(cifs_oplock_cachep, 121 GFP_KERNEL); 122 if (temp == NULL) 123 return temp; 124 else { 125 temp->pinode = pinode; 126 temp->tcon = tcon; 127 temp->netfid = fid; 128 spin_lock(&GlobalMid_Lock); 129 list_add_tail(&temp->qhead, &GlobalOplock_Q); 130 spin_unlock(&GlobalMid_Lock); 131 } 132 return temp; 133 134} 135 136void DeleteOplockQEntry(struct oplock_q_entry * oplockEntry) 137{ 138 spin_lock(&GlobalMid_Lock); 139 /* should we check if list empty first? */ 140 list_del(&oplockEntry->qhead); 141 spin_unlock(&GlobalMid_Lock); 142 kmem_cache_free(cifs_oplock_cachep, oplockEntry); 143} 144 145int 146smb_send(struct socket *ssocket, struct smb_hdr *smb_buffer, 147 unsigned int smb_buf_length, struct sockaddr *sin) 148{ 149 int rc = 0; 150 int i = 0; 151 struct msghdr smb_msg; 152 struct kvec iov; 153 unsigned len = smb_buf_length + 4; 154 155 if(ssocket == NULL) 156 return -ENOTSOCK; /* BB eventually add reconnect code here */ 157 iov.iov_base = smb_buffer; 158 iov.iov_len = len; 159 160 smb_msg.msg_name = sin; 161 smb_msg.msg_namelen = sizeof (struct sockaddr); 162 smb_msg.msg_control = NULL; 163 smb_msg.msg_controllen = 0; 164 smb_msg.msg_flags = MSG_DONTWAIT + MSG_NOSIGNAL; /* BB add more flags?*/ 165 166 /* smb header is converted in header_assemble. bcc and rest of SMB word 167 area, and byte area if necessary, is converted to littleendian in 168 cifssmb.c and RFC1001 len is converted to bigendian in smb_send 169 Flags2 is converted in SendReceive */ 170 171 smb_buffer->smb_buf_length = cpu_to_be32(smb_buffer->smb_buf_length); 172 cFYI(1, ("Sending smb of length %d", smb_buf_length)); 173 dump_smb(smb_buffer, len); 174 175 while (len > 0) { 176 rc = kernel_sendmsg(ssocket, &smb_msg, &iov, 1, len); 177 if ((rc == -ENOSPC) || (rc == -EAGAIN)) { 178 i++; 179 /* smaller timeout here than send2 since smaller size */ 180 /* Although it may not be required, this also is smaller 181 oplock break time */ 182 if(i > 12) { 183 cERROR(1, 184 ("sends on sock %p stuck for 7 seconds", 185 ssocket)); 186 rc = -EAGAIN; 187 break; 188 } 189 msleep(1 << i); 190 continue; 191 } 192 if (rc < 0) 193 break; 194 else 195 i = 0; /* reset i after each successful send */ 196 iov.iov_base += rc; 197 iov.iov_len -= rc; 198 len -= rc; 199 } 200 201 if (rc < 0) { 202 cERROR(1,("Error %d sending data on socket to server", rc)); 203 } else { 204 rc = 0; 205 } 206 207 /* Don't want to modify the buffer as a 208 side effect of this call. */ 209 smb_buffer->smb_buf_length = smb_buf_length; 210 211 return rc; 212} 213 214static int 215smb_send2(struct socket *ssocket, struct kvec *iov, int n_vec, 216 struct sockaddr *sin) 217{ 218 int rc = 0; 219 int i = 0; 220 struct msghdr smb_msg; 221 struct smb_hdr *smb_buffer = iov[0].iov_base; 222 unsigned int len = iov[0].iov_len; 223 unsigned int total_len; 224 int first_vec = 0; 225 unsigned int smb_buf_length = smb_buffer->smb_buf_length; 226 227 if(ssocket == NULL) 228 return -ENOTSOCK; /* BB eventually add reconnect code here */ 229 230 smb_msg.msg_name = sin; 231 smb_msg.msg_namelen = sizeof (struct sockaddr); 232 smb_msg.msg_control = NULL; 233 smb_msg.msg_controllen = 0; 234 smb_msg.msg_flags = MSG_DONTWAIT + MSG_NOSIGNAL; /* BB add more flags?*/ 235 236 /* smb header is converted in header_assemble. bcc and rest of SMB word 237 area, and byte area if necessary, is converted to littleendian in 238 cifssmb.c and RFC1001 len is converted to bigendian in smb_send 239 Flags2 is converted in SendReceive */ 240 241 242 total_len = 0; 243 for (i = 0; i < n_vec; i++) 244 total_len += iov[i].iov_len; 245 246 smb_buffer->smb_buf_length = cpu_to_be32(smb_buffer->smb_buf_length); 247 cFYI(1, ("Sending smb: total_len %d", total_len)); 248 dump_smb(smb_buffer, len); 249 250 while (total_len) { 251 rc = kernel_sendmsg(ssocket, &smb_msg, &iov[first_vec], 252 n_vec - first_vec, total_len); 253 if ((rc == -ENOSPC) || (rc == -EAGAIN)) { 254 i++; 255 if(i >= 14) { 256 cERROR(1, 257 ("sends on sock %p stuck for 15 seconds", 258 ssocket)); 259 rc = -EAGAIN; 260 break; 261 } 262 msleep(1 << i); 263 continue; 264 } 265 if (rc < 0) 266 break; 267 268 if (rc >= total_len) { 269 WARN_ON(rc > total_len); 270 break; 271 } 272 if(rc == 0) { 273 /* should never happen, letting socket clear before 274 retrying is our only obvious option here */ 275 cERROR(1,("tcp sent no data")); 276 msleep(500); 277 continue; 278 } 279 total_len -= rc; 280 /* the line below resets i */ 281 for (i = first_vec; i < n_vec; i++) { 282 if (iov[i].iov_len) { 283 if (rc > iov[i].iov_len) { 284 rc -= iov[i].iov_len; 285 iov[i].iov_len = 0; 286 } else { 287 iov[i].iov_base += rc; 288 iov[i].iov_len -= rc; 289 first_vec = i; 290 break; 291 } 292 } 293 } 294 i = 0; /* in case we get ENOSPC on the next send */ 295 } 296 297 if (rc < 0) { 298 cERROR(1,("Error %d sending data on socket to server", rc)); 299 } else 300 rc = 0; 301 302 /* Don't want to modify the buffer as a 303 side effect of this call. */ 304 smb_buffer->smb_buf_length = smb_buf_length; 305 306 return rc; 307} 308 309static int wait_for_free_request(struct cifsSesInfo *ses, const int long_op) 310{ 311 if(long_op == -1) { 312 /* oplock breaks must not be held up */ 313 atomic_inc(&ses->server->inFlight); 314 } else { 315 spin_lock(&GlobalMid_Lock); 316 while(1) { 317 if(atomic_read(&ses->server->inFlight) >= 318 cifs_max_pending){ 319 spin_unlock(&GlobalMid_Lock); 320#ifdef CONFIG_CIFS_STATS2 321 atomic_inc(&ses->server->num_waiters); 322#endif 323 wait_event(ses->server->request_q, 324 atomic_read(&ses->server->inFlight) 325 < cifs_max_pending); 326#ifdef CONFIG_CIFS_STATS2 327 atomic_dec(&ses->server->num_waiters); 328#endif 329 spin_lock(&GlobalMid_Lock); 330 } else { 331 if(ses->server->tcpStatus == CifsExiting) { 332 spin_unlock(&GlobalMid_Lock); 333 return -ENOENT; 334 } 335 336 /* can not count locking commands against total since 337 they are allowed to block on server */ 338 339 /* update # of requests on the wire to server */ 340 if (long_op < 3) 341 atomic_inc(&ses->server->inFlight); 342 spin_unlock(&GlobalMid_Lock); 343 break; 344 } 345 } 346 } 347 return 0; 348} 349 350static int allocate_mid(struct cifsSesInfo *ses, struct smb_hdr *in_buf, 351 struct mid_q_entry **ppmidQ) 352{ 353 if (ses->server->tcpStatus == CifsExiting) { 354 return -ENOENT; 355 } else if (ses->server->tcpStatus == CifsNeedReconnect) { 356 cFYI(1,("tcp session dead - return to caller to retry")); 357 return -EAGAIN; 358 } else if (ses->status != CifsGood) { 359 /* check if SMB session is bad because we are setting it up */ 360 if((in_buf->Command != SMB_COM_SESSION_SETUP_ANDX) && 361 (in_buf->Command != SMB_COM_NEGOTIATE)) { 362 return -EAGAIN; 363 } /* else ok - we are setting up session */ 364 } 365 *ppmidQ = AllocMidQEntry(in_buf, ses); 366 if (*ppmidQ == NULL) { 367 return -ENOMEM; 368 } 369 return 0; 370} 371 372static int wait_for_response(struct cifsSesInfo *ses, 373 struct mid_q_entry *midQ, 374 unsigned long timeout, 375 unsigned long time_to_wait) 376{ 377 unsigned long curr_timeout; 378 379 for (;;) { 380 curr_timeout = timeout + jiffies; 381 wait_event(ses->server->response_q, 382 (!(midQ->midState == MID_REQUEST_SUBMITTED)) || 383 time_after(jiffies, curr_timeout) || 384 ((ses->server->tcpStatus != CifsGood) && 385 (ses->server->tcpStatus != CifsNew))); 386 387 if (time_after(jiffies, curr_timeout) && 388 (midQ->midState == MID_REQUEST_SUBMITTED) && 389 ((ses->server->tcpStatus == CifsGood) || 390 (ses->server->tcpStatus == CifsNew))) { 391 392 unsigned long lrt; 393 394 /* We timed out. Is the server still 395 sending replies ? */ 396 spin_lock(&GlobalMid_Lock); 397 lrt = ses->server->lstrp; 398 spin_unlock(&GlobalMid_Lock); 399 400 /* Calculate time_to_wait past last receive time. 401 Although we prefer not to time out if the 402 server is still responding - we will time 403 out if the server takes more than 15 (or 45 404 or 180) seconds to respond to this request 405 and has not responded to any request from 406 other threads on the client within 10 seconds */ 407 lrt += time_to_wait; 408 if (time_after(jiffies, lrt)) { 409 /* No replies for time_to_wait. */ 410 cERROR(1,("server not responding")); 411 return -1; 412 } 413 } else { 414 return 0; 415 } 416 } 417} 418 419int 420SendReceive2(const unsigned int xid, struct cifsSesInfo *ses, 421 struct kvec *iov, int n_vec, int * pRespBufType /* ret */, 422 const int long_op) 423{ 424 int rc = 0; 425 unsigned int receive_len; 426 unsigned long timeout; 427 struct mid_q_entry *midQ; 428 struct smb_hdr *in_buf = iov[0].iov_base; 429 430 *pRespBufType = CIFS_NO_BUFFER; /* no response buf yet */ 431 432 if ((ses == NULL) || (ses->server == NULL)) { 433 cifs_small_buf_release(in_buf); 434 cERROR(1,("Null session")); 435 return -EIO; 436 } 437 438 if(ses->server->tcpStatus == CifsExiting) { 439 cifs_small_buf_release(in_buf); 440 return -ENOENT; 441 } 442 443 /* Ensure that we do not send more than 50 overlapping requests 444 to the same server. We may make this configurable later or 445 use ses->maxReq */ 446 447 rc = wait_for_free_request(ses, long_op); 448 if (rc) { 449 cifs_small_buf_release(in_buf); 450 return rc; 451 } 452 453 /* make sure that we sign in the same order that we send on this socket 454 and avoid races inside tcp sendmsg code that could cause corruption 455 of smb data */ 456 457 down(&ses->server->tcpSem); 458 459 rc = allocate_mid(ses, in_buf, &midQ); 460 if (rc) { 461 up(&ses->server->tcpSem); 462 cifs_small_buf_release(in_buf); 463 /* Update # of requests on wire to server */ 464 atomic_dec(&ses->server->inFlight); 465 wake_up(&ses->server->request_q); 466 return rc; 467 } 468 469 rc = cifs_sign_smb2(iov, n_vec, ses->server, &midQ->sequence_number); 470 471 midQ->midState = MID_REQUEST_SUBMITTED; 472#ifdef CONFIG_CIFS_STATS2 473 atomic_inc(&ses->server->inSend); 474#endif 475 rc = smb_send2(ses->server->ssocket, iov, n_vec, 476 (struct sockaddr *) &(ses->server->addr.sockAddr)); 477#ifdef CONFIG_CIFS_STATS2 478 atomic_dec(&ses->server->inSend); 479 midQ->when_sent = jiffies; 480#endif 481 482 up(&ses->server->tcpSem); 483 cifs_small_buf_release(in_buf); 484 485 if(rc < 0) 486 goto out; 487 488 if (long_op == -1) 489 goto out; 490 else if (long_op == 2) /* writes past end of file can take loong time */ 491 timeout = 180 * HZ; 492 else if (long_op == 1) 493 timeout = 45 * HZ; /* should be greater than 494 servers oplock break timeout (about 43 seconds) */ 495 else 496 timeout = 15 * HZ; 497 498 /* wait for 15 seconds or until woken up due to response arriving or 499 due to last connection to this server being unmounted */ 500 if (signal_pending(current)) { 501 /* if signal pending do not hold up user for full smb timeout 502 but we still give response a chance to complete */ 503 timeout = 2 * HZ; 504 } 505 506 /* No user interrupts in wait - wreaks havoc with performance */ 507 wait_for_response(ses, midQ, timeout, 10 * HZ); 508 509 spin_lock(&GlobalMid_Lock); 510 if (midQ->resp_buf) { 511 spin_unlock(&GlobalMid_Lock); 512 receive_len = midQ->resp_buf->smb_buf_length; 513 } else { 514 cERROR(1,("No response to cmd %d mid %d", 515 midQ->command, midQ->mid)); 516 if(midQ->midState == MID_REQUEST_SUBMITTED) { 517 if(ses->server->tcpStatus == CifsExiting) 518 rc = -EHOSTDOWN; 519 else { 520 ses->server->tcpStatus = CifsNeedReconnect; 521 midQ->midState = MID_RETRY_NEEDED; 522 } 523 } 524 525 if (rc != -EHOSTDOWN) { 526 if(midQ->midState == MID_RETRY_NEEDED) { 527 rc = -EAGAIN; 528 cFYI(1,("marking request for retry")); 529 } else { 530 rc = -EIO; 531 } 532 } 533 spin_unlock(&GlobalMid_Lock); 534 DeleteMidQEntry(midQ); 535 /* Update # of requests on wire to server */ 536 atomic_dec(&ses->server->inFlight); 537 wake_up(&ses->server->request_q); 538 return rc; 539 } 540 541 if (receive_len > CIFSMaxBufSize + MAX_CIFS_HDR_SIZE) { 542 cERROR(1, ("Frame too large received. Length: %d Xid: %d", 543 receive_len, xid)); 544 rc = -EIO; 545 } else { /* rcvd frame is ok */ 546 if (midQ->resp_buf && 547 (midQ->midState == MID_RESPONSE_RECEIVED)) { 548 549 iov[0].iov_base = (char *)midQ->resp_buf; 550 if(midQ->largeBuf) 551 *pRespBufType = CIFS_LARGE_BUFFER; 552 else 553 *pRespBufType = CIFS_SMALL_BUFFER; 554 iov[0].iov_len = receive_len + 4; 555 556 dump_smb(midQ->resp_buf, 80); 557 /* convert the length into a more usable form */ 558 if((receive_len > 24) && 559 (ses->server->secMode & (SECMODE_SIGN_REQUIRED | 560 SECMODE_SIGN_ENABLED))) { 561 rc = cifs_verify_signature(midQ->resp_buf, 562 ses->server->mac_signing_key, 563 midQ->sequence_number+1); 564 if(rc) { 565 cERROR(1,("Unexpected SMB signature")); 566 } 567 } 568 569 /* BB special case reconnect tid and uid here? */ 570 /* BB special case Errbadpassword and pwdexpired here */ 571 rc = map_smb_to_linux_error(midQ->resp_buf); 572 573 /* convert ByteCount if necessary */ 574 if (receive_len >= 575 sizeof (struct smb_hdr) - 576 4 /* do not count RFC1001 header */ + 577 (2 * midQ->resp_buf->WordCount) + 2 /* bcc */ ) 578 BCC(midQ->resp_buf) = 579 le16_to_cpu(BCC_LE(midQ->resp_buf)); 580 midQ->resp_buf = NULL; /* mark it so will not be freed 581 by DeleteMidQEntry */ 582 } else { 583 rc = -EIO; 584 cFYI(1,("Bad MID state?")); 585 } 586 } 587 588out: 589 DeleteMidQEntry(midQ); 590 atomic_dec(&ses->server->inFlight); 591 wake_up(&ses->server->request_q); 592 593 return rc; 594} 595 596int 597SendReceive(const unsigned int xid, struct cifsSesInfo *ses, 598 struct smb_hdr *in_buf, struct smb_hdr *out_buf, 599 int *pbytes_returned, const int long_op) 600{ 601 int rc = 0; 602 unsigned int receive_len; 603 unsigned long timeout; 604 struct mid_q_entry *midQ; 605 606 if (ses == NULL) { 607 cERROR(1,("Null smb session")); 608 return -EIO; 609 } 610 if(ses->server == NULL) { 611 cERROR(1,("Null tcp session")); 612 return -EIO; 613 } 614 615 if(ses->server->tcpStatus == CifsExiting) 616 return -ENOENT; 617 618 /* Ensure that we do not send more than 50 overlapping requests 619 to the same server. We may make this configurable later or 620 use ses->maxReq */ 621 622 rc = wait_for_free_request(ses, long_op); 623 if (rc) 624 return rc; 625 626 /* make sure that we sign in the same order that we send on this socket 627 and avoid races inside tcp sendmsg code that could cause corruption 628 of smb data */ 629 630 down(&ses->server->tcpSem); 631 632 rc = allocate_mid(ses, in_buf, &midQ); 633 if (rc) { 634 up(&ses->server->tcpSem); 635 /* Update # of requests on wire to server */ 636 atomic_dec(&ses->server->inFlight); 637 wake_up(&ses->server->request_q); 638 return rc; 639 } 640 641 if (in_buf->smb_buf_length > CIFSMaxBufSize + MAX_CIFS_HDR_SIZE - 4) { 642 cERROR(1, ("Illegal length, greater than maximum frame, %d", 643 in_buf->smb_buf_length)); 644 DeleteMidQEntry(midQ); 645 up(&ses->server->tcpSem); 646 /* Update # of requests on wire to server */ 647 atomic_dec(&ses->server->inFlight); 648 wake_up(&ses->server->request_q); 649 return -EIO; 650 } 651 652 rc = cifs_sign_smb(in_buf, ses->server, &midQ->sequence_number); 653 654 midQ->midState = MID_REQUEST_SUBMITTED; 655#ifdef CONFIG_CIFS_STATS2 656 atomic_inc(&ses->server->inSend); 657#endif 658 rc = smb_send(ses->server->ssocket, in_buf, in_buf->smb_buf_length, 659 (struct sockaddr *) &(ses->server->addr.sockAddr)); 660#ifdef CONFIG_CIFS_STATS2 661 atomic_dec(&ses->server->inSend); 662 midQ->when_sent = jiffies; 663#endif 664 up(&ses->server->tcpSem); 665 666 if(rc < 0) 667 goto out; 668 669 if (long_op == -1) 670 goto out; 671 else if (long_op == 2) /* writes past end of file can take loong time */ 672 timeout = 180 * HZ; 673 else if (long_op == 1) 674 timeout = 45 * HZ; /* should be greater than 675 servers oplock break timeout (about 43 seconds) */ 676 else 677 timeout = 15 * HZ; 678 /* wait for 15 seconds or until woken up due to response arriving or 679 due to last connection to this server being unmounted */ 680 if (signal_pending(current)) { 681 /* if signal pending do not hold up user for full smb timeout 682 but we still give response a chance to complete */ 683 timeout = 2 * HZ; 684 } 685 686 /* No user interrupts in wait - wreaks havoc with performance */ 687 wait_for_response(ses, midQ, timeout, 10 * HZ); 688 689 spin_lock(&GlobalMid_Lock); 690 if (midQ->resp_buf) { 691 spin_unlock(&GlobalMid_Lock); 692 receive_len = midQ->resp_buf->smb_buf_length; 693 } else { 694 cERROR(1,("No response for cmd %d mid %d", 695 midQ->command, midQ->mid)); 696 if(midQ->midState == MID_REQUEST_SUBMITTED) { 697 if(ses->server->tcpStatus == CifsExiting) 698 rc = -EHOSTDOWN; 699 else { 700 ses->server->tcpStatus = CifsNeedReconnect; 701 midQ->midState = MID_RETRY_NEEDED; 702 } 703 } 704 705 if (rc != -EHOSTDOWN) { 706 if(midQ->midState == MID_RETRY_NEEDED) { 707 rc = -EAGAIN; 708 cFYI(1,("marking request for retry")); 709 } else { 710 rc = -EIO; 711 } 712 } 713 spin_unlock(&GlobalMid_Lock); 714 DeleteMidQEntry(midQ); 715 /* Update # of requests on wire to server */ 716 atomic_dec(&ses->server->inFlight); 717 wake_up(&ses->server->request_q); 718 return rc; 719 } 720 721 if (receive_len > CIFSMaxBufSize + MAX_CIFS_HDR_SIZE) { 722 cERROR(1, ("Frame too large received. Length: %d Xid: %d", 723 receive_len, xid)); 724 rc = -EIO; 725 } else { /* rcvd frame is ok */ 726 727 if (midQ->resp_buf && out_buf 728 && (midQ->midState == MID_RESPONSE_RECEIVED)) { 729 out_buf->smb_buf_length = receive_len; 730 memcpy((char *)out_buf + 4, 731 (char *)midQ->resp_buf + 4, 732 receive_len); 733 734 dump_smb(out_buf, 92); 735 /* convert the length into a more usable form */ 736 if((receive_len > 24) && 737 (ses->server->secMode & (SECMODE_SIGN_REQUIRED | 738 SECMODE_SIGN_ENABLED))) { 739 rc = cifs_verify_signature(out_buf, 740 ses->server->mac_signing_key, 741 midQ->sequence_number+1); 742 if(rc) { 743 cERROR(1,("Unexpected SMB signature")); 744 } 745 } 746 747 *pbytes_returned = out_buf->smb_buf_length; 748 749 /* BB special case reconnect tid and uid here? */ 750 rc = map_smb_to_linux_error(out_buf); 751 752 /* convert ByteCount if necessary */ 753 if (receive_len >= 754 sizeof (struct smb_hdr) - 755 4 /* do not count RFC1001 header */ + 756 (2 * out_buf->WordCount) + 2 /* bcc */ ) 757 BCC(out_buf) = le16_to_cpu(BCC_LE(out_buf)); 758 } else { 759 rc = -EIO; 760 cERROR(1,("Bad MID state?")); 761 } 762 } 763 764out: 765 DeleteMidQEntry(midQ); 766 atomic_dec(&ses->server->inFlight); 767 wake_up(&ses->server->request_q); 768 769 return rc; 770} 771 772/* Send an NT_CANCEL SMB to cause the POSIX blocking lock to return. */ 773 774static int 775send_nt_cancel(struct cifsTconInfo *tcon, struct smb_hdr *in_buf, 776 struct mid_q_entry *midQ) 777{ 778 int rc = 0; 779 struct cifsSesInfo *ses = tcon->ses; 780 __u16 mid = in_buf->Mid; 781 782 header_assemble(in_buf, SMB_COM_NT_CANCEL, tcon, 0); 783 in_buf->Mid = mid; 784 down(&ses->server->tcpSem); 785 rc = cifs_sign_smb(in_buf, ses->server, &midQ->sequence_number); 786 if (rc) { 787 up(&ses->server->tcpSem); 788 return rc; 789 } 790 rc = smb_send(ses->server->ssocket, in_buf, in_buf->smb_buf_length, 791 (struct sockaddr *) &(ses->server->addr.sockAddr)); 792 up(&ses->server->tcpSem); 793 return rc; 794} 795 796/* We send a LOCKINGX_CANCEL_LOCK to cause the Windows 797 blocking lock to return. */ 798 799static int 800send_lock_cancel(const unsigned int xid, struct cifsTconInfo *tcon, 801 struct smb_hdr *in_buf, 802 struct smb_hdr *out_buf) 803{ 804 int bytes_returned; 805 struct cifsSesInfo *ses = tcon->ses; 806 LOCK_REQ *pSMB = (LOCK_REQ *)in_buf; 807 808 /* We just modify the current in_buf to change 809 the type of lock from LOCKING_ANDX_SHARED_LOCK 810 or LOCKING_ANDX_EXCLUSIVE_LOCK to 811 LOCKING_ANDX_CANCEL_LOCK. */ 812 813 pSMB->LockType = LOCKING_ANDX_CANCEL_LOCK|LOCKING_ANDX_LARGE_FILES; 814 pSMB->Timeout = 0; 815 pSMB->hdr.Mid = GetNextMid(ses->server); 816 817 return SendReceive(xid, ses, in_buf, out_buf, 818 &bytes_returned, 0); 819} 820 821int 822SendReceiveBlockingLock(const unsigned int xid, struct cifsTconInfo *tcon, 823 struct smb_hdr *in_buf, struct smb_hdr *out_buf, 824 int *pbytes_returned) 825{ 826 int rc = 0; 827 int rstart = 0; 828 unsigned int receive_len; 829 struct mid_q_entry *midQ; 830 struct cifsSesInfo *ses; 831 832 if (tcon == NULL || tcon->ses == NULL) { 833 cERROR(1,("Null smb session")); 834 return -EIO; 835 } 836 ses = tcon->ses; 837 838 if(ses->server == NULL) { 839 cERROR(1,("Null tcp session")); 840 return -EIO; 841 } 842 843 if(ses->server->tcpStatus == CifsExiting) 844 return -ENOENT; 845 846 /* Ensure that we do not send more than 50 overlapping requests 847 to the same server. We may make this configurable later or 848 use ses->maxReq */ 849 850 rc = wait_for_free_request(ses, 3); 851 if (rc) 852 return rc; 853 854 /* make sure that we sign in the same order that we send on this socket 855 and avoid races inside tcp sendmsg code that could cause corruption 856 of smb data */ 857 858 down(&ses->server->tcpSem); 859 860 rc = allocate_mid(ses, in_buf, &midQ); 861 if (rc) { 862 up(&ses->server->tcpSem); 863 return rc; 864 } 865 866 if (in_buf->smb_buf_length > CIFSMaxBufSize + MAX_CIFS_HDR_SIZE - 4) { 867 up(&ses->server->tcpSem); 868 cERROR(1, ("Illegal length, greater than maximum frame, %d", 869 in_buf->smb_buf_length)); 870 DeleteMidQEntry(midQ); 871 return -EIO; 872 } 873 874 rc = cifs_sign_smb(in_buf, ses->server, &midQ->sequence_number); 875 876 midQ->midState = MID_REQUEST_SUBMITTED; 877#ifdef CONFIG_CIFS_STATS2 878 atomic_inc(&ses->server->inSend); 879#endif 880 rc = smb_send(ses->server->ssocket, in_buf, in_buf->smb_buf_length, 881 (struct sockaddr *) &(ses->server->addr.sockAddr)); 882#ifdef CONFIG_CIFS_STATS2 883 atomic_dec(&ses->server->inSend); 884 midQ->when_sent = jiffies; 885#endif 886 up(&ses->server->tcpSem); 887 888 if(rc < 0) { 889 DeleteMidQEntry(midQ); 890 return rc; 891 } 892 893 /* Wait for a reply - allow signals to interrupt. */ 894 rc = wait_event_interruptible(ses->server->response_q, 895 (!(midQ->midState == MID_REQUEST_SUBMITTED)) || 896 ((ses->server->tcpStatus != CifsGood) && 897 (ses->server->tcpStatus != CifsNew))); 898 899 /* Were we interrupted by a signal ? */ 900 if ((rc == -ERESTARTSYS) && 901 (midQ->midState == MID_REQUEST_SUBMITTED) && 902 ((ses->server->tcpStatus == CifsGood) || 903 (ses->server->tcpStatus == CifsNew))) { 904 905 if (in_buf->Command == SMB_COM_TRANSACTION2) { 906 /* POSIX lock. We send a NT_CANCEL SMB to cause the 907 blocking lock to return. */ 908 909 rc = send_nt_cancel(tcon, in_buf, midQ); 910 if (rc) { 911 DeleteMidQEntry(midQ); 912 return rc; 913 } 914 } else { 915 /* Windows lock. We send a LOCKINGX_CANCEL_LOCK 916 to cause the blocking lock to return. */ 917 918 rc = send_lock_cancel(xid, tcon, in_buf, out_buf); 919 920 /* If we get -ENOLCK back the lock may have 921 already been removed. Don't exit in this case. */ 922 if (rc && rc != -ENOLCK) { 923 DeleteMidQEntry(midQ); 924 return rc; 925 } 926 } 927 928 /* Wait 5 seconds for the response. */ 929 if (wait_for_response(ses, midQ, 5 * HZ, 5 * HZ)==0) { 930 /* We got the response - restart system call. */ 931 rstart = 1; 932 } 933 } 934 935 spin_lock(&GlobalMid_Lock); 936 if (midQ->resp_buf) { 937 spin_unlock(&GlobalMid_Lock); 938 receive_len = midQ->resp_buf->smb_buf_length; 939 } else { 940 cERROR(1,("No response for cmd %d mid %d", 941 midQ->command, midQ->mid)); 942 if(midQ->midState == MID_REQUEST_SUBMITTED) { 943 if(ses->server->tcpStatus == CifsExiting) 944 rc = -EHOSTDOWN; 945 else { 946 ses->server->tcpStatus = CifsNeedReconnect; 947 midQ->midState = MID_RETRY_NEEDED; 948 } 949 } 950 951 if (rc != -EHOSTDOWN) { 952 if(midQ->midState == MID_RETRY_NEEDED) { 953 rc = -EAGAIN; 954 cFYI(1,("marking request for retry")); 955 } else { 956 rc = -EIO; 957 } 958 } 959 spin_unlock(&GlobalMid_Lock); 960 DeleteMidQEntry(midQ); 961 return rc; 962 } 963 964 if (receive_len > CIFSMaxBufSize + MAX_CIFS_HDR_SIZE) { 965 cERROR(1, ("Frame too large received. Length: %d Xid: %d", 966 receive_len, xid)); 967 rc = -EIO; 968 } else { /* rcvd frame is ok */ 969 970 if (midQ->resp_buf && out_buf 971 && (midQ->midState == MID_RESPONSE_RECEIVED)) { 972 out_buf->smb_buf_length = receive_len; 973 memcpy((char *)out_buf + 4, 974 (char *)midQ->resp_buf + 4, 975 receive_len); 976 977 dump_smb(out_buf, 92); 978 /* convert the length into a more usable form */ 979 if((receive_len > 24) && 980 (ses->server->secMode & (SECMODE_SIGN_REQUIRED | 981 SECMODE_SIGN_ENABLED))) { 982 rc = cifs_verify_signature(out_buf, 983 ses->server->mac_signing_key, 984 midQ->sequence_number+1); 985 if(rc) { 986 cERROR(1,("Unexpected SMB signature")); 987 } 988 } 989 990 *pbytes_returned = out_buf->smb_buf_length; 991 992 /* BB special case reconnect tid and uid here? */ 993 rc = map_smb_to_linux_error(out_buf); 994 995 /* convert ByteCount if necessary */ 996 if (receive_len >= 997 sizeof (struct smb_hdr) - 998 4 /* do not count RFC1001 header */ + 999 (2 * out_buf->WordCount) + 2 /* bcc */ ) 1000 BCC(out_buf) = le16_to_cpu(BCC_LE(out_buf)); 1001 } else { 1002 rc = -EIO; 1003 cERROR(1,("Bad MID state?")); 1004 } 1005 } 1006 DeleteMidQEntry(midQ); 1007 if (rstart && rc == -EACCES) 1008 return -ERESTARTSYS; 1009 return rc; 1010} 1011