linux/fs/cifs/smb2pdu.c
<<
>>
Prefs
   1/*
   2 *   fs/cifs/smb2pdu.c
   3 *
   4 *   Copyright (C) International Business Machines  Corp., 2009, 2013
   5 *                 Etersoft, 2012
   6 *   Author(s): Steve French (sfrench@us.ibm.com)
   7 *              Pavel Shilovsky (pshilovsky@samba.org) 2012
   8 *
   9 *   Contains the routines for constructing the SMB2 PDUs themselves
  10 *
  11 *   This library is free software; you can redistribute it and/or modify
  12 *   it under the terms of the GNU Lesser General Public License as published
  13 *   by the Free Software Foundation; either version 2.1 of the License, or
  14 *   (at your option) any later version.
  15 *
  16 *   This library is distributed in the hope that it will be useful,
  17 *   but WITHOUT ANY WARRANTY; without even the implied warranty of
  18 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
  19 *   the GNU Lesser General Public License for more details.
  20 *
  21 *   You should have received a copy of the GNU Lesser General Public License
  22 *   along with this library; if not, write to the Free Software
  23 *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  24 */
  25
  26 /* SMB2 PDU handling routines here - except for leftovers (eg session setup) */
  27 /* Note that there are handle based routines which must be                   */
  28 /* treated slightly differently for reconnection purposes since we never     */
  29 /* want to reuse a stale file handle and only the caller knows the file info */
  30
  31#include <linux/fs.h>
  32#include <linux/kernel.h>
  33#include <linux/vfs.h>
  34#include <linux/task_io_accounting_ops.h>
  35#include <linux/uaccess.h>
  36#include <linux/pagemap.h>
  37#include <linux/xattr.h>
  38#include "smb2pdu.h"
  39#include "cifsglob.h"
  40#include "cifsacl.h"
  41#include "cifsproto.h"
  42#include "smb2proto.h"
  43#include "cifs_unicode.h"
  44#include "cifs_debug.h"
  45#include "ntlmssp.h"
  46#include "smb2status.h"
  47#include "smb2glob.h"
  48#include "cifspdu.h"
  49
  50/*
  51 *  The following table defines the expected "StructureSize" of SMB2 requests
  52 *  in order by SMB2 command.  This is similar to "wct" in SMB/CIFS requests.
  53 *
  54 *  Note that commands are defined in smb2pdu.h in le16 but the array below is
  55 *  indexed by command in host byte order.
  56 */
  57static const int smb2_req_struct_sizes[NUMBER_OF_SMB2_COMMANDS] = {
  58        /* SMB2_NEGOTIATE */ 36,
  59        /* SMB2_SESSION_SETUP */ 25,
  60        /* SMB2_LOGOFF */ 4,
  61        /* SMB2_TREE_CONNECT */ 9,
  62        /* SMB2_TREE_DISCONNECT */ 4,
  63        /* SMB2_CREATE */ 57,
  64        /* SMB2_CLOSE */ 24,
  65        /* SMB2_FLUSH */ 24,
  66        /* SMB2_READ */ 49,
  67        /* SMB2_WRITE */ 49,
  68        /* SMB2_LOCK */ 48,
  69        /* SMB2_IOCTL */ 57,
  70        /* SMB2_CANCEL */ 4,
  71        /* SMB2_ECHO */ 4,
  72        /* SMB2_QUERY_DIRECTORY */ 33,
  73        /* SMB2_CHANGE_NOTIFY */ 32,
  74        /* SMB2_QUERY_INFO */ 41,
  75        /* SMB2_SET_INFO */ 33,
  76        /* SMB2_OPLOCK_BREAK */ 24 /* BB this is 36 for LEASE_BREAK variant */
  77};
  78
  79
  80static void
  81smb2_hdr_assemble(struct smb2_hdr *hdr, __le16 smb2_cmd /* command */ ,
  82                  const struct cifs_tcon *tcon)
  83{
  84        struct smb2_pdu *pdu = (struct smb2_pdu *)hdr;
  85        char *temp = (char *)hdr;
  86        /* lookup word count ie StructureSize from table */
  87        __u16 parmsize = smb2_req_struct_sizes[le16_to_cpu(smb2_cmd)];
  88
  89        /*
  90         * smaller than SMALL_BUFFER_SIZE but bigger than fixed area of
  91         * largest operations (Create)
  92         */
  93        memset(temp, 0, 256);
  94
  95        /* Note this is only network field converted to big endian */
  96        hdr->smb2_buf_length = cpu_to_be32(parmsize + sizeof(struct smb2_hdr)
  97                        - 4 /*  RFC 1001 length field itself not counted */);
  98
  99        hdr->ProtocolId[0] = 0xFE;
 100        hdr->ProtocolId[1] = 'S';
 101        hdr->ProtocolId[2] = 'M';
 102        hdr->ProtocolId[3] = 'B';
 103        hdr->StructureSize = cpu_to_le16(64);
 104        hdr->Command = smb2_cmd;
 105        hdr->CreditRequest = cpu_to_le16(2); /* BB make this dynamic */
 106        hdr->ProcessId = cpu_to_le32((__u16)current->tgid);
 107
 108        if (!tcon)
 109                goto out;
 110
 111        /* BB FIXME when we do write > 64K add +1 for every 64K in req or rsp */
 112        /* GLOBAL_CAP_LARGE_MTU will only be set if dialect > SMB2.02 */
 113        /* See sections 2.2.4 and 3.2.4.1.5 of MS-SMB2 */
 114        if ((tcon->ses) &&
 115            (tcon->ses->server->capabilities & SMB2_GLOBAL_CAP_LARGE_MTU))
 116                hdr->CreditCharge = cpu_to_le16(1);
 117        /* else CreditCharge MBZ */
 118
 119        hdr->TreeId = tcon->tid;
 120        /* Uid is not converted */
 121        if (tcon->ses)
 122                hdr->SessionId = tcon->ses->Suid;
 123
 124        /*
 125         * If we would set SMB2_FLAGS_DFS_OPERATIONS on open we also would have
 126         * to pass the path on the Open SMB prefixed by \\server\share.
 127         * Not sure when we would need to do the augmented path (if ever) and
 128         * setting this flag breaks the SMB2 open operation since it is
 129         * illegal to send an empty path name (without \\server\share prefix)
 130         * when the DFS flag is set in the SMB open header. We could
 131         * consider setting the flag on all operations other than open
 132         * but it is safer to net set it for now.
 133         */
 134/*      if (tcon->share_flags & SHI1005_FLAGS_DFS)
 135                hdr->Flags |= SMB2_FLAGS_DFS_OPERATIONS; */
 136
 137        if (tcon->ses && tcon->ses->server && tcon->ses->server->sign)
 138                hdr->Flags |= SMB2_FLAGS_SIGNED;
 139out:
 140        pdu->StructureSize2 = cpu_to_le16(parmsize);
 141        return;
 142}
 143
 144static int
 145smb2_reconnect(__le16 smb2_command, struct cifs_tcon *tcon)
 146{
 147        int rc = 0;
 148        struct nls_table *nls_codepage;
 149        struct cifs_ses *ses;
 150        struct TCP_Server_Info *server;
 151
 152        /*
 153         * SMB2s NegProt, SessSetup, Logoff do not have tcon yet so
 154         * check for tcp and smb session status done differently
 155         * for those three - in the calling routine.
 156         */
 157        if (tcon == NULL)
 158                return rc;
 159
 160        if (smb2_command == SMB2_TREE_CONNECT)
 161                return rc;
 162
 163        if (tcon->tidStatus == CifsExiting) {
 164                /*
 165                 * only tree disconnect, open, and write,
 166                 * (and ulogoff which does not have tcon)
 167                 * are allowed as we start force umount.
 168                 */
 169                if ((smb2_command != SMB2_WRITE) &&
 170                   (smb2_command != SMB2_CREATE) &&
 171                   (smb2_command != SMB2_TREE_DISCONNECT)) {
 172                        cifs_dbg(FYI, "can not send cmd %d while umounting\n",
 173                                 smb2_command);
 174                        return -ENODEV;
 175                }
 176        }
 177        if ((!tcon->ses) || (tcon->ses->status == CifsExiting) ||
 178            (!tcon->ses->server))
 179                return -EIO;
 180
 181        ses = tcon->ses;
 182        server = ses->server;
 183
 184        /*
 185         * Give demultiplex thread up to 10 seconds to reconnect, should be
 186         * greater than cifs socket timeout which is 7 seconds
 187         */
 188        while (server->tcpStatus == CifsNeedReconnect) {
 189                /*
 190                 * Return to caller for TREE_DISCONNECT and LOGOFF and CLOSE
 191                 * here since they are implicitly done when session drops.
 192                 */
 193                switch (smb2_command) {
 194                /*
 195                 * BB Should we keep oplock break and add flush to exceptions?
 196                 */
 197                case SMB2_TREE_DISCONNECT:
 198                case SMB2_CANCEL:
 199                case SMB2_CLOSE:
 200                case SMB2_OPLOCK_BREAK:
 201                        return -EAGAIN;
 202                }
 203
 204                wait_event_interruptible_timeout(server->response_q,
 205                        (server->tcpStatus != CifsNeedReconnect), 10 * HZ);
 206
 207                /* are we still trying to reconnect? */
 208                if (server->tcpStatus != CifsNeedReconnect)
 209                        break;
 210
 211                /*
 212                 * on "soft" mounts we wait once. Hard mounts keep
 213                 * retrying until process is killed or server comes
 214                 * back on-line
 215                 */
 216                if (!tcon->retry) {
 217                        cifs_dbg(FYI, "gave up waiting on reconnect in smb_init\n");
 218                        return -EHOSTDOWN;
 219                }
 220        }
 221
 222        if (!tcon->ses->need_reconnect && !tcon->need_reconnect)
 223                return rc;
 224
 225        nls_codepage = load_nls_default();
 226
 227        /*
 228         * need to prevent multiple threads trying to simultaneously reconnect
 229         * the same SMB session
 230         */
 231        mutex_lock(&tcon->ses->session_mutex);
 232        rc = cifs_negotiate_protocol(0, tcon->ses);
 233        if (!rc && tcon->ses->need_reconnect)
 234                rc = cifs_setup_session(0, tcon->ses, nls_codepage);
 235
 236        if (rc || !tcon->need_reconnect) {
 237                mutex_unlock(&tcon->ses->session_mutex);
 238                goto out;
 239        }
 240
 241        cifs_mark_open_files_invalid(tcon);
 242        rc = SMB2_tcon(0, tcon->ses, tcon->treeName, tcon, nls_codepage);
 243        mutex_unlock(&tcon->ses->session_mutex);
 244        cifs_dbg(FYI, "reconnect tcon rc = %d\n", rc);
 245        if (rc)
 246                goto out;
 247        atomic_inc(&tconInfoReconnectCount);
 248        /*
 249         * BB FIXME add code to check if wsize needs update due to negotiated
 250         * smb buffer size shrinking.
 251         */
 252out:
 253        /*
 254         * Check if handle based operation so we know whether we can continue
 255         * or not without returning to caller to reset file handle.
 256         */
 257        /*
 258         * BB Is flush done by server on drop of tcp session? Should we special
 259         * case it and skip above?
 260         */
 261        switch (smb2_command) {
 262        case SMB2_FLUSH:
 263        case SMB2_READ:
 264        case SMB2_WRITE:
 265        case SMB2_LOCK:
 266        case SMB2_IOCTL:
 267        case SMB2_QUERY_DIRECTORY:
 268        case SMB2_CHANGE_NOTIFY:
 269        case SMB2_QUERY_INFO:
 270        case SMB2_SET_INFO:
 271                return -EAGAIN;
 272        }
 273        unload_nls(nls_codepage);
 274        return rc;
 275}
 276
 277/*
 278 * Allocate and return pointer to an SMB request hdr, and set basic
 279 * SMB information in the SMB header. If the return code is zero, this
 280 * function must have filled in request_buf pointer.
 281 */
 282static int
 283small_smb2_init(__le16 smb2_command, struct cifs_tcon *tcon,
 284                void **request_buf)
 285{
 286        int rc = 0;
 287
 288        rc = smb2_reconnect(smb2_command, tcon);
 289        if (rc)
 290                return rc;
 291
 292        /* BB eventually switch this to SMB2 specific small buf size */
 293        *request_buf = cifs_small_buf_get();
 294        if (*request_buf == NULL) {
 295                /* BB should we add a retry in here if not a writepage? */
 296                return -ENOMEM;
 297        }
 298
 299        smb2_hdr_assemble((struct smb2_hdr *) *request_buf, smb2_command, tcon);
 300
 301        if (tcon != NULL) {
 302#ifdef CONFIG_CIFS_STATS2
 303                uint16_t com_code = le16_to_cpu(smb2_command);
 304                cifs_stats_inc(&tcon->stats.smb2_stats.smb2_com_sent[com_code]);
 305#endif
 306                cifs_stats_inc(&tcon->num_smbs_sent);
 307        }
 308
 309        return rc;
 310}
 311
 312static void
 313free_rsp_buf(int resp_buftype, void *rsp)
 314{
 315        if (resp_buftype == CIFS_SMALL_BUFFER)
 316                cifs_small_buf_release(rsp);
 317        else if (resp_buftype == CIFS_LARGE_BUFFER)
 318                cifs_buf_release(rsp);
 319}
 320
 321
 322/*
 323 *
 324 *      SMB2 Worker functions follow:
 325 *
 326 *      The general structure of the worker functions is:
 327 *      1) Call smb2_init (assembles SMB2 header)
 328 *      2) Initialize SMB2 command specific fields in fixed length area of SMB
 329 *      3) Call smb_sendrcv2 (sends request on socket and waits for response)
 330 *      4) Decode SMB2 command specific fields in the fixed length area
 331 *      5) Decode variable length data area (if any for this SMB2 command type)
 332 *      6) Call free smb buffer
 333 *      7) return
 334 *
 335 */
 336
 337int
 338SMB2_negotiate(const unsigned int xid, struct cifs_ses *ses)
 339{
 340        struct smb2_negotiate_req *req;
 341        struct smb2_negotiate_rsp *rsp;
 342        struct kvec iov[1];
 343        int rc = 0;
 344        int resp_buftype;
 345        struct TCP_Server_Info *server = ses->server;
 346        int blob_offset, blob_length;
 347        char *security_blob;
 348        int flags = CIFS_NEG_OP;
 349
 350        cifs_dbg(FYI, "Negotiate protocol\n");
 351
 352        if (!server) {
 353                WARN(1, "%s: server is NULL!\n", __func__);
 354                return -EIO;
 355        }
 356
 357        rc = small_smb2_init(SMB2_NEGOTIATE, NULL, (void **) &req);
 358        if (rc)
 359                return rc;
 360
 361        req->hdr.SessionId = 0;
 362
 363        req->Dialects[0] = cpu_to_le16(ses->server->vals->protocol_id);
 364
 365        req->DialectCount = cpu_to_le16(1); /* One vers= at a time for now */
 366        inc_rfc1001_len(req, 2);
 367
 368        /* only one of SMB2 signing flags may be set in SMB2 request */
 369        if (ses->sign)
 370                req->SecurityMode = cpu_to_le16(SMB2_NEGOTIATE_SIGNING_REQUIRED);
 371        else if (global_secflags & CIFSSEC_MAY_SIGN)
 372                req->SecurityMode = cpu_to_le16(SMB2_NEGOTIATE_SIGNING_ENABLED);
 373        else
 374                req->SecurityMode = 0;
 375
 376        req->Capabilities = cpu_to_le32(ses->server->vals->req_capabilities);
 377
 378        memcpy(req->ClientGUID, cifs_client_guid, SMB2_CLIENT_GUID_SIZE);
 379
 380        iov[0].iov_base = (char *)req;
 381        /* 4 for rfc1002 length field */
 382        iov[0].iov_len = get_rfc1002_length(req) + 4;
 383
 384        rc = SendReceive2(xid, ses, iov, 1, &resp_buftype, flags);
 385
 386        rsp = (struct smb2_negotiate_rsp *)iov[0].iov_base;
 387        /*
 388         * No tcon so can't do
 389         * cifs_stats_inc(&tcon->stats.smb2_stats.smb2_com_fail[SMB2...]);
 390         */
 391        if (rc != 0)
 392                goto neg_exit;
 393
 394        cifs_dbg(FYI, "mode 0x%x\n", rsp->SecurityMode);
 395
 396        /* BB we may eventually want to match the negotiated vs. requested
 397           dialect, even though we are only requesting one at a time */
 398        if (rsp->DialectRevision == cpu_to_le16(SMB20_PROT_ID))
 399                cifs_dbg(FYI, "negotiated smb2.0 dialect\n");
 400        else if (rsp->DialectRevision == cpu_to_le16(SMB21_PROT_ID))
 401                cifs_dbg(FYI, "negotiated smb2.1 dialect\n");
 402        else if (rsp->DialectRevision == cpu_to_le16(SMB30_PROT_ID))
 403                cifs_dbg(FYI, "negotiated smb3.0 dialect\n");
 404        else if (rsp->DialectRevision == cpu_to_le16(SMB302_PROT_ID))
 405                cifs_dbg(FYI, "negotiated smb3.02 dialect\n");
 406        else {
 407                cifs_dbg(VFS, "Illegal dialect returned by server %d\n",
 408                         le16_to_cpu(rsp->DialectRevision));
 409                rc = -EIO;
 410                goto neg_exit;
 411        }
 412        server->dialect = le16_to_cpu(rsp->DialectRevision);
 413
 414        /* SMB2 only has an extended negflavor */
 415        server->negflavor = CIFS_NEGFLAVOR_EXTENDED;
 416        server->maxBuf = le32_to_cpu(rsp->MaxTransactSize);
 417        server->max_read = le32_to_cpu(rsp->MaxReadSize);
 418        server->max_write = le32_to_cpu(rsp->MaxWriteSize);
 419        /* BB Do we need to validate the SecurityMode? */
 420        server->sec_mode = le16_to_cpu(rsp->SecurityMode);
 421        server->capabilities = le32_to_cpu(rsp->Capabilities);
 422        /* Internal types */
 423        server->capabilities |= SMB2_NT_FIND | SMB2_LARGE_FILES;
 424
 425        security_blob = smb2_get_data_area_len(&blob_offset, &blob_length,
 426                                               &rsp->hdr);
 427        /*
 428         * See MS-SMB2 section 2.2.4: if no blob, client picks default which
 429         * for us will be
 430         *      ses->sectype = RawNTLMSSP;
 431         * but for time being this is our only auth choice so doesn't matter.
 432         * We just found a server which sets blob length to zero expecting raw.
 433         */
 434        if (blob_length == 0)
 435                cifs_dbg(FYI, "missing security blob on negprot\n");
 436
 437        rc = cifs_enable_signing(server, ses->sign);
 438#ifdef CONFIG_SMB2_ASN1  /* BB REMOVEME when updated asn1.c ready */
 439        if (rc)
 440                goto neg_exit;
 441        if (blob_length)
 442                rc = decode_neg_token_init(security_blob, blob_length,
 443                                   &server->sec_type);
 444        if (rc == 1)
 445                rc = 0;
 446        else if (rc == 0) {
 447                rc = -EIO;
 448                goto neg_exit;
 449        }
 450#endif
 451
 452neg_exit:
 453        free_rsp_buf(resp_buftype, rsp);
 454        return rc;
 455}
 456
 457int
 458SMB2_sess_setup(const unsigned int xid, struct cifs_ses *ses,
 459                const struct nls_table *nls_cp)
 460{
 461        struct smb2_sess_setup_req *req;
 462        struct smb2_sess_setup_rsp *rsp = NULL;
 463        struct kvec iov[2];
 464        int rc = 0;
 465        int resp_buftype;
 466        __le32 phase = NtLmNegotiate; /* NTLMSSP, if needed, is multistage */
 467        struct TCP_Server_Info *server = ses->server;
 468        u16 blob_length = 0;
 469        char *security_blob;
 470        char *ntlmssp_blob = NULL;
 471        bool use_spnego = false; /* else use raw ntlmssp */
 472
 473        cifs_dbg(FYI, "Session Setup\n");
 474
 475        if (!server) {
 476                WARN(1, "%s: server is NULL!\n", __func__);
 477                return -EIO;
 478        }
 479
 480        /*
 481         * If memory allocation is successful, caller of this function
 482         * frees it.
 483         */
 484        ses->ntlmssp = kmalloc(sizeof(struct ntlmssp_auth), GFP_KERNEL);
 485        if (!ses->ntlmssp)
 486                return -ENOMEM;
 487
 488        /* FIXME: allow for other auth types besides NTLMSSP (e.g. krb5) */
 489        ses->sectype = RawNTLMSSP;
 490
 491ssetup_ntlmssp_authenticate:
 492        if (phase == NtLmChallenge)
 493                phase = NtLmAuthenticate; /* if ntlmssp, now final phase */
 494
 495        rc = small_smb2_init(SMB2_SESSION_SETUP, NULL, (void **) &req);
 496        if (rc)
 497                return rc;
 498
 499        req->hdr.SessionId = 0; /* First session, not a reauthenticate */
 500        req->VcNumber = 0; /* MBZ */
 501        /* to enable echos and oplocks */
 502        req->hdr.CreditRequest = cpu_to_le16(3);
 503
 504        /* only one of SMB2 signing flags may be set in SMB2 request */
 505        if (server->sign)
 506                req->SecurityMode = SMB2_NEGOTIATE_SIGNING_REQUIRED;
 507        else if (global_secflags & CIFSSEC_MAY_SIGN) /* one flag unlike MUST_ */
 508                req->SecurityMode = SMB2_NEGOTIATE_SIGNING_ENABLED;
 509        else
 510                req->SecurityMode = 0;
 511
 512        req->Capabilities = 0;
 513        req->Channel = 0; /* MBZ */
 514
 515        iov[0].iov_base = (char *)req;
 516        /* 4 for rfc1002 length field and 1 for pad */
 517        iov[0].iov_len = get_rfc1002_length(req) + 4 - 1;
 518        if (phase == NtLmNegotiate) {
 519                ntlmssp_blob = kmalloc(sizeof(struct _NEGOTIATE_MESSAGE),
 520                                       GFP_KERNEL);
 521                if (ntlmssp_blob == NULL) {
 522                        rc = -ENOMEM;
 523                        goto ssetup_exit;
 524                }
 525                build_ntlmssp_negotiate_blob(ntlmssp_blob, ses);
 526                if (use_spnego) {
 527                        /* blob_length = build_spnego_ntlmssp_blob(
 528                                        &security_blob,
 529                                        sizeof(struct _NEGOTIATE_MESSAGE),
 530                                        ntlmssp_blob); */
 531                        /* BB eventually need to add this */
 532                        cifs_dbg(VFS, "spnego not supported for SMB2 yet\n");
 533                        rc = -EOPNOTSUPP;
 534                        kfree(ntlmssp_blob);
 535                        goto ssetup_exit;
 536                } else {
 537                        blob_length = sizeof(struct _NEGOTIATE_MESSAGE);
 538                        /* with raw NTLMSSP we don't encapsulate in SPNEGO */
 539                        security_blob = ntlmssp_blob;
 540                }
 541        } else if (phase == NtLmAuthenticate) {
 542                req->hdr.SessionId = ses->Suid;
 543                ntlmssp_blob = kzalloc(sizeof(struct _NEGOTIATE_MESSAGE) + 500,
 544                                       GFP_KERNEL);
 545                if (ntlmssp_blob == NULL) {
 546                        rc = -ENOMEM;
 547                        goto ssetup_exit;
 548                }
 549                rc = build_ntlmssp_auth_blob(ntlmssp_blob, &blob_length, ses,
 550                                             nls_cp);
 551                if (rc) {
 552                        cifs_dbg(FYI, "build_ntlmssp_auth_blob failed %d\n",
 553                                 rc);
 554                        goto ssetup_exit; /* BB double check error handling */
 555                }
 556                if (use_spnego) {
 557                        /* blob_length = build_spnego_ntlmssp_blob(
 558                                                        &security_blob,
 559                                                        blob_length,
 560                                                        ntlmssp_blob); */
 561                        cifs_dbg(VFS, "spnego not supported for SMB2 yet\n");
 562                        rc = -EOPNOTSUPP;
 563                        kfree(ntlmssp_blob);
 564                        goto ssetup_exit;
 565                } else {
 566                        security_blob = ntlmssp_blob;
 567                }
 568        } else {
 569                cifs_dbg(VFS, "illegal ntlmssp phase\n");
 570                rc = -EIO;
 571                goto ssetup_exit;
 572        }
 573
 574        /* Testing shows that buffer offset must be at location of Buffer[0] */
 575        req->SecurityBufferOffset =
 576                                cpu_to_le16(sizeof(struct smb2_sess_setup_req) -
 577                                            1 /* pad */ - 4 /* rfc1001 len */);
 578        req->SecurityBufferLength = cpu_to_le16(blob_length);
 579        iov[1].iov_base = security_blob;
 580        iov[1].iov_len = blob_length;
 581
 582        inc_rfc1001_len(req, blob_length - 1 /* pad */);
 583
 584        /* BB add code to build os and lm fields */
 585
 586        rc = SendReceive2(xid, ses, iov, 2, &resp_buftype,
 587                          CIFS_LOG_ERROR | CIFS_NEG_OP);
 588
 589        kfree(security_blob);
 590        rsp = (struct smb2_sess_setup_rsp *)iov[0].iov_base;
 591        if (resp_buftype != CIFS_NO_BUFFER &&
 592            rsp->hdr.Status == STATUS_MORE_PROCESSING_REQUIRED) {
 593                if (phase != NtLmNegotiate) {
 594                        cifs_dbg(VFS, "Unexpected more processing error\n");
 595                        goto ssetup_exit;
 596                }
 597                if (offsetof(struct smb2_sess_setup_rsp, Buffer) - 4 !=
 598                                le16_to_cpu(rsp->SecurityBufferOffset)) {
 599                        cifs_dbg(VFS, "Invalid security buffer offset %d\n",
 600                                 le16_to_cpu(rsp->SecurityBufferOffset));
 601                        rc = -EIO;
 602                        goto ssetup_exit;
 603                }
 604
 605                /* NTLMSSP Negotiate sent now processing challenge (response) */
 606                phase = NtLmChallenge; /* process ntlmssp challenge */
 607                rc = 0; /* MORE_PROCESSING is not an error here but expected */
 608                ses->Suid = rsp->hdr.SessionId;
 609                rc = decode_ntlmssp_challenge(rsp->Buffer,
 610                                le16_to_cpu(rsp->SecurityBufferLength), ses);
 611        }
 612
 613        /*
 614         * BB eventually add code for SPNEGO decoding of NtlmChallenge blob,
 615         * but at least the raw NTLMSSP case works.
 616         */
 617        /*
 618         * No tcon so can't do
 619         * cifs_stats_inc(&tcon->stats.smb2_stats.smb2_com_fail[SMB2...]);
 620         */
 621        if (rc != 0)
 622                goto ssetup_exit;
 623
 624        ses->session_flags = le16_to_cpu(rsp->SessionFlags);
 625ssetup_exit:
 626        free_rsp_buf(resp_buftype, rsp);
 627
 628        /* if ntlmssp, and negotiate succeeded, proceed to authenticate phase */
 629        if ((phase == NtLmChallenge) && (rc == 0))
 630                goto ssetup_ntlmssp_authenticate;
 631        return rc;
 632}
 633
 634int
 635SMB2_logoff(const unsigned int xid, struct cifs_ses *ses)
 636{
 637        struct smb2_logoff_req *req; /* response is also trivial struct */
 638        int rc = 0;
 639        struct TCP_Server_Info *server;
 640
 641        cifs_dbg(FYI, "disconnect session %p\n", ses);
 642
 643        if (ses && (ses->server))
 644                server = ses->server;
 645        else
 646                return -EIO;
 647
 648        rc = small_smb2_init(SMB2_LOGOFF, NULL, (void **) &req);
 649        if (rc)
 650                return rc;
 651
 652         /* since no tcon, smb2_init can not do this, so do here */
 653        req->hdr.SessionId = ses->Suid;
 654        if (server->sign)
 655                req->hdr.Flags |= SMB2_FLAGS_SIGNED;
 656
 657        rc = SendReceiveNoRsp(xid, ses, (char *) &req->hdr, 0);
 658        /*
 659         * No tcon so can't do
 660         * cifs_stats_inc(&tcon->stats.smb2_stats.smb2_com_fail[SMB2...]);
 661         */
 662        return rc;
 663}
 664
 665static inline void cifs_stats_fail_inc(struct cifs_tcon *tcon, uint16_t code)
 666{
 667        cifs_stats_inc(&tcon->stats.smb2_stats.smb2_com_failed[code]);
 668}
 669
 670#define MAX_SHARENAME_LENGTH (255 /* server */ + 80 /* share */ + 1 /* NULL */)
 671
 672int
 673SMB2_tcon(const unsigned int xid, struct cifs_ses *ses, const char *tree,
 674          struct cifs_tcon *tcon, const struct nls_table *cp)
 675{
 676        struct smb2_tree_connect_req *req;
 677        struct smb2_tree_connect_rsp *rsp = NULL;
 678        struct kvec iov[2];
 679        int rc = 0;
 680        int resp_buftype;
 681        int unc_path_len;
 682        struct TCP_Server_Info *server;
 683        __le16 *unc_path = NULL;
 684
 685        cifs_dbg(FYI, "TCON\n");
 686
 687        if ((ses->server) && tree)
 688                server = ses->server;
 689        else
 690                return -EIO;
 691
 692        if (tcon && tcon->bad_network_name)
 693                return -ENOENT;
 694
 695        unc_path = kmalloc(MAX_SHARENAME_LENGTH * 2, GFP_KERNEL);
 696        if (unc_path == NULL)
 697                return -ENOMEM;
 698
 699        unc_path_len = cifs_strtoUTF16(unc_path, tree, strlen(tree), cp) + 1;
 700        unc_path_len *= 2;
 701        if (unc_path_len < 2) {
 702                kfree(unc_path);
 703                return -EINVAL;
 704        }
 705
 706        rc = small_smb2_init(SMB2_TREE_CONNECT, tcon, (void **) &req);
 707        if (rc) {
 708                kfree(unc_path);
 709                return rc;
 710        }
 711
 712        if (tcon == NULL) {
 713                /* since no tcon, smb2_init can not do this, so do here */
 714                req->hdr.SessionId = ses->Suid;
 715                /* if (ses->server->sec_mode & SECMODE_SIGN_REQUIRED)
 716                        req->hdr.Flags |= SMB2_FLAGS_SIGNED; */
 717        }
 718
 719        iov[0].iov_base = (char *)req;
 720        /* 4 for rfc1002 length field and 1 for pad */
 721        iov[0].iov_len = get_rfc1002_length(req) + 4 - 1;
 722
 723        /* Testing shows that buffer offset must be at location of Buffer[0] */
 724        req->PathOffset = cpu_to_le16(sizeof(struct smb2_tree_connect_req)
 725                        - 1 /* pad */ - 4 /* do not count rfc1001 len field */);
 726        req->PathLength = cpu_to_le16(unc_path_len - 2);
 727        iov[1].iov_base = unc_path;
 728        iov[1].iov_len = unc_path_len;
 729
 730        inc_rfc1001_len(req, unc_path_len - 1 /* pad */);
 731
 732        rc = SendReceive2(xid, ses, iov, 2, &resp_buftype, 0);
 733        rsp = (struct smb2_tree_connect_rsp *)iov[0].iov_base;
 734
 735        if (rc != 0) {
 736                if (tcon) {
 737                        cifs_stats_fail_inc(tcon, SMB2_TREE_CONNECT_HE);
 738                        tcon->need_reconnect = true;
 739                }
 740                goto tcon_error_exit;
 741        }
 742
 743        if (tcon == NULL) {
 744                ses->ipc_tid = rsp->hdr.TreeId;
 745                goto tcon_exit;
 746        }
 747
 748        if (rsp->ShareType & SMB2_SHARE_TYPE_DISK)
 749                cifs_dbg(FYI, "connection to disk share\n");
 750        else if (rsp->ShareType & SMB2_SHARE_TYPE_PIPE) {
 751                tcon->ipc = true;
 752                cifs_dbg(FYI, "connection to pipe share\n");
 753        } else if (rsp->ShareType & SMB2_SHARE_TYPE_PRINT) {
 754                tcon->print = true;
 755                cifs_dbg(FYI, "connection to printer\n");
 756        } else {
 757                cifs_dbg(VFS, "unknown share type %d\n", rsp->ShareType);
 758                rc = -EOPNOTSUPP;
 759                goto tcon_error_exit;
 760        }
 761
 762        tcon->share_flags = le32_to_cpu(rsp->ShareFlags);
 763        tcon->capabilities = rsp->Capabilities; /* we keep caps little endian */
 764        tcon->maximal_access = le32_to_cpu(rsp->MaximalAccess);
 765        tcon->tidStatus = CifsGood;
 766        tcon->need_reconnect = false;
 767        tcon->tid = rsp->hdr.TreeId;
 768        strlcpy(tcon->treeName, tree, sizeof(tcon->treeName));
 769
 770        if ((rsp->Capabilities & SMB2_SHARE_CAP_DFS) &&
 771            ((tcon->share_flags & SHI1005_FLAGS_DFS) == 0))
 772                cifs_dbg(VFS, "DFS capability contradicts DFS flag\n");
 773
 774tcon_exit:
 775        free_rsp_buf(resp_buftype, rsp);
 776        kfree(unc_path);
 777        return rc;
 778
 779tcon_error_exit:
 780        if (rsp->hdr.Status == STATUS_BAD_NETWORK_NAME) {
 781                cifs_dbg(VFS, "BAD_NETWORK_NAME: %s\n", tree);
 782                tcon->bad_network_name = true;
 783        }
 784        goto tcon_exit;
 785}
 786
 787int
 788SMB2_tdis(const unsigned int xid, struct cifs_tcon *tcon)
 789{
 790        struct smb2_tree_disconnect_req *req; /* response is trivial */
 791        int rc = 0;
 792        struct TCP_Server_Info *server;
 793        struct cifs_ses *ses = tcon->ses;
 794
 795        cifs_dbg(FYI, "Tree Disconnect\n");
 796
 797        if (ses && (ses->server))
 798                server = ses->server;
 799        else
 800                return -EIO;
 801
 802        if ((tcon->need_reconnect) || (tcon->ses->need_reconnect))
 803                return 0;
 804
 805        rc = small_smb2_init(SMB2_TREE_DISCONNECT, tcon, (void **) &req);
 806        if (rc)
 807                return rc;
 808
 809        rc = SendReceiveNoRsp(xid, ses, (char *)&req->hdr, 0);
 810        if (rc)
 811                cifs_stats_fail_inc(tcon, SMB2_TREE_DISCONNECT_HE);
 812
 813        return rc;
 814}
 815
 816static struct create_lease *
 817create_lease_buf(u8 *lease_key, u8 oplock)
 818{
 819        struct create_lease *buf;
 820
 821        buf = kzalloc(sizeof(struct create_lease), GFP_KERNEL);
 822        if (!buf)
 823                return NULL;
 824
 825        buf->lcontext.LeaseKeyLow = cpu_to_le64(*((u64 *)lease_key));
 826        buf->lcontext.LeaseKeyHigh = cpu_to_le64(*((u64 *)(lease_key + 8)));
 827        if (oplock == SMB2_OPLOCK_LEVEL_EXCLUSIVE)
 828                buf->lcontext.LeaseState = SMB2_LEASE_WRITE_CACHING |
 829                                           SMB2_LEASE_READ_CACHING;
 830        else if (oplock == SMB2_OPLOCK_LEVEL_II)
 831                buf->lcontext.LeaseState = SMB2_LEASE_READ_CACHING;
 832        else if (oplock == SMB2_OPLOCK_LEVEL_BATCH)
 833                buf->lcontext.LeaseState = SMB2_LEASE_HANDLE_CACHING |
 834                                           SMB2_LEASE_READ_CACHING |
 835                                           SMB2_LEASE_WRITE_CACHING;
 836
 837        buf->ccontext.DataOffset = cpu_to_le16(offsetof
 838                                        (struct create_lease, lcontext));
 839        buf->ccontext.DataLength = cpu_to_le32(sizeof(struct lease_context));
 840        buf->ccontext.NameOffset = cpu_to_le16(offsetof
 841                                (struct create_lease, Name));
 842        buf->ccontext.NameLength = cpu_to_le16(4);
 843        buf->Name[0] = 'R';
 844        buf->Name[1] = 'q';
 845        buf->Name[2] = 'L';
 846        buf->Name[3] = 's';
 847        return buf;
 848}
 849
 850static struct create_durable *
 851create_durable_buf(void)
 852{
 853        struct create_durable *buf;
 854
 855        buf = kzalloc(sizeof(struct create_durable), GFP_KERNEL);
 856        if (!buf)
 857                return NULL;
 858
 859        buf->ccontext.DataOffset = cpu_to_le16(offsetof
 860                                        (struct create_durable, Data));
 861        buf->ccontext.DataLength = cpu_to_le32(16);
 862        buf->ccontext.NameOffset = cpu_to_le16(offsetof
 863                                (struct create_durable, Name));
 864        buf->ccontext.NameLength = cpu_to_le16(4);
 865        buf->Name[0] = 'D';
 866        buf->Name[1] = 'H';
 867        buf->Name[2] = 'n';
 868        buf->Name[3] = 'Q';
 869        return buf;
 870}
 871
 872static struct create_durable *
 873create_reconnect_durable_buf(struct cifs_fid *fid)
 874{
 875        struct create_durable *buf;
 876
 877        buf = kzalloc(sizeof(struct create_durable), GFP_KERNEL);
 878        if (!buf)
 879                return NULL;
 880
 881        buf->ccontext.DataOffset = cpu_to_le16(offsetof
 882                                        (struct create_durable, Data));
 883        buf->ccontext.DataLength = cpu_to_le32(16);
 884        buf->ccontext.NameOffset = cpu_to_le16(offsetof
 885                                (struct create_durable, Name));
 886        buf->ccontext.NameLength = cpu_to_le16(4);
 887        buf->Data.Fid.PersistentFileId = fid->persistent_fid;
 888        buf->Data.Fid.VolatileFileId = fid->volatile_fid;
 889        buf->Name[0] = 'D';
 890        buf->Name[1] = 'H';
 891        buf->Name[2] = 'n';
 892        buf->Name[3] = 'C';
 893        return buf;
 894}
 895
 896static __u8
 897parse_lease_state(struct smb2_create_rsp *rsp)
 898{
 899        char *data_offset;
 900        struct create_lease *lc;
 901        bool found = false;
 902        unsigned int next = 0;
 903        char *name;
 904
 905        data_offset = (char *)rsp + 4 + le32_to_cpu(rsp->CreateContextsOffset);
 906        lc = (struct create_lease *)data_offset;
 907        do {
 908                lc = (struct create_lease *)((char *)lc + next);
 909                name = le16_to_cpu(lc->ccontext.NameOffset) + (char *)lc;
 910                if (le16_to_cpu(lc->ccontext.NameLength) != 4 ||
 911                    strncmp(name, "RqLs", 4)) {
 912                        next = le32_to_cpu(lc->ccontext.Next);
 913                        continue;
 914                }
 915                if (lc->lcontext.LeaseFlags & SMB2_LEASE_FLAG_BREAK_IN_PROGRESS)
 916                        return SMB2_OPLOCK_LEVEL_NOCHANGE;
 917                found = true;
 918                break;
 919        } while (next != 0);
 920
 921        if (!found)
 922                return 0;
 923
 924        return smb2_map_lease_to_oplock(lc->lcontext.LeaseState);
 925}
 926
 927static int
 928add_lease_context(struct kvec *iov, unsigned int *num_iovec, __u8 *oplock)
 929{
 930        struct smb2_create_req *req = iov[0].iov_base;
 931        unsigned int num = *num_iovec;
 932
 933        iov[num].iov_base = create_lease_buf(oplock+1, *oplock);
 934        if (iov[num].iov_base == NULL)
 935                return -ENOMEM;
 936        iov[num].iov_len = sizeof(struct create_lease);
 937        req->RequestedOplockLevel = SMB2_OPLOCK_LEVEL_LEASE;
 938        if (!req->CreateContextsOffset)
 939                req->CreateContextsOffset = cpu_to_le32(
 940                                sizeof(struct smb2_create_req) - 4 +
 941                                iov[num - 1].iov_len);
 942        req->CreateContextsLength = cpu_to_le32(
 943                                le32_to_cpu(req->CreateContextsLength) +
 944                                sizeof(struct create_lease));
 945        inc_rfc1001_len(&req->hdr, sizeof(struct create_lease));
 946        *num_iovec = num + 1;
 947        return 0;
 948}
 949
 950static int
 951add_durable_context(struct kvec *iov, unsigned int *num_iovec,
 952                    struct cifs_open_parms *oparms)
 953{
 954        struct smb2_create_req *req = iov[0].iov_base;
 955        unsigned int num = *num_iovec;
 956
 957        if (oparms->reconnect) {
 958                iov[num].iov_base = create_reconnect_durable_buf(oparms->fid);
 959                /* indicate that we don't need to relock the file */
 960                oparms->reconnect = false;
 961        } else
 962                iov[num].iov_base = create_durable_buf();
 963        if (iov[num].iov_base == NULL)
 964                return -ENOMEM;
 965        iov[num].iov_len = sizeof(struct create_durable);
 966        if (!req->CreateContextsOffset)
 967                req->CreateContextsOffset =
 968                        cpu_to_le32(sizeof(struct smb2_create_req) - 4 +
 969                                                                iov[1].iov_len);
 970        req->CreateContextsLength =
 971                        cpu_to_le32(le32_to_cpu(req->CreateContextsLength) +
 972                                                sizeof(struct create_durable));
 973        inc_rfc1001_len(&req->hdr, sizeof(struct create_durable));
 974        *num_iovec = num + 1;
 975        return 0;
 976}
 977
 978int
 979SMB2_open(const unsigned int xid, struct cifs_open_parms *oparms, __le16 *path,
 980          __u8 *oplock, struct smb2_file_all_info *buf)
 981{
 982        struct smb2_create_req *req;
 983        struct smb2_create_rsp *rsp;
 984        struct TCP_Server_Info *server;
 985        struct cifs_tcon *tcon = oparms->tcon;
 986        struct cifs_ses *ses = tcon->ses;
 987        struct kvec iov[4];
 988        int resp_buftype;
 989        int uni_path_len;
 990        __le16 *copy_path = NULL;
 991        int copy_size;
 992        int rc = 0;
 993        unsigned int num_iovecs = 2;
 994        __u32 file_attributes = 0;
 995
 996        cifs_dbg(FYI, "create/open\n");
 997
 998        if (ses && (ses->server))
 999                server = ses->server;
1000        else
1001                return -EIO;
1002
1003        rc = small_smb2_init(SMB2_CREATE, tcon, (void **) &req);
1004        if (rc)
1005                return rc;
1006
1007        if (oparms->create_options & CREATE_OPTION_READONLY)
1008                file_attributes |= ATTR_READONLY;
1009
1010        req->ImpersonationLevel = IL_IMPERSONATION;
1011        req->DesiredAccess = cpu_to_le32(oparms->desired_access);
1012        /* File attributes ignored on open (used in create though) */
1013        req->FileAttributes = cpu_to_le32(file_attributes);
1014        req->ShareAccess = FILE_SHARE_ALL_LE;
1015        req->CreateDisposition = cpu_to_le32(oparms->disposition);
1016        req->CreateOptions = cpu_to_le32(oparms->create_options & CREATE_OPTIONS_MASK);
1017        uni_path_len = (2 * UniStrnlen((wchar_t *)path, PATH_MAX)) + 2;
1018        /* do not count rfc1001 len field */
1019        req->NameOffset = cpu_to_le16(sizeof(struct smb2_create_req) - 4);
1020
1021        iov[0].iov_base = (char *)req;
1022        /* 4 for rfc1002 length field */
1023        iov[0].iov_len = get_rfc1002_length(req) + 4;
1024
1025        /* MUST set path len (NameLength) to 0 opening root of share */
1026        req->NameLength = cpu_to_le16(uni_path_len - 2);
1027        /* -1 since last byte is buf[0] which is sent below (path) */
1028        iov[0].iov_len--;
1029        if (uni_path_len % 8 != 0) {
1030                copy_size = uni_path_len / 8 * 8;
1031                if (copy_size < uni_path_len)
1032                        copy_size += 8;
1033
1034                copy_path = kzalloc(copy_size, GFP_KERNEL);
1035                if (!copy_path)
1036                        return -ENOMEM;
1037                memcpy((char *)copy_path, (const char *)path,
1038                        uni_path_len);
1039                uni_path_len = copy_size;
1040                path = copy_path;
1041        }
1042
1043        iov[1].iov_len = uni_path_len;
1044        iov[1].iov_base = path;
1045        /* -1 since last byte is buf[0] which was counted in smb2_buf_len */
1046        inc_rfc1001_len(req, uni_path_len - 1);
1047
1048        if (!server->oplocks)
1049                *oplock = SMB2_OPLOCK_LEVEL_NONE;
1050
1051        if (!(tcon->ses->server->capabilities & SMB2_GLOBAL_CAP_LEASING) ||
1052            *oplock == SMB2_OPLOCK_LEVEL_NONE)
1053                req->RequestedOplockLevel = *oplock;
1054        else {
1055                rc = add_lease_context(iov, &num_iovecs, oplock);
1056                if (rc) {
1057                        cifs_small_buf_release(req);
1058                        kfree(copy_path);
1059                        return rc;
1060                }
1061        }
1062
1063        if (*oplock == SMB2_OPLOCK_LEVEL_BATCH) {
1064                /* need to set Next field of lease context if we request it */
1065                if (tcon->ses->server->capabilities & SMB2_GLOBAL_CAP_LEASING) {
1066                        struct create_context *ccontext =
1067                            (struct create_context *)iov[num_iovecs-1].iov_base;
1068                        ccontext->Next =
1069                                cpu_to_le32(sizeof(struct create_lease));
1070                }
1071                rc = add_durable_context(iov, &num_iovecs, oparms);
1072                if (rc) {
1073                        cifs_small_buf_release(req);
1074                        kfree(copy_path);
1075                        kfree(iov[num_iovecs-1].iov_base);
1076                        return rc;
1077                }
1078        }
1079
1080        rc = SendReceive2(xid, ses, iov, num_iovecs, &resp_buftype, 0);
1081        rsp = (struct smb2_create_rsp *)iov[0].iov_base;
1082
1083        if (rc != 0) {
1084                cifs_stats_fail_inc(tcon, SMB2_CREATE_HE);
1085                goto creat_exit;
1086        }
1087
1088        oparms->fid->persistent_fid = rsp->PersistentFileId;
1089        oparms->fid->volatile_fid = rsp->VolatileFileId;
1090
1091        if (buf) {
1092                memcpy(buf, &rsp->CreationTime, 32);
1093                buf->AllocationSize = rsp->AllocationSize;
1094                buf->EndOfFile = rsp->EndofFile;
1095                buf->Attributes = rsp->FileAttributes;
1096                buf->NumberOfLinks = cpu_to_le32(1);
1097                buf->DeletePending = 0;
1098        }
1099
1100        if (rsp->OplockLevel == SMB2_OPLOCK_LEVEL_LEASE)
1101                *oplock = parse_lease_state(rsp);
1102        else
1103                *oplock = rsp->OplockLevel;
1104creat_exit:
1105        kfree(copy_path);
1106        free_rsp_buf(resp_buftype, rsp);
1107        return rc;
1108}
1109
1110/*
1111 *      SMB2 IOCTL is used for both IOCTLs and FSCTLs
1112 */
1113int
1114SMB2_ioctl(const unsigned int xid, struct cifs_tcon *tcon, u64 persistent_fid,
1115           u64 volatile_fid, u32 opcode, bool is_fsctl, char *in_data,
1116           u32 indatalen, char **out_data, u32 *plen /* returned data len */)
1117{
1118        struct smb2_ioctl_req *req;
1119        struct smb2_ioctl_rsp *rsp;
1120        struct TCP_Server_Info *server;
1121        struct cifs_ses *ses = tcon->ses;
1122        struct kvec iov[2];
1123        int resp_buftype;
1124        int num_iovecs;
1125        int rc = 0;
1126
1127        cifs_dbg(FYI, "SMB2 IOCTL\n");
1128
1129        /* zero out returned data len, in case of error */
1130        if (plen)
1131                *plen = 0;
1132
1133        if (ses && (ses->server))
1134                server = ses->server;
1135        else
1136                return -EIO;
1137
1138        rc = small_smb2_init(SMB2_IOCTL, tcon, (void **) &req);
1139        if (rc)
1140                return rc;
1141
1142        req->CtlCode = cpu_to_le32(opcode);
1143        req->PersistentFileId = persistent_fid;
1144        req->VolatileFileId = volatile_fid;
1145
1146        if (indatalen) {
1147                req->InputCount = cpu_to_le32(indatalen);
1148                /* do not set InputOffset if no input data */
1149                req->InputOffset =
1150                       cpu_to_le32(offsetof(struct smb2_ioctl_req, Buffer) - 4);
1151                iov[1].iov_base = in_data;
1152                iov[1].iov_len = indatalen;
1153                num_iovecs = 2;
1154        } else
1155                num_iovecs = 1;
1156
1157        req->OutputOffset = 0;
1158        req->OutputCount = 0; /* MBZ */
1159
1160        /*
1161         * Could increase MaxOutputResponse, but that would require more
1162         * than one credit. Windows typically sets this smaller, but for some
1163         * ioctls it may be useful to allow server to send more. No point
1164         * limiting what the server can send as long as fits in one credit
1165         */
1166        req->MaxOutputResponse = cpu_to_le32(0xFF00); /* < 64K uses 1 credit */
1167
1168        if (is_fsctl)
1169                req->Flags = cpu_to_le32(SMB2_0_IOCTL_IS_FSCTL);
1170        else
1171                req->Flags = 0;
1172
1173        iov[0].iov_base = (char *)req;
1174        /* 4 for rfc1002 length field */
1175        iov[0].iov_len = get_rfc1002_length(req) + 4;
1176
1177        if (indatalen)
1178                inc_rfc1001_len(req, indatalen);
1179
1180        rc = SendReceive2(xid, ses, iov, num_iovecs, &resp_buftype, 0);
1181        rsp = (struct smb2_ioctl_rsp *)iov[0].iov_base;
1182
1183        if (rc != 0) {
1184                if (tcon)
1185                        cifs_stats_fail_inc(tcon, SMB2_IOCTL_HE);
1186                goto ioctl_exit;
1187        }
1188
1189        /* check if caller wants to look at return data or just return rc */
1190        if ((plen == NULL) || (out_data == NULL))
1191                goto ioctl_exit;
1192
1193        *plen = le32_to_cpu(rsp->OutputCount);
1194
1195        /* We check for obvious errors in the output buffer length and offset */
1196        if (*plen == 0)
1197                goto ioctl_exit; /* server returned no data */
1198        else if (*plen > 0xFF00) {
1199                cifs_dbg(VFS, "srv returned invalid ioctl length: %d\n", *plen);
1200                *plen = 0;
1201                rc = -EIO;
1202                goto ioctl_exit;
1203        }
1204
1205        if (get_rfc1002_length(rsp) < le32_to_cpu(rsp->OutputOffset) + *plen) {
1206                cifs_dbg(VFS, "Malformed ioctl resp: len %d offset %d\n", *plen,
1207                        le32_to_cpu(rsp->OutputOffset));
1208                *plen = 0;
1209                rc = -EIO;
1210                goto ioctl_exit;
1211        }
1212
1213        *out_data = kmalloc(*plen, GFP_KERNEL);
1214        if (*out_data == NULL) {
1215                rc = -ENOMEM;
1216                goto ioctl_exit;
1217        }
1218
1219        memcpy(*out_data, rsp->hdr.ProtocolId + le32_to_cpu(rsp->OutputOffset),
1220               *plen);
1221ioctl_exit:
1222        free_rsp_buf(resp_buftype, rsp);
1223        return rc;
1224}
1225
1226int
1227SMB2_close(const unsigned int xid, struct cifs_tcon *tcon,
1228           u64 persistent_fid, u64 volatile_fid)
1229{
1230        struct smb2_close_req *req;
1231        struct smb2_close_rsp *rsp;
1232        struct TCP_Server_Info *server;
1233        struct cifs_ses *ses = tcon->ses;
1234        struct kvec iov[1];
1235        int resp_buftype;
1236        int rc = 0;
1237
1238        cifs_dbg(FYI, "Close\n");
1239
1240        if (ses && (ses->server))
1241                server = ses->server;
1242        else
1243                return -EIO;
1244
1245        rc = small_smb2_init(SMB2_CLOSE, tcon, (void **) &req);
1246        if (rc)
1247                return rc;
1248
1249        req->PersistentFileId = persistent_fid;
1250        req->VolatileFileId = volatile_fid;
1251
1252        iov[0].iov_base = (char *)req;
1253        /* 4 for rfc1002 length field */
1254        iov[0].iov_len = get_rfc1002_length(req) + 4;
1255
1256        rc = SendReceive2(xid, ses, iov, 1, &resp_buftype, 0);
1257        rsp = (struct smb2_close_rsp *)iov[0].iov_base;
1258
1259        if (rc != 0) {
1260                if (tcon)
1261                        cifs_stats_fail_inc(tcon, SMB2_CLOSE_HE);
1262                goto close_exit;
1263        }
1264
1265        /* BB FIXME - decode close response, update inode for caching */
1266
1267close_exit:
1268        free_rsp_buf(resp_buftype, rsp);
1269        return rc;
1270}
1271
1272static int
1273validate_buf(unsigned int offset, unsigned int buffer_length,
1274             struct smb2_hdr *hdr, unsigned int min_buf_size)
1275
1276{
1277        unsigned int smb_len = be32_to_cpu(hdr->smb2_buf_length);
1278        char *end_of_smb = smb_len + 4 /* RFC1001 length field */ + (char *)hdr;
1279        char *begin_of_buf = 4 /* RFC1001 len field */ + offset + (char *)hdr;
1280        char *end_of_buf = begin_of_buf + buffer_length;
1281
1282
1283        if (buffer_length < min_buf_size) {
1284                cifs_dbg(VFS, "buffer length %d smaller than minimum size %d\n",
1285                         buffer_length, min_buf_size);
1286                return -EINVAL;
1287        }
1288
1289        /* check if beyond RFC1001 maximum length */
1290        if ((smb_len > 0x7FFFFF) || (buffer_length > 0x7FFFFF)) {
1291                cifs_dbg(VFS, "buffer length %d or smb length %d too large\n",
1292                         buffer_length, smb_len);
1293                return -EINVAL;
1294        }
1295
1296        if ((begin_of_buf > end_of_smb) || (end_of_buf > end_of_smb)) {
1297                cifs_dbg(VFS, "illegal server response, bad offset to data\n");
1298                return -EINVAL;
1299        }
1300
1301        return 0;
1302}
1303
1304/*
1305 * If SMB buffer fields are valid, copy into temporary buffer to hold result.
1306 * Caller must free buffer.
1307 */
1308static int
1309validate_and_copy_buf(unsigned int offset, unsigned int buffer_length,
1310                      struct smb2_hdr *hdr, unsigned int minbufsize,
1311                      char *data)
1312
1313{
1314        char *begin_of_buf = 4 /* RFC1001 len field */ + offset + (char *)hdr;
1315        int rc;
1316
1317        if (!data)
1318                return -EINVAL;
1319
1320        rc = validate_buf(offset, buffer_length, hdr, minbufsize);
1321        if (rc)
1322                return rc;
1323
1324        memcpy(data, begin_of_buf, buffer_length);
1325
1326        return 0;
1327}
1328
1329static int
1330query_info(const unsigned int xid, struct cifs_tcon *tcon,
1331           u64 persistent_fid, u64 volatile_fid, u8 info_class,
1332           size_t output_len, size_t min_len, void *data)
1333{
1334        struct smb2_query_info_req *req;
1335        struct smb2_query_info_rsp *rsp = NULL;
1336        struct kvec iov[2];
1337        int rc = 0;
1338        int resp_buftype;
1339        struct TCP_Server_Info *server;
1340        struct cifs_ses *ses = tcon->ses;
1341
1342        cifs_dbg(FYI, "Query Info\n");
1343
1344        if (ses && (ses->server))
1345                server = ses->server;
1346        else
1347                return -EIO;
1348
1349        rc = small_smb2_init(SMB2_QUERY_INFO, tcon, (void **) &req);
1350        if (rc)
1351                return rc;
1352
1353        req->InfoType = SMB2_O_INFO_FILE;
1354        req->FileInfoClass = info_class;
1355        req->PersistentFileId = persistent_fid;
1356        req->VolatileFileId = volatile_fid;
1357        /* 4 for rfc1002 length field and 1 for Buffer */
1358        req->InputBufferOffset =
1359                cpu_to_le16(sizeof(struct smb2_query_info_req) - 1 - 4);
1360        req->OutputBufferLength = cpu_to_le32(output_len);
1361
1362        iov[0].iov_base = (char *)req;
1363        /* 4 for rfc1002 length field */
1364        iov[0].iov_len = get_rfc1002_length(req) + 4;
1365
1366        rc = SendReceive2(xid, ses, iov, 1, &resp_buftype, 0);
1367        rsp = (struct smb2_query_info_rsp *)iov[0].iov_base;
1368
1369        if (rc) {
1370                cifs_stats_fail_inc(tcon, SMB2_QUERY_INFO_HE);
1371                goto qinf_exit;
1372        }
1373
1374        rc = validate_and_copy_buf(le16_to_cpu(rsp->OutputBufferOffset),
1375                                   le32_to_cpu(rsp->OutputBufferLength),
1376                                   &rsp->hdr, min_len, data);
1377
1378qinf_exit:
1379        free_rsp_buf(resp_buftype, rsp);
1380        return rc;
1381}
1382
1383int
1384SMB2_query_info(const unsigned int xid, struct cifs_tcon *tcon,
1385                u64 persistent_fid, u64 volatile_fid,
1386                struct smb2_file_all_info *data)
1387{
1388        return query_info(xid, tcon, persistent_fid, volatile_fid,
1389                          FILE_ALL_INFORMATION,
1390                          sizeof(struct smb2_file_all_info) + MAX_NAME * 2,
1391                          sizeof(struct smb2_file_all_info), data);
1392}
1393
1394int
1395SMB2_get_srv_num(const unsigned int xid, struct cifs_tcon *tcon,
1396                 u64 persistent_fid, u64 volatile_fid, __le64 *uniqueid)
1397{
1398        return query_info(xid, tcon, persistent_fid, volatile_fid,
1399                          FILE_INTERNAL_INFORMATION,
1400                          sizeof(struct smb2_file_internal_info),
1401                          sizeof(struct smb2_file_internal_info), uniqueid);
1402}
1403
1404/*
1405 * This is a no-op for now. We're not really interested in the reply, but
1406 * rather in the fact that the server sent one and that server->lstrp
1407 * gets updated.
1408 *
1409 * FIXME: maybe we should consider checking that the reply matches request?
1410 */
1411static void
1412smb2_echo_callback(struct mid_q_entry *mid)
1413{
1414        struct TCP_Server_Info *server = mid->callback_data;
1415        struct smb2_echo_rsp *smb2 = (struct smb2_echo_rsp *)mid->resp_buf;
1416        unsigned int credits_received = 1;
1417
1418        if (mid->mid_state == MID_RESPONSE_RECEIVED)
1419                credits_received = le16_to_cpu(smb2->hdr.CreditRequest);
1420
1421        DeleteMidQEntry(mid);
1422        add_credits(server, credits_received, CIFS_ECHO_OP);
1423}
1424
1425int
1426SMB2_echo(struct TCP_Server_Info *server)
1427{
1428        struct smb2_echo_req *req;
1429        int rc = 0;
1430        struct kvec iov;
1431        struct smb_rqst rqst = { .rq_iov = &iov,
1432                                 .rq_nvec = 1 };
1433
1434        cifs_dbg(FYI, "In echo request\n");
1435
1436        rc = small_smb2_init(SMB2_ECHO, NULL, (void **)&req);
1437        if (rc)
1438                return rc;
1439
1440        req->hdr.CreditRequest = cpu_to_le16(1);
1441
1442        iov.iov_base = (char *)req;
1443        /* 4 for rfc1002 length field */
1444        iov.iov_len = get_rfc1002_length(req) + 4;
1445
1446        rc = cifs_call_async(server, &rqst, NULL, smb2_echo_callback, server,
1447                             CIFS_ECHO_OP);
1448        if (rc)
1449                cifs_dbg(FYI, "Echo request failed: %d\n", rc);
1450
1451        cifs_small_buf_release(req);
1452        return rc;
1453}
1454
1455int
1456SMB2_flush(const unsigned int xid, struct cifs_tcon *tcon, u64 persistent_fid,
1457           u64 volatile_fid)
1458{
1459        struct smb2_flush_req *req;
1460        struct TCP_Server_Info *server;
1461        struct cifs_ses *ses = tcon->ses;
1462        struct kvec iov[1];
1463        int resp_buftype;
1464        int rc = 0;
1465
1466        cifs_dbg(FYI, "Flush\n");
1467
1468        if (ses && (ses->server))
1469                server = ses->server;
1470        else
1471                return -EIO;
1472
1473        rc = small_smb2_init(SMB2_FLUSH, tcon, (void **) &req);
1474        if (rc)
1475                return rc;
1476
1477        req->PersistentFileId = persistent_fid;
1478        req->VolatileFileId = volatile_fid;
1479
1480        iov[0].iov_base = (char *)req;
1481        /* 4 for rfc1002 length field */
1482        iov[0].iov_len = get_rfc1002_length(req) + 4;
1483
1484        rc = SendReceive2(xid, ses, iov, 1, &resp_buftype, 0);
1485
1486        if ((rc != 0) && tcon)
1487                cifs_stats_fail_inc(tcon, SMB2_FLUSH_HE);
1488
1489        free_rsp_buf(resp_buftype, iov[0].iov_base);
1490        return rc;
1491}
1492
1493/*
1494 * To form a chain of read requests, any read requests after the first should
1495 * have the end_of_chain boolean set to true.
1496 */
1497static int
1498smb2_new_read_req(struct kvec *iov, struct cifs_io_parms *io_parms,
1499                  unsigned int remaining_bytes, int request_type)
1500{
1501        int rc = -EACCES;
1502        struct smb2_read_req *req = NULL;
1503
1504        rc = small_smb2_init(SMB2_READ, io_parms->tcon, (void **) &req);
1505        if (rc)
1506                return rc;
1507        if (io_parms->tcon->ses->server == NULL)
1508                return -ECONNABORTED;
1509
1510        req->hdr.ProcessId = cpu_to_le32(io_parms->pid);
1511
1512        req->PersistentFileId = io_parms->persistent_fid;
1513        req->VolatileFileId = io_parms->volatile_fid;
1514        req->ReadChannelInfoOffset = 0; /* reserved */
1515        req->ReadChannelInfoLength = 0; /* reserved */
1516        req->Channel = 0; /* reserved */
1517        req->MinimumCount = 0;
1518        req->Length = cpu_to_le32(io_parms->length);
1519        req->Offset = cpu_to_le64(io_parms->offset);
1520
1521        if (request_type & CHAINED_REQUEST) {
1522                if (!(request_type & END_OF_CHAIN)) {
1523                        /* 4 for rfc1002 length field */
1524                        req->hdr.NextCommand =
1525                                cpu_to_le32(get_rfc1002_length(req) + 4);
1526                } else /* END_OF_CHAIN */
1527                        req->hdr.NextCommand = 0;
1528                if (request_type & RELATED_REQUEST) {
1529                        req->hdr.Flags |= SMB2_FLAGS_RELATED_OPERATIONS;
1530                        /*
1531                         * Related requests use info from previous read request
1532                         * in chain.
1533                         */
1534                        req->hdr.SessionId = 0xFFFFFFFF;
1535                        req->hdr.TreeId = 0xFFFFFFFF;
1536                        req->PersistentFileId = 0xFFFFFFFF;
1537                        req->VolatileFileId = 0xFFFFFFFF;
1538                }
1539        }
1540        if (remaining_bytes > io_parms->length)
1541                req->RemainingBytes = cpu_to_le32(remaining_bytes);
1542        else
1543                req->RemainingBytes = 0;
1544
1545        iov[0].iov_base = (char *)req;
1546        /* 4 for rfc1002 length field */
1547        iov[0].iov_len = get_rfc1002_length(req) + 4;
1548        return rc;
1549}
1550
1551static void
1552smb2_readv_callback(struct mid_q_entry *mid)
1553{
1554        struct cifs_readdata *rdata = mid->callback_data;
1555        struct cifs_tcon *tcon = tlink_tcon(rdata->cfile->tlink);
1556        struct TCP_Server_Info *server = tcon->ses->server;
1557        struct smb2_hdr *buf = (struct smb2_hdr *)rdata->iov.iov_base;
1558        unsigned int credits_received = 1;
1559        struct smb_rqst rqst = { .rq_iov = &rdata->iov,
1560                                 .rq_nvec = 1,
1561                                 .rq_pages = rdata->pages,
1562                                 .rq_npages = rdata->nr_pages,
1563                                 .rq_pagesz = rdata->pagesz,
1564                                 .rq_tailsz = rdata->tailsz };
1565
1566        cifs_dbg(FYI, "%s: mid=%llu state=%d result=%d bytes=%u\n",
1567                 __func__, mid->mid, mid->mid_state, rdata->result,
1568                 rdata->bytes);
1569
1570        switch (mid->mid_state) {
1571        case MID_RESPONSE_RECEIVED:
1572                credits_received = le16_to_cpu(buf->CreditRequest);
1573                /* result already set, check signature */
1574                if (server->sign) {
1575                        int rc;
1576
1577                        rc = smb2_verify_signature(&rqst, server);
1578                        if (rc)
1579                                cifs_dbg(VFS, "SMB signature verification returned error = %d\n",
1580                                         rc);
1581                }
1582                /* FIXME: should this be counted toward the initiating task? */
1583                task_io_account_read(rdata->bytes);
1584                cifs_stats_bytes_read(tcon, rdata->bytes);
1585                break;
1586        case MID_REQUEST_SUBMITTED:
1587        case MID_RETRY_NEEDED:
1588                rdata->result = -EAGAIN;
1589                break;
1590        default:
1591                if (rdata->result != -ENODATA)
1592                        rdata->result = -EIO;
1593        }
1594
1595        if (rdata->result)
1596                cifs_stats_fail_inc(tcon, SMB2_READ_HE);
1597
1598        queue_work(cifsiod_wq, &rdata->work);
1599        DeleteMidQEntry(mid);
1600        add_credits(server, credits_received, 0);
1601}
1602
1603/* smb2_async_readv - send an async write, and set up mid to handle result */
1604int
1605smb2_async_readv(struct cifs_readdata *rdata)
1606{
1607        int rc;
1608        struct smb2_hdr *buf;
1609        struct cifs_io_parms io_parms;
1610        struct smb_rqst rqst = { .rq_iov = &rdata->iov,
1611                                 .rq_nvec = 1 };
1612
1613        cifs_dbg(FYI, "%s: offset=%llu bytes=%u\n",
1614                 __func__, rdata->offset, rdata->bytes);
1615
1616        io_parms.tcon = tlink_tcon(rdata->cfile->tlink);
1617        io_parms.offset = rdata->offset;
1618        io_parms.length = rdata->bytes;
1619        io_parms.persistent_fid = rdata->cfile->fid.persistent_fid;
1620        io_parms.volatile_fid = rdata->cfile->fid.volatile_fid;
1621        io_parms.pid = rdata->pid;
1622        rc = smb2_new_read_req(&rdata->iov, &io_parms, 0, 0);
1623        if (rc)
1624                return rc;
1625
1626        buf = (struct smb2_hdr *)rdata->iov.iov_base;
1627        /* 4 for rfc1002 length field */
1628        rdata->iov.iov_len = get_rfc1002_length(rdata->iov.iov_base) + 4;
1629
1630        kref_get(&rdata->refcount);
1631        rc = cifs_call_async(io_parms.tcon->ses->server, &rqst,
1632                             cifs_readv_receive, smb2_readv_callback,
1633                             rdata, 0);
1634        if (rc) {
1635                kref_put(&rdata->refcount, cifs_readdata_release);
1636                cifs_stats_fail_inc(io_parms.tcon, SMB2_READ_HE);
1637        }
1638
1639        cifs_small_buf_release(buf);
1640        return rc;
1641}
1642
1643int
1644SMB2_read(const unsigned int xid, struct cifs_io_parms *io_parms,
1645          unsigned int *nbytes, char **buf, int *buf_type)
1646{
1647        int resp_buftype, rc = -EACCES;
1648        struct smb2_read_rsp *rsp = NULL;
1649        struct kvec iov[1];
1650
1651        *nbytes = 0;
1652        rc = smb2_new_read_req(iov, io_parms, 0, 0);
1653        if (rc)
1654                return rc;
1655
1656        rc = SendReceive2(xid, io_parms->tcon->ses, iov, 1,
1657                          &resp_buftype, CIFS_LOG_ERROR);
1658
1659        rsp = (struct smb2_read_rsp *)iov[0].iov_base;
1660
1661        if (rsp->hdr.Status == STATUS_END_OF_FILE) {
1662                free_rsp_buf(resp_buftype, iov[0].iov_base);
1663                return 0;
1664        }
1665
1666        if (rc) {
1667                cifs_stats_fail_inc(io_parms->tcon, SMB2_READ_HE);
1668                cifs_dbg(VFS, "Send error in read = %d\n", rc);
1669        } else {
1670                *nbytes = le32_to_cpu(rsp->DataLength);
1671                if ((*nbytes > CIFS_MAX_MSGSIZE) ||
1672                    (*nbytes > io_parms->length)) {
1673                        cifs_dbg(FYI, "bad length %d for count %d\n",
1674                                 *nbytes, io_parms->length);
1675                        rc = -EIO;
1676                        *nbytes = 0;
1677                }
1678        }
1679
1680        if (*buf) {
1681                memcpy(*buf, (char *)rsp->hdr.ProtocolId + rsp->DataOffset,
1682                       *nbytes);
1683                free_rsp_buf(resp_buftype, iov[0].iov_base);
1684        } else if (resp_buftype != CIFS_NO_BUFFER) {
1685                *buf = iov[0].iov_base;
1686                if (resp_buftype == CIFS_SMALL_BUFFER)
1687                        *buf_type = CIFS_SMALL_BUFFER;
1688                else if (resp_buftype == CIFS_LARGE_BUFFER)
1689                        *buf_type = CIFS_LARGE_BUFFER;
1690        }
1691        return rc;
1692}
1693
1694/*
1695 * Check the mid_state and signature on received buffer (if any), and queue the
1696 * workqueue completion task.
1697 */
1698static void
1699smb2_writev_callback(struct mid_q_entry *mid)
1700{
1701        struct cifs_writedata *wdata = mid->callback_data;
1702        struct cifs_tcon *tcon = tlink_tcon(wdata->cfile->tlink);
1703        unsigned int written;
1704        struct smb2_write_rsp *rsp = (struct smb2_write_rsp *)mid->resp_buf;
1705        unsigned int credits_received = 1;
1706
1707        switch (mid->mid_state) {
1708        case MID_RESPONSE_RECEIVED:
1709                credits_received = le16_to_cpu(rsp->hdr.CreditRequest);
1710                wdata->result = smb2_check_receive(mid, tcon->ses->server, 0);
1711                if (wdata->result != 0)
1712                        break;
1713
1714                written = le32_to_cpu(rsp->DataLength);
1715                /*
1716                 * Mask off high 16 bits when bytes written as returned
1717                 * by the server is greater than bytes requested by the
1718                 * client. OS/2 servers are known to set incorrect
1719                 * CountHigh values.
1720                 */
1721                if (written > wdata->bytes)
1722                        written &= 0xFFFF;
1723
1724                if (written < wdata->bytes)
1725                        wdata->result = -ENOSPC;
1726                else
1727                        wdata->bytes = written;
1728                break;
1729        case MID_REQUEST_SUBMITTED:
1730        case MID_RETRY_NEEDED:
1731                wdata->result = -EAGAIN;
1732                break;
1733        default:
1734                wdata->result = -EIO;
1735                break;
1736        }
1737
1738        if (wdata->result)
1739                cifs_stats_fail_inc(tcon, SMB2_WRITE_HE);
1740
1741        queue_work(cifsiod_wq, &wdata->work);
1742        DeleteMidQEntry(mid);
1743        add_credits(tcon->ses->server, credits_received, 0);
1744}
1745
1746/* smb2_async_writev - send an async write, and set up mid to handle result */
1747int
1748smb2_async_writev(struct cifs_writedata *wdata)
1749{
1750        int rc = -EACCES;
1751        struct smb2_write_req *req = NULL;
1752        struct cifs_tcon *tcon = tlink_tcon(wdata->cfile->tlink);
1753        struct kvec iov;
1754        struct smb_rqst rqst;
1755
1756        rc = small_smb2_init(SMB2_WRITE, tcon, (void **) &req);
1757        if (rc)
1758                goto async_writev_out;
1759
1760        req->hdr.ProcessId = cpu_to_le32(wdata->cfile->pid);
1761
1762        req->PersistentFileId = wdata->cfile->fid.persistent_fid;
1763        req->VolatileFileId = wdata->cfile->fid.volatile_fid;
1764        req->WriteChannelInfoOffset = 0;
1765        req->WriteChannelInfoLength = 0;
1766        req->Channel = 0;
1767        req->Offset = cpu_to_le64(wdata->offset);
1768        /* 4 for rfc1002 length field */
1769        req->DataOffset = cpu_to_le16(
1770                                offsetof(struct smb2_write_req, Buffer) - 4);
1771        req->RemainingBytes = 0;
1772
1773        /* 4 for rfc1002 length field and 1 for Buffer */
1774        iov.iov_len = get_rfc1002_length(req) + 4 - 1;
1775        iov.iov_base = req;
1776
1777        rqst.rq_iov = &iov;
1778        rqst.rq_nvec = 1;
1779        rqst.rq_pages = wdata->pages;
1780        rqst.rq_npages = wdata->nr_pages;
1781        rqst.rq_pagesz = wdata->pagesz;
1782        rqst.rq_tailsz = wdata->tailsz;
1783
1784        cifs_dbg(FYI, "async write at %llu %u bytes\n",
1785                 wdata->offset, wdata->bytes);
1786
1787        req->Length = cpu_to_le32(wdata->bytes);
1788
1789        inc_rfc1001_len(&req->hdr, wdata->bytes - 1 /* Buffer */);
1790
1791        kref_get(&wdata->refcount);
1792        rc = cifs_call_async(tcon->ses->server, &rqst, NULL,
1793                                smb2_writev_callback, wdata, 0);
1794
1795        if (rc) {
1796                kref_put(&wdata->refcount, cifs_writedata_release);
1797                cifs_stats_fail_inc(tcon, SMB2_WRITE_HE);
1798        }
1799
1800async_writev_out:
1801        cifs_small_buf_release(req);
1802        return rc;
1803}
1804
1805/*
1806 * SMB2_write function gets iov pointer to kvec array with n_vec as a length.
1807 * The length field from io_parms must be at least 1 and indicates a number of
1808 * elements with data to write that begins with position 1 in iov array. All
1809 * data length is specified by count.
1810 */
1811int
1812SMB2_write(const unsigned int xid, struct cifs_io_parms *io_parms,
1813           unsigned int *nbytes, struct kvec *iov, int n_vec)
1814{
1815        int rc = 0;
1816        struct smb2_write_req *req = NULL;
1817        struct smb2_write_rsp *rsp = NULL;
1818        int resp_buftype;
1819        *nbytes = 0;
1820
1821        if (n_vec < 1)
1822                return rc;
1823
1824        rc = small_smb2_init(SMB2_WRITE, io_parms->tcon, (void **) &req);
1825        if (rc)
1826                return rc;
1827
1828        if (io_parms->tcon->ses->server == NULL)
1829                return -ECONNABORTED;
1830
1831        req->hdr.ProcessId = cpu_to_le32(io_parms->pid);
1832
1833        req->PersistentFileId = io_parms->persistent_fid;
1834        req->VolatileFileId = io_parms->volatile_fid;
1835        req->WriteChannelInfoOffset = 0;
1836        req->WriteChannelInfoLength = 0;
1837        req->Channel = 0;
1838        req->Length = cpu_to_le32(io_parms->length);
1839        req->Offset = cpu_to_le64(io_parms->offset);
1840        /* 4 for rfc1002 length field */
1841        req->DataOffset = cpu_to_le16(
1842                                offsetof(struct smb2_write_req, Buffer) - 4);
1843        req->RemainingBytes = 0;
1844
1845        iov[0].iov_base = (char *)req;
1846        /* 4 for rfc1002 length field and 1 for Buffer */
1847        iov[0].iov_len = get_rfc1002_length(req) + 4 - 1;
1848
1849        /* length of entire message including data to be written */
1850        inc_rfc1001_len(req, io_parms->length - 1 /* Buffer */);
1851
1852        rc = SendReceive2(xid, io_parms->tcon->ses, iov, n_vec + 1,
1853                          &resp_buftype, 0);
1854        rsp = (struct smb2_write_rsp *)iov[0].iov_base;
1855
1856        if (rc) {
1857                cifs_stats_fail_inc(io_parms->tcon, SMB2_WRITE_HE);
1858                cifs_dbg(VFS, "Send error in write = %d\n", rc);
1859        } else
1860                *nbytes = le32_to_cpu(rsp->DataLength);
1861
1862        free_rsp_buf(resp_buftype, rsp);
1863        return rc;
1864}
1865
1866static unsigned int
1867num_entries(char *bufstart, char *end_of_buf, char **lastentry, size_t size)
1868{
1869        int len;
1870        unsigned int entrycount = 0;
1871        unsigned int next_offset = 0;
1872        FILE_DIRECTORY_INFO *entryptr;
1873
1874        if (bufstart == NULL)
1875                return 0;
1876
1877        entryptr = (FILE_DIRECTORY_INFO *)bufstart;
1878
1879        while (1) {
1880                entryptr = (FILE_DIRECTORY_INFO *)
1881                                        ((char *)entryptr + next_offset);
1882
1883                if ((char *)entryptr + size > end_of_buf) {
1884                        cifs_dbg(VFS, "malformed search entry would overflow\n");
1885                        break;
1886                }
1887
1888                len = le32_to_cpu(entryptr->FileNameLength);
1889                if ((char *)entryptr + len + size > end_of_buf) {
1890                        cifs_dbg(VFS, "directory entry name would overflow frame end of buf %p\n",
1891                                 end_of_buf);
1892                        break;
1893                }
1894
1895                *lastentry = (char *)entryptr;
1896                entrycount++;
1897
1898                next_offset = le32_to_cpu(entryptr->NextEntryOffset);
1899                if (!next_offset)
1900                        break;
1901        }
1902
1903        return entrycount;
1904}
1905
1906/*
1907 * Readdir/FindFirst
1908 */
1909int
1910SMB2_query_directory(const unsigned int xid, struct cifs_tcon *tcon,
1911                     u64 persistent_fid, u64 volatile_fid, int index,
1912                     struct cifs_search_info *srch_inf)
1913{
1914        struct smb2_query_directory_req *req;
1915        struct smb2_query_directory_rsp *rsp = NULL;
1916        struct kvec iov[2];
1917        int rc = 0;
1918        int len;
1919        int resp_buftype;
1920        unsigned char *bufptr;
1921        struct TCP_Server_Info *server;
1922        struct cifs_ses *ses = tcon->ses;
1923        __le16 asteriks = cpu_to_le16('*');
1924        char *end_of_smb;
1925        unsigned int output_size = CIFSMaxBufSize;
1926        size_t info_buf_size;
1927
1928        if (ses && (ses->server))
1929                server = ses->server;
1930        else
1931                return -EIO;
1932
1933        rc = small_smb2_init(SMB2_QUERY_DIRECTORY, tcon, (void **) &req);
1934        if (rc)
1935                return rc;
1936
1937        switch (srch_inf->info_level) {
1938        case SMB_FIND_FILE_DIRECTORY_INFO:
1939                req->FileInformationClass = FILE_DIRECTORY_INFORMATION;
1940                info_buf_size = sizeof(FILE_DIRECTORY_INFO) - 1;
1941                break;
1942        case SMB_FIND_FILE_ID_FULL_DIR_INFO:
1943                req->FileInformationClass = FILEID_FULL_DIRECTORY_INFORMATION;
1944                info_buf_size = sizeof(SEARCH_ID_FULL_DIR_INFO) - 1;
1945                break;
1946        default:
1947                cifs_dbg(VFS, "info level %u isn't supported\n",
1948                         srch_inf->info_level);
1949                rc = -EINVAL;
1950                goto qdir_exit;
1951        }
1952
1953        req->FileIndex = cpu_to_le32(index);
1954        req->PersistentFileId = persistent_fid;
1955        req->VolatileFileId = volatile_fid;
1956
1957        len = 0x2;
1958        bufptr = req->Buffer;
1959        memcpy(bufptr, &asteriks, len);
1960
1961        req->FileNameOffset =
1962                cpu_to_le16(sizeof(struct smb2_query_directory_req) - 1 - 4);
1963        req->FileNameLength = cpu_to_le16(len);
1964        /*
1965         * BB could be 30 bytes or so longer if we used SMB2 specific
1966         * buffer lengths, but this is safe and close enough.
1967         */
1968        output_size = min_t(unsigned int, output_size, server->maxBuf);
1969        output_size = min_t(unsigned int, output_size, 2 << 15);
1970        req->OutputBufferLength = cpu_to_le32(output_size);
1971
1972        iov[0].iov_base = (char *)req;
1973        /* 4 for RFC1001 length and 1 for Buffer */
1974        iov[0].iov_len = get_rfc1002_length(req) + 4 - 1;
1975
1976        iov[1].iov_base = (char *)(req->Buffer);
1977        iov[1].iov_len = len;
1978
1979        inc_rfc1001_len(req, len - 1 /* Buffer */);
1980
1981        rc = SendReceive2(xid, ses, iov, 2, &resp_buftype, 0);
1982        rsp = (struct smb2_query_directory_rsp *)iov[0].iov_base;
1983
1984        if (rc) {
1985                cifs_stats_fail_inc(tcon, SMB2_QUERY_DIRECTORY_HE);
1986                goto qdir_exit;
1987        }
1988
1989        rc = validate_buf(le16_to_cpu(rsp->OutputBufferOffset),
1990                          le32_to_cpu(rsp->OutputBufferLength), &rsp->hdr,
1991                          info_buf_size);
1992        if (rc)
1993                goto qdir_exit;
1994
1995        srch_inf->unicode = true;
1996
1997        if (srch_inf->ntwrk_buf_start) {
1998                if (srch_inf->smallBuf)
1999                        cifs_small_buf_release(srch_inf->ntwrk_buf_start);
2000                else
2001                        cifs_buf_release(srch_inf->ntwrk_buf_start);
2002        }
2003        srch_inf->ntwrk_buf_start = (char *)rsp;
2004        srch_inf->srch_entries_start = srch_inf->last_entry = 4 /* rfclen */ +
2005                (char *)&rsp->hdr + le16_to_cpu(rsp->OutputBufferOffset);
2006        /* 4 for rfc1002 length field */
2007        end_of_smb = get_rfc1002_length(rsp) + 4 + (char *)&rsp->hdr;
2008        srch_inf->entries_in_buffer =
2009                        num_entries(srch_inf->srch_entries_start, end_of_smb,
2010                                    &srch_inf->last_entry, info_buf_size);
2011        srch_inf->index_of_last_entry += srch_inf->entries_in_buffer;
2012        cifs_dbg(FYI, "num entries %d last_index %lld srch start %p srch end %p\n",
2013                 srch_inf->entries_in_buffer, srch_inf->index_of_last_entry,
2014                 srch_inf->srch_entries_start, srch_inf->last_entry);
2015        if (resp_buftype == CIFS_LARGE_BUFFER)
2016                srch_inf->smallBuf = false;
2017        else if (resp_buftype == CIFS_SMALL_BUFFER)
2018                srch_inf->smallBuf = true;
2019        else
2020                cifs_dbg(VFS, "illegal search buffer type\n");
2021
2022        if (rsp->hdr.Status == STATUS_NO_MORE_FILES)
2023                srch_inf->endOfSearch = 1;
2024        else
2025                srch_inf->endOfSearch = 0;
2026
2027        return rc;
2028
2029qdir_exit:
2030        free_rsp_buf(resp_buftype, rsp);
2031        return rc;
2032}
2033
2034static int
2035send_set_info(const unsigned int xid, struct cifs_tcon *tcon,
2036               u64 persistent_fid, u64 volatile_fid, u32 pid, int info_class,
2037               unsigned int num, void **data, unsigned int *size)
2038{
2039        struct smb2_set_info_req *req;
2040        struct smb2_set_info_rsp *rsp = NULL;
2041        struct kvec *iov;
2042        int rc = 0;
2043        int resp_buftype;
2044        unsigned int i;
2045        struct TCP_Server_Info *server;
2046        struct cifs_ses *ses = tcon->ses;
2047
2048        if (ses && (ses->server))
2049                server = ses->server;
2050        else
2051                return -EIO;
2052
2053        if (!num)
2054                return -EINVAL;
2055
2056        iov = kmalloc(sizeof(struct kvec) * num, GFP_KERNEL);
2057        if (!iov)
2058                return -ENOMEM;
2059
2060        rc = small_smb2_init(SMB2_SET_INFO, tcon, (void **) &req);
2061        if (rc) {
2062                kfree(iov);
2063                return rc;
2064        }
2065
2066        req->hdr.ProcessId = cpu_to_le32(pid);
2067
2068        req->InfoType = SMB2_O_INFO_FILE;
2069        req->FileInfoClass = info_class;
2070        req->PersistentFileId = persistent_fid;
2071        req->VolatileFileId = volatile_fid;
2072
2073        /* 4 for RFC1001 length and 1 for Buffer */
2074        req->BufferOffset =
2075                        cpu_to_le16(sizeof(struct smb2_set_info_req) - 1 - 4);
2076        req->BufferLength = cpu_to_le32(*size);
2077
2078        inc_rfc1001_len(req, *size - 1 /* Buffer */);
2079
2080        memcpy(req->Buffer, *data, *size);
2081
2082        iov[0].iov_base = (char *)req;
2083        /* 4 for RFC1001 length */
2084        iov[0].iov_len = get_rfc1002_length(req) + 4;
2085
2086        for (i = 1; i < num; i++) {
2087                inc_rfc1001_len(req, size[i]);
2088                le32_add_cpu(&req->BufferLength, size[i]);
2089                iov[i].iov_base = (char *)data[i];
2090                iov[i].iov_len = size[i];
2091        }
2092
2093        rc = SendReceive2(xid, ses, iov, num, &resp_buftype, 0);
2094        rsp = (struct smb2_set_info_rsp *)iov[0].iov_base;
2095
2096        if (rc != 0) {
2097                cifs_stats_fail_inc(tcon, SMB2_SET_INFO_HE);
2098                goto out;
2099        }
2100out:
2101        free_rsp_buf(resp_buftype, rsp);
2102        kfree(iov);
2103        return rc;
2104}
2105
2106int
2107SMB2_rename(const unsigned int xid, struct cifs_tcon *tcon,
2108            u64 persistent_fid, u64 volatile_fid, __le16 *target_file)
2109{
2110        struct smb2_file_rename_info info;
2111        void **data;
2112        unsigned int size[2];
2113        int rc;
2114        int len = (2 * UniStrnlen((wchar_t *)target_file, PATH_MAX));
2115
2116        data = kmalloc(sizeof(void *) * 2, GFP_KERNEL);
2117        if (!data)
2118                return -ENOMEM;
2119
2120        info.ReplaceIfExists = 1; /* 1 = replace existing target with new */
2121                              /* 0 = fail if target already exists */
2122        info.RootDirectory = 0;  /* MBZ for network ops (why does spec say?) */
2123        info.FileNameLength = cpu_to_le32(len);
2124
2125        data[0] = &info;
2126        size[0] = sizeof(struct smb2_file_rename_info);
2127
2128        data[1] = target_file;
2129        size[1] = len + 2 /* null */;
2130
2131        rc = send_set_info(xid, tcon, persistent_fid, volatile_fid,
2132                           current->tgid, FILE_RENAME_INFORMATION, 2, data,
2133                           size);
2134        kfree(data);
2135        return rc;
2136}
2137
2138int
2139SMB2_set_hardlink(const unsigned int xid, struct cifs_tcon *tcon,
2140                  u64 persistent_fid, u64 volatile_fid, __le16 *target_file)
2141{
2142        struct smb2_file_link_info info;
2143        void **data;
2144        unsigned int size[2];
2145        int rc;
2146        int len = (2 * UniStrnlen((wchar_t *)target_file, PATH_MAX));
2147
2148        data = kmalloc(sizeof(void *) * 2, GFP_KERNEL);
2149        if (!data)
2150                return -ENOMEM;
2151
2152        info.ReplaceIfExists = 0; /* 1 = replace existing link with new */
2153                              /* 0 = fail if link already exists */
2154        info.RootDirectory = 0;  /* MBZ for network ops (why does spec say?) */
2155        info.FileNameLength = cpu_to_le32(len);
2156
2157        data[0] = &info;
2158        size[0] = sizeof(struct smb2_file_link_info);
2159
2160        data[1] = target_file;
2161        size[1] = len + 2 /* null */;
2162
2163        rc = send_set_info(xid, tcon, persistent_fid, volatile_fid,
2164                           current->tgid, FILE_LINK_INFORMATION, 2, data, size);
2165        kfree(data);
2166        return rc;
2167}
2168
2169int
2170SMB2_set_eof(const unsigned int xid, struct cifs_tcon *tcon, u64 persistent_fid,
2171             u64 volatile_fid, u32 pid, __le64 *eof)
2172{
2173        struct smb2_file_eof_info info;
2174        void *data;
2175        unsigned int size;
2176
2177        info.EndOfFile = *eof;
2178
2179        data = &info;
2180        size = sizeof(struct smb2_file_eof_info);
2181
2182        return send_set_info(xid, tcon, persistent_fid, volatile_fid, pid,
2183                             FILE_END_OF_FILE_INFORMATION, 1, &data, &size);
2184}
2185
2186int
2187SMB2_set_info(const unsigned int xid, struct cifs_tcon *tcon,
2188              u64 persistent_fid, u64 volatile_fid, FILE_BASIC_INFO *buf)
2189{
2190        unsigned int size;
2191        size = sizeof(FILE_BASIC_INFO);
2192        return send_set_info(xid, tcon, persistent_fid, volatile_fid,
2193                             current->tgid, FILE_BASIC_INFORMATION, 1,
2194                             (void **)&buf, &size);
2195}
2196
2197int
2198SMB2_oplock_break(const unsigned int xid, struct cifs_tcon *tcon,
2199                  const u64 persistent_fid, const u64 volatile_fid,
2200                  __u8 oplock_level)
2201{
2202        int rc;
2203        struct smb2_oplock_break *req = NULL;
2204
2205        cifs_dbg(FYI, "SMB2_oplock_break\n");
2206        rc = small_smb2_init(SMB2_OPLOCK_BREAK, tcon, (void **) &req);
2207
2208        if (rc)
2209                return rc;
2210
2211        req->VolatileFid = volatile_fid;
2212        req->PersistentFid = persistent_fid;
2213        req->OplockLevel = oplock_level;
2214        req->hdr.CreditRequest = cpu_to_le16(1);
2215
2216        rc = SendReceiveNoRsp(xid, tcon->ses, (char *) req, CIFS_OBREAK_OP);
2217        /* SMB2 buffer freed by function above */
2218
2219        if (rc) {
2220                cifs_stats_fail_inc(tcon, SMB2_OPLOCK_BREAK_HE);
2221                cifs_dbg(FYI, "Send error in Oplock Break = %d\n", rc);
2222        }
2223
2224        return rc;
2225}
2226
2227static void
2228copy_fs_info_to_kstatfs(struct smb2_fs_full_size_info *pfs_inf,
2229                        struct kstatfs *kst)
2230{
2231        kst->f_bsize = le32_to_cpu(pfs_inf->BytesPerSector) *
2232                          le32_to_cpu(pfs_inf->SectorsPerAllocationUnit);
2233        kst->f_blocks = le64_to_cpu(pfs_inf->TotalAllocationUnits);
2234        kst->f_bfree  = le64_to_cpu(pfs_inf->ActualAvailableAllocationUnits);
2235        kst->f_bavail = le64_to_cpu(pfs_inf->CallerAvailableAllocationUnits);
2236        return;
2237}
2238
2239static int
2240build_qfs_info_req(struct kvec *iov, struct cifs_tcon *tcon, int level,
2241                   int outbuf_len, u64 persistent_fid, u64 volatile_fid)
2242{
2243        int rc;
2244        struct smb2_query_info_req *req;
2245
2246        cifs_dbg(FYI, "Query FSInfo level %d\n", level);
2247
2248        if ((tcon->ses == NULL) || (tcon->ses->server == NULL))
2249                return -EIO;
2250
2251        rc = small_smb2_init(SMB2_QUERY_INFO, tcon, (void **) &req);
2252        if (rc)
2253                return rc;
2254
2255        req->InfoType = SMB2_O_INFO_FILESYSTEM;
2256        req->FileInfoClass = level;
2257        req->PersistentFileId = persistent_fid;
2258        req->VolatileFileId = volatile_fid;
2259        /* 4 for rfc1002 length field and 1 for pad */
2260        req->InputBufferOffset =
2261                        cpu_to_le16(sizeof(struct smb2_query_info_req) - 1 - 4);
2262        req->OutputBufferLength = cpu_to_le32(
2263                outbuf_len + sizeof(struct smb2_query_info_rsp) - 1 - 4);
2264
2265        iov->iov_base = (char *)req;
2266        /* 4 for rfc1002 length field */
2267        iov->iov_len = get_rfc1002_length(req) + 4;
2268        return 0;
2269}
2270
2271int
2272SMB2_QFS_info(const unsigned int xid, struct cifs_tcon *tcon,
2273              u64 persistent_fid, u64 volatile_fid, struct kstatfs *fsdata)
2274{
2275        struct smb2_query_info_rsp *rsp = NULL;
2276        struct kvec iov;
2277        int rc = 0;
2278        int resp_buftype;
2279        struct cifs_ses *ses = tcon->ses;
2280        struct smb2_fs_full_size_info *info = NULL;
2281
2282        rc = build_qfs_info_req(&iov, tcon, FS_FULL_SIZE_INFORMATION,
2283                                sizeof(struct smb2_fs_full_size_info),
2284                                persistent_fid, volatile_fid);
2285        if (rc)
2286                return rc;
2287
2288        rc = SendReceive2(xid, ses, &iov, 1, &resp_buftype, 0);
2289        if (rc) {
2290                cifs_stats_fail_inc(tcon, SMB2_QUERY_INFO_HE);
2291                goto qinf_exit;
2292        }
2293        rsp = (struct smb2_query_info_rsp *)iov.iov_base;
2294
2295        info = (struct smb2_fs_full_size_info *)(4 /* RFC1001 len */ +
2296                le16_to_cpu(rsp->OutputBufferOffset) + (char *)&rsp->hdr);
2297        rc = validate_buf(le16_to_cpu(rsp->OutputBufferOffset),
2298                          le32_to_cpu(rsp->OutputBufferLength), &rsp->hdr,
2299                          sizeof(struct smb2_fs_full_size_info));
2300        if (!rc)
2301                copy_fs_info_to_kstatfs(info, fsdata);
2302
2303qinf_exit:
2304        free_rsp_buf(resp_buftype, iov.iov_base);
2305        return rc;
2306}
2307
2308int
2309smb2_lockv(const unsigned int xid, struct cifs_tcon *tcon,
2310           const __u64 persist_fid, const __u64 volatile_fid, const __u32 pid,
2311           const __u32 num_lock, struct smb2_lock_element *buf)
2312{
2313        int rc = 0;
2314        struct smb2_lock_req *req = NULL;
2315        struct kvec iov[2];
2316        int resp_buf_type;
2317        unsigned int count;
2318
2319        cifs_dbg(FYI, "smb2_lockv num lock %d\n", num_lock);
2320
2321        rc = small_smb2_init(SMB2_LOCK, tcon, (void **) &req);
2322        if (rc)
2323                return rc;
2324
2325        req->hdr.ProcessId = cpu_to_le32(pid);
2326        req->LockCount = cpu_to_le16(num_lock);
2327
2328        req->PersistentFileId = persist_fid;
2329        req->VolatileFileId = volatile_fid;
2330
2331        count = num_lock * sizeof(struct smb2_lock_element);
2332        inc_rfc1001_len(req, count - sizeof(struct smb2_lock_element));
2333
2334        iov[0].iov_base = (char *)req;
2335        /* 4 for rfc1002 length field and count for all locks */
2336        iov[0].iov_len = get_rfc1002_length(req) + 4 - count;
2337        iov[1].iov_base = (char *)buf;
2338        iov[1].iov_len = count;
2339
2340        cifs_stats_inc(&tcon->stats.cifs_stats.num_locks);
2341        rc = SendReceive2(xid, tcon->ses, iov, 2, &resp_buf_type, CIFS_NO_RESP);
2342        if (rc) {
2343                cifs_dbg(FYI, "Send error in smb2_lockv = %d\n", rc);
2344                cifs_stats_fail_inc(tcon, SMB2_LOCK_HE);
2345        }
2346
2347        return rc;
2348}
2349
2350int
2351SMB2_lock(const unsigned int xid, struct cifs_tcon *tcon,
2352          const __u64 persist_fid, const __u64 volatile_fid, const __u32 pid,
2353          const __u64 length, const __u64 offset, const __u32 lock_flags,
2354          const bool wait)
2355{
2356        struct smb2_lock_element lock;
2357
2358        lock.Offset = cpu_to_le64(offset);
2359        lock.Length = cpu_to_le64(length);
2360        lock.Flags = cpu_to_le32(lock_flags);
2361        if (!wait && lock_flags != SMB2_LOCKFLAG_UNLOCK)
2362                lock.Flags |= cpu_to_le32(SMB2_LOCKFLAG_FAIL_IMMEDIATELY);
2363
2364        return smb2_lockv(xid, tcon, persist_fid, volatile_fid, pid, 1, &lock);
2365}
2366
2367int
2368SMB2_lease_break(const unsigned int xid, struct cifs_tcon *tcon,
2369                 __u8 *lease_key, const __le32 lease_state)
2370{
2371        int rc;
2372        struct smb2_lease_ack *req = NULL;
2373
2374        cifs_dbg(FYI, "SMB2_lease_break\n");
2375        rc = small_smb2_init(SMB2_OPLOCK_BREAK, tcon, (void **) &req);
2376
2377        if (rc)
2378                return rc;
2379
2380        req->hdr.CreditRequest = cpu_to_le16(1);
2381        req->StructureSize = cpu_to_le16(36);
2382        inc_rfc1001_len(req, 12);
2383
2384        memcpy(req->LeaseKey, lease_key, 16);
2385        req->LeaseState = lease_state;
2386
2387        rc = SendReceiveNoRsp(xid, tcon->ses, (char *) req, CIFS_OBREAK_OP);
2388        /* SMB2 buffer freed by function above */
2389
2390        if (rc) {
2391                cifs_stats_fail_inc(tcon, SMB2_OPLOCK_BREAK_HE);
2392                cifs_dbg(FYI, "Send error in Lease Break = %d\n", rc);
2393        }
2394
2395        return rc;
2396}
2397
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.