linux/fs/cifs/transport.c
<<
>>
Prefs
   1/*
   2 *   fs/cifs/transport.c
   3 *
   4 *   Copyright (C) International Business Machines  Corp., 2002,2008
   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/gfp.h>
  26#include <linux/wait.h>
  27#include <linux/net.h>
  28#include <linux/delay.h>
  29#include <linux/freezer.h>
  30#include <linux/tcp.h>
  31#include <linux/highmem.h>
  32#include <asm/uaccess.h>
  33#include <asm/processor.h>
  34#include <linux/mempool.h>
  35#include "cifspdu.h"
  36#include "cifsglob.h"
  37#include "cifsproto.h"
  38#include "cifs_debug.h"
  39
  40void
  41cifs_wake_up_task(struct mid_q_entry *mid)
  42{
  43        wake_up_process(mid->callback_data);
  44}
  45
  46struct mid_q_entry *
  47AllocMidQEntry(const struct smb_hdr *smb_buffer, struct TCP_Server_Info *server)
  48{
  49        struct mid_q_entry *temp;
  50
  51        if (server == NULL) {
  52                cifs_dbg(VFS, "Null TCP session in AllocMidQEntry\n");
  53                return NULL;
  54        }
  55
  56        temp = mempool_alloc(cifs_mid_poolp, GFP_NOFS);
  57        if (temp == NULL)
  58                return temp;
  59        else {
  60                memset(temp, 0, sizeof(struct mid_q_entry));
  61                temp->mid = smb_buffer->Mid;    /* always LE */
  62                temp->pid = current->pid;
  63                temp->command = cpu_to_le16(smb_buffer->Command);
  64                cifs_dbg(FYI, "For smb_command %d\n", smb_buffer->Command);
  65        /*      do_gettimeofday(&temp->when_sent);*/ /* easier to use jiffies */
  66                /* when mid allocated can be before when sent */
  67                temp->when_alloc = jiffies;
  68                temp->server = server;
  69
  70                /*
  71                 * The default is for the mid to be synchronous, so the
  72                 * default callback just wakes up the current task.
  73                 */
  74                temp->callback = cifs_wake_up_task;
  75                temp->callback_data = current;
  76        }
  77
  78        atomic_inc(&midCount);
  79        temp->mid_state = MID_REQUEST_ALLOCATED;
  80        return temp;
  81}
  82
  83void
  84DeleteMidQEntry(struct mid_q_entry *midEntry)
  85{
  86#ifdef CONFIG_CIFS_STATS2
  87        __le16 command = midEntry->server->vals->lock_cmd;
  88        unsigned long now;
  89#endif
  90        midEntry->mid_state = MID_FREE;
  91        atomic_dec(&midCount);
  92        if (midEntry->large_buf)
  93                cifs_buf_release(midEntry->resp_buf);
  94        else
  95                cifs_small_buf_release(midEntry->resp_buf);
  96#ifdef CONFIG_CIFS_STATS2
  97        now = jiffies;
  98        /* commands taking longer than one second are indications that
  99           something is wrong, unless it is quite a slow link or server */
 100        if ((now - midEntry->when_alloc) > HZ) {
 101                if ((cifsFYI & CIFS_TIMER) && (midEntry->command != command)) {
 102                        printk(KERN_DEBUG " CIFS slow rsp: cmd %d mid %llu",
 103                               midEntry->command, midEntry->mid);
 104                        printk(" A: 0x%lx S: 0x%lx R: 0x%lx\n",
 105                               now - midEntry->when_alloc,
 106                               now - midEntry->when_sent,
 107                               now - midEntry->when_received);
 108                }
 109        }
 110#endif
 111        mempool_free(midEntry, cifs_mid_poolp);
 112}
 113
 114void
 115cifs_delete_mid(struct mid_q_entry *mid)
 116{
 117        spin_lock(&GlobalMid_Lock);
 118        list_del(&mid->qhead);
 119        spin_unlock(&GlobalMid_Lock);
 120
 121        DeleteMidQEntry(mid);
 122}
 123
 124/*
 125 * smb_send_kvec - send an array of kvecs to the server
 126 * @server:     Server to send the data to
 127 * @iov:        Pointer to array of kvecs
 128 * @n_vec:      length of kvec array
 129 * @sent:       amount of data sent on socket is stored here
 130 *
 131 * Our basic "send data to server" function. Should be called with srv_mutex
 132 * held. The caller is responsible for handling the results.
 133 */
 134static int
 135smb_send_kvec(struct TCP_Server_Info *server, struct kvec *iov, size_t n_vec,
 136                size_t *sent)
 137{
 138        int rc = 0;
 139        int i = 0;
 140        struct msghdr smb_msg;
 141        unsigned int remaining;
 142        size_t first_vec = 0;
 143        struct socket *ssocket = server->ssocket;
 144
 145        *sent = 0;
 146
 147        smb_msg.msg_name = (struct sockaddr *) &server->dstaddr;
 148        smb_msg.msg_namelen = sizeof(struct sockaddr);
 149        smb_msg.msg_control = NULL;
 150        smb_msg.msg_controllen = 0;
 151        if (server->noblocksnd)
 152                smb_msg.msg_flags = MSG_DONTWAIT + MSG_NOSIGNAL;
 153        else
 154                smb_msg.msg_flags = MSG_NOSIGNAL;
 155
 156        remaining = 0;
 157        for (i = 0; i < n_vec; i++)
 158                remaining += iov[i].iov_len;
 159
 160        i = 0;
 161        while (remaining) {
 162                /*
 163                 * If blocking send, we try 3 times, since each can block
 164                 * for 5 seconds. For nonblocking  we have to try more
 165                 * but wait increasing amounts of time allowing time for
 166                 * socket to clear.  The overall time we wait in either
 167                 * case to send on the socket is about 15 seconds.
 168                 * Similarly we wait for 15 seconds for a response from
 169                 * the server in SendReceive[2] for the server to send
 170                 * a response back for most types of requests (except
 171                 * SMB Write past end of file which can be slow, and
 172                 * blocking lock operations). NFS waits slightly longer
 173                 * than CIFS, but this can make it take longer for
 174                 * nonresponsive servers to be detected and 15 seconds
 175                 * is more than enough time for modern networks to
 176                 * send a packet.  In most cases if we fail to send
 177                 * after the retries we will kill the socket and
 178                 * reconnect which may clear the network problem.
 179                 */
 180                rc = kernel_sendmsg(ssocket, &smb_msg, &iov[first_vec],
 181                                    n_vec - first_vec, remaining);
 182                if (rc == -EAGAIN) {
 183                        i++;
 184                        if (i >= 14 || (!server->noblocksnd && (i > 2))) {
 185                                cifs_dbg(VFS, "sends on sock %p stuck for 15 seconds\n",
 186                                         ssocket);
 187                                rc = -EAGAIN;
 188                                break;
 189                        }
 190                        msleep(1 << i);
 191                        continue;
 192                }
 193
 194                if (rc < 0)
 195                        break;
 196
 197                /* send was at least partially successful */
 198                *sent += rc;
 199
 200                if (rc == remaining) {
 201                        remaining = 0;
 202                        break;
 203                }
 204
 205                if (rc > remaining) {
 206                        cifs_dbg(VFS, "sent %d requested %d\n", rc, remaining);
 207                        break;
 208                }
 209
 210                if (rc == 0) {
 211                        /* should never happen, letting socket clear before
 212                           retrying is our only obvious option here */
 213                        cifs_dbg(VFS, "tcp sent no data\n");
 214                        msleep(500);
 215                        continue;
 216                }
 217
 218                remaining -= rc;
 219
 220                /* the line below resets i */
 221                for (i = first_vec; i < n_vec; i++) {
 222                        if (iov[i].iov_len) {
 223                                if (rc > iov[i].iov_len) {
 224                                        rc -= iov[i].iov_len;
 225                                        iov[i].iov_len = 0;
 226                                } else {
 227                                        iov[i].iov_base += rc;
 228                                        iov[i].iov_len -= rc;
 229                                        first_vec = i;
 230                                        break;
 231                                }
 232                        }
 233                }
 234
 235                i = 0; /* in case we get ENOSPC on the next send */
 236                rc = 0;
 237        }
 238        return rc;
 239}
 240
 241/**
 242 * rqst_page_to_kvec - Turn a slot in the smb_rqst page array into a kvec
 243 * @rqst: pointer to smb_rqst
 244 * @idx: index into the array of the page
 245 * @iov: pointer to struct kvec that will hold the result
 246 *
 247 * Helper function to convert a slot in the rqst->rq_pages array into a kvec.
 248 * The page will be kmapped and the address placed into iov_base. The length
 249 * will then be adjusted according to the ptailoff.
 250 */
 251void
 252cifs_rqst_page_to_kvec(struct smb_rqst *rqst, unsigned int idx,
 253                        struct kvec *iov)
 254{
 255        /*
 256         * FIXME: We could avoid this kmap altogether if we used
 257         * kernel_sendpage instead of kernel_sendmsg. That will only
 258         * work if signing is disabled though as sendpage inlines the
 259         * page directly into the fraglist. If userspace modifies the
 260         * page after we calculate the signature, then the server will
 261         * reject it and may break the connection. kernel_sendmsg does
 262         * an extra copy of the data and avoids that issue.
 263         */
 264        iov->iov_base = kmap(rqst->rq_pages[idx]);
 265
 266        /* if last page, don't send beyond this offset into page */
 267        if (idx == (rqst->rq_npages - 1))
 268                iov->iov_len = rqst->rq_tailsz;
 269        else
 270                iov->iov_len = rqst->rq_pagesz;
 271}
 272
 273static int
 274smb_send_rqst(struct TCP_Server_Info *server, struct smb_rqst *rqst)
 275{
 276        int rc;
 277        struct kvec *iov = rqst->rq_iov;
 278        int n_vec = rqst->rq_nvec;
 279        unsigned int smb_buf_length = get_rfc1002_length(iov[0].iov_base);
 280        unsigned int i;
 281        size_t total_len = 0, sent;
 282        struct socket *ssocket = server->ssocket;
 283        int val = 1;
 284
 285        if (ssocket == NULL)
 286                return -ENOTSOCK;
 287
 288        cifs_dbg(FYI, "Sending smb: smb_len=%u\n", smb_buf_length);
 289        dump_smb(iov[0].iov_base, iov[0].iov_len);
 290
 291        /* cork the socket */
 292        kernel_setsockopt(ssocket, SOL_TCP, TCP_CORK,
 293                                (char *)&val, sizeof(val));
 294
 295        rc = smb_send_kvec(server, iov, n_vec, &sent);
 296        if (rc < 0)
 297                goto uncork;
 298
 299        total_len += sent;
 300
 301        /* now walk the page array and send each page in it */
 302        for (i = 0; i < rqst->rq_npages; i++) {
 303                struct kvec p_iov;
 304
 305                cifs_rqst_page_to_kvec(rqst, i, &p_iov);
 306                rc = smb_send_kvec(server, &p_iov, 1, &sent);
 307                kunmap(rqst->rq_pages[i]);
 308                if (rc < 0)
 309                        break;
 310
 311                total_len += sent;
 312        }
 313
 314uncork:
 315        /* uncork it */
 316        val = 0;
 317        kernel_setsockopt(ssocket, SOL_TCP, TCP_CORK,
 318                                (char *)&val, sizeof(val));
 319
 320        if ((total_len > 0) && (total_len != smb_buf_length + 4)) {
 321                cifs_dbg(FYI, "partial send (wanted=%u sent=%zu): terminating session\n",
 322                         smb_buf_length + 4, total_len);
 323                /*
 324                 * If we have only sent part of an SMB then the next SMB could
 325                 * be taken as the remainder of this one. We need to kill the
 326                 * socket so the server throws away the partial SMB
 327                 */
 328                server->tcpStatus = CifsNeedReconnect;
 329        }
 330
 331        if (rc < 0 && rc != -EINTR)
 332                cifs_dbg(VFS, "Error %d sending data on socket to server\n",
 333                         rc);
 334        else
 335                rc = 0;
 336
 337        return rc;
 338}
 339
 340static int
 341smb_sendv(struct TCP_Server_Info *server, struct kvec *iov, int n_vec)
 342{
 343        struct smb_rqst rqst = { .rq_iov = iov,
 344                                 .rq_nvec = n_vec };
 345
 346        return smb_send_rqst(server, &rqst);
 347}
 348
 349int
 350smb_send(struct TCP_Server_Info *server, struct smb_hdr *smb_buffer,
 351         unsigned int smb_buf_length)
 352{
 353        struct kvec iov;
 354
 355        iov.iov_base = smb_buffer;
 356        iov.iov_len = smb_buf_length + 4;
 357
 358        return smb_sendv(server, &iov, 1);
 359}
 360
 361static int
 362wait_for_free_credits(struct TCP_Server_Info *server, const int timeout,
 363                      int *credits)
 364{
 365        int rc;
 366
 367        spin_lock(&server->req_lock);
 368        if (timeout == CIFS_ASYNC_OP) {
 369                /* oplock breaks must not be held up */
 370                server->in_flight++;
 371                *credits -= 1;
 372                spin_unlock(&server->req_lock);
 373                return 0;
 374        }
 375
 376        while (1) {
 377                if (*credits <= 0) {
 378                        spin_unlock(&server->req_lock);
 379                        cifs_num_waiters_inc(server);
 380                        rc = wait_event_killable(server->request_q,
 381                                                 has_credits(server, credits));
 382                        cifs_num_waiters_dec(server);
 383                        if (rc)
 384                                return rc;
 385                        spin_lock(&server->req_lock);
 386                } else {
 387                        if (server->tcpStatus == CifsExiting) {
 388                                spin_unlock(&server->req_lock);
 389                                return -ENOENT;
 390                        }
 391
 392                        /*
 393                         * Can not count locking commands against total
 394                         * as they are allowed to block on server.
 395                         */
 396
 397                        /* update # of requests on the wire to server */
 398                        if (timeout != CIFS_BLOCKING_OP) {
 399                                *credits -= 1;
 400                                server->in_flight++;
 401                        }
 402                        spin_unlock(&server->req_lock);
 403                        break;
 404                }
 405        }
 406        return 0;
 407}
 408
 409static int
 410wait_for_free_request(struct TCP_Server_Info *server, const int timeout,
 411                      const int optype)
 412{
 413        return wait_for_free_credits(server, timeout,
 414                                server->ops->get_credits_field(server, optype));
 415}
 416
 417static int allocate_mid(struct cifs_ses *ses, struct smb_hdr *in_buf,
 418                        struct mid_q_entry **ppmidQ)
 419{
 420        if (ses->server->tcpStatus == CifsExiting) {
 421                return -ENOENT;
 422        }
 423
 424        if (ses->server->tcpStatus == CifsNeedReconnect) {
 425                cifs_dbg(FYI, "tcp session dead - return to caller to retry\n");
 426                return -EAGAIN;
 427        }
 428
 429        if (ses->status != CifsGood) {
 430                /* check if SMB session is bad because we are setting it up */
 431                if ((in_buf->Command != SMB_COM_SESSION_SETUP_ANDX) &&
 432                        (in_buf->Command != SMB_COM_NEGOTIATE))
 433                        return -EAGAIN;
 434                /* else ok - we are setting up session */
 435        }
 436        *ppmidQ = AllocMidQEntry(in_buf, ses->server);
 437        if (*ppmidQ == NULL)
 438                return -ENOMEM;
 439        spin_lock(&GlobalMid_Lock);
 440        list_add_tail(&(*ppmidQ)->qhead, &ses->server->pending_mid_q);
 441        spin_unlock(&GlobalMid_Lock);
 442        return 0;
 443}
 444
 445static int
 446wait_for_response(struct TCP_Server_Info *server, struct mid_q_entry *midQ)
 447{
 448        int error;
 449
 450        error = wait_event_freezekillable_unsafe(server->response_q,
 451                                    midQ->mid_state != MID_REQUEST_SUBMITTED);
 452        if (error < 0)
 453                return -ERESTARTSYS;
 454
 455        return 0;
 456}
 457
 458struct mid_q_entry *
 459cifs_setup_async_request(struct TCP_Server_Info *server, struct smb_rqst *rqst)
 460{
 461        int rc;
 462        struct smb_hdr *hdr = (struct smb_hdr *)rqst->rq_iov[0].iov_base;
 463        struct mid_q_entry *mid;
 464
 465        /* enable signing if server requires it */
 466        if (server->sign)
 467                hdr->Flags2 |= SMBFLG2_SECURITY_SIGNATURE;
 468
 469        mid = AllocMidQEntry(hdr, server);
 470        if (mid == NULL)
 471                return ERR_PTR(-ENOMEM);
 472
 473        rc = cifs_sign_rqst(rqst, server, &mid->sequence_number);
 474        if (rc) {
 475                DeleteMidQEntry(mid);
 476                return ERR_PTR(rc);
 477        }
 478
 479        return mid;
 480}
 481
 482/*
 483 * Send a SMB request and set the callback function in the mid to handle
 484 * the result. Caller is responsible for dealing with timeouts.
 485 */
 486int
 487cifs_call_async(struct TCP_Server_Info *server, struct smb_rqst *rqst,
 488                mid_receive_t *receive, mid_callback_t *callback,
 489                void *cbdata, const int flags)
 490{
 491        int rc, timeout, optype;
 492        struct mid_q_entry *mid;
 493
 494        timeout = flags & CIFS_TIMEOUT_MASK;
 495        optype = flags & CIFS_OP_MASK;
 496
 497        rc = wait_for_free_request(server, timeout, optype);
 498        if (rc)
 499                return rc;
 500
 501        mutex_lock(&server->srv_mutex);
 502        mid = server->ops->setup_async_request(server, rqst);
 503        if (IS_ERR(mid)) {
 504                mutex_unlock(&server->srv_mutex);
 505                add_credits(server, 1, optype);
 506                wake_up(&server->request_q);
 507                return PTR_ERR(mid);
 508        }
 509
 510        mid->receive = receive;
 511        mid->callback = callback;
 512        mid->callback_data = cbdata;
 513        mid->mid_state = MID_REQUEST_SUBMITTED;
 514
 515        /* put it on the pending_mid_q */
 516        spin_lock(&GlobalMid_Lock);
 517        list_add_tail(&mid->qhead, &server->pending_mid_q);
 518        spin_unlock(&GlobalMid_Lock);
 519
 520
 521        cifs_in_send_inc(server);
 522        rc = smb_send_rqst(server, rqst);
 523        cifs_in_send_dec(server);
 524        cifs_save_when_sent(mid);
 525
 526        if (rc < 0)
 527                server->sequence_number -= 2;
 528        mutex_unlock(&server->srv_mutex);
 529
 530        if (rc == 0)
 531                return 0;
 532
 533        cifs_delete_mid(mid);
 534        add_credits(server, 1, optype);
 535        wake_up(&server->request_q);
 536        return rc;
 537}
 538
 539/*
 540 *
 541 * Send an SMB Request.  No response info (other than return code)
 542 * needs to be parsed.
 543 *
 544 * flags indicate the type of request buffer and how long to wait
 545 * and whether to log NT STATUS code (error) before mapping it to POSIX error
 546 *
 547 */
 548int
 549SendReceiveNoRsp(const unsigned int xid, struct cifs_ses *ses,
 550                 char *in_buf, int flags)
 551{
 552        int rc;
 553        struct kvec iov[1];
 554        int resp_buf_type;
 555
 556        iov[0].iov_base = in_buf;
 557        iov[0].iov_len = get_rfc1002_length(in_buf) + 4;
 558        flags |= CIFS_NO_RESP;
 559        rc = SendReceive2(xid, ses, iov, 1, &resp_buf_type, flags);
 560        cifs_dbg(NOISY, "SendRcvNoRsp flags %d rc %d\n", flags, rc);
 561
 562        return rc;
 563}
 564
 565static int
 566cifs_sync_mid_result(struct mid_q_entry *mid, struct TCP_Server_Info *server)
 567{
 568        int rc = 0;
 569
 570        cifs_dbg(FYI, "%s: cmd=%d mid=%llu state=%d\n",
 571                 __func__, le16_to_cpu(mid->command), mid->mid, mid->mid_state);
 572
 573        spin_lock(&GlobalMid_Lock);
 574        switch (mid->mid_state) {
 575        case MID_RESPONSE_RECEIVED:
 576                spin_unlock(&GlobalMid_Lock);
 577                return rc;
 578        case MID_RETRY_NEEDED:
 579                rc = -EAGAIN;
 580                break;
 581        case MID_RESPONSE_MALFORMED:
 582                rc = -EIO;
 583                break;
 584        case MID_SHUTDOWN:
 585                rc = -EHOSTDOWN;
 586                break;
 587        default:
 588                list_del_init(&mid->qhead);
 589                cifs_dbg(VFS, "%s: invalid mid state mid=%llu state=%d\n",
 590                         __func__, mid->mid, mid->mid_state);
 591                rc = -EIO;
 592        }
 593        spin_unlock(&GlobalMid_Lock);
 594
 595        DeleteMidQEntry(mid);
 596        return rc;
 597}
 598
 599static inline int
 600send_cancel(struct TCP_Server_Info *server, void *buf, struct mid_q_entry *mid)
 601{
 602        return server->ops->send_cancel ?
 603                                server->ops->send_cancel(server, buf, mid) : 0;
 604}
 605
 606int
 607cifs_check_receive(struct mid_q_entry *mid, struct TCP_Server_Info *server,
 608                   bool log_error)
 609{
 610        unsigned int len = get_rfc1002_length(mid->resp_buf) + 4;
 611
 612        dump_smb(mid->resp_buf, min_t(u32, 92, len));
 613
 614        /* convert the length into a more usable form */
 615        if (server->sign) {
 616                struct kvec iov;
 617                int rc = 0;
 618                struct smb_rqst rqst = { .rq_iov = &iov,
 619                                         .rq_nvec = 1 };
 620
 621                iov.iov_base = mid->resp_buf;
 622                iov.iov_len = len;
 623                /* FIXME: add code to kill session */
 624                rc = cifs_verify_signature(&rqst, server,
 625                                           mid->sequence_number);
 626                if (rc)
 627                        cifs_dbg(VFS, "SMB signature verification returned error = %d\n",
 628                                 rc);
 629        }
 630
 631        /* BB special case reconnect tid and uid here? */
 632        return map_smb_to_linux_error(mid->resp_buf, log_error);
 633}
 634
 635struct mid_q_entry *
 636cifs_setup_request(struct cifs_ses *ses, struct smb_rqst *rqst)
 637{
 638        int rc;
 639        struct smb_hdr *hdr = (struct smb_hdr *)rqst->rq_iov[0].iov_base;
 640        struct mid_q_entry *mid;
 641
 642        rc = allocate_mid(ses, hdr, &mid);
 643        if (rc)
 644                return ERR_PTR(rc);
 645        rc = cifs_sign_rqst(rqst, ses->server, &mid->sequence_number);
 646        if (rc) {
 647                cifs_delete_mid(mid);
 648                return ERR_PTR(rc);
 649        }
 650        return mid;
 651}
 652
 653int
 654SendReceive2(const unsigned int xid, struct cifs_ses *ses,
 655             struct kvec *iov, int n_vec, int *resp_buf_type /* ret */,
 656             const int flags)
 657{
 658        int rc = 0;
 659        int timeout, optype;
 660        struct mid_q_entry *midQ;
 661        char *buf = iov[0].iov_base;
 662        unsigned int credits = 1;
 663        struct smb_rqst rqst = { .rq_iov = iov,
 664                                 .rq_nvec = n_vec };
 665
 666        timeout = flags & CIFS_TIMEOUT_MASK;
 667        optype = flags & CIFS_OP_MASK;
 668
 669        *resp_buf_type = CIFS_NO_BUFFER;  /* no response buf yet */
 670
 671        if ((ses == NULL) || (ses->server == NULL)) {
 672                cifs_small_buf_release(buf);
 673                cifs_dbg(VFS, "Null session\n");
 674                return -EIO;
 675        }
 676
 677        if (ses->server->tcpStatus == CifsExiting) {
 678                cifs_small_buf_release(buf);
 679                return -ENOENT;
 680        }
 681
 682        /*
 683         * Ensure that we do not send more than 50 overlapping requests
 684         * to the same server. We may make this configurable later or
 685         * use ses->maxReq.
 686         */
 687
 688        rc = wait_for_free_request(ses->server, timeout, optype);
 689        if (rc) {
 690                cifs_small_buf_release(buf);
 691                return rc;
 692        }
 693
 694        /*
 695         * Make sure that we sign in the same order that we send on this socket
 696         * and avoid races inside tcp sendmsg code that could cause corruption
 697         * of smb data.
 698         */
 699
 700        mutex_lock(&ses->server->srv_mutex);
 701
 702        midQ = ses->server->ops->setup_request(ses, &rqst);
 703        if (IS_ERR(midQ)) {
 704                mutex_unlock(&ses->server->srv_mutex);
 705                cifs_small_buf_release(buf);
 706                /* Update # of requests on wire to server */
 707                add_credits(ses->server, 1, optype);
 708                return PTR_ERR(midQ);
 709        }
 710
 711        midQ->mid_state = MID_REQUEST_SUBMITTED;
 712        cifs_in_send_inc(ses->server);
 713        rc = smb_sendv(ses->server, iov, n_vec);
 714        cifs_in_send_dec(ses->server);
 715        cifs_save_when_sent(midQ);
 716
 717        if (rc < 0)
 718                ses->server->sequence_number -= 2;
 719        mutex_unlock(&ses->server->srv_mutex);
 720
 721        if (rc < 0) {
 722                cifs_small_buf_release(buf);
 723                goto out;
 724        }
 725
 726        if (timeout == CIFS_ASYNC_OP) {
 727                cifs_small_buf_release(buf);
 728                goto out;
 729        }
 730
 731        rc = wait_for_response(ses->server, midQ);
 732        if (rc != 0) {
 733                send_cancel(ses->server, buf, midQ);
 734                spin_lock(&GlobalMid_Lock);
 735                if (midQ->mid_state == MID_REQUEST_SUBMITTED) {
 736                        midQ->callback = DeleteMidQEntry;
 737                        spin_unlock(&GlobalMid_Lock);
 738                        cifs_small_buf_release(buf);
 739                        add_credits(ses->server, 1, optype);
 740                        return rc;
 741                }
 742                spin_unlock(&GlobalMid_Lock);
 743        }
 744
 745        cifs_small_buf_release(buf);
 746
 747        rc = cifs_sync_mid_result(midQ, ses->server);
 748        if (rc != 0) {
 749                add_credits(ses->server, 1, optype);
 750                return rc;
 751        }
 752
 753        if (!midQ->resp_buf || midQ->mid_state != MID_RESPONSE_RECEIVED) {
 754                rc = -EIO;
 755                cifs_dbg(FYI, "Bad MID state?\n");
 756                goto out;
 757        }
 758
 759        buf = (char *)midQ->resp_buf;
 760        iov[0].iov_base = buf;
 761        iov[0].iov_len = get_rfc1002_length(buf) + 4;
 762        if (midQ->large_buf)
 763                *resp_buf_type = CIFS_LARGE_BUFFER;
 764        else
 765                *resp_buf_type = CIFS_SMALL_BUFFER;
 766
 767        credits = ses->server->ops->get_credits(midQ);
 768
 769        rc = ses->server->ops->check_receive(midQ, ses->server,
 770                                             flags & CIFS_LOG_ERROR);
 771
 772        /* mark it so buf will not be freed by cifs_delete_mid */
 773        if ((flags & CIFS_NO_RESP) == 0)
 774                midQ->resp_buf = NULL;
 775out:
 776        cifs_delete_mid(midQ);
 777        add_credits(ses->server, credits, optype);
 778
 779        return rc;
 780}
 781
 782int
 783SendReceive(const unsigned int xid, struct cifs_ses *ses,
 784            struct smb_hdr *in_buf, struct smb_hdr *out_buf,
 785            int *pbytes_returned, const int timeout)
 786{
 787        int rc = 0;
 788        struct mid_q_entry *midQ;
 789
 790        if (ses == NULL) {
 791                cifs_dbg(VFS, "Null smb session\n");
 792                return -EIO;
 793        }
 794        if (ses->server == NULL) {
 795                cifs_dbg(VFS, "Null tcp session\n");
 796                return -EIO;
 797        }
 798
 799        if (ses->server->tcpStatus == CifsExiting)
 800                return -ENOENT;
 801
 802        /* Ensure that we do not send more than 50 overlapping requests
 803           to the same server. We may make this configurable later or
 804           use ses->maxReq */
 805
 806        if (be32_to_cpu(in_buf->smb_buf_length) > CIFSMaxBufSize +
 807                        MAX_CIFS_HDR_SIZE - 4) {
 808                cifs_dbg(VFS, "Illegal length, greater than maximum frame, %d\n",
 809                         be32_to_cpu(in_buf->smb_buf_length));
 810                return -EIO;
 811        }
 812
 813        rc = wait_for_free_request(ses->server, timeout, 0);
 814        if (rc)
 815                return rc;
 816
 817        /* make sure that we sign in the same order that we send on this socket
 818           and avoid races inside tcp sendmsg code that could cause corruption
 819           of smb data */
 820
 821        mutex_lock(&ses->server->srv_mutex);
 822
 823        rc = allocate_mid(ses, in_buf, &midQ);
 824        if (rc) {
 825                mutex_unlock(&ses->server->srv_mutex);
 826                /* Update # of requests on wire to server */
 827                add_credits(ses->server, 1, 0);
 828                return rc;
 829        }
 830
 831        rc = cifs_sign_smb(in_buf, ses->server, &midQ->sequence_number);
 832        if (rc) {
 833                mutex_unlock(&ses->server->srv_mutex);
 834                goto out;
 835        }
 836
 837        midQ->mid_state = MID_REQUEST_SUBMITTED;
 838
 839        cifs_in_send_inc(ses->server);
 840        rc = smb_send(ses->server, in_buf, be32_to_cpu(in_buf->smb_buf_length));
 841        cifs_in_send_dec(ses->server);
 842        cifs_save_when_sent(midQ);
 843
 844        if (rc < 0)
 845                ses->server->sequence_number -= 2;
 846
 847        mutex_unlock(&ses->server->srv_mutex);
 848
 849        if (rc < 0)
 850                goto out;
 851
 852        if (timeout == CIFS_ASYNC_OP)
 853                goto out;
 854
 855        rc = wait_for_response(ses->server, midQ);
 856        if (rc != 0) {
 857                send_cancel(ses->server, in_buf, midQ);
 858                spin_lock(&GlobalMid_Lock);
 859                if (midQ->mid_state == MID_REQUEST_SUBMITTED) {
 860                        /* no longer considered to be "in-flight" */
 861                        midQ->callback = DeleteMidQEntry;
 862                        spin_unlock(&GlobalMid_Lock);
 863                        add_credits(ses->server, 1, 0);
 864                        return rc;
 865                }
 866                spin_unlock(&GlobalMid_Lock);
 867        }
 868
 869        rc = cifs_sync_mid_result(midQ, ses->server);
 870        if (rc != 0) {
 871                add_credits(ses->server, 1, 0);
 872                return rc;
 873        }
 874
 875        if (!midQ->resp_buf || !out_buf ||
 876            midQ->mid_state != MID_RESPONSE_RECEIVED) {
 877                rc = -EIO;
 878                cifs_dbg(VFS, "Bad MID state?\n");
 879                goto out;
 880        }
 881
 882        *pbytes_returned = get_rfc1002_length(midQ->resp_buf);
 883        memcpy(out_buf, midQ->resp_buf, *pbytes_returned + 4);
 884        rc = cifs_check_receive(midQ, ses->server, 0);
 885out:
 886        cifs_delete_mid(midQ);
 887        add_credits(ses->server, 1, 0);
 888
 889        return rc;
 890}
 891
 892/* We send a LOCKINGX_CANCEL_LOCK to cause the Windows
 893   blocking lock to return. */
 894
 895static int
 896send_lock_cancel(const unsigned int xid, struct cifs_tcon *tcon,
 897                        struct smb_hdr *in_buf,
 898                        struct smb_hdr *out_buf)
 899{
 900        int bytes_returned;
 901        struct cifs_ses *ses = tcon->ses;
 902        LOCK_REQ *pSMB = (LOCK_REQ *)in_buf;
 903
 904        /* We just modify the current in_buf to change
 905           the type of lock from LOCKING_ANDX_SHARED_LOCK
 906           or LOCKING_ANDX_EXCLUSIVE_LOCK to
 907           LOCKING_ANDX_CANCEL_LOCK. */
 908
 909        pSMB->LockType = LOCKING_ANDX_CANCEL_LOCK|LOCKING_ANDX_LARGE_FILES;
 910        pSMB->Timeout = 0;
 911        pSMB->hdr.Mid = get_next_mid(ses->server);
 912
 913        return SendReceive(xid, ses, in_buf, out_buf,
 914                        &bytes_returned, 0);
 915}
 916
 917int
 918SendReceiveBlockingLock(const unsigned int xid, struct cifs_tcon *tcon,
 919            struct smb_hdr *in_buf, struct smb_hdr *out_buf,
 920            int *pbytes_returned)
 921{
 922        int rc = 0;
 923        int rstart = 0;
 924        struct mid_q_entry *midQ;
 925        struct cifs_ses *ses;
 926
 927        if (tcon == NULL || tcon->ses == NULL) {
 928                cifs_dbg(VFS, "Null smb session\n");
 929                return -EIO;
 930        }
 931        ses = tcon->ses;
 932
 933        if (ses->server == NULL) {
 934                cifs_dbg(VFS, "Null tcp session\n");
 935                return -EIO;
 936        }
 937
 938        if (ses->server->tcpStatus == CifsExiting)
 939                return -ENOENT;
 940
 941        /* Ensure that we do not send more than 50 overlapping requests
 942           to the same server. We may make this configurable later or
 943           use ses->maxReq */
 944
 945        if (be32_to_cpu(in_buf->smb_buf_length) > CIFSMaxBufSize +
 946                        MAX_CIFS_HDR_SIZE - 4) {
 947                cifs_dbg(VFS, "Illegal length, greater than maximum frame, %d\n",
 948                         be32_to_cpu(in_buf->smb_buf_length));
 949                return -EIO;
 950        }
 951
 952        rc = wait_for_free_request(ses->server, CIFS_BLOCKING_OP, 0);
 953        if (rc)
 954                return rc;
 955
 956        /* make sure that we sign in the same order that we send on this socket
 957           and avoid races inside tcp sendmsg code that could cause corruption
 958           of smb data */
 959
 960        mutex_lock(&ses->server->srv_mutex);
 961
 962        rc = allocate_mid(ses, in_buf, &midQ);
 963        if (rc) {
 964                mutex_unlock(&ses->server->srv_mutex);
 965                return rc;
 966        }
 967
 968        rc = cifs_sign_smb(in_buf, ses->server, &midQ->sequence_number);
 969        if (rc) {
 970                cifs_delete_mid(midQ);
 971                mutex_unlock(&ses->server->srv_mutex);
 972                return rc;
 973        }
 974
 975        midQ->mid_state = MID_REQUEST_SUBMITTED;
 976        cifs_in_send_inc(ses->server);
 977        rc = smb_send(ses->server, in_buf, be32_to_cpu(in_buf->smb_buf_length));
 978        cifs_in_send_dec(ses->server);
 979        cifs_save_when_sent(midQ);
 980
 981        if (rc < 0)
 982                ses->server->sequence_number -= 2;
 983
 984        mutex_unlock(&ses->server->srv_mutex);
 985
 986        if (rc < 0) {
 987                cifs_delete_mid(midQ);
 988                return rc;
 989        }
 990
 991        /* Wait for a reply - allow signals to interrupt. */
 992        rc = wait_event_interruptible(ses->server->response_q,
 993                (!(midQ->mid_state == MID_REQUEST_SUBMITTED)) ||
 994                ((ses->server->tcpStatus != CifsGood) &&
 995                 (ses->server->tcpStatus != CifsNew)));
 996
 997        /* Were we interrupted by a signal ? */
 998        if ((rc == -ERESTARTSYS) &&
 999                (midQ->mid_state == MID_REQUEST_SUBMITTED) &&
1000                ((ses->server->tcpStatus == CifsGood) ||
1001                 (ses->server->tcpStatus == CifsNew))) {
1002
1003                if (in_buf->Command == SMB_COM_TRANSACTION2) {
1004                        /* POSIX lock. We send a NT_CANCEL SMB to cause the
1005                           blocking lock to return. */
1006                        rc = send_cancel(ses->server, in_buf, midQ);
1007                        if (rc) {
1008                                cifs_delete_mid(midQ);
1009                                return rc;
1010                        }
1011                } else {
1012                        /* Windows lock. We send a LOCKINGX_CANCEL_LOCK
1013                           to cause the blocking lock to return. */
1014
1015                        rc = send_lock_cancel(xid, tcon, in_buf, out_buf);
1016
1017                        /* If we get -ENOLCK back the lock may have
1018                           already been removed. Don't exit in this case. */
1019                        if (rc && rc != -ENOLCK) {
1020                                cifs_delete_mid(midQ);
1021                                return rc;
1022                        }
1023                }
1024
1025                rc = wait_for_response(ses->server, midQ);
1026                if (rc) {
1027                        send_cancel(ses->server, in_buf, midQ);
1028                        spin_lock(&GlobalMid_Lock);
1029                        if (midQ->mid_state == MID_REQUEST_SUBMITTED) {
1030                                /* no longer considered to be "in-flight" */
1031                                midQ->callback = DeleteMidQEntry;
1032                                spin_unlock(&GlobalMid_Lock);
1033                                return rc;
1034                        }
1035                        spin_unlock(&GlobalMid_Lock);
1036                }
1037
1038                /* We got the response - restart system call. */
1039                rstart = 1;
1040        }
1041
1042        rc = cifs_sync_mid_result(midQ, ses->server);
1043        if (rc != 0)
1044                return rc;
1045
1046        /* rcvd frame is ok */
1047        if (out_buf == NULL || midQ->mid_state != MID_RESPONSE_RECEIVED) {
1048                rc = -EIO;
1049                cifs_dbg(VFS, "Bad MID state?\n");
1050                goto out;
1051        }
1052
1053        *pbytes_returned = get_rfc1002_length(midQ->resp_buf);
1054        memcpy(out_buf, midQ->resp_buf, *pbytes_returned + 4);
1055        rc = cifs_check_receive(midQ, ses->server, 0);
1056out:
1057        cifs_delete_mid(midQ);
1058        if (rstart && rc == -EACCES)
1059                return -ERESTARTSYS;
1060        return rc;
1061}
1062
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.