linux/fs/cifs/cifssmb.c
<<
>>
Prefs
   1// SPDX-License-Identifier: LGPL-2.1
   2/*
   3 *
   4 *   Copyright (C) International Business Machines  Corp., 2002,2010
   5 *   Author(s): Steve French (sfrench@us.ibm.com)
   6 *
   7 *   Contains the routines for constructing the SMB PDUs themselves
   8 *
   9 */
  10
  11 /* SMB/CIFS PDU handling routines here - except for leftovers in connect.c   */
  12 /* These are mostly routines that operate on a pathname, or on a tree id     */
  13 /* (mounted volume), but there are eight handle based routines which must be */
  14 /* treated slightly differently for reconnection purposes since we never     */
  15 /* want to reuse a stale file handle and only the caller knows the file info */
  16
  17#include <linux/fs.h>
  18#include <linux/kernel.h>
  19#include <linux/vfs.h>
  20#include <linux/slab.h>
  21#include <linux/posix_acl_xattr.h>
  22#include <linux/pagemap.h>
  23#include <linux/swap.h>
  24#include <linux/task_io_accounting_ops.h>
  25#include <linux/uaccess.h>
  26#include "cifspdu.h"
  27#include "cifsglob.h"
  28#include "cifsacl.h"
  29#include "cifsproto.h"
  30#include "cifs_unicode.h"
  31#include "cifs_debug.h"
  32#include "smb2proto.h"
  33#include "fscache.h"
  34#include "smbdirect.h"
  35#ifdef CONFIG_CIFS_DFS_UPCALL
  36#include "dfs_cache.h"
  37#endif
  38
  39#ifdef CONFIG_CIFS_POSIX
  40static struct {
  41        int index;
  42        char *name;
  43} protocols[] = {
  44        {CIFS_PROT, "\2NT LM 0.12"},
  45        {POSIX_PROT, "\2POSIX 2"},
  46        {BAD_PROT, "\2"}
  47};
  48#else
  49static struct {
  50        int index;
  51        char *name;
  52} protocols[] = {
  53        {CIFS_PROT, "\2NT LM 0.12"},
  54        {BAD_PROT, "\2"}
  55};
  56#endif
  57
  58/* define the number of elements in the cifs dialect array */
  59#ifdef CONFIG_CIFS_POSIX
  60#define CIFS_NUM_PROT 2
  61#else /* not posix */
  62#define CIFS_NUM_PROT 1
  63#endif /* CIFS_POSIX */
  64
  65/*
  66 * Mark as invalid, all open files on tree connections since they
  67 * were closed when session to server was lost.
  68 */
  69void
  70cifs_mark_open_files_invalid(struct cifs_tcon *tcon)
  71{
  72        struct cifsFileInfo *open_file = NULL;
  73        struct list_head *tmp;
  74        struct list_head *tmp1;
  75
  76        /* only send once per connect */
  77        spin_lock(&cifs_tcp_ses_lock);
  78        if ((tcon->ses->ses_status != SES_GOOD) || (tcon->status != TID_NEED_RECON)) {
  79                spin_unlock(&cifs_tcp_ses_lock);
  80                return;
  81        }
  82        tcon->status = TID_IN_FILES_INVALIDATE;
  83        spin_unlock(&cifs_tcp_ses_lock);
  84
  85        /* list all files open on tree connection and mark them invalid */
  86        spin_lock(&tcon->open_file_lock);
  87        list_for_each_safe(tmp, tmp1, &tcon->openFileList) {
  88                open_file = list_entry(tmp, struct cifsFileInfo, tlist);
  89                open_file->invalidHandle = true;
  90                open_file->oplock_break_cancelled = true;
  91        }
  92        spin_unlock(&tcon->open_file_lock);
  93
  94        mutex_lock(&tcon->crfid.fid_mutex);
  95        tcon->crfid.is_valid = false;
  96        /* cached handle is not valid, so SMB2_CLOSE won't be sent below */
  97        close_cached_dir_lease_locked(&tcon->crfid);
  98        memset(tcon->crfid.fid, 0, sizeof(struct cifs_fid));
  99        mutex_unlock(&tcon->crfid.fid_mutex);
 100
 101        spin_lock(&cifs_tcp_ses_lock);
 102        if (tcon->status == TID_IN_FILES_INVALIDATE)
 103                tcon->status = TID_NEED_TCON;
 104        spin_unlock(&cifs_tcp_ses_lock);
 105
 106        /*
 107         * BB Add call to invalidate_inodes(sb) for all superblocks mounted
 108         * to this tcon.
 109         */
 110}
 111
 112/* reconnect the socket, tcon, and smb session if needed */
 113static int
 114cifs_reconnect_tcon(struct cifs_tcon *tcon, int smb_command)
 115{
 116        int rc;
 117        struct cifs_ses *ses;
 118        struct TCP_Server_Info *server;
 119        struct nls_table *nls_codepage;
 120        int retries;
 121
 122        /*
 123         * SMBs NegProt, SessSetup, uLogoff do not have tcon yet so check for
 124         * tcp and smb session status done differently for those three - in the
 125         * calling routine
 126         */
 127        if (!tcon)
 128                return 0;
 129
 130        ses = tcon->ses;
 131        server = ses->server;
 132
 133        /*
 134         * only tree disconnect, open, and write, (and ulogoff which does not
 135         * have tcon) are allowed as we start force umount
 136         */
 137        spin_lock(&cifs_tcp_ses_lock);
 138        if (tcon->status == TID_EXITING) {
 139                if (smb_command != SMB_COM_WRITE_ANDX &&
 140                    smb_command != SMB_COM_OPEN_ANDX &&
 141                    smb_command != SMB_COM_TREE_DISCONNECT) {
 142                        spin_unlock(&cifs_tcp_ses_lock);
 143                        cifs_dbg(FYI, "can not send cmd %d while umounting\n",
 144                                 smb_command);
 145                        return -ENODEV;
 146                }
 147        }
 148        spin_unlock(&cifs_tcp_ses_lock);
 149
 150        retries = server->nr_targets;
 151
 152        /*
 153         * Give demultiplex thread up to 10 seconds to each target available for
 154         * reconnect -- should be greater than cifs socket timeout which is 7
 155         * seconds.
 156         */
 157        while (server->tcpStatus == CifsNeedReconnect) {
 158                rc = wait_event_interruptible_timeout(server->response_q,
 159                                                      (server->tcpStatus != CifsNeedReconnect),
 160                                                      10 * HZ);
 161                if (rc < 0) {
 162                        cifs_dbg(FYI, "%s: aborting reconnect due to a received signal by the process\n",
 163                                 __func__);
 164                        return -ERESTARTSYS;
 165                }
 166
 167                /* are we still trying to reconnect? */
 168                spin_lock(&cifs_tcp_ses_lock);
 169                if (server->tcpStatus != CifsNeedReconnect) {
 170                        spin_unlock(&cifs_tcp_ses_lock);
 171                        break;
 172                }
 173                spin_unlock(&cifs_tcp_ses_lock);
 174
 175                if (retries && --retries)
 176                        continue;
 177
 178                /*
 179                 * on "soft" mounts we wait once. Hard mounts keep
 180                 * retrying until process is killed or server comes
 181                 * back on-line
 182                 */
 183                if (!tcon->retry) {
 184                        cifs_dbg(FYI, "gave up waiting on reconnect in smb_init\n");
 185                        return -EHOSTDOWN;
 186                }
 187                retries = server->nr_targets;
 188        }
 189
 190        spin_lock(&ses->chan_lock);
 191        if (!cifs_chan_needs_reconnect(ses, server) && !tcon->need_reconnect) {
 192                spin_unlock(&ses->chan_lock);
 193                return 0;
 194        }
 195        spin_unlock(&ses->chan_lock);
 196
 197        nls_codepage = load_nls_default();
 198
 199        /*
 200         * Recheck after acquire mutex. If another thread is negotiating
 201         * and the server never sends an answer the socket will be closed
 202         * and tcpStatus set to reconnect.
 203         */
 204        spin_lock(&cifs_tcp_ses_lock);
 205        if (server->tcpStatus == CifsNeedReconnect) {
 206                spin_unlock(&cifs_tcp_ses_lock);
 207                rc = -EHOSTDOWN;
 208                goto out;
 209        }
 210        spin_unlock(&cifs_tcp_ses_lock);
 211
 212        /*
 213         * need to prevent multiple threads trying to simultaneously
 214         * reconnect the same SMB session
 215         */
 216        spin_lock(&ses->chan_lock);
 217        if (!cifs_chan_needs_reconnect(ses, server)) {
 218                spin_unlock(&ses->chan_lock);
 219
 220                /* this means that we only need to tree connect */
 221                if (tcon->need_reconnect)
 222                        goto skip_sess_setup;
 223
 224                rc = -EHOSTDOWN;
 225                goto out;
 226        }
 227        spin_unlock(&ses->chan_lock);
 228
 229        mutex_lock(&ses->session_mutex);
 230        rc = cifs_negotiate_protocol(0, ses, server);
 231        if (!rc)
 232                rc = cifs_setup_session(0, ses, server, nls_codepage);
 233
 234        /* do we need to reconnect tcon? */
 235        if (rc || !tcon->need_reconnect) {
 236                mutex_unlock(&ses->session_mutex);
 237                goto out;
 238        }
 239
 240skip_sess_setup:
 241        cifs_mark_open_files_invalid(tcon);
 242        rc = cifs_tree_connect(0, tcon, nls_codepage);
 243        mutex_unlock(&ses->session_mutex);
 244        cifs_dbg(FYI, "reconnect tcon rc = %d\n", rc);
 245
 246        if (rc) {
 247                pr_warn_once("reconnect tcon failed rc = %d\n", rc);
 248                goto out;
 249        }
 250
 251        atomic_inc(&tconInfoReconnectCount);
 252
 253        /* tell server Unix caps we support */
 254        if (cap_unix(ses))
 255                reset_cifs_unix_caps(0, tcon, NULL, NULL);
 256
 257        /*
 258         * Removed call to reopen open files here. It is safer (and faster) to
 259         * reopen files one at a time as needed in read and write.
 260         *
 261         * FIXME: what about file locks? don't we need to reclaim them ASAP?
 262         */
 263
 264out:
 265        /*
 266         * Check if handle based operation so we know whether we can continue
 267         * or not without returning to caller to reset file handle
 268         */
 269        switch (smb_command) {
 270        case SMB_COM_READ_ANDX:
 271        case SMB_COM_WRITE_ANDX:
 272        case SMB_COM_CLOSE:
 273        case SMB_COM_FIND_CLOSE2:
 274        case SMB_COM_LOCKING_ANDX:
 275                rc = -EAGAIN;
 276        }
 277
 278        unload_nls(nls_codepage);
 279        return rc;
 280}
 281
 282/* Allocate and return pointer to an SMB request buffer, and set basic
 283   SMB information in the SMB header.  If the return code is zero, this
 284   function must have filled in request_buf pointer */
 285static int
 286small_smb_init(int smb_command, int wct, struct cifs_tcon *tcon,
 287                void **request_buf)
 288{
 289        int rc;
 290
 291        rc = cifs_reconnect_tcon(tcon, smb_command);
 292        if (rc)
 293                return rc;
 294
 295        *request_buf = cifs_small_buf_get();
 296        if (*request_buf == NULL) {
 297                /* BB should we add a retry in here if not a writepage? */
 298                return -ENOMEM;
 299        }
 300
 301        header_assemble((struct smb_hdr *) *request_buf, smb_command,
 302                        tcon, wct);
 303
 304        if (tcon != NULL)
 305                cifs_stats_inc(&tcon->num_smbs_sent);
 306
 307        return 0;
 308}
 309
 310int
 311small_smb_init_no_tc(const int smb_command, const int wct,
 312                     struct cifs_ses *ses, void **request_buf)
 313{
 314        int rc;
 315        struct smb_hdr *buffer;
 316
 317        rc = small_smb_init(smb_command, wct, NULL, request_buf);
 318        if (rc)
 319                return rc;
 320
 321        buffer = (struct smb_hdr *)*request_buf;
 322        buffer->Mid = get_next_mid(ses->server);
 323        if (ses->capabilities & CAP_UNICODE)
 324                buffer->Flags2 |= SMBFLG2_UNICODE;
 325        if (ses->capabilities & CAP_STATUS32)
 326                buffer->Flags2 |= SMBFLG2_ERR_STATUS;
 327
 328        /* uid, tid can stay at zero as set in header assemble */
 329
 330        /* BB add support for turning on the signing when
 331        this function is used after 1st of session setup requests */
 332
 333        return rc;
 334}
 335
 336/* If the return code is zero, this function must fill in request_buf pointer */
 337static int
 338__smb_init(int smb_command, int wct, struct cifs_tcon *tcon,
 339                        void **request_buf, void **response_buf)
 340{
 341        *request_buf = cifs_buf_get();
 342        if (*request_buf == NULL) {
 343                /* BB should we add a retry in here if not a writepage? */
 344                return -ENOMEM;
 345        }
 346    /* Although the original thought was we needed the response buf for  */
 347    /* potential retries of smb operations it turns out we can determine */
 348    /* from the mid flags when the request buffer can be resent without  */
 349    /* having to use a second distinct buffer for the response */
 350        if (response_buf)
 351                *response_buf = *request_buf;
 352
 353        header_assemble((struct smb_hdr *) *request_buf, smb_command, tcon,
 354                        wct);
 355
 356        if (tcon != NULL)
 357                cifs_stats_inc(&tcon->num_smbs_sent);
 358
 359        return 0;
 360}
 361
 362/* If the return code is zero, this function must fill in request_buf pointer */
 363static int
 364smb_init(int smb_command, int wct, struct cifs_tcon *tcon,
 365         void **request_buf, void **response_buf)
 366{
 367        int rc;
 368
 369        rc = cifs_reconnect_tcon(tcon, smb_command);
 370        if (rc)
 371                return rc;
 372
 373        return __smb_init(smb_command, wct, tcon, request_buf, response_buf);
 374}
 375
 376static int
 377smb_init_no_reconnect(int smb_command, int wct, struct cifs_tcon *tcon,
 378                        void **request_buf, void **response_buf)
 379{
 380        spin_lock(&tcon->ses->chan_lock);
 381        if (cifs_chan_needs_reconnect(tcon->ses, tcon->ses->server) ||
 382            tcon->need_reconnect) {
 383                spin_unlock(&tcon->ses->chan_lock);
 384                return -EHOSTDOWN;
 385        }
 386        spin_unlock(&tcon->ses->chan_lock);
 387
 388        return __smb_init(smb_command, wct, tcon, request_buf, response_buf);
 389}
 390
 391static int validate_t2(struct smb_t2_rsp *pSMB)
 392{
 393        unsigned int total_size;
 394
 395        /* check for plausible wct */
 396        if (pSMB->hdr.WordCount < 10)
 397                goto vt2_err;
 398
 399        /* check for parm and data offset going beyond end of smb */
 400        if (get_unaligned_le16(&pSMB->t2_rsp.ParameterOffset) > 1024 ||
 401            get_unaligned_le16(&pSMB->t2_rsp.DataOffset) > 1024)
 402                goto vt2_err;
 403
 404        total_size = get_unaligned_le16(&pSMB->t2_rsp.ParameterCount);
 405        if (total_size >= 512)
 406                goto vt2_err;
 407
 408        /* check that bcc is at least as big as parms + data, and that it is
 409         * less than negotiated smb buffer
 410         */
 411        total_size += get_unaligned_le16(&pSMB->t2_rsp.DataCount);
 412        if (total_size > get_bcc(&pSMB->hdr) ||
 413            total_size >= CIFSMaxBufSize + MAX_CIFS_HDR_SIZE)
 414                goto vt2_err;
 415
 416        return 0;
 417vt2_err:
 418        cifs_dump_mem("Invalid transact2 SMB: ", (char *)pSMB,
 419                sizeof(struct smb_t2_rsp) + 16);
 420        return -EINVAL;
 421}
 422
 423static int
 424decode_ext_sec_blob(struct cifs_ses *ses, NEGOTIATE_RSP *pSMBr)
 425{
 426        int     rc = 0;
 427        u16     count;
 428        char    *guid = pSMBr->u.extended_response.GUID;
 429        struct TCP_Server_Info *server = ses->server;
 430
 431        count = get_bcc(&pSMBr->hdr);
 432        if (count < SMB1_CLIENT_GUID_SIZE)
 433                return -EIO;
 434
 435        spin_lock(&cifs_tcp_ses_lock);
 436        if (server->srv_count > 1) {
 437                spin_unlock(&cifs_tcp_ses_lock);
 438                if (memcmp(server->server_GUID, guid, SMB1_CLIENT_GUID_SIZE) != 0) {
 439                        cifs_dbg(FYI, "server UID changed\n");
 440                        memcpy(server->server_GUID, guid, SMB1_CLIENT_GUID_SIZE);
 441                }
 442        } else {
 443                spin_unlock(&cifs_tcp_ses_lock);
 444                memcpy(server->server_GUID, guid, SMB1_CLIENT_GUID_SIZE);
 445        }
 446
 447        if (count == SMB1_CLIENT_GUID_SIZE) {
 448                server->sec_ntlmssp = true;
 449        } else {
 450                count -= SMB1_CLIENT_GUID_SIZE;
 451                rc = decode_negTokenInit(
 452                        pSMBr->u.extended_response.SecurityBlob, count, server);
 453                if (rc != 1)
 454                        return -EINVAL;
 455        }
 456
 457        return 0;
 458}
 459
 460int
 461cifs_enable_signing(struct TCP_Server_Info *server, bool mnt_sign_required)
 462{
 463        bool srv_sign_required = server->sec_mode & server->vals->signing_required;
 464        bool srv_sign_enabled = server->sec_mode & server->vals->signing_enabled;
 465        bool mnt_sign_enabled = global_secflags & CIFSSEC_MAY_SIGN;
 466
 467        /*
 468         * Is signing required by mnt options? If not then check
 469         * global_secflags to see if it is there.
 470         */
 471        if (!mnt_sign_required)
 472                mnt_sign_required = ((global_secflags & CIFSSEC_MUST_SIGN) ==
 473                                                CIFSSEC_MUST_SIGN);
 474
 475        /*
 476         * If signing is required then it's automatically enabled too,
 477         * otherwise, check to see if the secflags allow it.
 478         */
 479        mnt_sign_enabled = mnt_sign_required ? mnt_sign_required :
 480                                (global_secflags & CIFSSEC_MAY_SIGN);
 481
 482        /* If server requires signing, does client allow it? */
 483        if (srv_sign_required) {
 484                if (!mnt_sign_enabled) {
 485                        cifs_dbg(VFS, "Server requires signing, but it's disabled in SecurityFlags!\n");
 486                        return -ENOTSUPP;
 487                }
 488                server->sign = true;
 489        }
 490
 491        /* If client requires signing, does server allow it? */
 492        if (mnt_sign_required) {
 493                if (!srv_sign_enabled) {
 494                        cifs_dbg(VFS, "Server does not support signing!\n");
 495                        return -ENOTSUPP;
 496                }
 497                server->sign = true;
 498        }
 499
 500        if (cifs_rdma_enabled(server) && server->sign)
 501                cifs_dbg(VFS, "Signing is enabled, and RDMA read/write will be disabled\n");
 502
 503        return 0;
 504}
 505
 506static bool
 507should_set_ext_sec_flag(enum securityEnum sectype)
 508{
 509        switch (sectype) {
 510        case RawNTLMSSP:
 511        case Kerberos:
 512                return true;
 513        case Unspecified:
 514                if (global_secflags &
 515                    (CIFSSEC_MAY_KRB5 | CIFSSEC_MAY_NTLMSSP))
 516                        return true;
 517                fallthrough;
 518        default:
 519                return false;
 520        }
 521}
 522
 523int
 524CIFSSMBNegotiate(const unsigned int xid,
 525                 struct cifs_ses *ses,
 526                 struct TCP_Server_Info *server)
 527{
 528        NEGOTIATE_REQ *pSMB;
 529        NEGOTIATE_RSP *pSMBr;
 530        int rc = 0;
 531        int bytes_returned;
 532        int i;
 533        u16 count;
 534
 535        if (!server) {
 536                WARN(1, "%s: server is NULL!\n", __func__);
 537                return -EIO;
 538        }
 539
 540        rc = smb_init(SMB_COM_NEGOTIATE, 0, NULL /* no tcon yet */ ,
 541                      (void **) &pSMB, (void **) &pSMBr);
 542        if (rc)
 543                return rc;
 544
 545        pSMB->hdr.Mid = get_next_mid(server);
 546        pSMB->hdr.Flags2 |= (SMBFLG2_UNICODE | SMBFLG2_ERR_STATUS);
 547
 548        if (should_set_ext_sec_flag(ses->sectype)) {
 549                cifs_dbg(FYI, "Requesting extended security\n");
 550                pSMB->hdr.Flags2 |= SMBFLG2_EXT_SEC;
 551        }
 552
 553        count = 0;
 554        /*
 555         * We know that all the name entries in the protocols array
 556         * are short (< 16 bytes anyway) and are NUL terminated.
 557         */
 558        for (i = 0; i < CIFS_NUM_PROT; i++) {
 559                size_t len = strlen(protocols[i].name) + 1;
 560
 561                memcpy(pSMB->DialectsArray+count, protocols[i].name, len);
 562                count += len;
 563        }
 564        inc_rfc1001_len(pSMB, count);
 565        pSMB->ByteCount = cpu_to_le16(count);
 566
 567        rc = SendReceive(xid, ses, (struct smb_hdr *) pSMB,
 568                         (struct smb_hdr *) pSMBr, &bytes_returned, 0);
 569        if (rc != 0)
 570                goto neg_err_exit;
 571
 572        server->dialect = le16_to_cpu(pSMBr->DialectIndex);
 573        cifs_dbg(FYI, "Dialect: %d\n", server->dialect);
 574        /* Check wct = 1 error case */
 575        if ((pSMBr->hdr.WordCount <= 13) || (server->dialect == BAD_PROT)) {
 576                /* core returns wct = 1, but we do not ask for core - otherwise
 577                small wct just comes when dialect index is -1 indicating we
 578                could not negotiate a common dialect */
 579                rc = -EOPNOTSUPP;
 580                goto neg_err_exit;
 581        } else if (pSMBr->hdr.WordCount != 17) {
 582                /* unknown wct */
 583                rc = -EOPNOTSUPP;
 584                goto neg_err_exit;
 585        }
 586        /* else wct == 17, NTLM or better */
 587
 588        server->sec_mode = pSMBr->SecurityMode;
 589        if ((server->sec_mode & SECMODE_USER) == 0)
 590                cifs_dbg(FYI, "share mode security\n");
 591
 592        /* one byte, so no need to convert this or EncryptionKeyLen from
 593           little endian */
 594        server->maxReq = min_t(unsigned int, le16_to_cpu(pSMBr->MaxMpxCount),
 595                               cifs_max_pending);
 596        set_credits(server, server->maxReq);
 597        /* probably no need to store and check maxvcs */
 598        server->maxBuf = le32_to_cpu(pSMBr->MaxBufferSize);
 599        /* set up max_read for readahead check */
 600        server->max_read = server->maxBuf;
 601        server->max_rw = le32_to_cpu(pSMBr->MaxRawSize);
 602        cifs_dbg(NOISY, "Max buf = %d\n", ses->server->maxBuf);
 603        server->capabilities = le32_to_cpu(pSMBr->Capabilities);
 604        server->timeAdj = (int)(__s16)le16_to_cpu(pSMBr->ServerTimeZone);
 605        server->timeAdj *= 60;
 606
 607        if (pSMBr->EncryptionKeyLength == CIFS_CRYPTO_KEY_SIZE) {
 608                server->negflavor = CIFS_NEGFLAVOR_UNENCAP;
 609                memcpy(ses->server->cryptkey, pSMBr->u.EncryptionKey,
 610                       CIFS_CRYPTO_KEY_SIZE);
 611        } else if (pSMBr->hdr.Flags2 & SMBFLG2_EXT_SEC ||
 612                        server->capabilities & CAP_EXTENDED_SECURITY) {
 613                server->negflavor = CIFS_NEGFLAVOR_EXTENDED;
 614                rc = decode_ext_sec_blob(ses, pSMBr);
 615        } else if (server->sec_mode & SECMODE_PW_ENCRYPT) {
 616                rc = -EIO; /* no crypt key only if plain text pwd */
 617        } else {
 618                server->negflavor = CIFS_NEGFLAVOR_UNENCAP;
 619                server->capabilities &= ~CAP_EXTENDED_SECURITY;
 620        }
 621
 622        if (!rc)
 623                rc = cifs_enable_signing(server, ses->sign);
 624neg_err_exit:
 625        cifs_buf_release(pSMB);
 626
 627        cifs_dbg(FYI, "negprot rc %d\n", rc);
 628        return rc;
 629}
 630
 631int
 632CIFSSMBTDis(const unsigned int xid, struct cifs_tcon *tcon)
 633{
 634        struct smb_hdr *smb_buffer;
 635        int rc = 0;
 636
 637        cifs_dbg(FYI, "In tree disconnect\n");
 638
 639        /* BB: do we need to check this? These should never be NULL. */
 640        if ((tcon->ses == NULL) || (tcon->ses->server == NULL))
 641                return -EIO;
 642
 643        /*
 644         * No need to return error on this operation if tid invalidated and
 645         * closed on server already e.g. due to tcp session crashing. Also,
 646         * the tcon is no longer on the list, so no need to take lock before
 647         * checking this.
 648         */
 649        spin_lock(&tcon->ses->chan_lock);
 650        if ((tcon->need_reconnect) || CIFS_ALL_CHANS_NEED_RECONNECT(tcon->ses)) {
 651                spin_unlock(&tcon->ses->chan_lock);
 652                return -EIO;
 653        }
 654        spin_unlock(&tcon->ses->chan_lock);
 655
 656        rc = small_smb_init(SMB_COM_TREE_DISCONNECT, 0, tcon,
 657                            (void **)&smb_buffer);
 658        if (rc)
 659                return rc;
 660
 661        rc = SendReceiveNoRsp(xid, tcon->ses, (char *)smb_buffer, 0);
 662        cifs_small_buf_release(smb_buffer);
 663        if (rc)
 664                cifs_dbg(FYI, "Tree disconnect failed %d\n", rc);
 665
 666        /* No need to return error on this operation if tid invalidated and
 667           closed on server already e.g. due to tcp session crashing */
 668        if (rc == -EAGAIN)
 669                rc = 0;
 670
 671        return rc;
 672}
 673
 674/*
 675 * This is a no-op for now. We're not really interested in the reply, but
 676 * rather in the fact that the server sent one and that server->lstrp
 677 * gets updated.
 678 *
 679 * FIXME: maybe we should consider checking that the reply matches request?
 680 */
 681static void
 682cifs_echo_callback(struct mid_q_entry *mid)
 683{
 684        struct TCP_Server_Info *server = mid->callback_data;
 685        struct cifs_credits credits = { .value = 1, .instance = 0 };
 686
 687        DeleteMidQEntry(mid);
 688        add_credits(server, &credits, CIFS_ECHO_OP);
 689}
 690
 691int
 692CIFSSMBEcho(struct TCP_Server_Info *server)
 693{
 694        ECHO_REQ *smb;
 695        int rc = 0;
 696        struct kvec iov[2];
 697        struct smb_rqst rqst = { .rq_iov = iov,
 698                                 .rq_nvec = 2 };
 699
 700        cifs_dbg(FYI, "In echo request\n");
 701
 702        rc = small_smb_init(SMB_COM_ECHO, 0, NULL, (void **)&smb);
 703        if (rc)
 704                return rc;
 705
 706        if (server->capabilities & CAP_UNICODE)
 707                smb->hdr.Flags2 |= SMBFLG2_UNICODE;
 708
 709        /* set up echo request */
 710        smb->hdr.Tid = 0xffff;
 711        smb->hdr.WordCount = 1;
 712        put_unaligned_le16(1, &smb->EchoCount);
 713        put_bcc(1, &smb->hdr);
 714        smb->Data[0] = 'a';
 715        inc_rfc1001_len(smb, 3);
 716
 717        iov[0].iov_len = 4;
 718        iov[0].iov_base = smb;
 719        iov[1].iov_len = get_rfc1002_length(smb);
 720        iov[1].iov_base = (char *)smb + 4;
 721
 722        rc = cifs_call_async(server, &rqst, NULL, cifs_echo_callback, NULL,
 723                             server, CIFS_NON_BLOCKING | CIFS_ECHO_OP, NULL);
 724        if (rc)
 725                cifs_dbg(FYI, "Echo request failed: %d\n", rc);
 726
 727        cifs_small_buf_release(smb);
 728
 729        return rc;
 730}
 731
 732int
 733CIFSSMBLogoff(const unsigned int xid, struct cifs_ses *ses)
 734{
 735        LOGOFF_ANDX_REQ *pSMB;
 736        int rc = 0;
 737
 738        cifs_dbg(FYI, "In SMBLogoff for session disconnect\n");
 739
 740        /*
 741         * BB: do we need to check validity of ses and server? They should
 742         * always be valid since we have an active reference. If not, that
 743         * should probably be a BUG()
 744         */
 745        if (!ses || !ses->server)
 746                return -EIO;
 747
 748        mutex_lock(&ses->session_mutex);
 749        spin_lock(&ses->chan_lock);
 750        if (CIFS_ALL_CHANS_NEED_RECONNECT(ses)) {
 751                spin_unlock(&ses->chan_lock);
 752                goto session_already_dead; /* no need to send SMBlogoff if uid
 753                                              already closed due to reconnect */
 754        }
 755        spin_unlock(&ses->chan_lock);
 756
 757        rc = small_smb_init(SMB_COM_LOGOFF_ANDX, 2, NULL, (void **)&pSMB);
 758        if (rc) {
 759                mutex_unlock(&ses->session_mutex);
 760                return rc;
 761        }
 762
 763        pSMB->hdr.Mid = get_next_mid(ses->server);
 764
 765        if (ses->server->sign)
 766                pSMB->hdr.Flags2 |= SMBFLG2_SECURITY_SIGNATURE;
 767
 768        pSMB->hdr.Uid = ses->Suid;
 769
 770        pSMB->AndXCommand = 0xFF;
 771        rc = SendReceiveNoRsp(xid, ses, (char *) pSMB, 0);
 772        cifs_small_buf_release(pSMB);
 773session_already_dead:
 774        mutex_unlock(&ses->session_mutex);
 775
 776        /* if session dead then we do not need to do ulogoff,
 777                since server closed smb session, no sense reporting
 778                error */
 779        if (rc == -EAGAIN)
 780                rc = 0;
 781        return rc;
 782}
 783
 784int
 785CIFSPOSIXDelFile(const unsigned int xid, struct cifs_tcon *tcon,
 786                 const char *fileName, __u16 type,
 787                 const struct nls_table *nls_codepage, int remap)
 788{
 789        TRANSACTION2_SPI_REQ *pSMB = NULL;
 790        TRANSACTION2_SPI_RSP *pSMBr = NULL;
 791        struct unlink_psx_rq *pRqD;
 792        int name_len;
 793        int rc = 0;
 794        int bytes_returned = 0;
 795        __u16 params, param_offset, offset, byte_count;
 796
 797        cifs_dbg(FYI, "In POSIX delete\n");
 798PsxDelete:
 799        rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
 800                      (void **) &pSMBr);
 801        if (rc)
 802                return rc;
 803
 804        if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
 805                name_len =
 806                    cifsConvertToUTF16((__le16 *) pSMB->FileName, fileName,
 807                                       PATH_MAX, nls_codepage, remap);
 808                name_len++;     /* trailing null */
 809                name_len *= 2;
 810        } else {
 811                name_len = copy_path_name(pSMB->FileName, fileName);
 812        }
 813
 814        params = 6 + name_len;
 815        pSMB->MaxParameterCount = cpu_to_le16(2);
 816        pSMB->MaxDataCount = 0; /* BB double check this with jra */
 817        pSMB->MaxSetupCount = 0;
 818        pSMB->Reserved = 0;
 819        pSMB->Flags = 0;
 820        pSMB->Timeout = 0;
 821        pSMB->Reserved2 = 0;
 822        param_offset = offsetof(struct smb_com_transaction2_spi_req,
 823                                InformationLevel) - 4;
 824        offset = param_offset + params;
 825
 826        /* Setup pointer to Request Data (inode type).
 827         * Note that SMB offsets are from the beginning of SMB which is 4 bytes
 828         * in, after RFC1001 field
 829         */
 830        pRqD = (struct unlink_psx_rq *)((char *)(pSMB) + offset + 4);
 831        pRqD->type = cpu_to_le16(type);
 832        pSMB->ParameterOffset = cpu_to_le16(param_offset);
 833        pSMB->DataOffset = cpu_to_le16(offset);
 834        pSMB->SetupCount = 1;
 835        pSMB->Reserved3 = 0;
 836        pSMB->SubCommand = cpu_to_le16(TRANS2_SET_PATH_INFORMATION);
 837        byte_count = 3 /* pad */  + params + sizeof(struct unlink_psx_rq);
 838
 839        pSMB->DataCount = cpu_to_le16(sizeof(struct unlink_psx_rq));
 840        pSMB->TotalDataCount = cpu_to_le16(sizeof(struct unlink_psx_rq));
 841        pSMB->ParameterCount = cpu_to_le16(params);
 842        pSMB->TotalParameterCount = pSMB->ParameterCount;
 843        pSMB->InformationLevel = cpu_to_le16(SMB_POSIX_UNLINK);
 844        pSMB->Reserved4 = 0;
 845        inc_rfc1001_len(pSMB, byte_count);
 846        pSMB->ByteCount = cpu_to_le16(byte_count);
 847        rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
 848                         (struct smb_hdr *) pSMBr, &bytes_returned, 0);
 849        if (rc)
 850                cifs_dbg(FYI, "Posix delete returned %d\n", rc);
 851        cifs_buf_release(pSMB);
 852
 853        cifs_stats_inc(&tcon->stats.cifs_stats.num_deletes);
 854
 855        if (rc == -EAGAIN)
 856                goto PsxDelete;
 857
 858        return rc;
 859}
 860
 861int
 862CIFSSMBDelFile(const unsigned int xid, struct cifs_tcon *tcon, const char *name,
 863               struct cifs_sb_info *cifs_sb)
 864{
 865        DELETE_FILE_REQ *pSMB = NULL;
 866        DELETE_FILE_RSP *pSMBr = NULL;
 867        int rc = 0;
 868        int bytes_returned;
 869        int name_len;
 870        int remap = cifs_remap(cifs_sb);
 871
 872DelFileRetry:
 873        rc = smb_init(SMB_COM_DELETE, 1, tcon, (void **) &pSMB,
 874                      (void **) &pSMBr);
 875        if (rc)
 876                return rc;
 877
 878        if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
 879                name_len = cifsConvertToUTF16((__le16 *) pSMB->fileName, name,
 880                                              PATH_MAX, cifs_sb->local_nls,
 881                                              remap);
 882                name_len++;     /* trailing null */
 883                name_len *= 2;
 884        } else {
 885                name_len = copy_path_name(pSMB->fileName, name);
 886        }
 887        pSMB->SearchAttributes =
 888            cpu_to_le16(ATTR_READONLY | ATTR_HIDDEN | ATTR_SYSTEM);
 889        pSMB->BufferFormat = 0x04;
 890        inc_rfc1001_len(pSMB, name_len + 1);
 891        pSMB->ByteCount = cpu_to_le16(name_len + 1);
 892        rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
 893                         (struct smb_hdr *) pSMBr, &bytes_returned, 0);
 894        cifs_stats_inc(&tcon->stats.cifs_stats.num_deletes);
 895        if (rc)
 896                cifs_dbg(FYI, "Error in RMFile = %d\n", rc);
 897
 898        cifs_buf_release(pSMB);
 899        if (rc == -EAGAIN)
 900                goto DelFileRetry;
 901
 902        return rc;
 903}
 904
 905int
 906CIFSSMBRmDir(const unsigned int xid, struct cifs_tcon *tcon, const char *name,
 907             struct cifs_sb_info *cifs_sb)
 908{
 909        DELETE_DIRECTORY_REQ *pSMB = NULL;
 910        DELETE_DIRECTORY_RSP *pSMBr = NULL;
 911        int rc = 0;
 912        int bytes_returned;
 913        int name_len;
 914        int remap = cifs_remap(cifs_sb);
 915
 916        cifs_dbg(FYI, "In CIFSSMBRmDir\n");
 917RmDirRetry:
 918        rc = smb_init(SMB_COM_DELETE_DIRECTORY, 0, tcon, (void **) &pSMB,
 919                      (void **) &pSMBr);
 920        if (rc)
 921                return rc;
 922
 923        if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
 924                name_len = cifsConvertToUTF16((__le16 *) pSMB->DirName, name,
 925                                              PATH_MAX, cifs_sb->local_nls,
 926                                              remap);
 927                name_len++;     /* trailing null */
 928                name_len *= 2;
 929        } else {
 930                name_len = copy_path_name(pSMB->DirName, name);
 931        }
 932
 933        pSMB->BufferFormat = 0x04;
 934        inc_rfc1001_len(pSMB, name_len + 1);
 935        pSMB->ByteCount = cpu_to_le16(name_len + 1);
 936        rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
 937                         (struct smb_hdr *) pSMBr, &bytes_returned, 0);
 938        cifs_stats_inc(&tcon->stats.cifs_stats.num_rmdirs);
 939        if (rc)
 940                cifs_dbg(FYI, "Error in RMDir = %d\n", rc);
 941
 942        cifs_buf_release(pSMB);
 943        if (rc == -EAGAIN)
 944                goto RmDirRetry;
 945        return rc;
 946}
 947
 948int
 949CIFSSMBMkDir(const unsigned int xid, struct inode *inode, umode_t mode,
 950             struct cifs_tcon *tcon, const char *name,
 951             struct cifs_sb_info *cifs_sb)
 952{
 953        int rc = 0;
 954        CREATE_DIRECTORY_REQ *pSMB = NULL;
 955        CREATE_DIRECTORY_RSP *pSMBr = NULL;
 956        int bytes_returned;
 957        int name_len;
 958        int remap = cifs_remap(cifs_sb);
 959
 960        cifs_dbg(FYI, "In CIFSSMBMkDir\n");
 961MkDirRetry:
 962        rc = smb_init(SMB_COM_CREATE_DIRECTORY, 0, tcon, (void **) &pSMB,
 963                      (void **) &pSMBr);
 964        if (rc)
 965                return rc;
 966
 967        if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
 968                name_len = cifsConvertToUTF16((__le16 *) pSMB->DirName, name,
 969                                              PATH_MAX, cifs_sb->local_nls,
 970                                              remap);
 971                name_len++;     /* trailing null */
 972                name_len *= 2;
 973        } else {
 974                name_len = copy_path_name(pSMB->DirName, name);
 975        }
 976
 977        pSMB->BufferFormat = 0x04;
 978        inc_rfc1001_len(pSMB, name_len + 1);
 979        pSMB->ByteCount = cpu_to_le16(name_len + 1);
 980        rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
 981                         (struct smb_hdr *) pSMBr, &bytes_returned, 0);
 982        cifs_stats_inc(&tcon->stats.cifs_stats.num_mkdirs);
 983        if (rc)
 984                cifs_dbg(FYI, "Error in Mkdir = %d\n", rc);
 985
 986        cifs_buf_release(pSMB);
 987        if (rc == -EAGAIN)
 988                goto MkDirRetry;
 989        return rc;
 990}
 991
 992int
 993CIFSPOSIXCreate(const unsigned int xid, struct cifs_tcon *tcon,
 994                __u32 posix_flags, __u64 mode, __u16 *netfid,
 995                FILE_UNIX_BASIC_INFO *pRetData, __u32 *pOplock,
 996                const char *name, const struct nls_table *nls_codepage,
 997                int remap)
 998{
 999        TRANSACTION2_SPI_REQ *pSMB = NULL;
1000        TRANSACTION2_SPI_RSP *pSMBr = NULL;
1001        int name_len;
1002        int rc = 0;
1003        int bytes_returned = 0;
1004        __u16 params, param_offset, offset, byte_count, count;
1005        OPEN_PSX_REQ *pdata;
1006        OPEN_PSX_RSP *psx_rsp;
1007
1008        cifs_dbg(FYI, "In POSIX Create\n");
1009PsxCreat:
1010        rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
1011                      (void **) &pSMBr);
1012        if (rc)
1013                return rc;
1014
1015        if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
1016                name_len =
1017                    cifsConvertToUTF16((__le16 *) pSMB->FileName, name,
1018                                       PATH_MAX, nls_codepage, remap);
1019                name_len++;     /* trailing null */
1020                name_len *= 2;
1021        } else {
1022                name_len = copy_path_name(pSMB->FileName, name);
1023        }
1024
1025        params = 6 + name_len;
1026        count = sizeof(OPEN_PSX_REQ);
1027        pSMB->MaxParameterCount = cpu_to_le16(2);
1028        pSMB->MaxDataCount = cpu_to_le16(1000); /* large enough */
1029        pSMB->MaxSetupCount = 0;
1030        pSMB->Reserved = 0;
1031        pSMB->Flags = 0;
1032        pSMB->Timeout = 0;
1033        pSMB->Reserved2 = 0;
1034        param_offset = offsetof(struct smb_com_transaction2_spi_req,
1035                                InformationLevel) - 4;
1036        offset = param_offset + params;
1037        /* SMB offsets are from the beginning of SMB which is 4 bytes in, after RFC1001 field */
1038        pdata = (OPEN_PSX_REQ *)((char *)(pSMB) + offset + 4);
1039        pdata->Level = cpu_to_le16(SMB_QUERY_FILE_UNIX_BASIC);
1040        pdata->Permissions = cpu_to_le64(mode);
1041        pdata->PosixOpenFlags = cpu_to_le32(posix_flags);
1042        pdata->OpenFlags =  cpu_to_le32(*pOplock);
1043        pSMB->ParameterOffset = cpu_to_le16(param_offset);
1044        pSMB->DataOffset = cpu_to_le16(offset);
1045        pSMB->SetupCount = 1;
1046        pSMB->Reserved3 = 0;
1047        pSMB->SubCommand = cpu_to_le16(TRANS2_SET_PATH_INFORMATION);
1048        byte_count = 3 /* pad */  + params + count;
1049
1050        pSMB->DataCount = cpu_to_le16(count);
1051        pSMB->ParameterCount = cpu_to_le16(params);
1052        pSMB->TotalDataCount = pSMB->DataCount;
1053        pSMB->TotalParameterCount = pSMB->ParameterCount;
1054        pSMB->InformationLevel = cpu_to_le16(SMB_POSIX_OPEN);
1055        pSMB->Reserved4 = 0;
1056        inc_rfc1001_len(pSMB, byte_count);
1057        pSMB->ByteCount = cpu_to_le16(byte_count);
1058        rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
1059                         (struct smb_hdr *) pSMBr, &bytes_returned, 0);
1060        if (rc) {
1061                cifs_dbg(FYI, "Posix create returned %d\n", rc);
1062                goto psx_create_err;
1063        }
1064
1065        cifs_dbg(FYI, "copying inode info\n");
1066        rc = validate_t2((struct smb_t2_rsp *)pSMBr);
1067
1068        if (rc || get_bcc(&pSMBr->hdr) < sizeof(OPEN_PSX_RSP)) {
1069                rc = -EIO;      /* bad smb */
1070                goto psx_create_err;
1071        }
1072
1073        /* copy return information to pRetData */
1074        psx_rsp = (OPEN_PSX_RSP *)((char *) &pSMBr->hdr.Protocol
1075                        + le16_to_cpu(pSMBr->t2.DataOffset));
1076
1077        *pOplock = le16_to_cpu(psx_rsp->OplockFlags);
1078        if (netfid)
1079                *netfid = psx_rsp->Fid;   /* cifs fid stays in le */
1080        /* Let caller know file was created so we can set the mode. */
1081        /* Do we care about the CreateAction in any other cases? */
1082        if (cpu_to_le32(FILE_CREATE) == psx_rsp->CreateAction)
1083                *pOplock |= CIFS_CREATE_ACTION;
1084        /* check to make sure response data is there */
1085        if (psx_rsp->ReturnedLevel != cpu_to_le16(SMB_QUERY_FILE_UNIX_BASIC)) {
1086                pRetData->Type = cpu_to_le32(-1); /* unknown */
1087                cifs_dbg(NOISY, "unknown type\n");
1088        } else {
1089                if (get_bcc(&pSMBr->hdr) < sizeof(OPEN_PSX_RSP)
1090                                        + sizeof(FILE_UNIX_BASIC_INFO)) {
1091                        cifs_dbg(VFS, "Open response data too small\n");
1092                        pRetData->Type = cpu_to_le32(-1);
1093                        goto psx_create_err;
1094                }
1095                memcpy((char *) pRetData,
1096                        (char *)psx_rsp + sizeof(OPEN_PSX_RSP),
1097                        sizeof(FILE_UNIX_BASIC_INFO));
1098        }
1099
1100psx_create_err:
1101        cifs_buf_release(pSMB);
1102
1103        if (posix_flags & SMB_O_DIRECTORY)
1104                cifs_stats_inc(&tcon->stats.cifs_stats.num_posixmkdirs);
1105        else
1106                cifs_stats_inc(&tcon->stats.cifs_stats.num_posixopens);
1107
1108        if (rc == -EAGAIN)
1109                goto PsxCreat;
1110
1111        return rc;
1112}
1113
1114static __u16 convert_disposition(int disposition)
1115{
1116        __u16 ofun = 0;
1117
1118        switch (disposition) {
1119                case FILE_SUPERSEDE:
1120                        ofun = SMBOPEN_OCREATE | SMBOPEN_OTRUNC;
1121                        break;
1122                case FILE_OPEN:
1123                        ofun = SMBOPEN_OAPPEND;
1124                        break;
1125                case FILE_CREATE:
1126                        ofun = SMBOPEN_OCREATE;
1127                        break;
1128                case FILE_OPEN_IF:
1129                        ofun = SMBOPEN_OCREATE | SMBOPEN_OAPPEND;
1130                        break;
1131                case FILE_OVERWRITE:
1132                        ofun = SMBOPEN_OTRUNC;
1133                        break;
1134                case FILE_OVERWRITE_IF:
1135                        ofun = SMBOPEN_OCREATE | SMBOPEN_OTRUNC;
1136                        break;
1137                default:
1138                        cifs_dbg(FYI, "unknown disposition %d\n", disposition);
1139                        ofun =  SMBOPEN_OAPPEND; /* regular open */
1140        }
1141        return ofun;
1142}
1143
1144static int
1145access_flags_to_smbopen_mode(const int access_flags)
1146{
1147        int masked_flags = access_flags & (GENERIC_READ | GENERIC_WRITE);
1148
1149        if (masked_flags == GENERIC_READ)
1150                return SMBOPEN_READ;
1151        else if (masked_flags == GENERIC_WRITE)
1152                return SMBOPEN_WRITE;
1153
1154        /* just go for read/write */
1155        return SMBOPEN_READWRITE;
1156}
1157
1158int
1159SMBLegacyOpen(const unsigned int xid, struct cifs_tcon *tcon,
1160            const char *fileName, const int openDisposition,
1161            const int access_flags, const int create_options, __u16 *netfid,
1162            int *pOplock, FILE_ALL_INFO *pfile_info,
1163            const struct nls_table *nls_codepage, int remap)
1164{
1165        int rc;
1166        OPENX_REQ *pSMB = NULL;
1167        OPENX_RSP *pSMBr = NULL;
1168        int bytes_returned;
1169        int name_len;
1170        __u16 count;
1171
1172OldOpenRetry:
1173        rc = smb_init(SMB_COM_OPEN_ANDX, 15, tcon, (void **) &pSMB,
1174                      (void **) &pSMBr);
1175        if (rc)
1176                return rc;
1177
1178        pSMB->AndXCommand = 0xFF;       /* none */
1179
1180        if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
1181                count = 1;      /* account for one byte pad to word boundary */
1182                name_len =
1183                   cifsConvertToUTF16((__le16 *) (pSMB->fileName + 1),
1184                                      fileName, PATH_MAX, nls_codepage, remap);
1185                name_len++;     /* trailing null */
1186                name_len *= 2;
1187        } else {
1188                count = 0;      /* no pad */
1189                name_len = copy_path_name(pSMB->fileName, fileName);
1190        }
1191        if (*pOplock & REQ_OPLOCK)
1192                pSMB->OpenFlags = cpu_to_le16(REQ_OPLOCK);
1193        else if (*pOplock & REQ_BATCHOPLOCK)
1194                pSMB->OpenFlags = cpu_to_le16(REQ_BATCHOPLOCK);
1195
1196        pSMB->OpenFlags |= cpu_to_le16(REQ_MORE_INFO);
1197        pSMB->Mode = cpu_to_le16(access_flags_to_smbopen_mode(access_flags));
1198        pSMB->Mode |= cpu_to_le16(0x40); /* deny none */
1199        /* set file as system file if special file such
1200           as fifo and server expecting SFU style and
1201           no Unix extensions */
1202
1203        if (create_options & CREATE_OPTION_SPECIAL)
1204                pSMB->FileAttributes = cpu_to_le16(ATTR_SYSTEM);
1205        else /* BB FIXME BB */
1206                pSMB->FileAttributes = cpu_to_le16(0/*ATTR_NORMAL*/);
1207
1208        if (create_options & CREATE_OPTION_READONLY)
1209                pSMB->FileAttributes |= cpu_to_le16(ATTR_READONLY);
1210
1211        /* BB FIXME BB */
1212/*      pSMB->CreateOptions = cpu_to_le32(create_options &
1213                                                 CREATE_OPTIONS_MASK); */
1214        /* BB FIXME END BB */
1215
1216        pSMB->Sattr = cpu_to_le16(ATTR_HIDDEN | ATTR_SYSTEM | ATTR_DIRECTORY);
1217        pSMB->OpenFunction = cpu_to_le16(convert_disposition(openDisposition));
1218        count += name_len;
1219        inc_rfc1001_len(pSMB, count);
1220
1221        pSMB->ByteCount = cpu_to_le16(count);
1222        rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
1223                        (struct smb_hdr *)pSMBr, &bytes_returned, 0);
1224        cifs_stats_inc(&tcon->stats.cifs_stats.num_opens);
1225        if (rc) {
1226                cifs_dbg(FYI, "Error in Open = %d\n", rc);
1227        } else {
1228        /* BB verify if wct == 15 */
1229
1230/*              *pOplock = pSMBr->OplockLevel; */ /* BB take from action field*/
1231
1232                *netfid = pSMBr->Fid;   /* cifs fid stays in le */
1233                /* Let caller know file was created so we can set the mode. */
1234                /* Do we care about the CreateAction in any other cases? */
1235        /* BB FIXME BB */
1236/*              if (cpu_to_le32(FILE_CREATE) == pSMBr->CreateAction)
1237                        *pOplock |= CIFS_CREATE_ACTION; */
1238        /* BB FIXME END */
1239
1240                if (pfile_info) {
1241                        pfile_info->CreationTime = 0; /* BB convert CreateTime*/
1242                        pfile_info->LastAccessTime = 0; /* BB fixme */
1243                        pfile_info->LastWriteTime = 0; /* BB fixme */
1244                        pfile_info->ChangeTime = 0;  /* BB fixme */
1245                        pfile_info->Attributes =
1246                                cpu_to_le32(le16_to_cpu(pSMBr->FileAttributes));
1247                        /* the file_info buf is endian converted by caller */
1248                        pfile_info->AllocationSize =
1249                                cpu_to_le64(le32_to_cpu(pSMBr->EndOfFile));
1250                        pfile_info->EndOfFile = pfile_info->AllocationSize;
1251                        pfile_info->NumberOfLinks = cpu_to_le32(1);
1252                        pfile_info->DeletePending = 0;
1253                }
1254        }
1255
1256        cifs_buf_release(pSMB);
1257        if (rc == -EAGAIN)
1258                goto OldOpenRetry;
1259        return rc;
1260}
1261
1262int
1263CIFS_open(const unsigned int xid, struct cifs_open_parms *oparms, int *oplock,
1264          FILE_ALL_INFO *buf)
1265{
1266        int rc;
1267        OPEN_REQ *req = NULL;
1268        OPEN_RSP *rsp = NULL;
1269        int bytes_returned;
1270        int name_len;
1271        __u16 count;
1272        struct cifs_sb_info *cifs_sb = oparms->cifs_sb;
1273        struct cifs_tcon *tcon = oparms->tcon;
1274        int remap = cifs_remap(cifs_sb);
1275        const struct nls_table *nls = cifs_sb->local_nls;
1276        int create_options = oparms->create_options;
1277        int desired_access = oparms->desired_access;
1278        int disposition = oparms->disposition;
1279        const char *path = oparms->path;
1280
1281openRetry:
1282        rc = smb_init(SMB_COM_NT_CREATE_ANDX, 24, tcon, (void **)&req,
1283                      (void **)&rsp);
1284        if (rc)
1285                return rc;
1286
1287        /* no commands go after this */
1288        req->AndXCommand = 0xFF;
1289
1290        if (req->hdr.Flags2 & SMBFLG2_UNICODE) {
1291                /* account for one byte pad to word boundary */
1292                count = 1;
1293                name_len = cifsConvertToUTF16((__le16 *)(req->fileName + 1),
1294                                              path, PATH_MAX, nls, remap);
1295                /* trailing null */
1296                name_len++;
1297                name_len *= 2;
1298                req->NameLength = cpu_to_le16(name_len);
1299        } else {
1300                /* BB improve check for buffer overruns BB */
1301                /* no pad */
1302                count = 0;
1303                name_len = copy_path_name(req->fileName, path);
1304                req->NameLength = cpu_to_le16(name_len);
1305        }
1306
1307        if (*oplock & REQ_OPLOCK)
1308                req->OpenFlags = cpu_to_le32(REQ_OPLOCK);
1309        else if (*oplock & REQ_BATCHOPLOCK)
1310                req->OpenFlags = cpu_to_le32(REQ_BATCHOPLOCK);
1311
1312        req->DesiredAccess = cpu_to_le32(desired_access);
1313        req->AllocationSize = 0;
1314
1315        /*
1316         * Set file as system file if special file such as fifo and server
1317         * expecting SFU style and no Unix extensions.
1318         */
1319        if (create_options & CREATE_OPTION_SPECIAL)
1320                req->FileAttributes = cpu_to_le32(ATTR_SYSTEM);
1321        else
1322                req->FileAttributes = cpu_to_le32(ATTR_NORMAL);
1323
1324        /*
1325         * XP does not handle ATTR_POSIX_SEMANTICS but it helps speed up case
1326         * sensitive checks for other servers such as Samba.
1327         */
1328        if (tcon->ses->capabilities & CAP_UNIX)
1329                req->FileAttributes |= cpu_to_le32(ATTR_POSIX_SEMANTICS);
1330
1331        if (create_options & CREATE_OPTION_READONLY)
1332                req->FileAttributes |= cpu_to_le32(ATTR_READONLY);
1333
1334        req->ShareAccess = cpu_to_le32(FILE_SHARE_ALL);
1335        req->CreateDisposition = cpu_to_le32(disposition);
1336        req->CreateOptions = cpu_to_le32(create_options & CREATE_OPTIONS_MASK);
1337
1338        /* BB Expirement with various impersonation levels and verify */
1339        req->ImpersonationLevel = cpu_to_le32(SECURITY_IMPERSONATION);
1340        req->SecurityFlags = SECURITY_CONTEXT_TRACKING|SECURITY_EFFECTIVE_ONLY;
1341
1342        count += name_len;
1343        inc_rfc1001_len(req, count);
1344
1345        req->ByteCount = cpu_to_le16(count);
1346        rc = SendReceive(xid, tcon->ses, (struct smb_hdr *)req,
1347                         (struct smb_hdr *)rsp, &bytes_returned, 0);
1348        cifs_stats_inc(&tcon->stats.cifs_stats.num_opens);
1349        if (rc) {
1350                cifs_dbg(FYI, "Error in Open = %d\n", rc);
1351                cifs_buf_release(req);
1352                if (rc == -EAGAIN)
1353                        goto openRetry;
1354                return rc;
1355        }
1356
1357        /* 1 byte no need to le_to_cpu */
1358        *oplock = rsp->OplockLevel;
1359        /* cifs fid stays in le */
1360        oparms->fid->netfid = rsp->Fid;
1361        oparms->fid->access = desired_access;
1362
1363        /* Let caller know file was created so we can set the mode. */
1364        /* Do we care about the CreateAction in any other cases? */
1365        if (cpu_to_le32(FILE_CREATE) == rsp->CreateAction)
1366                *oplock |= CIFS_CREATE_ACTION;
1367
1368        if (buf) {
1369                /* copy from CreationTime to Attributes */
1370                memcpy((char *)buf, (char *)&rsp->CreationTime, 36);
1371                /* the file_info buf is endian converted by caller */
1372                buf->AllocationSize = rsp->AllocationSize;
1373                buf->EndOfFile = rsp->EndOfFile;
1374                buf->NumberOfLinks = cpu_to_le32(1);
1375                buf->DeletePending = 0;
1376        }
1377
1378        cifs_buf_release(req);
1379        return rc;
1380}
1381
1382/*
1383 * Discard any remaining data in the current SMB. To do this, we borrow the
1384 * current bigbuf.
1385 */
1386int
1387cifs_discard_remaining_data(struct TCP_Server_Info *server)
1388{
1389        unsigned int rfclen = server->pdu_size;
1390        int remaining = rfclen + server->vals->header_preamble_size -
1391                server->total_read;
1392
1393        while (remaining > 0) {
1394                int length;
1395
1396                length = cifs_discard_from_socket(server,
1397                                min_t(size_t, remaining,
1398                                      CIFSMaxBufSize + MAX_HEADER_SIZE(server)));
1399                if (length < 0)
1400                        return length;
1401                server->total_read += length;
1402                remaining -= length;
1403        }
1404
1405        return 0;
1406}
1407
1408static int
1409__cifs_readv_discard(struct TCP_Server_Info *server, struct mid_q_entry *mid,
1410                     bool malformed)
1411{
1412        int length;
1413
1414        length = cifs_discard_remaining_data(server);
1415        dequeue_mid(mid, malformed);
1416        mid->resp_buf = server->smallbuf;
1417        server->smallbuf = NULL;
1418        return length;
1419}
1420
1421static int
1422cifs_readv_discard(struct TCP_Server_Info *server, struct mid_q_entry *mid)
1423{
1424        struct cifs_readdata *rdata = mid->callback_data;
1425
1426        return  __cifs_readv_discard(server, mid, rdata->result);
1427}
1428
1429int
1430cifs_readv_receive(struct TCP_Server_Info *server, struct mid_q_entry *mid)
1431{
1432        int length, len;
1433        unsigned int data_offset, data_len;
1434        struct cifs_readdata *rdata = mid->callback_data;
1435        char *buf = server->smallbuf;
1436        unsigned int buflen = server->pdu_size +
1437                server->vals->header_preamble_size;
1438        bool use_rdma_mr = false;
1439
1440        cifs_dbg(FYI, "%s: mid=%llu offset=%llu bytes=%u\n",
1441                 __func__, mid->mid, rdata->offset, rdata->bytes);
1442
1443        /*
1444         * read the rest of READ_RSP header (sans Data array), or whatever we
1445         * can if there's not enough data. At this point, we've read down to
1446         * the Mid.
1447         */
1448        len = min_t(unsigned int, buflen, server->vals->read_rsp_size) -
1449                                                        HEADER_SIZE(server) + 1;
1450
1451        length = cifs_read_from_socket(server,
1452                                       buf + HEADER_SIZE(server) - 1, len);
1453        if (length < 0)
1454                return length;
1455        server->total_read += length;
1456
1457        if (server->ops->is_session_expired &&
1458            server->ops->is_session_expired(buf)) {
1459                cifs_reconnect(server, true);
1460                return -1;
1461        }
1462
1463        if (server->ops->is_status_pending &&
1464            server->ops->is_status_pending(buf, server)) {
1465                cifs_discard_remaining_data(server);
1466                return -1;
1467        }
1468
1469        /* set up first two iov for signature check and to get credits */
1470        rdata->iov[0].iov_base = buf;
1471        rdata->iov[0].iov_len = server->vals->header_preamble_size;
1472        rdata->iov[1].iov_base = buf + server->vals->header_preamble_size;
1473        rdata->iov[1].iov_len =
1474                server->total_read - server->vals->header_preamble_size;
1475        cifs_dbg(FYI, "0: iov_base=%p iov_len=%zu\n",
1476                 rdata->iov[0].iov_base, rdata->iov[0].iov_len);
1477        cifs_dbg(FYI, "1: iov_base=%p iov_len=%zu\n",
1478                 rdata->iov[1].iov_base, rdata->iov[1].iov_len);
1479
1480        /* Was the SMB read successful? */
1481        rdata->result = server->ops->map_error(buf, false);
1482        if (rdata->result != 0) {
1483                cifs_dbg(FYI, "%s: server returned error %d\n",
1484                         __func__, rdata->result);
1485                /* normal error on read response */
1486                return __cifs_readv_discard(server, mid, false);
1487        }
1488
1489        /* Is there enough to get to the rest of the READ_RSP header? */
1490        if (server->total_read < server->vals->read_rsp_size) {
1491                cifs_dbg(FYI, "%s: server returned short header. got=%u expected=%zu\n",
1492                         __func__, server->total_read,
1493                         server->vals->read_rsp_size);
1494                rdata->result = -EIO;
1495                return cifs_readv_discard(server, mid);
1496        }
1497
1498        data_offset = server->ops->read_data_offset(buf) +
1499                server->vals->header_preamble_size;
1500        if (data_offset < server->total_read) {
1501                /*
1502                 * win2k8 sometimes sends an offset of 0 when the read
1503                 * is beyond the EOF. Treat it as if the data starts just after
1504                 * the header.
1505                 */
1506                cifs_dbg(FYI, "%s: data offset (%u) inside read response header\n",
1507                         __func__, data_offset);
1508                data_offset = server->total_read;
1509        } else if (data_offset > MAX_CIFS_SMALL_BUFFER_SIZE) {
1510                /* data_offset is beyond the end of smallbuf */
1511                cifs_dbg(FYI, "%s: data offset (%u) beyond end of smallbuf\n",
1512                         __func__, data_offset);
1513                rdata->result = -EIO;
1514                return cifs_readv_discard(server, mid);
1515        }
1516
1517        cifs_dbg(FYI, "%s: total_read=%u data_offset=%u\n",
1518                 __func__, server->total_read, data_offset);
1519
1520        len = data_offset - server->total_read;
1521        if (len > 0) {
1522                /* read any junk before data into the rest of smallbuf */
1523                length = cifs_read_from_socket(server,
1524                                               buf + server->total_read, len);
1525                if (length < 0)
1526                        return length;
1527                server->total_read += length;
1528        }
1529
1530        /* how much data is in the response? */
1531#ifdef CONFIG_CIFS_SMB_DIRECT
1532        use_rdma_mr = rdata->mr;
1533#endif
1534        data_len = server->ops->read_data_length(buf, use_rdma_mr);
1535        if (!use_rdma_mr && (data_offset + data_len > buflen)) {
1536                /* data_len is corrupt -- discard frame */
1537                rdata->result = -EIO;
1538                return cifs_readv_discard(server, mid);
1539        }
1540
1541        length = rdata->read_into_pages(server, rdata, data_len);
1542        if (length < 0)
1543                return length;
1544
1545        server->total_read += length;
1546
1547        cifs_dbg(FYI, "total_read=%u buflen=%u remaining=%u\n",
1548                 server->total_read, buflen, data_len);
1549
1550        /* discard anything left over */
1551        if (server->total_read < buflen)
1552                return cifs_readv_discard(server, mid);
1553
1554        dequeue_mid(mid, false);
1555        mid->resp_buf = server->smallbuf;
1556        server->smallbuf = NULL;
1557        return length;
1558}
1559
1560static void
1561cifs_readv_callback(struct mid_q_entry *mid)
1562{
1563        struct cifs_readdata *rdata = mid->callback_data;
1564        struct cifs_tcon *tcon = tlink_tcon(rdata->cfile->tlink);
1565        struct TCP_Server_Info *server = tcon->ses->server;
1566        struct smb_rqst rqst = { .rq_iov = rdata->iov,
1567                                 .rq_nvec = 2,
1568                                 .rq_pages = rdata->pages,
1569                                 .rq_offset = rdata->page_offset,
1570                                 .rq_npages = rdata->nr_pages,
1571                                 .rq_pagesz = rdata->pagesz,
1572                                 .rq_tailsz = rdata->tailsz };
1573        struct cifs_credits credits = { .value = 1, .instance = 0 };
1574
1575        cifs_dbg(FYI, "%s: mid=%llu state=%d result=%d bytes=%u\n",
1576                 __func__, mid->mid, mid->mid_state, rdata->result,
1577                 rdata->bytes);
1578
1579        switch (mid->mid_state) {
1580        case MID_RESPONSE_RECEIVED:
1581                /* result already set, check signature */
1582                if (server->sign) {
1583                        int rc = 0;
1584
1585                        rc = cifs_verify_signature(&rqst, server,
1586                                                  mid->sequence_number);
1587                        if (rc)
1588                                cifs_dbg(VFS, "SMB signature verification returned error = %d\n",
1589                                         rc);
1590                }
1591                /* FIXME: should this be counted toward the initiating task? */
1592                task_io_account_read(rdata->got_bytes);
1593                cifs_stats_bytes_read(tcon, rdata->got_bytes);
1594                break;
1595        case MID_REQUEST_SUBMITTED:
1596        case MID_RETRY_NEEDED:
1597                rdata->result = -EAGAIN;
1598                if (server->sign && rdata->got_bytes)
1599                        /* reset bytes number since we can not check a sign */
1600                        rdata->got_bytes = 0;
1601                /* FIXME: should this be counted toward the initiating task? */
1602                task_io_account_read(rdata->got_bytes);
1603                cifs_stats_bytes_read(tcon, rdata->got_bytes);
1604                break;
1605        default:
1606                rdata->result = -EIO;
1607        }
1608
1609        queue_work(cifsiod_wq, &rdata->work);
1610        DeleteMidQEntry(mid);
1611        add_credits(server, &credits, 0);
1612}
1613
1614/* cifs_async_readv - send an async write, and set up mid to handle result */
1615int
1616cifs_async_readv(struct cifs_readdata *rdata)
1617{
1618        int rc;
1619        READ_REQ *smb = NULL;
1620        int wct;
1621        struct cifs_tcon *tcon = tlink_tcon(rdata->cfile->tlink);
1622        struct smb_rqst rqst = { .rq_iov = rdata->iov,
1623                                 .rq_nvec = 2 };
1624
1625        cifs_dbg(FYI, "%s: offset=%llu bytes=%u\n",
1626                 __func__, rdata->offset, rdata->bytes);
1627
1628        if (tcon->ses->capabilities & CAP_LARGE_FILES)
1629                wct = 12;
1630        else {
1631                wct = 10; /* old style read */
1632                if ((rdata->offset >> 32) > 0)  {
1633                        /* can not handle this big offset for old */
1634                        return -EIO;
1635                }
1636        }
1637
1638        rc = small_smb_init(SMB_COM_READ_ANDX, wct, tcon, (void **)&smb);
1639        if (rc)
1640                return rc;
1641
1642        smb->hdr.Pid = cpu_to_le16((__u16)rdata->pid);
1643        smb->hdr.PidHigh = cpu_to_le16((__u16)(rdata->pid >> 16));
1644
1645        smb->AndXCommand = 0xFF;        /* none */
1646        smb->Fid = rdata->cfile->fid.netfid;
1647        smb->OffsetLow = cpu_to_le32(rdata->offset & 0xFFFFFFFF);
1648        if (wct == 12)
1649                smb->OffsetHigh = cpu_to_le32(rdata->offset >> 32);
1650        smb->Remaining = 0;
1651        smb->MaxCount = cpu_to_le16(rdata->bytes & 0xFFFF);
1652        smb->MaxCountHigh = cpu_to_le32(rdata->bytes >> 16);
1653        if (wct == 12)
1654                smb->ByteCount = 0;
1655        else {
1656                /* old style read */
1657                struct smb_com_readx_req *smbr =
1658                        (struct smb_com_readx_req *)smb;
1659                smbr->ByteCount = 0;
1660        }
1661
1662        /* 4 for RFC1001 length + 1 for BCC */
1663        rdata->iov[0].iov_base = smb;
1664        rdata->iov[0].iov_len = 4;
1665        rdata->iov[1].iov_base = (char *)smb + 4;
1666        rdata->iov[1].iov_len = get_rfc1002_length(smb);
1667
1668        kref_get(&rdata->refcount);
1669        rc = cifs_call_async(tcon->ses->server, &rqst, cifs_readv_receive,
1670                             cifs_readv_callback, NULL, rdata, 0, NULL);
1671
1672        if (rc == 0)
1673                cifs_stats_inc(&tcon->stats.cifs_stats.num_reads);
1674        else
1675                kref_put(&rdata->refcount, cifs_readdata_release);
1676
1677        cifs_small_buf_release(smb);
1678        return rc;
1679}
1680
1681int
1682CIFSSMBRead(const unsigned int xid, struct cifs_io_parms *io_parms,
1683            unsigned int *nbytes, char **buf, int *pbuf_type)
1684{
1685        int rc = -EACCES;
1686        READ_REQ *pSMB = NULL;
1687        READ_RSP *pSMBr = NULL;
1688        char *pReadData = NULL;
1689        int wct;
1690        int resp_buf_type = 0;
1691        struct kvec iov[1];
1692        struct kvec rsp_iov;
1693        __u32 pid = io_parms->pid;
1694        __u16 netfid = io_parms->netfid;
1695        __u64 offset = io_parms->offset;
1696        struct cifs_tcon *tcon = io_parms->tcon;
1697        unsigned int count = io_parms->length;
1698
1699        cifs_dbg(FYI, "Reading %d bytes on fid %d\n", count, netfid);
1700        if (tcon->ses->capabilities & CAP_LARGE_FILES)
1701                wct = 12;
1702        else {
1703                wct = 10; /* old style read */
1704                if ((offset >> 32) > 0)  {
1705                        /* can not handle this big offset for old */
1706                        return -EIO;
1707                }
1708        }
1709
1710        *nbytes = 0;
1711        rc = small_smb_init(SMB_COM_READ_ANDX, wct, tcon, (void **) &pSMB);
1712        if (rc)
1713                return rc;
1714
1715        pSMB->hdr.Pid = cpu_to_le16((__u16)pid);
1716        pSMB->hdr.PidHigh = cpu_to_le16((__u16)(pid >> 16));
1717
1718        /* tcon and ses pointer are checked in smb_init */
1719        if (tcon->ses->server == NULL)
1720                return -ECONNABORTED;
1721
1722        pSMB->AndXCommand = 0xFF;       /* none */
1723        pSMB->Fid = netfid;
1724        pSMB->OffsetLow = cpu_to_le32(offset & 0xFFFFFFFF);
1725        if (wct == 12)
1726                pSMB->OffsetHigh = cpu_to_le32(offset >> 32);
1727
1728        pSMB->Remaining = 0;
1729        pSMB->MaxCount = cpu_to_le16(count & 0xFFFF);
1730        pSMB->MaxCountHigh = cpu_to_le32(count >> 16);
1731        if (wct == 12)
1732                pSMB->ByteCount = 0;  /* no need to do le conversion since 0 */
1733        else {
1734                /* old style read */
1735                struct smb_com_readx_req *pSMBW =
1736                        (struct smb_com_readx_req *)pSMB;
1737                pSMBW->ByteCount = 0;
1738        }
1739
1740        iov[0].iov_base = (char *)pSMB;
1741        iov[0].iov_len = be32_to_cpu(pSMB->hdr.smb_buf_length) + 4;
1742        rc = SendReceive2(xid, tcon->ses, iov, 1, &resp_buf_type,
1743                          CIFS_LOG_ERROR, &rsp_iov);
1744        cifs_small_buf_release(pSMB);
1745        cifs_stats_inc(&tcon->stats.cifs_stats.num_reads);
1746        pSMBr = (READ_RSP *)rsp_iov.iov_base;
1747        if (rc) {
1748                cifs_dbg(VFS, "Send error in read = %d\n", rc);
1749        } else {
1750                int data_length = le16_to_cpu(pSMBr->DataLengthHigh);
1751                data_length = data_length << 16;
1752                data_length += le16_to_cpu(pSMBr->DataLength);
1753                *nbytes = data_length;
1754
1755                /*check that DataLength would not go beyond end of SMB */
1756                if ((data_length > CIFSMaxBufSize)
1757                                || (data_length > count)) {
1758                        cifs_dbg(FYI, "bad length %d for count %d\n",
1759                                 data_length, count);
1760                        rc = -EIO;
1761                        *nbytes = 0;
1762                } else {
1763                        pReadData = (char *) (&pSMBr->hdr.Protocol) +
1764                                        le16_to_cpu(pSMBr->DataOffset);
1765/*                      if (rc = copy_to_user(buf, pReadData, data_length)) {
1766                                cifs_dbg(VFS, "Faulting on read rc = %d\n",rc);
1767                                rc = -EFAULT;
1768                        }*/ /* can not use copy_to_user when using page cache*/
1769                        if (*buf)
1770                                memcpy(*buf, pReadData, data_length);
1771                }
1772        }
1773
1774        if (*buf) {
1775                free_rsp_buf(resp_buf_type, rsp_iov.iov_base);
1776        } else if (resp_buf_type != CIFS_NO_BUFFER) {
1777                /* return buffer to caller to free */
1778                *buf = rsp_iov.iov_base;
1779                if (resp_buf_type == CIFS_SMALL_BUFFER)
1780                        *pbuf_type = CIFS_SMALL_BUFFER;
1781                else if (resp_buf_type == CIFS_LARGE_BUFFER)
1782                        *pbuf_type = CIFS_LARGE_BUFFER;
1783        } /* else no valid buffer on return - leave as null */
1784
1785        /* Note: On -EAGAIN error only caller can retry on handle based calls
1786                since file handle passed in no longer valid */
1787        return rc;
1788}
1789
1790
1791int
1792CIFSSMBWrite(const unsigned int xid, struct cifs_io_parms *io_parms,
1793             unsigned int *nbytes, const char *buf)
1794{
1795        int rc = -EACCES;
1796        WRITE_REQ *pSMB = NULL;
1797        WRITE_RSP *pSMBr = NULL;
1798        int bytes_returned, wct;
1799        __u32 bytes_sent;
1800        __u16 byte_count;
1801        __u32 pid = io_parms->pid;
1802        __u16 netfid = io_parms->netfid;
1803        __u64 offset = io_parms->offset;
1804        struct cifs_tcon *tcon = io_parms->tcon;
1805        unsigned int count = io_parms->length;
1806
1807        *nbytes = 0;
1808
1809        /* cifs_dbg(FYI, "write at %lld %d bytes\n", offset, count);*/
1810        if (tcon->ses == NULL)
1811                return -ECONNABORTED;
1812
1813        if (tcon->ses->capabilities & CAP_LARGE_FILES)
1814                wct = 14;
1815        else {
1816                wct = 12;
1817                if ((offset >> 32) > 0) {
1818                        /* can not handle big offset for old srv */
1819                        return -EIO;
1820                }
1821        }
1822
1823        rc = smb_init(SMB_COM_WRITE_ANDX, wct, tcon, (void **) &pSMB,
1824                      (void **) &pSMBr);
1825        if (rc)
1826                return rc;
1827
1828        pSMB->hdr.Pid = cpu_to_le16((__u16)pid);
1829        pSMB->hdr.PidHigh = cpu_to_le16((__u16)(pid >> 16));
1830
1831        /* tcon and ses pointer are checked in smb_init */
1832        if (tcon->ses->server == NULL)
1833                return -ECONNABORTED;
1834
1835        pSMB->AndXCommand = 0xFF;       /* none */
1836        pSMB->Fid = netfid;
1837        pSMB->OffsetLow = cpu_to_le32(offset & 0xFFFFFFFF);
1838        if (wct == 14)
1839                pSMB->OffsetHigh = cpu_to_le32(offset >> 32);
1840
1841        pSMB->Reserved = 0xFFFFFFFF;
1842        pSMB->WriteMode = 0;
1843        pSMB->Remaining = 0;
1844
1845        /* Can increase buffer size if buffer is big enough in some cases ie we
1846        can send more if LARGE_WRITE_X capability returned by the server and if
1847        our buffer is big enough or if we convert to iovecs on socket writes
1848        and eliminate the copy to the CIFS buffer */
1849        if (tcon->ses->capabilities & CAP_LARGE_WRITE_X) {
1850                bytes_sent = min_t(const unsigned int, CIFSMaxBufSize, count);
1851        } else {
1852                bytes_sent = (tcon->ses->server->maxBuf - MAX_CIFS_HDR_SIZE)
1853                         & ~0xFF;
1854        }
1855
1856        if (bytes_sent > count)
1857                bytes_sent = count;
1858        pSMB->DataOffset =
1859                cpu_to_le16(offsetof(struct smb_com_write_req, Data) - 4);
1860        if (buf)
1861                memcpy(pSMB->Data, buf, bytes_sent);
1862        else if (count != 0) {
1863                /* No buffer */
1864                cifs_buf_release(pSMB);
1865                return -EINVAL;
1866        } /* else setting file size with write of zero bytes */
1867        if (wct == 14)
1868                byte_count = bytes_sent + 1; /* pad */
1869        else /* wct == 12 */
1870                byte_count = bytes_sent + 5; /* bigger pad, smaller smb hdr */
1871
1872        pSMB->DataLengthLow = cpu_to_le16(bytes_sent & 0xFFFF);
1873        pSMB->DataLengthHigh = cpu_to_le16(bytes_sent >> 16);
1874        inc_rfc1001_len(pSMB, byte_count);
1875
1876        if (wct == 14)
1877                pSMB->ByteCount = cpu_to_le16(byte_count);
1878        else { /* old style write has byte count 4 bytes earlier
1879                  so 4 bytes pad  */
1880                struct smb_com_writex_req *pSMBW =
1881                        (struct smb_com_writex_req *)pSMB;
1882                pSMBW->ByteCount = cpu_to_le16(byte_count);
1883        }
1884
1885        rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
1886                         (struct smb_hdr *) pSMBr, &bytes_returned, 0);
1887        cifs_stats_inc(&tcon->stats.cifs_stats.num_writes);
1888        if (rc) {
1889                cifs_dbg(FYI, "Send error in write = %d\n", rc);
1890        } else {
1891                *nbytes = le16_to_cpu(pSMBr->CountHigh);
1892                *nbytes = (*nbytes) << 16;
1893                *nbytes += le16_to_cpu(pSMBr->Count);
1894
1895                /*
1896                 * Mask off high 16 bits when bytes written as returned by the
1897                 * server is greater than bytes requested by the client. Some
1898                 * OS/2 servers are known to set incorrect CountHigh values.
1899                 */
1900                if (*nbytes > count)
1901                        *nbytes &= 0xFFFF;
1902        }
1903
1904        cifs_buf_release(pSMB);
1905
1906        /* Note: On -EAGAIN error only caller can retry on handle based calls
1907                since file handle passed in no longer valid */
1908
1909        return rc;
1910}
1911
1912void
1913cifs_writedata_release(struct kref *refcount)
1914{
1915        struct cifs_writedata *wdata = container_of(refcount,
1916                                        struct cifs_writedata, refcount);
1917#ifdef CONFIG_CIFS_SMB_DIRECT
1918        if (wdata->mr) {
1919                smbd_deregister_mr(wdata->mr);
1920                wdata->mr = NULL;
1921        }
1922#endif
1923
1924        if (wdata->cfile)
1925                cifsFileInfo_put(wdata->cfile);
1926
1927        kvfree(wdata->pages);
1928        kfree(wdata);
1929}
1930
1931/*
1932 * Write failed with a retryable error. Resend the write request. It's also
1933 * possible that the page was redirtied so re-clean the page.
1934 */
1935static void
1936cifs_writev_requeue(struct cifs_writedata *wdata)
1937{
1938        int i, rc = 0;
1939        struct inode *inode = d_inode(wdata->cfile->dentry);
1940        struct TCP_Server_Info *server;
1941        unsigned int rest_len;
1942
1943        server = tlink_tcon(wdata->cfile->tlink)->ses->server;
1944        i = 0;
1945        rest_len = wdata->bytes;
1946        do {
1947                struct cifs_writedata *wdata2;
1948                unsigned int j, nr_pages, wsize, tailsz, cur_len;
1949
1950                wsize = server->ops->wp_retry_size(inode);
1951                if (wsize < rest_len) {
1952                        nr_pages = wsize / PAGE_SIZE;
1953                        if (!nr_pages) {
1954                                rc = -ENOTSUPP;
1955                                break;
1956                        }
1957                        cur_len = nr_pages * PAGE_SIZE;
1958                        tailsz = PAGE_SIZE;
1959                } else {
1960                        nr_pages = DIV_ROUND_UP(rest_len, PAGE_SIZE);
1961                        cur_len = rest_len;
1962                        tailsz = rest_len - (nr_pages - 1) * PAGE_SIZE;
1963                }
1964
1965                wdata2 = cifs_writedata_alloc(nr_pages, cifs_writev_complete);
1966                if (!wdata2) {
1967                        rc = -ENOMEM;
1968                        break;
1969                }
1970
1971                for (j = 0; j < nr_pages; j++) {
1972                        wdata2->pages[j] = wdata->pages[i + j];
1973                        lock_page(wdata2->pages[j]);
1974                        clear_page_dirty_for_io(wdata2->pages[j]);
1975                }
1976
1977                wdata2->sync_mode = wdata->sync_mode;
1978                wdata2->nr_pages = nr_pages;
1979                wdata2->offset = page_offset(wdata2->pages[0]);
1980                wdata2->pagesz = PAGE_SIZE;
1981                wdata2->tailsz = tailsz;
1982                wdata2->bytes = cur_len;
1983
1984                rc = cifs_get_writable_file(CIFS_I(inode), FIND_WR_ANY,
1985                                            &wdata2->cfile);
1986                if (!wdata2->cfile) {
1987                        cifs_dbg(VFS, "No writable handle to retry writepages rc=%d\n",
1988                                 rc);
1989                        if (!is_retryable_error(rc))
1990                                rc = -EBADF;
1991                } else {
1992                        wdata2->pid = wdata2->cfile->pid;
1993                        rc = server->ops->async_writev(wdata2,
1994                                                       cifs_writedata_release);
1995                }
1996
1997                for (j = 0; j < nr_pages; j++) {
1998                        unlock_page(wdata2->pages[j]);
1999                        if (rc != 0 && !is_retryable_error(rc)) {
2000                                SetPageError(wdata2->pages[j]);
2001                                end_page_writeback(wdata2->pages[j]);
2002                                put_page(wdata2->pages[j]);
2003                        }
2004                }
2005
2006                kref_put(&wdata2->refcount, cifs_writedata_release);
2007                if (rc) {
2008                        if (is_retryable_error(rc))
2009                                continue;
2010                        i += nr_pages;
2011                        break;
2012                }
2013
2014                rest_len -= cur_len;
2015                i += nr_pages;
2016        } while (i < wdata->nr_pages);
2017
2018        /* cleanup remaining pages from the original wdata */
2019        for (; i < wdata->nr_pages; i++) {
2020                SetPageError(wdata->pages[i]);
2021                end_page_writeback(wdata->pages[i]);
2022                put_page(wdata->pages[i]);
2023        }
2024
2025        if (rc != 0 && !is_retryable_error(rc))
2026                mapping_set_error(inode->i_mapping, rc);
2027        kref_put(&wdata->refcount, cifs_writedata_release);
2028}
2029
2030void
2031cifs_writev_complete(struct work_struct *work)
2032{
2033        struct cifs_writedata *wdata = container_of(work,
2034                                                struct cifs_writedata, work);
2035        struct inode *inode = d_inode(wdata->cfile->dentry);
2036        int i = 0;
2037
2038        if (wdata->result == 0) {
2039                spin_lock(&inode->i_lock);
2040                cifs_update_eof(CIFS_I(inode), wdata->offset, wdata->bytes);
2041                spin_unlock(&inode->i_lock);
2042                cifs_stats_bytes_written(tlink_tcon(wdata->cfile->tlink),
2043                                         wdata->bytes);
2044        } else if (wdata->sync_mode == WB_SYNC_ALL && wdata->result == -EAGAIN)
2045                return cifs_writev_requeue(wdata);
2046
2047        for (i = 0; i < wdata->nr_pages; i++) {
2048                struct page *page = wdata->pages[i];
2049                if (wdata->result == -EAGAIN)
2050                        __set_page_dirty_nobuffers(page);
2051                else if (wdata->result < 0)
2052                        SetPageError(page);
2053                end_page_writeback(page);
2054                cifs_readpage_to_fscache(inode, page);
2055                put_page(page);
2056        }
2057        if (wdata->result != -EAGAIN)
2058                mapping_set_error(inode->i_mapping, wdata->result);
2059        kref_put(&wdata->refcount, cifs_writedata_release);
2060}
2061
2062struct cifs_writedata *
2063cifs_writedata_alloc(unsigned int nr_pages, work_func_t complete)
2064{
2065        struct page **pages =
2066                kcalloc(nr_pages, sizeof(struct page *), GFP_NOFS);
2067        if (pages)
2068                return cifs_writedata_direct_alloc(pages, complete);
2069
2070        return NULL;
2071}
2072
2073struct cifs_writedata *
2074cifs_writedata_direct_alloc(struct page **pages, work_func_t complete)
2075{
2076        struct cifs_writedata *wdata;
2077
2078        wdata = kzalloc(sizeof(*wdata), GFP_NOFS);
2079        if (wdata != NULL) {
2080                wdata->pages = pages;
2081                kref_init(&wdata->refcount);
2082                INIT_LIST_HEAD(&wdata->list);
2083                init_completion(&wdata->done);
2084                INIT_WORK(&wdata->work, complete);
2085        }
2086        return wdata;
2087}
2088
2089/*
2090 * Check the mid_state and signature on received buffer (if any), and queue the
2091 * workqueue completion task.
2092 */
2093static void
2094cifs_writev_callback(struct mid_q_entry *mid)
2095{
2096        struct cifs_writedata *wdata = mid->callback_data;
2097        struct cifs_tcon *tcon = tlink_tcon(wdata->cfile->tlink);
2098        unsigned int written;
2099        WRITE_RSP *smb = (WRITE_RSP *)mid->resp_buf;
2100        struct cifs_credits credits = { .value = 1, .instance = 0 };
2101
2102        switch (mid->mid_state) {
2103        case MID_RESPONSE_RECEIVED:
2104                wdata->result = cifs_check_receive(mid, tcon->ses->server, 0);
2105                if (wdata->result != 0)
2106                        break;
2107
2108                written = le16_to_cpu(smb->CountHigh);
2109                written <<= 16;
2110                written += le16_to_cpu(smb->Count);
2111                /*
2112                 * Mask off high 16 bits when bytes written as returned
2113                 * by the server is greater than bytes requested by the
2114                 * client. OS/2 servers are known to set incorrect
2115                 * CountHigh values.
2116                 */
2117                if (written > wdata->bytes)
2118                        written &= 0xFFFF;
2119
2120                if (written < wdata->bytes)
2121                        wdata->result = -ENOSPC;
2122                else
2123                        wdata->bytes = written;
2124                break;
2125        case MID_REQUEST_SUBMITTED:
2126        case MID_RETRY_NEEDED:
2127                wdata->result = -EAGAIN;
2128                break;
2129        default:
2130                wdata->result = -EIO;
2131                break;
2132        }
2133
2134        queue_work(cifsiod_wq, &wdata->work);
2135        DeleteMidQEntry(mid);
2136        add_credits(tcon->ses->server, &credits, 0);
2137}
2138
2139/* cifs_async_writev - send an async write, and set up mid to handle result */
2140int
2141cifs_async_writev(struct cifs_writedata *wdata,
2142                  void (*release)(struct kref *kref))
2143{
2144        int rc = -EACCES;
2145        WRITE_REQ *smb = NULL;
2146        int wct;
2147        struct cifs_tcon *tcon = tlink_tcon(wdata->cfile->tlink);
2148        struct kvec iov[2];
2149        struct smb_rqst rqst = { };
2150
2151        if (tcon->ses->capabilities & CAP_LARGE_FILES) {
2152                wct = 14;
2153        } else {
2154                wct = 12;
2155                if (wdata->offset >> 32 > 0) {
2156                        /* can not handle big offset for old srv */
2157                        return -EIO;
2158                }
2159        }
2160
2161        rc = small_smb_init(SMB_COM_WRITE_ANDX, wct, tcon, (void **)&smb);
2162        if (rc)
2163                goto async_writev_out;
2164
2165        smb->hdr.Pid = cpu_to_le16((__u16)wdata->pid);
2166        smb->hdr.PidHigh = cpu_to_le16((__u16)(wdata->pid >> 16));
2167
2168        smb->AndXCommand = 0xFF;        /* none */
2169        smb->Fid = wdata->cfile->fid.netfid;
2170        smb->OffsetLow = cpu_to_le32(wdata->offset & 0xFFFFFFFF);
2171        if (wct == 14)
2172                smb->OffsetHigh = cpu_to_le32(wdata->offset >> 32);
2173        smb->Reserved = 0xFFFFFFFF;
2174        smb->WriteMode = 0;
2175        smb->Remaining = 0;
2176
2177        smb->DataOffset =
2178            cpu_to_le16(offsetof(struct smb_com_write_req, Data) - 4);
2179
2180        /* 4 for RFC1001 length + 1 for BCC */
2181        iov[0].iov_len = 4;
2182        iov[0].iov_base = smb;
2183        iov[1].iov_len = get_rfc1002_length(smb) + 1;
2184        iov[1].iov_base = (char *)smb + 4;
2185
2186        rqst.rq_iov = iov;
2187        rqst.rq_nvec = 2;
2188        rqst.rq_pages = wdata->pages;
2189        rqst.rq_offset = wdata->page_offset;
2190        rqst.rq_npages = wdata->nr_pages;
2191        rqst.rq_pagesz = wdata->pagesz;
2192        rqst.rq_tailsz = wdata->tailsz;
2193
2194        cifs_dbg(FYI, "async write at %llu %u bytes\n",
2195                 wdata->offset, wdata->bytes);
2196
2197        smb->DataLengthLow = cpu_to_le16(wdata->bytes & 0xFFFF);
2198        smb->DataLengthHigh = cpu_to_le16(wdata->bytes >> 16);
2199
2200        if (wct == 14) {
2201                inc_rfc1001_len(&smb->hdr, wdata->bytes + 1);
2202                put_bcc(wdata->bytes + 1, &smb->hdr);
2203        } else {
2204                /* wct == 12 */
2205                struct smb_com_writex_req *smbw =
2206                                (struct smb_com_writex_req *)smb;
2207                inc_rfc1001_len(&smbw->hdr, wdata->bytes + 5);
2208                put_bcc(wdata->bytes + 5, &smbw->hdr);
2209                iov[1].iov_len += 4; /* pad bigger by four bytes */
2210        }
2211
2212        kref_get(&wdata->refcount);
2213        rc = cifs_call_async(tcon->ses->server, &rqst, NULL,
2214                             cifs_writev_callback, NULL, wdata, 0, NULL);
2215
2216        if (rc == 0)
2217                cifs_stats_inc(&tcon->stats.cifs_stats.num_writes);
2218        else
2219                kref_put(&wdata->refcount, release);
2220
2221async_writev_out:
2222        cifs_small_buf_release(smb);
2223        return rc;
2224}
2225
2226int
2227CIFSSMBWrite2(const unsigned int xid, struct cifs_io_parms *io_parms,
2228              unsigned int *nbytes, struct kvec *iov, int n_vec)
2229{
2230        int rc;
2231        WRITE_REQ *pSMB = NULL;
2232        int wct;
2233        int smb_hdr_len;
2234        int resp_buf_type = 0;
2235        __u32 pid = io_parms->pid;
2236        __u16 netfid = io_parms->netfid;
2237        __u64 offset = io_parms->offset;
2238        struct cifs_tcon *tcon = io_parms->tcon;
2239        unsigned int count = io_parms->length;
2240        struct kvec rsp_iov;
2241
2242        *nbytes = 0;
2243
2244        cifs_dbg(FYI, "write2 at %lld %d bytes\n", (long long)offset, count);
2245
2246        if (tcon->ses->capabilities & CAP_LARGE_FILES) {
2247                wct = 14;
2248        } else {
2249                wct = 12;
2250                if ((offset >> 32) > 0) {
2251                        /* can not handle big offset for old srv */
2252                        return -EIO;
2253                }
2254        }
2255        rc = small_smb_init(SMB_COM_WRITE_ANDX, wct, tcon, (void **) &pSMB);
2256        if (rc)
2257                return rc;
2258
2259        pSMB->hdr.Pid = cpu_to_le16((__u16)pid);
2260        pSMB->hdr.PidHigh = cpu_to_le16((__u16)(pid >> 16));
2261
2262        /* tcon and ses pointer are checked in smb_init */
2263        if (tcon->ses->server == NULL)
2264                return -ECONNABORTED;
2265
2266        pSMB->AndXCommand = 0xFF;       /* none */
2267        pSMB->Fid = netfid;
2268        pSMB->OffsetLow = cpu_to_le32(offset & 0xFFFFFFFF);
2269        if (wct == 14)
2270                pSMB->OffsetHigh = cpu_to_le32(offset >> 32);
2271        pSMB->Reserved = 0xFFFFFFFF;
2272        pSMB->WriteMode = 0;
2273        pSMB->Remaining = 0;
2274
2275        pSMB->DataOffset =
2276            cpu_to_le16(offsetof(struct smb_com_write_req, Data) - 4);
2277
2278        pSMB->DataLengthLow = cpu_to_le16(count & 0xFFFF);
2279        pSMB->DataLengthHigh = cpu_to_le16(count >> 16);
2280        /* header + 1 byte pad */
2281        smb_hdr_len = be32_to_cpu(pSMB->hdr.smb_buf_length) + 1;
2282        if (wct == 14)
2283                inc_rfc1001_len(pSMB, count + 1);
2284        else /* wct == 12 */
2285                inc_rfc1001_len(pSMB, count + 5); /* smb data starts later */
2286        if (wct == 14)
2287                pSMB->ByteCount = cpu_to_le16(count + 1);
2288        else /* wct == 12 */ /* bigger pad, smaller smb hdr, keep offset ok */ {
2289                struct smb_com_writex_req *pSMBW =
2290                                (struct smb_com_writex_req *)pSMB;
2291                pSMBW->ByteCount = cpu_to_le16(count + 5);
2292        }
2293        iov[0].iov_base = pSMB;
2294        if (wct == 14)
2295                iov[0].iov_len = smb_hdr_len + 4;
2296        else /* wct == 12 pad bigger by four bytes */
2297                iov[0].iov_len = smb_hdr_len + 8;
2298
2299        rc = SendReceive2(xid, tcon->ses, iov, n_vec + 1, &resp_buf_type, 0,
2300                          &rsp_iov);
2301        cifs_small_buf_release(pSMB);
2302        cifs_stats_inc(&tcon->stats.cifs_stats.num_writes);
2303        if (rc) {
2304                cifs_dbg(FYI, "Send error Write2 = %d\n", rc);
2305        } else if (resp_buf_type == 0) {
2306                /* presumably this can not happen, but best to be safe */
2307                rc = -EIO;
2308        } else {
2309                WRITE_RSP *pSMBr = (WRITE_RSP *)rsp_iov.iov_base;
2310                *nbytes = le16_to_cpu(pSMBr->CountHigh);
2311                *nbytes = (*nbytes) << 16;
2312                *nbytes += le16_to_cpu(pSMBr->Count);
2313
2314                /*
2315                 * Mask off high 16 bits when bytes written as returned by the
2316                 * server is greater than bytes requested by the client. OS/2
2317                 * servers are known to set incorrect CountHigh values.
2318                 */
2319                if (*nbytes > count)
2320                        *nbytes &= 0xFFFF;
2321        }
2322
2323        free_rsp_buf(resp_buf_type, rsp_iov.iov_base);
2324
2325        /* Note: On -EAGAIN error only caller can retry on handle based calls
2326                since file handle passed in no longer valid */
2327
2328        return rc;
2329}
2330
2331int cifs_lockv(const unsigned int xid, struct cifs_tcon *tcon,
2332               const __u16 netfid, const __u8 lock_type, const __u32 num_unlock,
2333               const __u32 num_lock, LOCKING_ANDX_RANGE *buf)
2334{
2335        int rc = 0;
2336        LOCK_REQ *pSMB = NULL;
2337        struct kvec iov[2];
2338        struct kvec rsp_iov;
2339        int resp_buf_type;
2340        __u16 count;
2341
2342        cifs_dbg(FYI, "cifs_lockv num lock %d num unlock %d\n",
2343                 num_lock, num_unlock);
2344
2345        rc = small_smb_init(SMB_COM_LOCKING_ANDX, 8, tcon, (void **) &pSMB);
2346        if (rc)
2347                return rc;
2348
2349        pSMB->Timeout = 0;
2350        pSMB->NumberOfLocks = cpu_to_le16(num_lock);
2351        pSMB->NumberOfUnlocks = cpu_to_le16(num_unlock);
2352        pSMB->LockType = lock_type;
2353        pSMB->AndXCommand = 0xFF; /* none */
2354        pSMB->Fid = netfid; /* netfid stays le */
2355
2356        count = (num_unlock + num_lock) * sizeof(LOCKING_ANDX_RANGE);
2357        inc_rfc1001_len(pSMB, count);
2358        pSMB->ByteCount = cpu_to_le16(count);
2359
2360        iov[0].iov_base = (char *)pSMB;
2361        iov[0].iov_len = be32_to_cpu(pSMB->hdr.smb_buf_length) + 4 -
2362                         (num_unlock + num_lock) * sizeof(LOCKING_ANDX_RANGE);
2363        iov[1].iov_base = (char *)buf;
2364        iov[1].iov_len = (num_unlock + num_lock) * sizeof(LOCKING_ANDX_RANGE);
2365
2366        cifs_stats_inc(&tcon->stats.cifs_stats.num_locks);
2367        rc = SendReceive2(xid, tcon->ses, iov, 2, &resp_buf_type,
2368                          CIFS_NO_RSP_BUF, &rsp_iov);
2369        cifs_small_buf_release(pSMB);
2370        if (rc)
2371                cifs_dbg(FYI, "Send error in cifs_lockv = %d\n", rc);
2372
2373        return rc;
2374}
2375
2376int
2377CIFSSMBLock(const unsigned int xid, struct cifs_tcon *tcon,
2378            const __u16 smb_file_id, const __u32 netpid, const __u64 len,
2379            const __u64 offset, const __u32 numUnlock,
2380            const __u32 numLock, const __u8 lockType,
2381            const bool waitFlag, const __u8 oplock_level)
2382{
2383        int rc = 0;
2384        LOCK_REQ *pSMB = NULL;
2385/*      LOCK_RSP *pSMBr = NULL; */ /* No response data other than rc to parse */
2386        int bytes_returned;
2387        int flags = 0;
2388        __u16 count;
2389
2390        cifs_dbg(FYI, "CIFSSMBLock timeout %d numLock %d\n",
2391                 (int)waitFlag, numLock);
2392        rc = small_smb_init(SMB_COM_LOCKING_ANDX, 8, tcon, (void **) &pSMB);
2393
2394        if (rc)
2395                return rc;
2396
2397        if (lockType == LOCKING_ANDX_OPLOCK_RELEASE) {
2398                /* no response expected */
2399                flags = CIFS_NO_SRV_RSP | CIFS_NON_BLOCKING | CIFS_OBREAK_OP;
2400                pSMB->Timeout = 0;
2401        } else if (waitFlag) {
2402                flags = CIFS_BLOCKING_OP; /* blocking operation, no timeout */
2403                pSMB->Timeout = cpu_to_le32(-1);/* blocking - do not time out */
2404        } else {
2405                pSMB->Timeout = 0;
2406        }
2407
2408        pSMB->NumberOfLocks = cpu_to_le16(numLock);
2409        pSMB->NumberOfUnlocks = cpu_to_le16(numUnlock);
2410        pSMB->LockType = lockType;
2411        pSMB->OplockLevel = oplock_level;
2412        pSMB->AndXCommand = 0xFF;       /* none */
2413        pSMB->Fid = smb_file_id; /* netfid stays le */
2414
2415        if ((numLock != 0) || (numUnlock != 0)) {
2416                pSMB->Locks[0].Pid = cpu_to_le16(netpid);
2417                /* BB where to store pid high? */
2418                pSMB->Locks[0].LengthLow = cpu_to_le32((u32)len);
2419                pSMB->Locks[0].LengthHigh = cpu_to_le32((u32)(len>>32));
2420                pSMB->Locks[0].OffsetLow = cpu_to_le32((u32)offset);
2421                pSMB->Locks[0].OffsetHigh = cpu_to_le32((u32)(offset>>32));
2422                count = sizeof(LOCKING_ANDX_RANGE);
2423        } else {
2424                /* oplock break */
2425                count = 0;
2426        }
2427        inc_rfc1001_len(pSMB, count);
2428        pSMB->ByteCount = cpu_to_le16(count);
2429
2430        if (waitFlag)
2431                rc = SendReceiveBlockingLock(xid, tcon, (struct smb_hdr *) pSMB,
2432                        (struct smb_hdr *) pSMB, &bytes_returned);
2433        else
2434                rc = SendReceiveNoRsp(xid, tcon->ses, (char *)pSMB, flags);
2435        cifs_small_buf_release(pSMB);
2436        cifs_stats_inc(&tcon->stats.cifs_stats.num_locks);
2437        if (rc)
2438                cifs_dbg(FYI, "Send error in Lock = %d\n", rc);
2439
2440        /* Note: On -EAGAIN error only caller can retry on handle based calls
2441        since file handle passed in no longer valid */
2442        return rc;
2443}
2444
2445int
2446CIFSSMBPosixLock(const unsigned int xid, struct cifs_tcon *tcon,
2447                const __u16 smb_file_id, const __u32 netpid,
2448                const loff_t start_offset, const __u64 len,
2449                struct file_lock *pLockData, const __u16 lock_type,
2450                const bool waitFlag)
2451{
2452        struct smb_com_transaction2_sfi_req *pSMB  = NULL;
2453        struct smb_com_transaction2_sfi_rsp *pSMBr = NULL;
2454        struct cifs_posix_lock *parm_data;
2455        int rc = 0;
2456        int timeout = 0;
2457        int bytes_returned = 0;
2458        int resp_buf_type = 0;
2459        __u16 params, param_offset, offset, byte_count, count;
2460        struct kvec iov[1];
2461        struct kvec rsp_iov;
2462
2463        cifs_dbg(FYI, "Posix Lock\n");
2464
2465        rc = small_smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB);
2466
2467        if (rc)
2468                return rc;
2469
2470        pSMBr = (struct smb_com_transaction2_sfi_rsp *)pSMB;
2471
2472        params = 6;
2473        pSMB->MaxSetupCount = 0;
2474        pSMB->Reserved = 0;
2475        pSMB->Flags = 0;
2476        pSMB->Reserved2 = 0;
2477        param_offset = offsetof(struct smb_com_transaction2_sfi_req, Fid) - 4;
2478        offset = param_offset + params;
2479
2480        count = sizeof(struct cifs_posix_lock);
2481        pSMB->MaxParameterCount = cpu_to_le16(2);
2482        pSMB->MaxDataCount = cpu_to_le16(1000); /* BB find max SMB from sess */
2483        pSMB->SetupCount = 1;
2484        pSMB->Reserved3 = 0;
2485        if (pLockData)
2486                pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_FILE_INFORMATION);
2487        else
2488                pSMB->SubCommand = cpu_to_le16(TRANS2_SET_FILE_INFORMATION);
2489        byte_count = 3 /* pad */  + params + count;
2490        pSMB->DataCount = cpu_to_le16(count);
2491        pSMB->ParameterCount = cpu_to_le16(params);
2492        pSMB->TotalDataCount = pSMB->DataCount;
2493        pSMB->TotalParameterCount = pSMB->ParameterCount;
2494        pSMB->ParameterOffset = cpu_to_le16(param_offset);
2495        /* SMB offsets are from the beginning of SMB which is 4 bytes in, after RFC1001 field */
2496        parm_data = (struct cifs_posix_lock *)
2497                        (((char *)pSMB) + offset + 4);
2498
2499        parm_data->lock_type = cpu_to_le16(lock_type);
2500        if (waitFlag) {
2501                timeout = CIFS_BLOCKING_OP; /* blocking operation, no timeout */
2502                parm_data->lock_flags = cpu_to_le16(1);
2503                pSMB->Timeout = cpu_to_le32(-1);
2504        } else
2505                pSMB->Timeout = 0;
2506
2507        parm_data->pid = cpu_to_le32(netpid);
2508        parm_data->start = cpu_to_le64(start_offset);
2509        parm_data->length = cpu_to_le64(len);  /* normalize negative numbers */
2510
2511        pSMB->DataOffset = cpu_to_le16(offset);
2512        pSMB->Fid = smb_file_id;
2513        pSMB->InformationLevel = cpu_to_le16(SMB_SET_POSIX_LOCK);
2514        pSMB->Reserved4 = 0;
2515        inc_rfc1001_len(pSMB, byte_count);
2516        pSMB->ByteCount = cpu_to_le16(byte_count);
2517        if (waitFlag) {
2518                rc = SendReceiveBlockingLock(xid, tcon, (struct smb_hdr *) pSMB,
2519                        (struct smb_hdr *) pSMBr, &bytes_returned);
2520        } else {
2521                iov[0].iov_base = (char *)pSMB;
2522                iov[0].iov_len = be32_to_cpu(pSMB->hdr.smb_buf_length) + 4;
2523                rc = SendReceive2(xid, tcon->ses, iov, 1 /* num iovecs */,
2524                                &resp_buf_type, timeout, &rsp_iov);
2525                pSMBr = (struct smb_com_transaction2_sfi_rsp *)rsp_iov.iov_base;
2526        }
2527        cifs_small_buf_release(pSMB);
2528
2529        if (rc) {
2530                cifs_dbg(FYI, "Send error in Posix Lock = %d\n", rc);
2531        } else if (pLockData) {
2532                /* lock structure can be returned on get */
2533                __u16 data_offset;
2534                __u16 data_count;
2535                rc = validate_t2((struct smb_t2_rsp *)pSMBr);
2536
2537                if (rc || get_bcc(&pSMBr->hdr) < sizeof(*parm_data)) {
2538                        rc = -EIO;      /* bad smb */
2539                        goto plk_err_exit;
2540                }
2541                data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
2542                data_count  = le16_to_cpu(pSMBr->t2.DataCount);
2543                if (data_count < sizeof(struct cifs_posix_lock)) {
2544                        rc = -EIO;
2545                        goto plk_err_exit;
2546                }
2547                parm_data = (struct cifs_posix_lock *)
2548                        ((char *)&pSMBr->hdr.Protocol + data_offset);
2549                if (parm_data->lock_type == cpu_to_le16(CIFS_UNLCK))
2550                        pLockData->fl_type = F_UNLCK;
2551                else {
2552                        if (parm_data->lock_type ==
2553                                        cpu_to_le16(CIFS_RDLCK))
2554                                pLockData->fl_type = F_RDLCK;
2555                        else if (parm_data->lock_type ==
2556                                        cpu_to_le16(CIFS_WRLCK))
2557                                pLockData->fl_type = F_WRLCK;
2558
2559                        pLockData->fl_start = le64_to_cpu(parm_data->start);
2560                        pLockData->fl_end = pLockData->fl_start +
2561                                (le64_to_cpu(parm_data->length) ?
2562                                 le64_to_cpu(parm_data->length) - 1 : 0);
2563                        pLockData->fl_pid = -le32_to_cpu(parm_data->pid);
2564                }
2565        }
2566
2567plk_err_exit:
2568        free_rsp_buf(resp_buf_type, rsp_iov.iov_base);
2569
2570        /* Note: On -EAGAIN error only caller can retry on handle based calls
2571           since file handle passed in no longer valid */
2572
2573        return rc;
2574}
2575
2576
2577int
2578CIFSSMBClose(const unsigned int xid, struct cifs_tcon *tcon, int smb_file_id)
2579{
2580        int rc = 0;
2581        CLOSE_REQ *pSMB = NULL;
2582        cifs_dbg(FYI, "In CIFSSMBClose\n");
2583
2584/* do not retry on dead session on close */
2585        rc = small_smb_init(SMB_COM_CLOSE, 3, tcon, (void **) &pSMB);
2586        if (rc == -EAGAIN)
2587                return 0;
2588        if (rc)
2589                return rc;
2590
2591        pSMB->FileID = (__u16) smb_file_id;
2592        pSMB->LastWriteTime = 0xFFFFFFFF;
2593        pSMB->ByteCount = 0;
2594        rc = SendReceiveNoRsp(xid, tcon->ses, (char *) pSMB, 0);
2595        cifs_small_buf_release(pSMB);
2596        cifs_stats_inc(&tcon->stats.cifs_stats.num_closes);
2597        if (rc) {
2598                if (rc != -EINTR) {
2599                        /* EINTR is expected when user ctl-c to kill app */
2600                        cifs_dbg(VFS, "Send error in Close = %d\n", rc);
2601                }
2602        }
2603
2604        /* Since session is dead, file will be closed on server already */
2605        if (rc == -EAGAIN)
2606                rc = 0;
2607
2608        return rc;
2609}
2610
2611int
2612CIFSSMBFlush(const unsigned int xid, struct cifs_tcon *tcon, int smb_file_id)
2613{
2614        int rc = 0;
2615        FLUSH_REQ *pSMB = NULL;
2616        cifs_dbg(FYI, "In CIFSSMBFlush\n");
2617
2618        rc = small_smb_init(SMB_COM_FLUSH, 1, tcon, (void **) &pSMB);
2619        if (rc)
2620                return rc;
2621
2622        pSMB->FileID = (__u16) smb_file_id;
2623        pSMB->ByteCount = 0;
2624        rc = SendReceiveNoRsp(xid, tcon->ses, (char *) pSMB, 0);
2625        cifs_small_buf_release(pSMB);
2626        cifs_stats_inc(&tcon->stats.cifs_stats.num_flushes);
2627        if (rc)
2628                cifs_dbg(VFS, "Send error in Flush = %d\n", rc);
2629
2630        return rc;
2631}
2632
2633int
2634CIFSSMBRename(const unsigned int xid, struct cifs_tcon *tcon,
2635              const char *from_name, const char *to_name,
2636              struct cifs_sb_info *cifs_sb)
2637{
2638        int rc = 0;
2639        RENAME_REQ *pSMB = NULL;
2640        RENAME_RSP *pSMBr = NULL;
2641        int bytes_returned;
2642        int name_len, name_len2;
2643        __u16 count;
2644        int remap = cifs_remap(cifs_sb);
2645
2646        cifs_dbg(FYI, "In CIFSSMBRename\n");
2647renameRetry:
2648        rc = smb_init(SMB_COM_RENAME, 1, tcon, (void **) &pSMB,
2649                      (void **) &pSMBr);
2650        if (rc)
2651                return rc;
2652
2653        pSMB->BufferFormat = 0x04;
2654        pSMB->SearchAttributes =
2655            cpu_to_le16(ATTR_READONLY | ATTR_HIDDEN | ATTR_SYSTEM |
2656                        ATTR_DIRECTORY);
2657
2658        if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
2659                name_len = cifsConvertToUTF16((__le16 *) pSMB->OldFileName,
2660                                              from_name, PATH_MAX,
2661                                              cifs_sb->local_nls, remap);
2662                name_len++;     /* trailing null */
2663                name_len *= 2;
2664                pSMB->OldFileName[name_len] = 0x04;     /* pad */
2665        /* protocol requires ASCII signature byte on Unicode string */
2666                pSMB->OldFileName[name_len + 1] = 0x00;
2667                name_len2 =
2668                    cifsConvertToUTF16((__le16 *)&pSMB->OldFileName[name_len+2],
2669                                       to_name, PATH_MAX, cifs_sb->local_nls,
2670                                       remap);
2671                name_len2 += 1 /* trailing null */  + 1 /* Signature word */ ;
2672                name_len2 *= 2; /* convert to bytes */
2673        } else {
2674                name_len = copy_path_name(pSMB->OldFileName, from_name);
2675                name_len2 = copy_path_name(pSMB->OldFileName+name_len+1, to_name);
2676                pSMB->OldFileName[name_len] = 0x04;  /* 2nd buffer format */
2677                name_len2++;    /* signature byte */
2678        }
2679
2680        count = 1 /* 1st signature byte */  + name_len + name_len2;
2681        inc_rfc1001_len(pSMB, count);
2682        pSMB->ByteCount = cpu_to_le16(count);
2683
2684        rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
2685                         (struct smb_hdr *) pSMBr, &bytes_returned, 0);
2686        cifs_stats_inc(&tcon->stats.cifs_stats.num_renames);
2687        if (rc)
2688                cifs_dbg(FYI, "Send error in rename = %d\n", rc);
2689
2690        cifs_buf_release(pSMB);
2691
2692        if (rc == -EAGAIN)
2693                goto renameRetry;
2694
2695        return rc;
2696}
2697
2698int CIFSSMBRenameOpenFile(const unsigned int xid, struct cifs_tcon *pTcon,
2699                int netfid, const char *target_name,
2700                const struct nls_table *nls_codepage, int remap)
2701{
2702        struct smb_com_transaction2_sfi_req *pSMB  = NULL;
2703        struct smb_com_transaction2_sfi_rsp *pSMBr = NULL;
2704        struct set_file_rename *rename_info;
2705        char *data_offset;
2706        char dummy_string[30];
2707        int rc = 0;
2708        int bytes_returned = 0;
2709        int len_of_str;
2710        __u16 params, param_offset, offset, count, byte_count;
2711
2712        cifs_dbg(FYI, "Rename to File by handle\n");
2713        rc = smb_init(SMB_COM_TRANSACTION2, 15, pTcon, (void **) &pSMB,
2714                        (void **) &pSMBr);
2715        if (rc)
2716                return rc;
2717
2718        params = 6;
2719        pSMB->MaxSetupCount = 0;
2720        pSMB->Reserved = 0;
2721        pSMB->Flags = 0;
2722        pSMB->Timeout = 0;
2723        pSMB->Reserved2 = 0;
2724        param_offset = offsetof(struct smb_com_transaction2_sfi_req, Fid) - 4;
2725        offset = param_offset + params;
2726
2727        /* SMB offsets are from the beginning of SMB which is 4 bytes in, after RFC1001 field */
2728        data_offset = (char *)(pSMB) + offset + 4;
2729        rename_info = (struct set_file_rename *) data_offset;
2730        pSMB->MaxParameterCount = cpu_to_le16(2);
2731        pSMB->MaxDataCount = cpu_to_le16(1000); /* BB find max SMB from sess */
2732        pSMB->SetupCount = 1;
2733        pSMB->Reserved3 = 0;
2734        pSMB->SubCommand = cpu_to_le16(TRANS2_SET_FILE_INFORMATION);
2735        byte_count = 3 /* pad */  + params;
2736        pSMB->ParameterCount = cpu_to_le16(params);
2737        pSMB->TotalParameterCount = pSMB->ParameterCount;
2738        pSMB->ParameterOffset = cpu_to_le16(param_offset);
2739        pSMB->DataOffset = cpu_to_le16(offset);
2740        /* construct random name ".cifs_tmp<inodenum><mid>" */
2741        rename_info->overwrite = cpu_to_le32(1);
2742        rename_info->root_fid  = 0;
2743        /* unicode only call */
2744        if (target_name == NULL) {
2745                sprintf(dummy_string, "cifs%x", pSMB->hdr.Mid);
2746                len_of_str =
2747                        cifsConvertToUTF16((__le16 *)rename_info->target_name,
2748                                        dummy_string, 24, nls_codepage, remap);
2749        } else {
2750                len_of_str =
2751                        cifsConvertToUTF16((__le16 *)rename_info->target_name,
2752                                        target_name, PATH_MAX, nls_codepage,
2753                                        remap);
2754        }
2755        rename_info->target_name_len = cpu_to_le32(2 * len_of_str);
2756        count = 12 /* sizeof(struct set_file_rename) */ + (2 * len_of_str);
2757        byte_count += count;
2758        pSMB->DataCount = cpu_to_le16(count);
2759        pSMB->TotalDataCount = pSMB->DataCount;
2760        pSMB->Fid = netfid;
2761        pSMB->InformationLevel =
2762                cpu_to_le16(SMB_SET_FILE_RENAME_INFORMATION);
2763        pSMB->Reserved4 = 0;
2764        inc_rfc1001_len(pSMB, byte_count);
2765        pSMB->ByteCount = cpu_to_le16(byte_count);
2766        rc = SendReceive(xid, pTcon->ses, (struct smb_hdr *) pSMB,
2767                         (struct smb_hdr *) pSMBr, &bytes_returned, 0);
2768        cifs_stats_inc(&pTcon->stats.cifs_stats.num_t2renames);
2769        if (rc)
2770                cifs_dbg(FYI, "Send error in Rename (by file handle) = %d\n",
2771                         rc);
2772
2773        cifs_buf_release(pSMB);
2774
2775        /* Note: On -EAGAIN error only caller can retry on handle based calls
2776                since file handle passed in no longer valid */
2777
2778        return rc;
2779}
2780
2781int
2782CIFSSMBCopy(const unsigned int xid, struct cifs_tcon *tcon,
2783            const char *fromName, const __u16 target_tid, const char *toName,
2784            const int flags, const struct nls_table *nls_codepage, int remap)
2785{
2786        int rc = 0;
2787        COPY_REQ *pSMB = NULL;
2788        COPY_RSP *pSMBr = NULL;
2789        int bytes_returned;
2790        int name_len, name_len2;
2791        __u16 count;
2792
2793        cifs_dbg(FYI, "In CIFSSMBCopy\n");
2794copyRetry:
2795        rc = smb_init(SMB_COM_COPY, 1, tcon, (void **) &pSMB,
2796                        (void **) &pSMBr);
2797        if (rc)
2798                return rc;
2799
2800        pSMB->BufferFormat = 0x04;
2801        pSMB->Tid2 = target_tid;
2802
2803        pSMB->Flags = cpu_to_le16(flags & COPY_TREE);
2804
2805        if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
2806                name_len = cifsConvertToUTF16((__le16 *) pSMB->OldFileName,
2807                                              fromName, PATH_MAX, nls_codepage,
2808                                              remap);
2809                name_len++;     /* trailing null */
2810                name_len *= 2;
2811                pSMB->OldFileName[name_len] = 0x04;     /* pad */
2812                /* protocol requires ASCII signature byte on Unicode string */
2813                pSMB->OldFileName[name_len + 1] = 0x00;
2814                name_len2 =
2815                    cifsConvertToUTF16((__le16 *)&pSMB->OldFileName[name_len+2],
2816                                       toName, PATH_MAX, nls_codepage, remap);
2817                name_len2 += 1 /* trailing null */  + 1 /* Signature word */ ;
2818                name_len2 *= 2; /* convert to bytes */
2819        } else {
2820                name_len = copy_path_name(pSMB->OldFileName, fromName);
2821                pSMB->OldFileName[name_len] = 0x04;  /* 2nd buffer format */
2822                name_len2 = copy_path_name(pSMB->OldFileName+name_len+1, toName);
2823                name_len2++;    /* signature byte */
2824        }
2825
2826        count = 1 /* 1st signature byte */  + name_len + name_len2;
2827        inc_rfc1001_len(pSMB, count);
2828        pSMB->ByteCount = cpu_to_le16(count);
2829
2830        rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
2831                (struct smb_hdr *) pSMBr, &bytes_returned, 0);
2832        if (rc) {
2833                cifs_dbg(FYI, "Send error in copy = %d with %d files copied\n",
2834                         rc, le16_to_cpu(pSMBr->CopyCount));
2835        }
2836        cifs_buf_release(pSMB);
2837
2838        if (rc == -EAGAIN)
2839                goto copyRetry;
2840
2841        return rc;
2842}
2843
2844int
2845CIFSUnixCreateSymLink(const unsigned int xid, struct cifs_tcon *tcon,
2846                      const char *fromName, const char *toName,
2847                      const struct nls_table *nls_codepage, int remap)
2848{
2849        TRANSACTION2_SPI_REQ *pSMB = NULL;
2850        TRANSACTION2_SPI_RSP *pSMBr = NULL;
2851        char *data_offset;
2852        int name_len;
2853        int name_len_target;
2854        int rc = 0;
2855        int bytes_returned = 0;
2856        __u16 params, param_offset, offset, byte_count;
2857
2858        cifs_dbg(FYI, "In Symlink Unix style\n");
2859createSymLinkRetry:
2860        rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
2861                      (void **) &pSMBr);
2862        if (rc)
2863                return rc;
2864
2865        if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
2866                name_len =
2867                    cifsConvertToUTF16((__le16 *) pSMB->FileName, fromName,
2868                                /* find define for this maxpathcomponent */
2869                                        PATH_MAX, nls_codepage, remap);
2870                name_len++;     /* trailing null */
2871                name_len *= 2;
2872
2873        } else {
2874                name_len = copy_path_name(pSMB->FileName, fromName);
2875        }
2876        params = 6 + name_len;
2877        pSMB->MaxSetupCount = 0;
2878        pSMB->Reserved = 0;
2879        pSMB->Flags = 0;
2880        pSMB->Timeout = 0;
2881        pSMB->Reserved2 = 0;
2882        param_offset = offsetof(struct smb_com_transaction2_spi_req,
2883                                InformationLevel) - 4;
2884        offset = param_offset + params;
2885
2886        /* SMB offsets are from the beginning of SMB which is 4 bytes in, after RFC1001 field */
2887        data_offset = (char *)pSMB + offset + 4;
2888        if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
2889                name_len_target =
2890                    cifsConvertToUTF16((__le16 *) data_offset, toName,
2891                                /* find define for this maxpathcomponent */
2892                                        PATH_MAX, nls_codepage, remap);
2893                name_len_target++;      /* trailing null */
2894                name_len_target *= 2;
2895        } else {
2896                name_len_target = copy_path_name(data_offset, toName);
2897        }
2898
2899        pSMB->MaxParameterCount = cpu_to_le16(2);
2900        /* BB find exact max on data count below from sess */
2901        pSMB->MaxDataCount = cpu_to_le16(1000);
2902        pSMB->SetupCount = 1;
2903        pSMB->Reserved3 = 0;
2904        pSMB->SubCommand = cpu_to_le16(TRANS2_SET_PATH_INFORMATION);
2905        byte_count = 3 /* pad */  + params + name_len_target;
2906        pSMB->DataCount = cpu_to_le16(name_len_target);
2907        pSMB->ParameterCount = cpu_to_le16(params);
2908        pSMB->TotalDataCount = pSMB->DataCount;
2909        pSMB->TotalParameterCount = pSMB->ParameterCount;
2910        pSMB->ParameterOffset = cpu_to_le16(param_offset);
2911        pSMB->DataOffset = cpu_to_le16(offset);
2912        pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_UNIX_LINK);
2913        pSMB->Reserved4 = 0;
2914        inc_rfc1001_len(pSMB, byte_count);
2915        pSMB->ByteCount = cpu_to_le16(byte_count);
2916        rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
2917                         (struct smb_hdr *) pSMBr, &bytes_returned, 0);
2918        cifs_stats_inc(&tcon->stats.cifs_stats.num_symlinks);
2919        if (rc)
2920                cifs_dbg(FYI, "Send error in SetPathInfo create symlink = %d\n",
2921                         rc);
2922
2923        cifs_buf_release(pSMB);
2924
2925        if (rc == -EAGAIN)
2926                goto createSymLinkRetry;
2927
2928        return rc;
2929}
2930
2931int
2932CIFSUnixCreateHardLink(const unsigned int xid, struct cifs_tcon *tcon,
2933                       const char *fromName, const char *toName,
2934                       const struct nls_table *nls_codepage, int remap)
2935{
2936        TRANSACTION2_SPI_REQ *pSMB = NULL;
2937        TRANSACTION2_SPI_RSP *pSMBr = NULL;
2938        char *data_offset;
2939        int name_len;
2940        int name_len_target;
2941        int rc = 0;
2942        int bytes_returned = 0;
2943        __u16 params, param_offset, offset, byte_count;
2944
2945        cifs_dbg(FYI, "In Create Hard link Unix style\n");
2946createHardLinkRetry:
2947        rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
2948                      (void **) &pSMBr);
2949        if (rc)
2950                return rc;
2951
2952        if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
2953                name_len = cifsConvertToUTF16((__le16 *) pSMB->FileName, toName,
2954                                              PATH_MAX, nls_codepage, remap);
2955                name_len++;     /* trailing null */
2956                name_len *= 2;
2957
2958        } else {
2959                name_len = copy_path_name(pSMB->FileName, toName);
2960        }
2961        params = 6 + name_len;
2962        pSMB->MaxSetupCount = 0;
2963        pSMB->Reserved = 0;
2964        pSMB->Flags = 0;
2965        pSMB->Timeout = 0;
2966        pSMB->Reserved2 = 0;
2967        param_offset = offsetof(struct smb_com_transaction2_spi_req,
2968                                InformationLevel) - 4;
2969        offset = param_offset + params;
2970
2971        /* SMB offsets are from the beginning of SMB which is 4 bytes in, after RFC1001 field */
2972        data_offset = (char *)pSMB + offset + 4;
2973        if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
2974                name_len_target =
2975                    cifsConvertToUTF16((__le16 *) data_offset, fromName,
2976                                       PATH_MAX, nls_codepage, remap);
2977                name_len_target++;      /* trailing null */
2978                name_len_target *= 2;
2979        } else {
2980                name_len_target = copy_path_name(data_offset, fromName);
2981        }
2982
2983        pSMB->MaxParameterCount = cpu_to_le16(2);
2984        /* BB find exact max on data count below from sess*/
2985        pSMB->MaxDataCount = cpu_to_le16(1000);
2986        pSMB->SetupCount = 1;
2987        pSMB->Reserved3 = 0;
2988        pSMB->SubCommand = cpu_to_le16(TRANS2_SET_PATH_INFORMATION);
2989        byte_count = 3 /* pad */  + params + name_len_target;
2990        pSMB->ParameterCount = cpu_to_le16(params);
2991        pSMB->TotalParameterCount = pSMB->ParameterCount;
2992        pSMB->DataCount = cpu_to_le16(name_len_target);
2993        pSMB->TotalDataCount = pSMB->DataCount;
2994        pSMB->ParameterOffset = cpu_to_le16(param_offset);
2995        pSMB->DataOffset = cpu_to_le16(offset);
2996        pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_UNIX_HLINK);
2997        pSMB->Reserved4 = 0;
2998        inc_rfc1001_len(pSMB, byte_count);
2999        pSMB->ByteCount = cpu_to_le16(byte_count);
3000        rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
3001                         (struct smb_hdr *) pSMBr, &bytes_returned, 0);
3002        cifs_stats_inc(&tcon->stats.cifs_stats.num_hardlinks);
3003        if (rc)
3004                cifs_dbg(FYI, "Send error in SetPathInfo (hard link) = %d\n",
3005                         rc);
3006
3007        cifs_buf_release(pSMB);
3008        if (rc == -EAGAIN)
3009                goto createHardLinkRetry;
3010
3011        return rc;
3012}
3013
3014int
3015CIFSCreateHardLink(const unsigned int xid, struct cifs_tcon *tcon,
3016                   const char *from_name, const char *to_name,
3017                   struct cifs_sb_info *cifs_sb)
3018{
3019        int rc = 0;
3020        NT_RENAME_REQ *pSMB = NULL;
3021        RENAME_RSP *pSMBr = NULL;
3022        int bytes_returned;
3023        int name_len, name_len2;
3024        __u16 count;
3025        int remap = cifs_remap(cifs_sb);
3026
3027        cifs_dbg(FYI, "In CIFSCreateHardLink\n");
3028winCreateHardLinkRetry:
3029
3030        rc = smb_init(SMB_COM_NT_RENAME, 4, tcon, (void **) &pSMB,
3031                      (void **) &pSMBr);
3032        if (rc)
3033                return rc;
3034
3035        pSMB->SearchAttributes =
3036            cpu_to_le16(ATTR_READONLY | ATTR_HIDDEN | ATTR_SYSTEM |
3037                        ATTR_DIRECTORY);
3038        pSMB->Flags = cpu_to_le16(CREATE_HARD_LINK);
3039        pSMB->ClusterCount = 0;
3040
3041        pSMB->BufferFormat = 0x04;
3042
3043        if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
3044                name_len =
3045                    cifsConvertToUTF16((__le16 *) pSMB->OldFileName, from_name,
3046                                       PATH_MAX, cifs_sb->local_nls, remap);
3047                name_len++;     /* trailing null */
3048                name_len *= 2;
3049
3050                /* protocol specifies ASCII buffer format (0x04) for unicode */
3051                pSMB->OldFileName[name_len] = 0x04;
3052                pSMB->OldFileName[name_len + 1] = 0x00; /* pad */
3053                name_len2 =
3054                    cifsConvertToUTF16((__le16 *)&pSMB->OldFileName[name_len+2],
3055                                       to_name, PATH_MAX, cifs_sb->local_nls,
3056                                       remap);
3057                name_len2 += 1 /* trailing null */  + 1 /* Signature word */ ;
3058                name_len2 *= 2; /* convert to bytes */
3059        } else {
3060                name_len = copy_path_name(pSMB->OldFileName, from_name);
3061                pSMB->OldFileName[name_len] = 0x04;     /* 2nd buffer format */
3062                name_len2 = copy_path_name(pSMB->OldFileName+name_len+1, to_name);
3063                name_len2++;    /* signature byte */
3064        }
3065
3066        count = 1 /* string type byte */  + name_len + name_len2;
3067        inc_rfc1001_len(pSMB, count);
3068        pSMB->ByteCount = cpu_to_le16(count);
3069
3070        rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
3071                         (struct smb_hdr *) pSMBr, &bytes_returned, 0);
3072        cifs_stats_inc(&tcon->stats.cifs_stats.num_hardlinks);
3073        if (rc)
3074                cifs_dbg(FYI, "Send error in hard link (NT rename) = %d\n", rc);
3075
3076        cifs_buf_release(pSMB);
3077        if (rc == -EAGAIN)
3078                goto winCreateHardLinkRetry;
3079
3080        return rc;
3081}
3082
3083int
3084CIFSSMBUnixQuerySymLink(const unsigned int xid, struct cifs_tcon *tcon,
3085                        const unsigned char *searchName, char **symlinkinfo,
3086                        const struct nls_table *nls_codepage, int remap)
3087{
3088/* SMB_QUERY_FILE_UNIX_LINK */
3089        TRANSACTION2_QPI_REQ *pSMB = NULL;
3090        TRANSACTION2_QPI_RSP *pSMBr = NULL;
3091        int rc = 0;
3092        int bytes_returned;
3093        int name_len;
3094        __u16 params, byte_count;
3095        char *data_start;
3096
3097        cifs_dbg(FYI, "In QPathSymLinkInfo (Unix) for path %s\n", searchName);
3098
3099querySymLinkRetry:
3100        rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
3101                      (void **) &pSMBr);
3102        if (rc)
3103                return rc;
3104
3105        if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
3106                name_len =
3107                        cifsConvertToUTF16((__le16 *) pSMB->FileName,
3108                                           searchName, PATH_MAX, nls_codepage,
3109                                           remap);
3110                name_len++;     /* trailing null */
3111                name_len *= 2;
3112        } else {
3113                name_len = copy_path_name(pSMB->FileName, searchName);
3114        }
3115
3116        params = 2 /* level */  + 4 /* rsrvd */  + name_len /* incl null */ ;
3117        pSMB->TotalDataCount = 0;
3118        pSMB->MaxParameterCount = cpu_to_le16(2);
3119        pSMB->MaxDataCount = cpu_to_le16(CIFSMaxBufSize);
3120        pSMB->MaxSetupCount = 0;
3121        pSMB->Reserved = 0;
3122        pSMB->Flags = 0;
3123        pSMB->Timeout = 0;
3124        pSMB->Reserved2 = 0;
3125        pSMB->ParameterOffset = cpu_to_le16(offsetof(
3126        struct smb_com_transaction2_qpi_req, InformationLevel) - 4);
3127        pSMB->DataCount = 0;
3128        pSMB->DataOffset = 0;
3129        pSMB->SetupCount = 1;
3130        pSMB->Reserved3 = 0;
3131        pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_PATH_INFORMATION);
3132        byte_count = params + 1 /* pad */ ;
3133        pSMB->TotalParameterCount = cpu_to_le16(params);
3134        pSMB->ParameterCount = pSMB->TotalParameterCount;
3135        pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FILE_UNIX_LINK);
3136        pSMB->Reserved4 = 0;
3137        inc_rfc1001_len(pSMB, byte_count);
3138        pSMB->ByteCount = cpu_to_le16(byte_count);
3139
3140        rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
3141                         (struct smb_hdr *) pSMBr, &bytes_returned, 0);
3142        if (rc) {
3143                cifs_dbg(FYI, "Send error in QuerySymLinkInfo = %d\n", rc);
3144        } else {
3145                /* decode response */
3146
3147                rc = validate_t2((struct smb_t2_rsp *)pSMBr);
3148                /* BB also check enough total bytes returned */
3149                if (rc || get_bcc(&pSMBr->hdr) < 2)
3150                        rc = -EIO;
3151                else {
3152                        bool is_unicode;
3153                        u16 count = le16_to_cpu(pSMBr->t2.DataCount);
3154
3155                        data_start = ((char *) &pSMBr->hdr.Protocol) +
3156                                           le16_to_cpu(pSMBr->t2.DataOffset);
3157
3158                        if (pSMBr->hdr.Flags2 & SMBFLG2_UNICODE)
3159                                is_unicode = true;
3160                        else
3161                                is_unicode = false;
3162
3163                        /* BB FIXME investigate remapping reserved chars here */
3164                        *symlinkinfo = cifs_strndup_from_utf16(data_start,
3165                                        count, is_unicode, nls_codepage);
3166                        if (!*symlinkinfo)
3167                                rc = -ENOMEM;
3168                }
3169        }
3170        cifs_buf_release(pSMB);
3171        if (rc == -EAGAIN)
3172                goto querySymLinkRetry;
3173        return rc;
3174}
3175
3176/*
3177 *      Recent Windows versions now create symlinks more frequently
3178 *      and they use the "reparse point" mechanism below.  We can of course
3179 *      do symlinks nicely to Samba and other servers which support the
3180 *      CIFS Unix Extensions and we can also do SFU symlinks and "client only"
3181 *      "MF" symlinks optionally, but for recent Windows we really need to
3182 *      reenable the code below and fix the cifs_symlink callers to handle this.
3183 *      In the interim this code has been moved to its own config option so
3184 *      it is not compiled in by default until callers fixed up and more tested.
3185 */
3186int
3187CIFSSMBQuerySymLink(const unsigned int xid, struct cifs_tcon *tcon,
3188                    __u16 fid, char **symlinkinfo,
3189                    const struct nls_table *nls_codepage)
3190{
3191        int rc = 0;
3192        int bytes_returned;
3193        struct smb_com_transaction_ioctl_req *pSMB;
3194        struct smb_com_transaction_ioctl_rsp *pSMBr;
3195        bool is_unicode;
3196        unsigned int sub_len;
3197        char *sub_start;
3198        struct reparse_symlink_data *reparse_buf;
3199        struct reparse_posix_data *posix_buf;
3200        __u32 data_offset, data_count;
3201        char *end_of_smb;
3202
3203        cifs_dbg(FYI, "In Windows reparse style QueryLink for fid %u\n", fid);
3204        rc = smb_init(SMB_COM_NT_TRANSACT, 23, tcon, (void **) &pSMB,
3205                      (void **) &pSMBr);
3206        if (rc)
3207                return rc;
3208
3209        pSMB->TotalParameterCount = 0 ;
3210        pSMB->TotalDataCount = 0;
3211        pSMB->MaxParameterCount = cpu_to_le32(2);
3212        /* BB find exact data count max from sess structure BB */
3213        pSMB->MaxDataCount = cpu_to_le32(CIFSMaxBufSize & 0xFFFFFF00);
3214        pSMB->MaxSetupCount = 4;
3215        pSMB->Reserved = 0;
3216        pSMB->ParameterOffset = 0;
3217        pSMB->DataCount = 0;
3218        pSMB->DataOffset = 0;
3219        pSMB->SetupCount = 4;
3220        pSMB->SubCommand = cpu_to_le16(NT_TRANSACT_IOCTL);
3221        pSMB->ParameterCount = pSMB->TotalParameterCount;
3222        pSMB->FunctionCode = cpu_to_le32(FSCTL_GET_REPARSE_POINT);
3223        pSMB->IsFsctl = 1; /* FSCTL */
3224        pSMB->IsRootFlag = 0;
3225        pSMB->Fid = fid; /* file handle always le */
3226        pSMB->ByteCount = 0;
3227
3228        rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
3229                         (struct smb_hdr *) pSMBr, &bytes_returned, 0);
3230        if (rc) {
3231                cifs_dbg(FYI, "Send error in QueryReparseLinkInfo = %d\n", rc);
3232                goto qreparse_out;
3233        }
3234
3235        data_offset = le32_to_cpu(pSMBr->DataOffset);
3236        data_count = le32_to_cpu(pSMBr->DataCount);
3237        if (get_bcc(&pSMBr->hdr) < 2 || data_offset > 512) {
3238                /* BB also check enough total bytes returned */
3239                rc = -EIO;      /* bad smb */
3240                goto qreparse_out;
3241        }
3242        if (!data_count || (data_count > 2048)) {
3243                rc = -EIO;
3244                cifs_dbg(FYI, "Invalid return data count on get reparse info ioctl\n");
3245                goto qreparse_out;
3246        }
3247        end_of_smb = 2 + get_bcc(&pSMBr->hdr) + (char *)&pSMBr->ByteCount;
3248        reparse_buf = (struct reparse_symlink_data *)
3249                                ((char *)&pSMBr->hdr.Protocol + data_offset);
3250        if ((char *)reparse_buf >= end_of_smb) {
3251                rc = -EIO;
3252                goto qreparse_out;
3253        }
3254        if (reparse_buf->ReparseTag == cpu_to_le32(IO_REPARSE_TAG_NFS)) {
3255                cifs_dbg(FYI, "NFS style reparse tag\n");
3256                posix_buf =  (struct reparse_posix_data *)reparse_buf;
3257
3258                if (posix_buf->InodeType != cpu_to_le64(NFS_SPECFILE_LNK)) {
3259                        cifs_dbg(FYI, "unsupported file type 0x%llx\n",
3260                                 le64_to_cpu(posix_buf->InodeType));
3261                        rc = -EOPNOTSUPP;
3262                        goto qreparse_out;
3263                }
3264                is_unicode = true;
3265                sub_len = le16_to_cpu(reparse_buf->ReparseDataLength);
3266                if (posix_buf->PathBuffer + sub_len > end_of_smb) {
3267                        cifs_dbg(FYI, "reparse buf beyond SMB\n");
3268                        rc = -EIO;
3269                        goto qreparse_out;
3270                }
3271                *symlinkinfo = cifs_strndup_from_utf16(posix_buf->PathBuffer,
3272                                sub_len, is_unicode, nls_codepage);
3273                goto qreparse_out;
3274        } else if (reparse_buf->ReparseTag !=
3275                        cpu_to_le32(IO_REPARSE_TAG_SYMLINK)) {
3276                rc = -EOPNOTSUPP;
3277                goto qreparse_out;
3278        }
3279
3280        /* Reparse tag is NTFS symlink */
3281        sub_start = le16_to_cpu(reparse_buf->SubstituteNameOffset) +
3282                                reparse_buf->PathBuffer;
3283        sub_len = le16_to_cpu(reparse_buf->SubstituteNameLength);
3284        if (sub_start + sub_len > end_of_smb) {
3285                cifs_dbg(FYI, "reparse buf beyond SMB\n");
3286                rc = -EIO;
3287                goto qreparse_out;
3288        }
3289        if (pSMBr->hdr.Flags2 & SMBFLG2_UNICODE)
3290                is_unicode = true;
3291        else
3292                is_unicode = false;
3293
3294        /* BB FIXME investigate remapping reserved chars here */
3295        *symlinkinfo = cifs_strndup_from_utf16(sub_start, sub_len, is_unicode,
3296                                               nls_codepage);
3297        if (!*symlinkinfo)
3298                rc = -ENOMEM;
3299qreparse_out:
3300        cifs_buf_release(pSMB);
3301
3302        /*
3303         * Note: On -EAGAIN error only caller can retry on handle based calls
3304         * since file handle passed in no longer valid.
3305         */
3306        return rc;
3307}
3308
3309int
3310CIFSSMB_set_compression(const unsigned int xid, struct cifs_tcon *tcon,
3311                    __u16 fid)
3312{
3313        int rc = 0;
3314        int bytes_returned;
3315        struct smb_com_transaction_compr_ioctl_req *pSMB;
3316        struct smb_com_transaction_ioctl_rsp *pSMBr;
3317
3318        cifs_dbg(FYI, "Set compression for %u\n", fid);
3319        rc = smb_init(SMB_COM_NT_TRANSACT, 23, tcon, (void **) &pSMB,
3320                      (void **) &pSMBr);
3321        if (rc)
3322                return rc;
3323
3324        pSMB->compression_state = cpu_to_le16(COMPRESSION_FORMAT_DEFAULT);
3325
3326        pSMB->TotalParameterCount = 0;
3327        pSMB->TotalDataCount = cpu_to_le32(2);
3328        pSMB->MaxParameterCount = 0;
3329        pSMB->MaxDataCount = 0;
3330        pSMB->MaxSetupCount = 4;
3331        pSMB->Reserved = 0;
3332        pSMB->ParameterOffset = 0;
3333        pSMB->DataCount = cpu_to_le32(2);
3334        pSMB->DataOffset =
3335                cpu_to_le32(offsetof(struct smb_com_transaction_compr_ioctl_req,
3336                                compression_state) - 4);  /* 84 */
3337        pSMB->SetupCount = 4;
3338        pSMB->SubCommand = cpu_to_le16(NT_TRANSACT_IOCTL);
3339        pSMB->ParameterCount = 0;
3340        pSMB->FunctionCode = cpu_to_le32(FSCTL_SET_COMPRESSION);
3341        pSMB->IsFsctl = 1; /* FSCTL */
3342        pSMB->IsRootFlag = 0;
3343        pSMB->Fid = fid; /* file handle always le */
3344        /* 3 byte pad, followed by 2 byte compress state */
3345        pSMB->ByteCount = cpu_to_le16(5);
3346        inc_rfc1001_len(pSMB, 5);
3347
3348        rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
3349                         (struct smb_hdr *) pSMBr, &bytes_returned, 0);
3350        if (rc)
3351                cifs_dbg(FYI, "Send error in SetCompression = %d\n", rc);
3352
3353        cifs_buf_release(pSMB);
3354
3355        /*
3356         * Note: On -EAGAIN error only caller can retry on handle based calls
3357         * since file handle passed in no longer valid.
3358         */
3359        return rc;
3360}
3361
3362
3363#ifdef CONFIG_CIFS_POSIX
3364
3365/*Convert an Access Control Entry from wire format to local POSIX xattr format*/
3366static void cifs_convert_ace(struct posix_acl_xattr_entry *ace,
3367                             struct cifs_posix_ace *cifs_ace)
3368{
3369        /* u8 cifs fields do not need le conversion */
3370        ace->e_perm = cpu_to_le16(cifs_ace->cifs_e_perm);
3371        ace->e_tag  = cpu_to_le16(cifs_ace->cifs_e_tag);
3372        ace->e_id   = cpu_to_le32(le64_to_cpu(cifs_ace->cifs_uid));
3373/*
3374        cifs_dbg(FYI, "perm %d tag %d id %d\n",
3375                 ace->e_perm, ace->e_tag, ace->e_id);
3376*/
3377
3378        return;
3379}
3380
3381/* Convert ACL from CIFS POSIX wire format to local Linux POSIX ACL xattr */
3382static int cifs_copy_posix_acl(char *trgt, char *src, const int buflen,
3383                               const int acl_type, const int size_of_data_area)
3384{
3385        int size =  0;
3386        int i;
3387        __u16 count;
3388        struct cifs_posix_ace *pACE;
3389        struct cifs_posix_acl *cifs_acl = (struct cifs_posix_acl *)src;
3390        struct posix_acl_xattr_header *local_acl = (void *)trgt;
3391
3392        if (le16_to_cpu(cifs_acl->version) != CIFS_ACL_VERSION)
3393                return -EOPNOTSUPP;
3394
3395        if (acl_type == ACL_TYPE_ACCESS) {
3396                count = le16_to_cpu(cifs_acl->access_entry_count);
3397                pACE = &cifs_acl->ace_array[0];
3398                size = sizeof(struct cifs_posix_acl);
3399                size += sizeof(struct cifs_posix_ace) * count;
3400                /* check if we would go beyond end of SMB */
3401                if (size_of_data_area < size) {
3402                        cifs_dbg(FYI, "bad CIFS POSIX ACL size %d vs. %d\n",
3403                                 size_of_data_area, size);
3404                        return -EINVAL;
3405                }
3406        } else if (acl_type == ACL_TYPE_DEFAULT) {
3407                count = le16_to_cpu(cifs_acl->access_entry_count);
3408                size = sizeof(struct cifs_posix_acl);
3409                size += sizeof(struct cifs_posix_ace) * count;
3410/* skip past access ACEs to get to default ACEs */
3411                pACE = &cifs_acl->ace_array[count];
3412                count = le16_to_cpu(cifs_acl->default_entry_count);
3413                size += sizeof(struct cifs_posix_ace) * count;
3414                /* check if we would go beyond end of SMB */
3415                if (size_of_data_area < size)
3416                        return -EINVAL;
3417        } else {
3418                /* illegal type */
3419                return -EINVAL;
3420        }
3421
3422        size = posix_acl_xattr_size(count);
3423        if ((buflen == 0) || (local_acl == NULL)) {
3424                /* used to query ACL EA size */
3425        } else if (size > buflen) {
3426                return -ERANGE;
3427        } else /* buffer big enough */ {
3428                struct posix_acl_xattr_entry *ace = (void *)(local_acl + 1);
3429
3430                local_acl->a_version = cpu_to_le32(POSIX_ACL_XATTR_VERSION);
3431                for (i = 0; i < count ; i++) {
3432                        cifs_convert_ace(&ace[i], pACE);
3433                        pACE++;
3434                }
3435        }
3436        return size;
3437}
3438
3439static void convert_ace_to_cifs_ace(struct cifs_posix_ace *cifs_ace,
3440                                     const struct posix_acl_xattr_entry *local_ace)
3441{
3442        cifs_ace->cifs_e_perm = le16_to_cpu(local_ace->e_perm);
3443        cifs_ace->cifs_e_tag =  le16_to_cpu(local_ace->e_tag);
3444        /* BB is there a better way to handle the large uid? */
3445        if (local_ace->e_id == cpu_to_le32(-1)) {
3446        /* Probably no need to le convert -1 on any arch but can not hurt */
3447                cifs_ace->cifs_uid = cpu_to_le64(-1);
3448        } else
3449                cifs_ace->cifs_uid = cpu_to_le64(le32_to_cpu(local_ace->e_id));
3450/*
3451        cifs_dbg(FYI, "perm %d tag %d id %d\n",
3452                 ace->e_perm, ace->e_tag, ace->e_id);
3453*/
3454}
3455
3456/* Convert ACL from local Linux POSIX xattr to CIFS POSIX ACL wire format */
3457static __u16 ACL_to_cifs_posix(char *parm_data, const char *pACL,
3458                               const int buflen, const int acl_type)
3459{
3460        __u16 rc = 0;
3461        struct cifs_posix_acl *cifs_acl = (struct cifs_posix_acl *)parm_data;
3462        struct posix_acl_xattr_header *local_acl = (void *)pACL;
3463        struct posix_acl_xattr_entry *ace = (void *)(local_acl + 1);
3464        int count;
3465        int i;
3466
3467        if ((buflen == 0) || (pACL == NULL) || (cifs_acl == NULL))
3468                return 0;
3469
3470        count = posix_acl_xattr_count((size_t)buflen);
3471        cifs_dbg(FYI, "setting acl with %d entries from buf of length %d and version of %d\n",
3472                 count, buflen, le32_to_cpu(local_acl->a_version));
3473        if (le32_to_cpu(local_acl->a_version) != 2) {
3474                cifs_dbg(FYI, "unknown POSIX ACL version %d\n",
3475                         le32_to_cpu(local_acl->a_version));
3476                return 0;
3477        }
3478        cifs_acl->version = cpu_to_le16(1);
3479        if (acl_type == ACL_TYPE_ACCESS) {
3480                cifs_acl->access_entry_count = cpu_to_le16(count);
3481                cifs_acl->default_entry_count = cpu_to_le16(0xFFFF);
3482        } else if (acl_type == ACL_TYPE_DEFAULT) {
3483                cifs_acl->default_entry_count = cpu_to_le16(count);
3484                cifs_acl->access_entry_count = cpu_to_le16(0xFFFF);
3485        } else {
3486                cifs_dbg(FYI, "unknown ACL type %d\n", acl_type);
3487                return 0;
3488        }
3489        for (i = 0; i < count; i++)
3490                convert_ace_to_cifs_ace(&cifs_acl->ace_array[i], &ace[i]);
3491        if (rc == 0) {
3492                rc = (__u16)(count * sizeof(struct cifs_posix_ace));
3493                rc += sizeof(struct cifs_posix_acl);
3494                /* BB add check to make sure ACL does not overflow SMB */
3495        }
3496        return rc;
3497}
3498
3499int
3500CIFSSMBGetPosixACL(const unsigned int xid, struct cifs_tcon *tcon,
3501                   const unsigned char *searchName,
3502                   char *acl_inf, const int buflen, const int acl_type,
3503                   const struct nls_table *nls_codepage, int remap)
3504{
3505/* SMB_QUERY_POSIX_ACL */
3506        TRANSACTION2_QPI_REQ *pSMB = NULL;
3507        TRANSACTION2_QPI_RSP *pSMBr = NULL;
3508        int rc = 0;
3509        int bytes_returned;
3510        int name_len;
3511        __u16 params, byte_count;
3512
3513        cifs_dbg(FYI, "In GetPosixACL (Unix) for path %s\n", searchName);
3514
3515queryAclRetry:
3516        rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
3517                (void **) &pSMBr);
3518        if (rc)
3519                return rc;
3520
3521        if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
3522                name_len =
3523                        cifsConvertToUTF16((__le16 *) pSMB->FileName,
3524                                           searchName, PATH_MAX, nls_codepage,
3525                                           remap);
3526                name_len++;     /* trailing null */
3527                name_len *= 2;
3528                pSMB->FileName[name_len] = 0;
3529                pSMB->FileName[name_len+1] = 0;
3530        } else {
3531                name_len = copy_path_name(pSMB->FileName, searchName);
3532        }
3533
3534        params = 2 /* level */  + 4 /* rsrvd */  + name_len /* incl null */ ;
3535        pSMB->TotalDataCount = 0;
3536        pSMB->MaxParameterCount = cpu_to_le16(2);
3537        /* BB find exact max data count below from sess structure BB */
3538        pSMB->MaxDataCount = cpu_to_le16(4000);
3539        pSMB->MaxSetupCount = 0;
3540        pSMB->Reserved = 0;
3541        pSMB->Flags = 0;
3542        pSMB->Timeout = 0;
3543        pSMB->Reserved2 = 0;
3544        pSMB->ParameterOffset = cpu_to_le16(
3545                offsetof(struct smb_com_transaction2_qpi_req,
3546                         InformationLevel) - 4);
3547        pSMB->DataCount = 0;
3548        pSMB->DataOffset = 0;
3549        pSMB->SetupCount = 1;
3550        pSMB->Reserved3 = 0;
3551        pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_PATH_INFORMATION);
3552        byte_count = params + 1 /* pad */ ;
3553        pSMB->TotalParameterCount = cpu_to_le16(params);
3554        pSMB->ParameterCount = pSMB->TotalParameterCount;
3555        pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_POSIX_ACL);
3556        pSMB->Reserved4 = 0;
3557        inc_rfc1001_len(pSMB, byte_count);
3558        pSMB->ByteCount = cpu_to_le16(byte_count);
3559
3560        rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
3561                (struct smb_hdr *) pSMBr, &bytes_returned, 0);
3562        cifs_stats_inc(&tcon->stats.cifs_stats.num_acl_get);
3563        if (rc) {
3564                cifs_dbg(FYI, "Send error in Query POSIX ACL = %d\n", rc);
3565        } else {
3566                /* decode response */
3567
3568                rc = validate_t2((struct smb_t2_rsp *)pSMBr);
3569                /* BB also check enough total bytes returned */
3570                if (rc || get_bcc(&pSMBr->hdr) < 2)
3571                        rc = -EIO;      /* bad smb */
3572                else {
3573                        __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
3574                        __u16 count = le16_to_cpu(pSMBr->t2.DataCount);
3575                        rc = cifs_copy_posix_acl(acl_inf,
3576                                (char *)&pSMBr->hdr.Protocol+data_offset,
3577                                buflen, acl_type, count);
3578                }
3579        }
3580        cifs_buf_release(pSMB);
3581        if (rc == -EAGAIN)
3582                goto queryAclRetry;
3583        return rc;
3584}
3585
3586int
3587CIFSSMBSetPosixACL(const unsigned int xid, struct cifs_tcon *tcon,
3588                   const unsigned char *fileName,
3589                   const char *local_acl, const int buflen,
3590                   const int acl_type,
3591                   const struct nls_table *nls_codepage, int remap)
3592{
3593        struct smb_com_transaction2_spi_req *pSMB = NULL;
3594        struct smb_com_transaction2_spi_rsp *pSMBr = NULL;
3595        char *parm_data;
3596        int name_len;
3597        int rc = 0;
3598        int bytes_returned = 0;
3599        __u16 params, byte_count, data_count, param_offset, offset;
3600
3601        cifs_dbg(FYI, "In SetPosixACL (Unix) for path %s\n", fileName);
3602setAclRetry:
3603        rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
3604                      (void **) &pSMBr);
3605        if (rc)
3606                return rc;
3607        if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
3608                name_len =
3609                        cifsConvertToUTF16((__le16 *) pSMB->FileName, fileName,
3610                                           PATH_MAX, nls_codepage, remap);
3611                name_len++;     /* trailing null */
3612                name_len *= 2;
3613        } else {
3614                name_len = copy_path_name(pSMB->FileName, fileName);
3615        }
3616        params = 6 + name_len;
3617        pSMB->MaxParameterCount = cpu_to_le16(2);
3618        /* BB find max SMB size from sess */
3619        pSMB->MaxDataCount = cpu_to_le16(1000);
3620        pSMB->MaxSetupCount = 0;
3621        pSMB->Reserved = 0;
3622        pSMB->Flags = 0;
3623        pSMB->Timeout = 0;
3624        pSMB->Reserved2 = 0;
3625        param_offset = offsetof(struct smb_com_transaction2_spi_req,
3626                                InformationLevel) - 4;
3627        offset = param_offset + params;
3628        parm_data = ((char *) &pSMB->hdr.Protocol) + offset;
3629        pSMB->ParameterOffset = cpu_to_le16(param_offset);
3630
3631        /* convert to on the wire format for POSIX ACL */
3632        data_count = ACL_to_cifs_posix(parm_data, local_acl, buflen, acl_type);
3633
3634        if (data_count == 0) {
3635                rc = -EOPNOTSUPP;
3636                goto setACLerrorExit;
3637        }
3638        pSMB->DataOffset = cpu_to_le16(offset);
3639        pSMB->SetupCount = 1;
3640        pSMB->Reserved3 = 0;
3641        pSMB->SubCommand = cpu_to_le16(TRANS2_SET_PATH_INFORMATION);
3642        pSMB->InformationLevel = cpu_to_le16(SMB_SET_POSIX_ACL);
3643        byte_count = 3 /* pad */  + params + data_count;
3644        pSMB->DataCount = cpu_to_le16(data_count);
3645        pSMB->TotalDataCount = pSMB->DataCount;
3646        pSMB->ParameterCount = cpu_to_le16(params);
3647        pSMB->TotalParameterCount = pSMB->ParameterCount;
3648        pSMB->Reserved4 = 0;
3649        inc_rfc1001_len(pSMB, byte_count);
3650        pSMB->ByteCount = cpu_to_le16(byte_count);
3651        rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
3652                         (struct smb_hdr *) pSMBr, &bytes_returned, 0);
3653        if (rc)
3654                cifs_dbg(FYI, "Set POSIX ACL returned %d\n", rc);
3655
3656setACLerrorExit:
3657        cifs_buf_release(pSMB);
3658        if (rc == -EAGAIN)
3659                goto setAclRetry;
3660        return rc;
3661}
3662
3663/* BB fix tabs in this function FIXME BB */
3664int
3665CIFSGetExtAttr(const unsigned int xid, struct cifs_tcon *tcon,
3666               const int netfid, __u64 *pExtAttrBits, __u64 *pMask)
3667{
3668        int rc = 0;
3669        struct smb_t2_qfi_req *pSMB = NULL;
3670        struct smb_t2_qfi_rsp *pSMBr = NULL;
3671        int bytes_returned;
3672        __u16 params, byte_count;
3673
3674        cifs_dbg(FYI, "In GetExtAttr\n");
3675        if (tcon == NULL)
3676                return -ENODEV;
3677
3678GetExtAttrRetry:
3679        rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
3680                        (void **) &pSMBr);
3681        if (rc)
3682                return rc;
3683
3684        params = 2 /* level */ + 2 /* fid */;
3685        pSMB->t2.TotalDataCount = 0;
3686        pSMB->t2.MaxParameterCount = cpu_to_le16(4);
3687        /* BB find exact max data count below from sess structure BB */
3688        pSMB->t2.MaxDataCount = cpu_to_le16(4000);
3689        pSMB->t2.MaxSetupCount = 0;
3690        pSMB->t2.Reserved = 0;
3691        pSMB->t2.Flags = 0;
3692        pSMB->t2.Timeout = 0;
3693        pSMB->t2.Reserved2 = 0;
3694        pSMB->t2.ParameterOffset = cpu_to_le16(offsetof(struct smb_t2_qfi_req,
3695                                               Fid) - 4);
3696        pSMB->t2.DataCount = 0;
3697        pSMB->t2.DataOffset = 0;
3698        pSMB->t2.SetupCount = 1;
3699        pSMB->t2.Reserved3 = 0;
3700        pSMB->t2.SubCommand = cpu_to_le16(TRANS2_QUERY_FILE_INFORMATION);
3701        byte_count = params + 1 /* pad */ ;
3702        pSMB->t2.TotalParameterCount = cpu_to_le16(params);
3703        pSMB->t2.ParameterCount = pSMB->t2.TotalParameterCount;
3704        pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_ATTR_FLAGS);
3705        pSMB->Pad = 0;
3706        pSMB->Fid = netfid;
3707        inc_rfc1001_len(pSMB, byte_count);
3708        pSMB->t2.ByteCount = cpu_to_le16(byte_count);
3709
3710        rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
3711                         (struct smb_hdr *) pSMBr, &bytes_returned, 0);
3712        if (rc) {
3713                cifs_dbg(FYI, "error %d in GetExtAttr\n", rc);
3714        } else {
3715                /* decode response */
3716                rc = validate_t2((struct smb_t2_rsp *)pSMBr);
3717                /* BB also check enough total bytes returned */
3718                if (rc || get_bcc(&pSMBr->hdr) < 2)
3719                        /* If rc should we check for EOPNOSUPP and
3720                           disable the srvino flag? or in caller? */
3721                        rc = -EIO;      /* bad smb */
3722                else {
3723                        __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
3724                        __u16 count = le16_to_cpu(pSMBr->t2.DataCount);
3725                        struct file_chattr_info *pfinfo;
3726                        /* BB Do we need a cast or hash here ? */
3727                        if (count != 16) {
3728                                cifs_dbg(FYI, "Invalid size ret in GetExtAttr\n");
3729                                rc = -EIO;
3730                                goto GetExtAttrOut;
3731                        }
3732                        pfinfo = (struct file_chattr_info *)
3733                                 (data_offset + (char *) &pSMBr->hdr.Protocol);
3734                        *pExtAttrBits = le64_to_cpu(pfinfo->mode);
3735                        *pMask = le64_to_cpu(pfinfo->mask);
3736                }
3737        }
3738GetExtAttrOut:
3739        cifs_buf_release(pSMB);
3740        if (rc == -EAGAIN)
3741                goto GetExtAttrRetry;
3742        return rc;
3743}
3744
3745#endif /* CONFIG_POSIX */
3746
3747/*
3748 * Initialize NT TRANSACT SMB into small smb request buffer.  This assumes that
3749 * all NT TRANSACTS that we init here have total parm and data under about 400
3750 * bytes (to fit in small cifs buffer size), which is the case so far, it
3751 * easily fits. NB: Setup words themselves and ByteCount MaxSetupCount (size of
3752 * returned setup area) and MaxParameterCount (returned parms size) must be set
3753 * by caller
3754 */
3755static int
3756smb_init_nttransact(const __u16 sub_command, const int setup_count,
3757                   const int parm_len, struct cifs_tcon *tcon,
3758                   void **ret_buf)
3759{
3760        int rc;
3761        __u32 temp_offset;
3762        struct smb_com_ntransact_req *pSMB;
3763
3764        rc = small_smb_init(SMB_COM_NT_TRANSACT, 19 + setup_count, tcon,
3765                                (void **)&pSMB);
3766        if (rc)
3767                return rc;
3768        *ret_buf = (void *)pSMB;
3769        pSMB->Reserved = 0;
3770        pSMB->TotalParameterCount = cpu_to_le32(parm_len);
3771        pSMB->TotalDataCount  = 0;
3772        pSMB->MaxDataCount = cpu_to_le32(CIFSMaxBufSize & 0xFFFFFF00);
3773        pSMB->ParameterCount = pSMB->TotalParameterCount;
3774        pSMB->DataCount  = pSMB->TotalDataCount;
3775        temp_offset = offsetof(struct smb_com_ntransact_req, Parms) +
3776                        (setup_count * 2) - 4 /* for rfc1001 length itself */;
3777        pSMB->ParameterOffset = cpu_to_le32(temp_offset);
3778        pSMB->DataOffset = cpu_to_le32(temp_offset + parm_len);
3779        pSMB->SetupCount = setup_count; /* no need to le convert byte fields */
3780        pSMB->SubCommand = cpu_to_le16(sub_command);
3781        return 0;
3782}
3783
3784static int
3785validate_ntransact(char *buf, char **ppparm, char **ppdata,
3786                   __u32 *pparmlen, __u32 *pdatalen)
3787{
3788        char *end_of_smb;
3789        __u32 data_count, data_offset, parm_count, parm_offset;
3790        struct smb_com_ntransact_rsp *pSMBr;
3791        u16 bcc;
3792
3793        *pdatalen = 0;
3794        *pparmlen = 0;
3795
3796        if (buf == NULL)
3797                return -EINVAL;
3798
3799        pSMBr = (struct smb_com_ntransact_rsp *)buf;
3800
3801        bcc = get_bcc(&pSMBr->hdr);
3802        end_of_smb = 2 /* sizeof byte count */ + bcc +
3803                        (char *)&pSMBr->ByteCount;
3804
3805        data_offset = le32_to_cpu(pSMBr->DataOffset);
3806        data_count = le32_to_cpu(pSMBr->DataCount);
3807        parm_offset = le32_to_cpu(pSMBr->ParameterOffset);
3808        parm_count = le32_to_cpu(pSMBr->ParameterCount);
3809
3810        *ppparm = (char *)&pSMBr->hdr.Protocol + parm_offset;
3811        *ppdata = (char *)&pSMBr->hdr.Protocol + data_offset;
3812
3813        /* should we also check that parm and data areas do not overlap? */
3814        if (*ppparm > end_of_smb) {
3815                cifs_dbg(FYI, "parms start after end of smb\n");
3816                return -EINVAL;
3817        } else if (parm_count + *ppparm > end_of_smb) {
3818                cifs_dbg(FYI, "parm end after end of smb\n");
3819                return -EINVAL;
3820        } else if (*ppdata > end_of_smb) {
3821                cifs_dbg(FYI, "data starts after end of smb\n");
3822                return -EINVAL;
3823        } else if (data_count + *ppdata > end_of_smb) {
3824                cifs_dbg(FYI, "data %p + count %d (%p) past smb end %p start %p\n",
3825                         *ppdata, data_count, (data_count + *ppdata),
3826                         end_of_smb, pSMBr);
3827                return -EINVAL;
3828        } else if (parm_count + data_count > bcc) {
3829                cifs_dbg(FYI, "parm count and data count larger than SMB\n");
3830                return -EINVAL;
3831        }
3832        *pdatalen = data_count;
3833        *pparmlen = parm_count;
3834        return 0;
3835}
3836
3837/* Get Security Descriptor (by handle) from remote server for a file or dir */
3838int
3839CIFSSMBGetCIFSACL(const unsigned int xid, struct cifs_tcon *tcon, __u16 fid,
3840                  struct cifs_ntsd **acl_inf, __u32 *pbuflen)
3841{
3842        int rc = 0;
3843        int buf_type = 0;
3844        QUERY_SEC_DESC_REQ *pSMB;
3845        struct kvec iov[1];
3846        struct kvec rsp_iov;
3847
3848        cifs_dbg(FYI, "GetCifsACL\n");
3849
3850        *pbuflen = 0;
3851        *acl_inf = NULL;
3852
3853        rc = smb_init_nttransact(NT_TRANSACT_QUERY_SECURITY_DESC, 0,
3854                        8 /* parm len */, tcon, (void **) &pSMB);
3855        if (rc)
3856                return rc;
3857
3858        pSMB->MaxParameterCount = cpu_to_le32(4);
3859        /* BB TEST with big acls that might need to be e.g. larger than 16K */
3860        pSMB->MaxSetupCount = 0;
3861        pSMB->Fid = fid; /* file handle always le */
3862        pSMB->AclFlags = cpu_to_le32(CIFS_ACL_OWNER | CIFS_ACL_GROUP |
3863                                     CIFS_ACL_DACL);
3864        pSMB->ByteCount = cpu_to_le16(11); /* 3 bytes pad + 8 bytes parm */
3865        inc_rfc1001_len(pSMB, 11);
3866        iov[0].iov_base = (char *)pSMB;
3867        iov[0].iov_len = be32_to_cpu(pSMB->hdr.smb_buf_length) + 4;
3868
3869        rc = SendReceive2(xid, tcon->ses, iov, 1 /* num iovec */, &buf_type,
3870                          0, &rsp_iov);
3871        cifs_small_buf_release(pSMB);
3872        cifs_stats_inc(&tcon->stats.cifs_stats.num_acl_get);
3873        if (rc) {
3874                cifs_dbg(FYI, "Send error in QuerySecDesc = %d\n", rc);
3875        } else {                /* decode response */
3876                __le32 *parm;
3877                __u32 parm_len;
3878                __u32 acl_len;
3879                struct smb_com_ntransact_rsp *pSMBr;
3880                char *pdata;
3881
3882/* validate_nttransact */
3883                rc = validate_ntransact(rsp_iov.iov_base, (char **)&parm,
3884                                        &pdata, &parm_len, pbuflen);
3885                if (rc)
3886                        goto qsec_out;
3887                pSMBr = (struct smb_com_ntransact_rsp *)rsp_iov.iov_base;
3888
3889                cifs_dbg(FYI, "smb %p parm %p data %p\n",
3890                         pSMBr, parm, *acl_inf);
3891
3892                if (le32_to_cpu(pSMBr->ParameterCount) != 4) {
3893                        rc = -EIO;      /* bad smb */
3894                        *pbuflen = 0;
3895                        goto qsec_out;
3896                }
3897
3898/* BB check that data area is minimum length and as big as acl_len */
3899
3900                acl_len = le32_to_cpu(*parm);
3901                if (acl_len != *pbuflen) {
3902                        cifs_dbg(VFS, "acl length %d does not match %d\n",
3903                                 acl_len, *pbuflen);
3904                        if (*pbuflen > acl_len)
3905                                *pbuflen = acl_len;
3906                }
3907
3908                /* check if buffer is big enough for the acl
3909                   header followed by the smallest SID */
3910                if ((*pbuflen < sizeof(struct cifs_ntsd) + 8) ||
3911                    (*pbuflen >= 64 * 1024)) {
3912                        cifs_dbg(VFS, "bad acl length %d\n", *pbuflen);
3913                        rc = -EINVAL;
3914                        *pbuflen = 0;
3915                } else {
3916                        *acl_inf = kmemdup(pdata, *pbuflen, GFP_KERNEL);
3917                        if (*acl_inf == NULL) {
3918                                *pbuflen = 0;
3919                                rc = -ENOMEM;
3920                        }
3921                }
3922        }
3923qsec_out:
3924        free_rsp_buf(buf_type, rsp_iov.iov_base);
3925        return rc;
3926}
3927
3928int
3929CIFSSMBSetCIFSACL(const unsigned int xid, struct cifs_tcon *tcon, __u16 fid,
3930                        struct cifs_ntsd *pntsd, __u32 acllen, int aclflag)
3931{
3932        __u16 byte_count, param_count, data_count, param_offset, data_offset;
3933        int rc = 0;
3934        int bytes_returned = 0;
3935        SET_SEC_DESC_REQ *pSMB = NULL;
3936        void *pSMBr;
3937
3938setCifsAclRetry:
3939        rc = smb_init(SMB_COM_NT_TRANSACT, 19, tcon, (void **) &pSMB, &pSMBr);
3940        if (rc)
3941                return rc;
3942
3943        pSMB->MaxSetupCount = 0;
3944        pSMB->Reserved = 0;
3945
3946        param_count = 8;
3947        param_offset = offsetof(struct smb_com_transaction_ssec_req, Fid) - 4;
3948        data_count = acllen;
3949        data_offset = param_offset + param_count;
3950        byte_count = 3 /* pad */  + param_count;
3951
3952        pSMB->DataCount = cpu_to_le32(data_count);
3953        pSMB->TotalDataCount = pSMB->DataCount;
3954        pSMB->MaxParameterCount = cpu_to_le32(4);
3955        pSMB->MaxDataCount = cpu_to_le32(16384);
3956        pSMB->ParameterCount = cpu_to_le32(param_count);
3957        pSMB->ParameterOffset = cpu_to_le32(param_offset);
3958        pSMB->TotalParameterCount = pSMB->ParameterCount;
3959        pSMB->DataOffset = cpu_to_le32(data_offset);
3960        pSMB->SetupCount = 0;
3961        pSMB->SubCommand = cpu_to_le16(NT_TRANSACT_SET_SECURITY_DESC);
3962        pSMB->ByteCount = cpu_to_le16(byte_count+data_count);
3963
3964        pSMB->Fid = fid; /* file handle always le */
3965        pSMB->Reserved2 = 0;
3966        pSMB->AclFlags = cpu_to_le32(aclflag);
3967
3968        if (pntsd && acllen) {
3969                memcpy((char *)pSMBr + offsetof(struct smb_hdr, Protocol) +
3970                                data_offset, pntsd, acllen);
3971                inc_rfc1001_len(pSMB, byte_count + data_count);
3972        } else
3973                inc_rfc1001_len(pSMB, byte_count);
3974
3975        rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
3976                (struct smb_hdr *) pSMBr, &bytes_returned, 0);
3977
3978        cifs_dbg(FYI, "SetCIFSACL bytes_returned: %d, rc: %d\n",
3979                 bytes_returned, rc);
3980        if (rc)
3981                cifs_dbg(FYI, "Set CIFS ACL returned %d\n", rc);
3982        cifs_buf_release(pSMB);
3983
3984        if (rc == -EAGAIN)
3985                goto setCifsAclRetry;
3986
3987        return (rc);
3988}
3989
3990
3991/* Legacy Query Path Information call for lookup to old servers such
3992   as Win9x/WinME */
3993int
3994SMBQueryInformation(const unsigned int xid, struct cifs_tcon *tcon,
3995                    const char *search_name, FILE_ALL_INFO *data,
3996                    const struct nls_table *nls_codepage, int remap)
3997{
3998        QUERY_INFORMATION_REQ *pSMB;
3999        QUERY_INFORMATION_RSP *pSMBr;
4000        int rc = 0;
4001        int bytes_returned;
4002        int name_len;
4003
4004        cifs_dbg(FYI, "In SMBQPath path %s\n", search_name);
4005QInfRetry:
4006        rc = smb_init(SMB_COM_QUERY_INFORMATION, 0, tcon, (void **) &pSMB,
4007                      (void **) &pSMBr);
4008        if (rc)
4009                return rc;
4010
4011        if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
4012                name_len =
4013                        cifsConvertToUTF16((__le16 *) pSMB->FileName,
4014                                           search_name, PATH_MAX, nls_codepage,
4015                                           remap);
4016                name_len++;     /* trailing null */
4017                name_len *= 2;
4018        } else {
4019                name_len = copy_path_name(pSMB->FileName, search_name);
4020        }
4021        pSMB->BufferFormat = 0x04;
4022        name_len++; /* account for buffer type byte */
4023        inc_rfc1001_len(pSMB, (__u16)name_len);
4024        pSMB->ByteCount = cpu_to_le16(name_len);
4025
4026        rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
4027                         (struct smb_hdr *) pSMBr, &bytes_returned, 0);
4028        if (rc) {
4029                cifs_dbg(FYI, "Send error in QueryInfo = %d\n", rc);
4030        } else if (data) {
4031                struct timespec64 ts;
4032                __u32 time = le32_to_cpu(pSMBr->last_write_time);
4033
4034                /* decode response */
4035                /* BB FIXME - add time zone adjustment BB */
4036                memset(data, 0, sizeof(FILE_ALL_INFO));
4037                ts.tv_nsec = 0;
4038                ts.tv_sec = time;
4039                /* decode time fields */
4040                data->ChangeTime = cpu_to_le64(cifs_UnixTimeToNT(ts));
4041                data->LastWriteTime = data->ChangeTime;
4042                data->LastAccessTime = 0;
4043                data->AllocationSize =
4044                        cpu_to_le64(le32_to_cpu(pSMBr->size));
4045                data->EndOfFile = data->AllocationSize;
4046                data->Attributes =
4047                        cpu_to_le32(le16_to_cpu(pSMBr->attr));
4048        } else
4049                rc = -EIO; /* bad buffer passed in */
4050
4051        cifs_buf_release(pSMB);
4052
4053        if (rc == -EAGAIN)
4054                goto QInfRetry;
4055
4056        return rc;
4057}
4058
4059int
4060CIFSSMBQFileInfo(const unsigned int xid, struct cifs_tcon *tcon,
4061                 u16 netfid, FILE_ALL_INFO *pFindData)
4062{
4063        struct smb_t2_qfi_req *pSMB = NULL;
4064        struct smb_t2_qfi_rsp *pSMBr = NULL;
4065        int rc = 0;
4066        int bytes_returned;
4067        __u16 params, byte_count;
4068
4069QFileInfoRetry:
4070        rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
4071                      (void **) &pSMBr);
4072        if (rc)
4073                return rc;
4074
4075        params = 2 /* level */ + 2 /* fid */;
4076        pSMB->t2.TotalDataCount = 0;
4077        pSMB->t2.MaxParameterCount = cpu_to_le16(4);
4078        /* BB find exact max data count below from sess structure BB */
4079        pSMB->t2.MaxDataCount = cpu_to_le16(CIFSMaxBufSize);
4080        pSMB->t2.MaxSetupCount = 0;
4081        pSMB->t2.Reserved = 0;
4082        pSMB->t2.Flags = 0;
4083        pSMB->t2.Timeout = 0;
4084        pSMB->t2.Reserved2 = 0;
4085        pSMB->t2.ParameterOffset = cpu_to_le16(offsetof(struct smb_t2_qfi_req,
4086                                               Fid) - 4);
4087        pSMB->t2.DataCount = 0;
4088        pSMB->t2.DataOffset = 0;
4089        pSMB->t2.SetupCount = 1;
4090        pSMB->t2.Reserved3 = 0;
4091        pSMB->t2.SubCommand = cpu_to_le16(TRANS2_QUERY_FILE_INFORMATION);
4092        byte_count = params + 1 /* pad */ ;
4093        pSMB->t2.TotalParameterCount = cpu_to_le16(params);
4094        pSMB->t2.ParameterCount = pSMB->t2.TotalParameterCount;
4095        pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FILE_ALL_INFO);
4096        pSMB->Pad = 0;
4097        pSMB->Fid = netfid;
4098        inc_rfc1001_len(pSMB, byte_count);
4099        pSMB->t2.ByteCount = cpu_to_le16(byte_count);
4100
4101        rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
4102                         (struct smb_hdr *) pSMBr, &bytes_returned, 0);
4103        if (rc) {
4104                cifs_dbg(FYI, "Send error in QFileInfo = %d\n", rc);
4105        } else {                /* decode response */
4106                rc = validate_t2((struct smb_t2_rsp *)pSMBr);
4107
4108                if (rc) /* BB add auto retry on EOPNOTSUPP? */
4109                        rc = -EIO;
4110                else if (get_bcc(&pSMBr->hdr) < 40)
4111                        rc = -EIO;      /* bad smb */
4112                else if (pFindData) {
4113                        __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
4114                        memcpy((char *) pFindData,
4115                               (char *) &pSMBr->hdr.Protocol +
4116                               data_offset, sizeof(FILE_ALL_INFO));
4117                } else
4118                    rc = -ENOMEM;
4119        }
4120        cifs_buf_release(pSMB);
4121        if (rc == -EAGAIN)
4122                goto QFileInfoRetry;
4123
4124        return rc;
4125}
4126
4127int
4128CIFSSMBQPathInfo(const unsigned int xid, struct cifs_tcon *tcon,
4129                 const char *search_name, FILE_ALL_INFO *data,
4130                 int legacy /* old style infolevel */,
4131                 const struct nls_table *nls_codepage, int remap)
4132{
4133        /* level 263 SMB_QUERY_FILE_ALL_INFO */
4134        TRANSACTION2_QPI_REQ *pSMB = NULL;
4135        TRANSACTION2_QPI_RSP *pSMBr = NULL;
4136        int rc = 0;
4137        int bytes_returned;
4138        int name_len;
4139        __u16 params, byte_count;
4140
4141        /* cifs_dbg(FYI, "In QPathInfo path %s\n", search_name); */
4142QPathInfoRetry:
4143        rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
4144                      (void **) &pSMBr);
4145        if (rc)
4146                return rc;
4147
4148        if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
4149                name_len =
4150                    cifsConvertToUTF16((__le16 *) pSMB->FileName, search_name,
4151                                       PATH_MAX, nls_codepage, remap);
4152                name_len++;     /* trailing null */
4153                name_len *= 2;
4154        } else {
4155                name_len = copy_path_name(pSMB->FileName, search_name);
4156        }
4157
4158        params = 2 /* level */ + 4 /* reserved */ + name_len /* includes NUL */;
4159        pSMB->TotalDataCount = 0;
4160        pSMB->MaxParameterCount = cpu_to_le16(2);
4161        /* BB find exact max SMB PDU from sess structure BB */
4162        pSMB->MaxDataCount = cpu_to_le16(4000);
4163        pSMB->MaxSetupCount = 0;
4164        pSMB->Reserved = 0;
4165        pSMB->Flags = 0;
4166        pSMB->Timeout = 0;
4167        pSMB->Reserved2 = 0;
4168        pSMB->ParameterOffset = cpu_to_le16(offsetof(
4169        struct smb_com_transaction2_qpi_req, InformationLevel) - 4);
4170        pSMB->DataCount = 0;
4171        pSMB->DataOffset = 0;
4172        pSMB->SetupCount = 1;
4173        pSMB->Reserved3 = 0;
4174        pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_PATH_INFORMATION);
4175        byte_count = params + 1 /* pad */ ;
4176        pSMB->TotalParameterCount = cpu_to_le16(params);
4177        pSMB->ParameterCount = pSMB->TotalParameterCount;
4178        if (legacy)
4179                pSMB->InformationLevel = cpu_to_le16(SMB_INFO_STANDARD);
4180        else
4181                pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FILE_ALL_INFO);
4182        pSMB->Reserved4 = 0;
4183        inc_rfc1001_len(pSMB, byte_count);
4184        pSMB->ByteCount = cpu_to_le16(byte_count);
4185
4186        rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
4187                         (struct smb_hdr *) pSMBr, &bytes_returned, 0);
4188        if (rc) {
4189                cifs_dbg(FYI, "Send error in QPathInfo = %d\n", rc);
4190        } else {                /* decode response */
4191                rc = validate_t2((struct smb_t2_rsp *)pSMBr);
4192
4193                if (rc) /* BB add auto retry on EOPNOTSUPP? */
4194                        rc = -EIO;
4195                else if (!legacy && get_bcc(&pSMBr->hdr) < 40)
4196                        rc = -EIO;      /* bad smb */
4197                else if (legacy && get_bcc(&pSMBr->hdr) < 24)
4198                        rc = -EIO;  /* 24 or 26 expected but we do not read
4199                                        last field */
4200                else if (data) {
4201                        int size;
4202                        __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
4203
4204                        /*
4205                         * On legacy responses we do not read the last field,
4206                         * EAsize, fortunately since it varies by subdialect and
4207                         * also note it differs on Set vs Get, ie two bytes or 4
4208                         * bytes depending but we don't care here.
4209                         */
4210                        if (legacy)
4211                                size = sizeof(FILE_INFO_STANDARD);
4212                        else
4213                                size = sizeof(FILE_ALL_INFO);
4214                        memcpy((char *) data, (char *) &pSMBr->hdr.Protocol +
4215                               data_offset, size);
4216                } else
4217                    rc = -ENOMEM;
4218        }
4219        cifs_buf_release(pSMB);
4220        if (rc == -EAGAIN)
4221                goto QPathInfoRetry;
4222
4223        return rc;
4224}
4225
4226int
4227CIFSSMBUnixQFileInfo(const unsigned int xid, struct cifs_tcon *tcon,
4228                 u16 netfid, FILE_UNIX_BASIC_INFO *pFindData)
4229{
4230        struct smb_t2_qfi_req *pSMB = NULL;
4231        struct smb_t2_qfi_rsp *pSMBr = NULL;
4232        int rc = 0;
4233        int bytes_returned;
4234        __u16 params, byte_count;
4235
4236UnixQFileInfoRetry:
4237        rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
4238                      (void **) &pSMBr);
4239        if (rc)
4240                return rc;
4241
4242        params = 2 /* level */ + 2 /* fid */;
4243        pSMB->t2.TotalDataCount = 0;
4244        pSMB->t2.MaxParameterCount = cpu_to_le16(4);
4245        /* BB find exact max data count below from sess structure BB */
4246        pSMB->t2.MaxDataCount = cpu_to_le16(CIFSMaxBufSize);
4247        pSMB->t2.MaxSetupCount = 0;
4248        pSMB->t2.Reserved = 0;
4249        pSMB->t2.Flags = 0;
4250        pSMB->t2.Timeout = 0;
4251        pSMB->t2.Reserved2 = 0;
4252        pSMB->t2.ParameterOffset = cpu_to_le16(offsetof(struct smb_t2_qfi_req,
4253                                               Fid) - 4);
4254        pSMB->t2.DataCount = 0;
4255        pSMB->t2.DataOffset = 0;
4256        pSMB->t2.SetupCount = 1;
4257        pSMB->t2.Reserved3 = 0;
4258        pSMB->t2.SubCommand = cpu_to_le16(TRANS2_QUERY_FILE_INFORMATION);
4259        byte_count = params + 1 /* pad */ ;
4260        pSMB->t2.TotalParameterCount = cpu_to_le16(params);
4261        pSMB->t2.ParameterCount = pSMB->t2.TotalParameterCount;
4262        pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FILE_UNIX_BASIC);
4263        pSMB->Pad = 0;
4264        pSMB->Fid = netfid;
4265        inc_rfc1001_len(pSMB, byte_count);
4266        pSMB->t2.ByteCount = cpu_to_le16(byte_count);
4267
4268        rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
4269                         (struct smb_hdr *) pSMBr, &bytes_returned, 0);
4270        if (rc) {
4271                cifs_dbg(FYI, "Send error in UnixQFileInfo = %d\n", rc);
4272        } else {                /* decode response */
4273                rc = validate_t2((struct smb_t2_rsp *)pSMBr);
4274
4275                if (rc || get_bcc(&pSMBr->hdr) < sizeof(FILE_UNIX_BASIC_INFO)) {
4276                        cifs_dbg(VFS, "Malformed FILE_UNIX_BASIC_INFO response. Unix Extensions can be disabled on mount by specifying the nosfu mount option.\n");
4277                        rc = -EIO;      /* bad smb */
4278                } else {
4279                        __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
4280                        memcpy((char *) pFindData,
4281                               (char *) &pSMBr->hdr.Protocol +
4282                               data_offset,
4283                               sizeof(FILE_UNIX_BASIC_INFO));
4284                }
4285        }
4286
4287        cifs_buf_release(pSMB);
4288        if (rc == -EAGAIN)
4289                goto UnixQFileInfoRetry;
4290
4291        return rc;
4292}
4293
4294int
4295CIFSSMBUnixQPathInfo(const unsigned int xid, struct cifs_tcon *tcon,
4296                     const unsigned char *searchName,
4297                     FILE_UNIX_BASIC_INFO *pFindData,
4298                     const struct nls_table *nls_codepage, int remap)
4299{
4300/* SMB_QUERY_FILE_UNIX_BASIC */
4301        TRANSACTION2_QPI_REQ *pSMB = NULL;
4302        TRANSACTION2_QPI_RSP *pSMBr = NULL;
4303        int rc = 0;
4304        int bytes_returned = 0;
4305        int name_len;
4306        __u16 params, byte_count;
4307
4308        cifs_dbg(FYI, "In QPathInfo (Unix) the path %s\n", searchName);
4309UnixQPathInfoRetry:
4310        rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
4311                      (void **) &pSMBr);
4312        if (rc)
4313                return rc;
4314
4315        if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
4316                name_len =
4317                    cifsConvertToUTF16((__le16 *) pSMB->FileName, searchName,
4318                                       PATH_MAX, nls_codepage, remap);
4319                name_len++;     /* trailing null */
4320                name_len *= 2;
4321        } else {
4322                name_len = copy_path_name(pSMB->FileName, searchName);
4323        }
4324
4325        params = 2 /* level */ + 4 /* reserved */ + name_len /* includes NUL */;
4326        pSMB->TotalDataCount = 0;
4327        pSMB->MaxParameterCount = cpu_to_le16(2);
4328        /* BB find exact max SMB PDU from sess structure BB */
4329        pSMB->MaxDataCount = cpu_to_le16(4000);
4330        pSMB->MaxSetupCount = 0;
4331        pSMB->Reserved = 0;
4332        pSMB->Flags = 0;
4333        pSMB->Timeout = 0;
4334        pSMB->Reserved2 = 0;
4335        pSMB->ParameterOffset = cpu_to_le16(offsetof(
4336        struct smb_com_transaction2_qpi_req, InformationLevel) - 4);
4337        pSMB->DataCount = 0;
4338        pSMB->DataOffset = 0;
4339        pSMB->SetupCount = 1;
4340        pSMB->Reserved3 = 0;
4341        pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_PATH_INFORMATION);
4342        byte_count = params + 1 /* pad */ ;
4343        pSMB->TotalParameterCount = cpu_to_le16(params);
4344        pSMB->ParameterCount = pSMB->TotalParameterCount;
4345        pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FILE_UNIX_BASIC);
4346        pSMB->Reserved4 = 0;
4347        inc_rfc1001_len(pSMB, byte_count);
4348        pSMB->ByteCount = cpu_to_le16(byte_count);
4349
4350        rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
4351                         (struct smb_hdr *) pSMBr, &bytes_returned, 0);
4352        if (rc) {
4353                cifs_dbg(FYI, "Send error in UnixQPathInfo = %d\n", rc);
4354        } else {                /* decode response */
4355                rc = validate_t2((struct smb_t2_rsp *)pSMBr);
4356
4357                if (rc || get_bcc(&pSMBr->hdr) < sizeof(FILE_UNIX_BASIC_INFO)) {
4358                        cifs_dbg(VFS, "Malformed FILE_UNIX_BASIC_INFO response. Unix Extensions can be disabled on mount by specifying the nosfu mount option.\n");
4359                        rc = -EIO;      /* bad smb */
4360                } else {
4361                        __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
4362                        memcpy((char *) pFindData,
4363                               (char *) &pSMBr->hdr.Protocol +
4364                               data_offset,
4365                               sizeof(FILE_UNIX_BASIC_INFO));
4366                }
4367        }
4368        cifs_buf_release(pSMB);
4369        if (rc == -EAGAIN)
4370                goto UnixQPathInfoRetry;
4371
4372        return rc;
4373}
4374
4375/* xid, tcon, searchName and codepage are input parms, rest are returned */
4376int
4377CIFSFindFirst(const unsigned int xid, struct cifs_tcon *tcon,
4378              const char *searchName, struct cifs_sb_info *cifs_sb,
4379              __u16 *pnetfid, __u16 search_flags,
4380              struct cifs_search_info *psrch_inf, bool msearch)
4381{
4382/* level 257 SMB_ */
4383        TRANSACTION2_FFIRST_REQ *pSMB = NULL;
4384        TRANSACTION2_FFIRST_RSP *pSMBr = NULL;
4385        T2_FFIRST_RSP_PARMS *parms;
4386        int rc = 0;
4387        int bytes_returned = 0;
4388        int name_len, remap;
4389        __u16 params, byte_count;
4390        struct nls_table *nls_codepage;
4391
4392        cifs_dbg(FYI, "In FindFirst for %s\n", searchName);
4393
4394findFirstRetry:
4395        rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
4396                      (void **) &pSMBr);
4397        if (rc)
4398                return rc;
4399
4400        nls_codepage = cifs_sb->local_nls;
4401        remap = cifs_remap(cifs_sb);
4402
4403        if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
4404                name_len =
4405                    cifsConvertToUTF16((__le16 *) pSMB->FileName, searchName,
4406                                       PATH_MAX, nls_codepage, remap);
4407                /* We can not add the asterik earlier in case
4408                it got remapped to 0xF03A as if it were part of the
4409                directory name instead of a wildcard */
4410                name_len *= 2;
4411                if (msearch) {
4412                        pSMB->FileName[name_len] = CIFS_DIR_SEP(cifs_sb);
4413                        pSMB->FileName[name_len+1] = 0;
4414                        pSMB->FileName[name_len+2] = '*';
4415                        pSMB->FileName[name_len+3] = 0;
4416                        name_len += 4; /* now the trailing null */
4417                        /* null terminate just in case */
4418                        pSMB->FileName[name_len] = 0;
4419                        pSMB->FileName[name_len+1] = 0;
4420                        name_len += 2;
4421                }
4422        } else {
4423                name_len = copy_path_name(pSMB->FileName, searchName);
4424                if (msearch) {
4425                        if (WARN_ON_ONCE(name_len > PATH_MAX-2))
4426                                name_len = PATH_MAX-2;
4427                        /* overwrite nul byte */
4428                        pSMB->FileName[name_len-1] = CIFS_DIR_SEP(cifs_sb);
4429                        pSMB->FileName[name_len] = '*';
4430                        pSMB->FileName[name_len+1] = 0;
4431                        name_len += 2;
4432                }
4433        }
4434
4435        params = 12 + name_len /* includes null */ ;
4436        pSMB->TotalDataCount = 0;       /* no EAs */
4437        pSMB->MaxParameterCount = cpu_to_le16(10);
4438        pSMB->MaxDataCount = cpu_to_le16(CIFSMaxBufSize & 0xFFFFFF00);
4439        pSMB->MaxSetupCount = 0;
4440        pSMB->Reserved = 0;
4441        pSMB->Flags = 0;
4442        pSMB->Timeout = 0;
4443        pSMB->Reserved2 = 0;
4444        byte_count = params + 1 /* pad */ ;
4445        pSMB->TotalParameterCount = cpu_to_le16(params);
4446        pSMB->ParameterCount = pSMB->TotalParameterCount;
4447        pSMB->ParameterOffset = cpu_to_le16(
4448              offsetof(struct smb_com_transaction2_ffirst_req, SearchAttributes)
4449                - 4);
4450        pSMB->DataCount = 0;
4451        pSMB->DataOffset = 0;
4452        pSMB->SetupCount = 1;   /* one byte, no need to make endian neutral */
4453        pSMB->Reserved3 = 0;
4454        pSMB->SubCommand = cpu_to_le16(TRANS2_FIND_FIRST);
4455        pSMB->SearchAttributes =
4456            cpu_to_le16(ATTR_READONLY | ATTR_HIDDEN | ATTR_SYSTEM |
4457                        ATTR_DIRECTORY);
4458        pSMB->SearchCount = cpu_to_le16(CIFSMaxBufSize/sizeof(FILE_UNIX_INFO));
4459        pSMB->SearchFlags = cpu_to_le16(search_flags);
4460        pSMB->InformationLevel = cpu_to_le16(psrch_inf->info_level);
4461
4462        /* BB what should we set StorageType to? Does it matter? BB */
4463        pSMB->SearchStorageType = 0;
4464        inc_rfc1001_len(pSMB, byte_count);
4465        pSMB->ByteCount = cpu_to_le16(byte_count);
4466
4467        rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
4468                         (struct smb_hdr *) pSMBr, &bytes_returned, 0);
4469        cifs_stats_inc(&tcon->stats.cifs_stats.num_ffirst);
4470
4471        if (rc) {/* BB add logic to retry regular search if Unix search
4472                        rejected unexpectedly by server */
4473                /* BB Add code to handle unsupported level rc */
4474                cifs_dbg(FYI, "Error in FindFirst = %d\n", rc);
4475
4476                cifs_buf_release(pSMB);
4477
4478                /* BB eventually could optimize out free and realloc of buf */
4479                /*    for this case */
4480                if (rc == -EAGAIN)
4481                        goto findFirstRetry;
4482        } else { /* decode response */
4483                /* BB remember to free buffer if error BB */
4484                rc = validate_t2((struct smb_t2_rsp *)pSMBr);
4485                if (rc == 0) {
4486                        unsigned int lnoff;
4487
4488                        if (pSMBr->hdr.Flags2 & SMBFLG2_UNICODE)
4489                                psrch_inf->unicode = true;
4490                        else
4491                                psrch_inf->unicode = false;
4492
4493                        psrch_inf->ntwrk_buf_start = (char *)pSMBr;
4494                        psrch_inf->smallBuf = false;
4495                        psrch_inf->srch_entries_start =
4496                                (char *) &pSMBr->hdr.Protocol +
4497                                        le16_to_cpu(pSMBr->t2.DataOffset);
4498                        parms = (T2_FFIRST_RSP_PARMS *)((char *) &pSMBr->hdr.Protocol +
4499                               le16_to_cpu(pSMBr->t2.ParameterOffset));
4500
4501                        if (parms->EndofSearch)
4502                                psrch_inf->endOfSearch = true;
4503                        else
4504                                psrch_inf->endOfSearch = false;
4505
4506                        psrch_inf->entries_in_buffer =
4507                                        le16_to_cpu(parms->SearchCount);
4508                        psrch_inf->index_of_last_entry = 2 /* skip . and .. */ +
4509                                psrch_inf->entries_in_buffer;
4510                        lnoff = le16_to_cpu(parms->LastNameOffset);
4511                        if (CIFSMaxBufSize < lnoff) {
4512                                cifs_dbg(VFS, "ignoring corrupt resume name\n");
4513                                psrch_inf->last_entry = NULL;
4514                                return rc;
4515                        }
4516
4517                        psrch_inf->last_entry = psrch_inf->srch_entries_start +
4518                                                        lnoff;
4519
4520                        if (pnetfid)
4521                                *pnetfid = parms->SearchHandle;
4522                } else {
4523                        cifs_buf_release(pSMB);
4524                }
4525        }
4526
4527        return rc;
4528}
4529
4530int CIFSFindNext(const unsigned int xid, struct cifs_tcon *tcon,
4531                 __u16 searchHandle, __u16 search_flags,
4532                 struct cifs_search_info *psrch_inf)
4533{
4534        TRANSACTION2_FNEXT_REQ *pSMB = NULL;
4535        TRANSACTION2_FNEXT_RSP *pSMBr = NULL;
4536        T2_FNEXT_RSP_PARMS *parms;
4537        char *response_data;
4538        int rc = 0;
4539        int bytes_returned;
4540        unsigned int name_len;
4541        __u16 params, byte_count;
4542
4543        cifs_dbg(FYI, "In FindNext\n");
4544
4545        if (psrch_inf->endOfSearch)
4546                return -ENOENT;
4547
4548        rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
4549                (void **) &pSMBr);
4550        if (rc)
4551                return rc;
4552
4553        params = 14; /* includes 2 bytes of null string, converted to LE below*/
4554        byte_count = 0;
4555        pSMB->TotalDataCount = 0;       /* no EAs */
4556        pSMB->MaxParameterCount = cpu_to_le16(8);
4557        pSMB->MaxDataCount = cpu_to_le16(CIFSMaxBufSize & 0xFFFFFF00);
4558        pSMB->MaxSetupCount = 0;
4559        pSMB->Reserved = 0;
4560        pSMB->Flags = 0;
4561        pSMB->Timeout = 0;
4562        pSMB->Reserved2 = 0;
4563        pSMB->ParameterOffset =  cpu_to_le16(
4564              offsetof(struct smb_com_transaction2_fnext_req,SearchHandle) - 4);
4565        pSMB->DataCount = 0;
4566        pSMB->DataOffset = 0;
4567        pSMB->SetupCount = 1;
4568        pSMB->Reserved3 = 0;
4569        pSMB->SubCommand = cpu_to_le16(TRANS2_FIND_NEXT);
4570        pSMB->SearchHandle = searchHandle;      /* always kept as le */
4571        pSMB->SearchCount =
4572                cpu_to_le16(CIFSMaxBufSize / sizeof(FILE_UNIX_INFO));
4573        pSMB->InformationLevel = cpu_to_le16(psrch_inf->info_level);
4574        pSMB->ResumeKey = psrch_inf->resume_key;
4575        pSMB->SearchFlags = cpu_to_le16(search_flags);
4576
4577        name_len = psrch_inf->resume_name_len;
4578        params += name_len;
4579        if (name_len < PATH_MAX) {
4580                memcpy(pSMB->ResumeFileName, psrch_inf->presume_name, name_len);
4581                byte_count += name_len;
4582                /* 14 byte parm len above enough for 2 byte null terminator */
4583                pSMB->ResumeFileName[name_len] = 0;
4584                pSMB->ResumeFileName[name_len+1] = 0;
4585        } else {
4586                rc = -EINVAL;
4587                goto FNext2_err_exit;
4588        }
4589        byte_count = params + 1 /* pad */ ;
4590        pSMB->TotalParameterCount = cpu_to_le16(params);
4591        pSMB->ParameterCount = pSMB->TotalParameterCount;
4592        inc_rfc1001_len(pSMB, byte_count);
4593        pSMB->ByteCount = cpu_to_le16(byte_count);
4594
4595        rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
4596                        (struct smb_hdr *) pSMBr, &bytes_returned, 0);
4597        cifs_stats_inc(&tcon->stats.cifs_stats.num_fnext);
4598        if (rc) {
4599                if (rc == -EBADF) {
4600                        psrch_inf->endOfSearch = true;
4601                        cifs_buf_release(pSMB);
4602                        rc = 0; /* search probably was closed at end of search*/
4603                } else
4604                        cifs_dbg(FYI, "FindNext returned = %d\n", rc);
4605        } else {                /* decode response */
4606                rc = validate_t2((struct smb_t2_rsp *)pSMBr);
4607
4608                if (rc == 0) {
4609                        unsigned int lnoff;
4610
4611                        /* BB fixme add lock for file (srch_info) struct here */
4612                        if (pSMBr->hdr.Flags2 & SMBFLG2_UNICODE)
4613                                psrch_inf->unicode = true;
4614                        else
4615                                psrch_inf->unicode = false;
4616                        response_data = (char *) &pSMBr->hdr.Protocol +
4617                               le16_to_cpu(pSMBr->t2.ParameterOffset);
4618                        parms = (T2_FNEXT_RSP_PARMS *)response_data;
4619                        response_data = (char *)&pSMBr->hdr.Protocol +
4620                                le16_to_cpu(pSMBr->t2.DataOffset);
4621                        if (psrch_inf->smallBuf)
4622                                cifs_small_buf_release(
4623                                        psrch_inf->ntwrk_buf_start);
4624                        else
4625                                cifs_buf_release(psrch_inf->ntwrk_buf_start);
4626                        psrch_inf->srch_entries_start = response_data;
4627                        psrch_inf->ntwrk_buf_start = (char *)pSMB;
4628                        psrch_inf->smallBuf = false;
4629                        if (parms->EndofSearch)
4630                                psrch_inf->endOfSearch = true;
4631                        else
4632                                psrch_inf->endOfSearch = false;
4633                        psrch_inf->entries_in_buffer =
4634                                                le16_to_cpu(parms->SearchCount);
4635                        psrch_inf->index_of_last_entry +=
4636                                psrch_inf->entries_in_buffer;
4637                        lnoff = le16_to_cpu(parms->LastNameOffset);
4638                        if (CIFSMaxBufSize < lnoff) {
4639                                cifs_dbg(VFS, "ignoring corrupt resume name\n");
4640                                psrch_inf->last_entry = NULL;
4641                                return rc;
4642                        } else
4643                                psrch_inf->last_entry =
4644                                        psrch_inf->srch_entries_start + lnoff;
4645
4646/*  cifs_dbg(FYI, "fnxt2 entries in buf %d index_of_last %d\n",
4647    psrch_inf->entries_in_buffer, psrch_inf->index_of_last_entry); */
4648
4649                        /* BB fixme add unlock here */
4650                }
4651
4652        }
4653
4654        /* BB On error, should we leave previous search buf (and count and
4655        last entry fields) intact or free the previous one? */
4656
4657        /* Note: On -EAGAIN error only caller can retry on handle based calls
4658        since file handle passed in no longer valid */
4659FNext2_err_exit:
4660        if (rc != 0)
4661                cifs_buf_release(pSMB);
4662        return rc;
4663}
4664
4665int
4666CIFSFindClose(const unsigned int xid, struct cifs_tcon *tcon,
4667              const __u16 searchHandle)
4668{
4669        int rc = 0;
4670        FINDCLOSE_REQ *pSMB = NULL;
4671
4672        cifs_dbg(FYI, "In CIFSSMBFindClose\n");
4673        rc = small_smb_init(SMB_COM_FIND_CLOSE2, 1, tcon, (void **)&pSMB);
4674
4675        /* no sense returning error if session restarted
4676                as file handle has been closed */
4677        if (rc == -EAGAIN)
4678                return 0;
4679        if (rc)
4680                return rc;
4681
4682        pSMB->FileID = searchHandle;
4683        pSMB->ByteCount = 0;
4684        rc = SendReceiveNoRsp(xid, tcon->ses, (char *) pSMB, 0);
4685        cifs_small_buf_release(pSMB);
4686        if (rc)
4687                cifs_dbg(VFS, "Send error in FindClose = %d\n", rc);
4688
4689        cifs_stats_inc(&tcon->stats.cifs_stats.num_fclose);
4690
4691        /* Since session is dead, search handle closed on server already */
4692        if (rc == -EAGAIN)
4693                rc = 0;
4694
4695        return rc;
4696}
4697
4698int
4699CIFSGetSrvInodeNumber(const unsigned int xid, struct cifs_tcon *tcon,
4700                      const char *search_name, __u64 *inode_number,
4701                      const struct nls_table *nls_codepage, int remap)
4702{
4703        int rc = 0;
4704        TRANSACTION2_QPI_REQ *pSMB = NULL;
4705        TRANSACTION2_QPI_RSP *pSMBr = NULL;
4706        int name_len, bytes_returned;
4707        __u16 params, byte_count;
4708
4709        cifs_dbg(FYI, "In GetSrvInodeNum for %s\n", search_name);
4710        if (tcon == NULL)
4711                return -ENODEV;
4712
4713GetInodeNumberRetry:
4714        rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
4715                      (void **) &pSMBr);
4716        if (rc)
4717                return rc;
4718
4719        if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
4720                name_len =
4721                        cifsConvertToUTF16((__le16 *) pSMB->FileName,
4722                                           search_name, PATH_MAX, nls_codepage,
4723                                           remap);
4724                name_len++;     /* trailing null */
4725                name_len *= 2;
4726        } else {
4727                name_len = copy_path_name(pSMB->FileName, search_name);
4728        }
4729
4730        params = 2 /* level */  + 4 /* rsrvd */  + name_len /* incl null */ ;
4731        pSMB->TotalDataCount = 0;
4732        pSMB->MaxParameterCount = cpu_to_le16(2);
4733        /* BB find exact max data count below from sess structure BB */
4734        pSMB->MaxDataCount = cpu_to_le16(4000);
4735        pSMB->MaxSetupCount = 0;
4736        pSMB->Reserved = 0;
4737        pSMB->Flags = 0;
4738        pSMB->Timeout = 0;
4739        pSMB->Reserved2 = 0;
4740        pSMB->ParameterOffset = cpu_to_le16(offsetof(
4741                struct smb_com_transaction2_qpi_req, InformationLevel) - 4);
4742        pSMB->DataCount = 0;
4743        pSMB->DataOffset = 0;
4744        pSMB->SetupCount = 1;
4745        pSMB->Reserved3 = 0;
4746        pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_PATH_INFORMATION);
4747        byte_count = params + 1 /* pad */ ;
4748        pSMB->TotalParameterCount = cpu_to_le16(params);
4749        pSMB->ParameterCount = pSMB->TotalParameterCount;
4750        pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FILE_INTERNAL_INFO);
4751        pSMB->Reserved4 = 0;
4752        inc_rfc1001_len(pSMB, byte_count);
4753        pSMB->ByteCount = cpu_to_le16(byte_count);
4754
4755        rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
4756                (struct smb_hdr *) pSMBr, &bytes_returned, 0);
4757        if (rc) {
4758                cifs_dbg(FYI, "error %d in QueryInternalInfo\n", rc);
4759        } else {
4760                /* decode response */
4761                rc = validate_t2((struct smb_t2_rsp *)pSMBr);
4762                /* BB also check enough total bytes returned */
4763                if (rc || get_bcc(&pSMBr->hdr) < 2)
4764                        /* If rc should we check for EOPNOSUPP and
4765                        disable the srvino flag? or in caller? */
4766                        rc = -EIO;      /* bad smb */
4767                else {
4768                        __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
4769                        __u16 count = le16_to_cpu(pSMBr->t2.DataCount);
4770                        struct file_internal_info *pfinfo;
4771                        /* BB Do we need a cast or hash here ? */
4772                        if (count < 8) {
4773                                cifs_dbg(FYI, "Invalid size ret in QryIntrnlInf\n");
4774                                rc = -EIO;
4775                                goto GetInodeNumOut;
4776                        }
4777                        pfinfo = (struct file_internal_info *)
4778                                (data_offset + (char *) &pSMBr->hdr.Protocol);
4779                        *inode_number = le64_to_cpu(pfinfo->UniqueId);
4780                }
4781        }
4782GetInodeNumOut:
4783        cifs_buf_release(pSMB);
4784        if (rc == -EAGAIN)
4785                goto GetInodeNumberRetry;
4786        return rc;
4787}
4788
4789int
4790CIFSGetDFSRefer(const unsigned int xid, struct cifs_ses *ses,
4791                const char *search_name, struct dfs_info3_param **target_nodes,
4792                unsigned int *num_of_nodes,
4793                const struct nls_table *nls_codepage, int remap)
4794{
4795/* TRANS2_GET_DFS_REFERRAL */
4796        TRANSACTION2_GET_DFS_REFER_REQ *pSMB = NULL;
4797        TRANSACTION2_GET_DFS_REFER_RSP *pSMBr = NULL;
4798        int rc = 0;
4799        int bytes_returned;
4800        int name_len;
4801        __u16 params, byte_count;
4802        *num_of_nodes = 0;
4803        *target_nodes = NULL;
4804
4805        cifs_dbg(FYI, "In GetDFSRefer the path %s\n", search_name);
4806        if (ses == NULL || ses->tcon_ipc == NULL)
4807                return -ENODEV;
4808
4809getDFSRetry:
4810        rc = smb_init(SMB_COM_TRANSACTION2, 15, ses->tcon_ipc, (void **) &pSMB,
4811                      (void **) &pSMBr);
4812        if (rc)
4813                return rc;
4814
4815        /* server pointer checked in called function,
4816        but should never be null here anyway */
4817        pSMB->hdr.Mid = get_next_mid(ses->server);
4818        pSMB->hdr.Tid = ses->tcon_ipc->tid;
4819        pSMB->hdr.Uid = ses->Suid;
4820        if (ses->capabilities & CAP_STATUS32)
4821                pSMB->hdr.Flags2 |= SMBFLG2_ERR_STATUS;
4822        if (ses->capabilities & CAP_DFS)
4823                pSMB->hdr.Flags2 |= SMBFLG2_DFS;
4824
4825        if (ses->capabilities & CAP_UNICODE) {
4826                pSMB->hdr.Flags2 |= SMBFLG2_UNICODE;
4827                name_len =
4828                    cifsConvertToUTF16((__le16 *) pSMB->RequestFileName,
4829                                       search_name, PATH_MAX, nls_codepage,
4830                                       remap);
4831                name_len++;     /* trailing null */
4832                name_len *= 2;
4833        } else {        /* BB improve the check for buffer overruns BB */
4834                name_len = copy_path_name(pSMB->RequestFileName, search_name);
4835        }
4836
4837        if (ses->server->sign)
4838                pSMB->hdr.Flags2 |= SMBFLG2_SECURITY_SIGNATURE;
4839
4840        pSMB->hdr.Uid = ses->Suid;
4841
4842        params = 2 /* level */  + name_len /*includes null */ ;
4843        pSMB->TotalDataCount = 0;
4844        pSMB->DataCount = 0;
4845        pSMB->DataOffset = 0;
4846        pSMB->MaxParameterCount = 0;
4847        /* BB find exact max SMB PDU from sess structure BB */
4848        pSMB->MaxDataCount = cpu_to_le16(4000);
4849        pSMB->MaxSetupCount = 0;
4850        pSMB->Reserved = 0;
4851        pSMB->Flags = 0;
4852        pSMB->Timeout = 0;
4853        pSMB->Reserved2 = 0;
4854        pSMB->ParameterOffset = cpu_to_le16(offsetof(
4855          struct smb_com_transaction2_get_dfs_refer_req, MaxReferralLevel) - 4);
4856        pSMB->SetupCount = 1;
4857        pSMB->Reserved3 = 0;
4858        pSMB->SubCommand = cpu_to_le16(TRANS2_GET_DFS_REFERRAL);
4859        byte_count = params + 3 /* pad */ ;
4860        pSMB->ParameterCount = cpu_to_le16(params);
4861        pSMB->TotalParameterCount = pSMB->ParameterCount;
4862        pSMB->MaxReferralLevel = cpu_to_le16(3);
4863        inc_rfc1001_len(pSMB, byte_count);
4864        pSMB->ByteCount = cpu_to_le16(byte_count);
4865
4866        rc = SendReceive(xid, ses, (struct smb_hdr *) pSMB,
4867                         (struct smb_hdr *) pSMBr, &bytes_returned, 0);
4868        if (rc) {
4869                cifs_dbg(FYI, "Send error in GetDFSRefer = %d\n", rc);
4870                goto GetDFSRefExit;
4871        }
4872        rc = validate_t2((struct smb_t2_rsp *)pSMBr);
4873
4874        /* BB Also check if enough total bytes returned? */
4875        if (rc || get_bcc(&pSMBr->hdr) < 17) {
4876                rc = -EIO;      /* bad smb */
4877                goto GetDFSRefExit;
4878        }
4879
4880        cifs_dbg(FYI, "Decoding GetDFSRefer response BCC: %d  Offset %d\n",
4881                 get_bcc(&pSMBr->hdr), le16_to_cpu(pSMBr->t2.DataOffset));
4882
4883        /* parse returned result into more usable form */
4884        rc = parse_dfs_referrals(&pSMBr->dfs_data,
4885                                 le16_to_cpu(pSMBr->t2.DataCount),
4886                                 num_of_nodes, target_nodes, nls_codepage,
4887                                 remap, search_name,
4888                                 (pSMBr->hdr.Flags2 & SMBFLG2_UNICODE) != 0);
4889
4890GetDFSRefExit:
4891        cifs_buf_release(pSMB);
4892
4893        if (rc == -EAGAIN)
4894                goto getDFSRetry;
4895
4896        return rc;
4897}
4898
4899/* Query File System Info such as free space to old servers such as Win 9x */
4900int
4901SMBOldQFSInfo(const unsigned int xid, struct cifs_tcon *tcon,
4902              struct kstatfs *FSData)
4903{
4904/* level 0x01 SMB_QUERY_FILE_SYSTEM_INFO */
4905        TRANSACTION2_QFSI_REQ *pSMB = NULL;
4906        TRANSACTION2_QFSI_RSP *pSMBr = NULL;
4907        FILE_SYSTEM_ALLOC_INFO *response_data;
4908        int rc = 0;
4909        int bytes_returned = 0;
4910        __u16 params, byte_count;
4911
4912        cifs_dbg(FYI, "OldQFSInfo\n");
4913oldQFSInfoRetry:
4914        rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
4915                (void **) &pSMBr);
4916        if (rc)
4917                return rc;
4918
4919        params = 2;     /* level */
4920        pSMB->TotalDataCount = 0;
4921        pSMB->MaxParameterCount = cpu_to_le16(2);
4922        pSMB->MaxDataCount = cpu_to_le16(1000);
4923        pSMB->MaxSetupCount = 0;
4924        pSMB->Reserved = 0;
4925        pSMB->Flags = 0;
4926        pSMB->Timeout = 0;
4927        pSMB->Reserved2 = 0;
4928        byte_count = params + 1 /* pad */ ;
4929        pSMB->TotalParameterCount = cpu_to_le16(params);
4930        pSMB->ParameterCount = pSMB->TotalParameterCount;
4931        pSMB->ParameterOffset = cpu_to_le16(offsetof(
4932        struct smb_com_transaction2_qfsi_req, InformationLevel) - 4);
4933        pSMB->DataCount = 0;
4934        pSMB->DataOffset = 0;
4935        pSMB->SetupCount = 1;
4936        pSMB->Reserved3 = 0;
4937        pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_FS_INFORMATION);
4938        pSMB->InformationLevel = cpu_to_le16(SMB_INFO_ALLOCATION);
4939        inc_rfc1001_len(pSMB, byte_count);
4940        pSMB->ByteCount = cpu_to_le16(byte_count);
4941
4942        rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
4943                (struct smb_hdr *) pSMBr, &bytes_returned, 0);
4944        if (rc) {
4945                cifs_dbg(FYI, "Send error in QFSInfo = %d\n", rc);
4946        } else {                /* decode response */
4947                rc = validate_t2((struct smb_t2_rsp *)pSMBr);
4948
4949                if (rc || get_bcc(&pSMBr->hdr) < 18)
4950                        rc = -EIO;      /* bad smb */
4951                else {
4952                        __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
4953                        cifs_dbg(FYI, "qfsinf resp BCC: %d  Offset %d\n",
4954                                 get_bcc(&pSMBr->hdr), data_offset);
4955
4956                        response_data = (FILE_SYSTEM_ALLOC_INFO *)
4957                                (((char *) &pSMBr->hdr.Protocol) + data_offset);
4958                        FSData->f_bsize =
4959                                le16_to_cpu(response_data->BytesPerSector) *
4960                                le32_to_cpu(response_data->
4961                                        SectorsPerAllocationUnit);
4962                        /*
4963                         * much prefer larger but if server doesn't report
4964                         * a valid size than 4K is a reasonable minimum
4965                         */
4966                        if (FSData->f_bsize < 512)
4967                                FSData->f_bsize = 4096;
4968
4969                        FSData->f_blocks =
4970                               le32_to_cpu(response_data->TotalAllocationUnits);
4971                        FSData->f_bfree = FSData->f_bavail =
4972                                le32_to_cpu(response_data->FreeAllocationUnits);
4973                        cifs_dbg(FYI, "Blocks: %lld  Free: %lld Block size %ld\n",
4974                                 (unsigned long long)FSData->f_blocks,
4975                                 (unsigned long long)FSData->f_bfree,
4976                                 FSData->f_bsize);
4977                }
4978        }
4979        cifs_buf_release(pSMB);
4980
4981        if (rc == -EAGAIN)
4982                goto oldQFSInfoRetry;
4983
4984        return rc;
4985}
4986
4987int
4988CIFSSMBQFSInfo(const unsigned int xid, struct cifs_tcon *tcon,
4989               struct kstatfs *FSData)
4990{
4991/* level 0x103 SMB_QUERY_FILE_SYSTEM_INFO */
4992        TRANSACTION2_QFSI_REQ *pSMB = NULL;
4993        TRANSACTION2_QFSI_RSP *pSMBr = NULL;
4994        FILE_SYSTEM_INFO *response_data;
4995        int rc = 0;
4996        int bytes_returned = 0;
4997        __u16 params, byte_count;
4998
4999        cifs_dbg(FYI, "In QFSInfo\n");
5000QFSInfoRetry:
5001        rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
5002                      (void **) &pSMBr);
5003        if (rc)
5004                return rc;
5005
5006        params = 2;     /* level */
5007        pSMB->TotalDataCount = 0;
5008        pSMB->MaxParameterCount = cpu_to_le16(2);
5009        pSMB->MaxDataCount = cpu_to_le16(1000);
5010        pSMB->MaxSetupCount = 0;
5011        pSMB->Reserved = 0;
5012        pSMB->Flags = 0;
5013        pSMB->Timeout = 0;
5014        pSMB->Reserved2 = 0;
5015        byte_count = params + 1 /* pad */ ;
5016        pSMB->TotalParameterCount = cpu_to_le16(params);
5017        pSMB->ParameterCount = pSMB->TotalParameterCount;
5018        pSMB->ParameterOffset = cpu_to_le16(offsetof(
5019                struct smb_com_transaction2_qfsi_req, InformationLevel) - 4);
5020        pSMB->DataCount = 0;
5021        pSMB->DataOffset = 0;
5022        pSMB->SetupCount = 1;
5023        pSMB->Reserved3 = 0;
5024        pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_FS_INFORMATION);
5025        pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FS_SIZE_INFO);
5026        inc_rfc1001_len(pSMB, byte_count);
5027        pSMB->ByteCount = cpu_to_le16(byte_count);
5028
5029        rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
5030                         (struct smb_hdr *) pSMBr, &bytes_returned, 0);
5031        if (rc) {
5032                cifs_dbg(FYI, "Send error in QFSInfo = %d\n", rc);
5033        } else {                /* decode response */
5034                rc = validate_t2((struct smb_t2_rsp *)pSMBr);
5035
5036                if (rc || get_bcc(&pSMBr->hdr) < 24)
5037                        rc = -EIO;      /* bad smb */
5038                else {
5039                        __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
5040
5041                        response_data =
5042                            (FILE_SYSTEM_INFO
5043                             *) (((char *) &pSMBr->hdr.Protocol) +
5044                                 data_offset);
5045                        FSData->f_bsize =
5046                            le32_to_cpu(response_data->BytesPerSector) *
5047                            le32_to_cpu(response_data->
5048                                        SectorsPerAllocationUnit);
5049                        /*
5050                         * much prefer larger but if server doesn't report
5051                         * a valid size than 4K is a reasonable minimum
5052                         */
5053                        if (FSData->f_bsize < 512)
5054                                FSData->f_bsize = 4096;
5055
5056                        FSData->f_blocks =
5057                            le64_to_cpu(response_data->TotalAllocationUnits);
5058                        FSData->f_bfree = FSData->f_bavail =
5059                            le64_to_cpu(response_data->FreeAllocationUnits);
5060                        cifs_dbg(FYI, "Blocks: %lld  Free: %lld Block size %ld\n",
5061                                 (unsigned long long)FSData->f_blocks,
5062                                 (unsigned long long)FSData->f_bfree,
5063                                 FSData->f_bsize);
5064                }
5065        }
5066        cifs_buf_release(pSMB);
5067
5068        if (rc == -EAGAIN)
5069                goto QFSInfoRetry;
5070
5071        return rc;
5072}
5073
5074int
5075CIFSSMBQFSAttributeInfo(const unsigned int xid, struct cifs_tcon *tcon)
5076{
5077/* level 0x105  SMB_QUERY_FILE_SYSTEM_INFO */
5078        TRANSACTION2_QFSI_REQ *pSMB = NULL;
5079        TRANSACTION2_QFSI_RSP *pSMBr = NULL;
5080        FILE_SYSTEM_ATTRIBUTE_INFO *response_data;
5081        int rc = 0;
5082        int bytes_returned = 0;
5083        __u16 params, byte_count;
5084
5085        cifs_dbg(FYI, "In QFSAttributeInfo\n");
5086QFSAttributeRetry:
5087        rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
5088                      (void **) &pSMBr);
5089        if (rc)
5090                return rc;
5091
5092        params = 2;     /* level */
5093        pSMB->TotalDataCount = 0;
5094        pSMB->MaxParameterCount = cpu_to_le16(2);
5095        /* BB find exact max SMB PDU from sess structure BB */
5096        pSMB->MaxDataCount = cpu_to_le16(1000);
5097        pSMB->MaxSetupCount = 0;
5098        pSMB->Reserved = 0;
5099        pSMB->Flags = 0;
5100        pSMB->Timeout = 0;
5101        pSMB->Reserved2 = 0;
5102        byte_count = params + 1 /* pad */ ;
5103        pSMB->TotalParameterCount = cpu_to_le16(params);
5104        pSMB->ParameterCount = pSMB->TotalParameterCount;
5105        pSMB->ParameterOffset = cpu_to_le16(offsetof(
5106                struct smb_com_transaction2_qfsi_req, InformationLevel) - 4);
5107        pSMB->DataCount = 0;
5108        pSMB->DataOffset = 0;
5109        pSMB->SetupCount = 1;
5110        pSMB->Reserved3 = 0;
5111        pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_FS_INFORMATION);
5112        pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FS_ATTRIBUTE_INFO);
5113        inc_rfc1001_len(pSMB, byte_count);
5114        pSMB->ByteCount = cpu_to_le16(byte_count);
5115
5116        rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
5117                         (struct smb_hdr *) pSMBr, &bytes_returned, 0);
5118        if (rc) {
5119                cifs_dbg(VFS, "Send error in QFSAttributeInfo = %d\n", rc);
5120        } else {                /* decode response */
5121                rc = validate_t2((struct smb_t2_rsp *)pSMBr);
5122
5123                if (rc || get_bcc(&pSMBr->hdr) < 13) {
5124                        /* BB also check if enough bytes returned */
5125                        rc = -EIO;      /* bad smb */
5126                } else {
5127                        __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
5128                        response_data =
5129                            (FILE_SYSTEM_ATTRIBUTE_INFO
5130                             *) (((char *) &pSMBr->hdr.Protocol) +
5131                                 data_offset);
5132                        memcpy(&tcon->fsAttrInfo, response_data,
5133                               sizeof(FILE_SYSTEM_ATTRIBUTE_INFO));
5134                }
5135        }
5136        cifs_buf_release(pSMB);
5137
5138        if (rc == -EAGAIN)
5139                goto QFSAttributeRetry;
5140
5141        return rc;
5142}
5143
5144int
5145CIFSSMBQFSDeviceInfo(const unsigned int xid, struct cifs_tcon *tcon)
5146{
5147/* level 0x104 SMB_QUERY_FILE_SYSTEM_INFO */
5148        TRANSACTION2_QFSI_REQ *pSMB = NULL;
5149        TRANSACTION2_QFSI_RSP *pSMBr = NULL;
5150        FILE_SYSTEM_DEVICE_INFO *response_data;
5151        int rc = 0;
5152        int bytes_returned = 0;
5153        __u16 params, byte_count;
5154
5155        cifs_dbg(FYI, "In QFSDeviceInfo\n");
5156QFSDeviceRetry:
5157        rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
5158                      (void **) &pSMBr);
5159        if (rc)
5160                return rc;
5161
5162        params = 2;     /* level */
5163        pSMB->TotalDataCount = 0;
5164        pSMB->MaxParameterCount = cpu_to_le16(2);
5165        /* BB find exact max SMB PDU from sess structure BB */
5166        pSMB->MaxDataCount = cpu_to_le16(1000);
5167        pSMB->MaxSetupCount = 0;
5168        pSMB->Reserved = 0;
5169        pSMB->Flags = 0;
5170        pSMB->Timeout = 0;
5171        pSMB->Reserved2 = 0;
5172        byte_count = params + 1 /* pad */ ;
5173        pSMB->TotalParameterCount = cpu_to_le16(params);
5174        pSMB->ParameterCount = pSMB->TotalParameterCount;
5175        pSMB->ParameterOffset = cpu_to_le16(offsetof(
5176                struct smb_com_transaction2_qfsi_req, InformationLevel) - 4);
5177
5178        pSMB->DataCount = 0;
5179        pSMB->DataOffset = 0;
5180        pSMB->SetupCount = 1;
5181        pSMB->Reserved3 = 0;
5182        pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_FS_INFORMATION);
5183        pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FS_DEVICE_INFO);
5184        inc_rfc1001_len(pSMB, byte_count);
5185        pSMB->ByteCount = cpu_to_le16(byte_count);
5186
5187        rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
5188                         (struct smb_hdr *) pSMBr, &bytes_returned, 0);
5189        if (rc) {
5190                cifs_dbg(FYI, "Send error in QFSDeviceInfo = %d\n", rc);
5191        } else {                /* decode response */
5192                rc = validate_t2((struct smb_t2_rsp *)pSMBr);
5193
5194                if (rc || get_bcc(&pSMBr->hdr) <
5195                          sizeof(FILE_SYSTEM_DEVICE_INFO))
5196                        rc = -EIO;      /* bad smb */
5197                else {
5198                        __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
5199                        response_data =
5200                            (FILE_SYSTEM_DEVICE_INFO *)
5201                                (((char *) &pSMBr->hdr.Protocol) +
5202                                 data_offset);
5203                        memcpy(&tcon->fsDevInfo, response_data,
5204                               sizeof(FILE_SYSTEM_DEVICE_INFO));
5205                }
5206        }
5207        cifs_buf_release(pSMB);
5208
5209        if (rc == -EAGAIN)
5210                goto QFSDeviceRetry;
5211
5212        return rc;
5213}
5214
5215int
5216CIFSSMBQFSUnixInfo(const unsigned int xid, struct cifs_tcon *tcon)
5217{
5218/* level 0x200  SMB_QUERY_CIFS_UNIX_INFO */
5219        TRANSACTION2_QFSI_REQ *pSMB = NULL;
5220        TRANSACTION2_QFSI_RSP *pSMBr = NULL;
5221        FILE_SYSTEM_UNIX_INFO *response_data;
5222        int rc = 0;
5223        int bytes_returned = 0;
5224        __u16 params, byte_count;
5225
5226        cifs_dbg(FYI, "In QFSUnixInfo\n");
5227QFSUnixRetry:
5228        rc = smb_init_no_reconnect(SMB_COM_TRANSACTION2, 15, tcon,
5229                                   (void **) &pSMB, (void **) &pSMBr);
5230        if (rc)
5231                return rc;
5232
5233        params = 2;     /* level */
5234        pSMB->TotalDataCount = 0;
5235        pSMB->DataCount = 0;
5236        pSMB->DataOffset = 0;
5237        pSMB->MaxParameterCount = cpu_to_le16(2);
5238        /* BB find exact max SMB PDU from sess structure BB */
5239        pSMB->MaxDataCount = cpu_to_le16(100);
5240        pSMB->MaxSetupCount = 0;
5241        pSMB->Reserved = 0;
5242        pSMB->Flags = 0;
5243        pSMB->Timeout = 0;
5244        pSMB->Reserved2 = 0;
5245        byte_count = params + 1 /* pad */ ;
5246        pSMB->ParameterCount = cpu_to_le16(params);
5247        pSMB->TotalParameterCount = pSMB->ParameterCount;
5248        pSMB->ParameterOffset = cpu_to_le16(offsetof(struct
5249                        smb_com_transaction2_qfsi_req, InformationLevel) - 4);
5250        pSMB->SetupCount = 1;
5251        pSMB->Reserved3 = 0;
5252        pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_FS_INFORMATION);
5253        pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_CIFS_UNIX_INFO);
5254        inc_rfc1001_len(pSMB, byte_count);
5255        pSMB->ByteCount = cpu_to_le16(byte_count);
5256
5257        rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
5258                         (struct smb_hdr *) pSMBr, &bytes_returned, 0);
5259        if (rc) {
5260                cifs_dbg(VFS, "Send error in QFSUnixInfo = %d\n", rc);
5261        } else {                /* decode response */
5262                rc = validate_t2((struct smb_t2_rsp *)pSMBr);
5263
5264                if (rc || get_bcc(&pSMBr->hdr) < 13) {
5265                        rc = -EIO;      /* bad smb */
5266                } else {
5267                        __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
5268                        response_data =
5269                            (FILE_SYSTEM_UNIX_INFO
5270                             *) (((char *) &pSMBr->hdr.Protocol) +
5271                                 data_offset);
5272                        memcpy(&tcon->fsUnixInfo, response_data,
5273                               sizeof(FILE_SYSTEM_UNIX_INFO));
5274                }
5275        }
5276        cifs_buf_release(pSMB);
5277
5278        if (rc == -EAGAIN)
5279                goto QFSUnixRetry;
5280
5281
5282        return rc;
5283}
5284
5285int
5286CIFSSMBSetFSUnixInfo(const unsigned int xid, struct cifs_tcon *tcon, __u64 cap)
5287{
5288/* level 0x200  SMB_SET_CIFS_UNIX_INFO */
5289        TRANSACTION2_SETFSI_REQ *pSMB = NULL;
5290        TRANSACTION2_SETFSI_RSP *pSMBr = NULL;
5291        int rc = 0;
5292        int bytes_returned = 0;
5293        __u16 params, param_offset, offset, byte_count;
5294
5295        cifs_dbg(FYI, "In SETFSUnixInfo\n");
5296SETFSUnixRetry:
5297        /* BB switch to small buf init to save memory */
5298        rc = smb_init_no_reconnect(SMB_COM_TRANSACTION2, 15, tcon,
5299                                        (void **) &pSMB, (void **) &pSMBr);
5300        if (rc)
5301                return rc;
5302
5303        params = 4;     /* 2 bytes zero followed by info level. */
5304        pSMB->MaxSetupCount = 0;
5305        pSMB->Reserved = 0;
5306        pSMB->Flags = 0;
5307        pSMB->Timeout = 0;
5308        pSMB->Reserved2 = 0;
5309        param_offset = offsetof(struct smb_com_transaction2_setfsi_req, FileNum)
5310                                - 4;
5311        offset = param_offset + params;
5312
5313        pSMB->MaxParameterCount = cpu_to_le16(4);
5314        /* BB find exact max SMB PDU from sess structure BB */
5315        pSMB->MaxDataCount = cpu_to_le16(100);
5316        pSMB->SetupCount = 1;
5317        pSMB->Reserved3 = 0;
5318        pSMB->SubCommand = cpu_to_le16(TRANS2_SET_FS_INFORMATION);
5319        byte_count = 1 /* pad */ + params + 12;
5320
5321        pSMB->DataCount = cpu_to_le16(12);
5322        pSMB->ParameterCount = cpu_to_le16(params);
5323        pSMB->TotalDataCount = pSMB->DataCount;
5324        pSMB->TotalParameterCount = pSMB->ParameterCount;
5325        pSMB->ParameterOffset = cpu_to_le16(param_offset);
5326        pSMB->DataOffset = cpu_to_le16(offset);
5327
5328        /* Params. */
5329        pSMB->FileNum = 0;
5330        pSMB->InformationLevel = cpu_to_le16(SMB_SET_CIFS_UNIX_INFO);
5331
5332        /* Data. */
5333        pSMB->ClientUnixMajor = cpu_to_le16(CIFS_UNIX_MAJOR_VERSION);
5334        pSMB->ClientUnixMinor = cpu_to_le16(CIFS_UNIX_MINOR_VERSION);
5335        pSMB->ClientUnixCap = cpu_to_le64(cap);
5336
5337        inc_rfc1001_len(pSMB, byte_count);
5338        pSMB->ByteCount = cpu_to_le16(byte_count);
5339
5340        rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
5341                         (struct smb_hdr *) pSMBr, &bytes_returned, 0);
5342        if (rc) {
5343                cifs_dbg(VFS, "Send error in SETFSUnixInfo = %d\n", rc);
5344        } else {                /* decode response */
5345                rc = validate_t2((struct smb_t2_rsp *)pSMBr);
5346                if (rc)
5347                        rc = -EIO;      /* bad smb */
5348        }
5349        cifs_buf_release(pSMB);
5350
5351        if (rc == -EAGAIN)
5352                goto SETFSUnixRetry;
5353
5354        return rc;
5355}
5356
5357
5358
5359int
5360CIFSSMBQFSPosixInfo(const unsigned int xid, struct cifs_tcon *tcon,
5361                   struct kstatfs *FSData)
5362{
5363/* level 0x201  SMB_QUERY_CIFS_POSIX_INFO */
5364        TRANSACTION2_QFSI_REQ *pSMB = NULL;
5365        TRANSACTION2_QFSI_RSP *pSMBr = NULL;
5366        FILE_SYSTEM_POSIX_INFO *response_data;
5367        int rc = 0;
5368        int bytes_returned = 0;
5369        __u16 params, byte_count;
5370
5371        cifs_dbg(FYI, "In QFSPosixInfo\n");
5372QFSPosixRetry:
5373        rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
5374                      (void **) &pSMBr);
5375        if (rc)
5376                return rc;
5377
5378        params = 2;     /* level */
5379        pSMB->TotalDataCount = 0;
5380        pSMB->DataCount = 0;
5381        pSMB->DataOffset = 0;
5382        pSMB->MaxParameterCount = cpu_to_le16(2);
5383        /* BB find exact max SMB PDU from sess structure BB */
5384        pSMB->MaxDataCount = cpu_to_le16(100);
5385        pSMB->MaxSetupCount = 0;
5386        pSMB->Reserved = 0;
5387        pSMB->Flags = 0;
5388        pSMB->Timeout = 0;
5389        pSMB->Reserved2 = 0;
5390        byte_count = params + 1 /* pad */ ;
5391        pSMB->ParameterCount = cpu_to_le16(params);
5392        pSMB->TotalParameterCount = pSMB->ParameterCount;
5393        pSMB->ParameterOffset = cpu_to_le16(offsetof(struct
5394                        smb_com_transaction2_qfsi_req, InformationLevel) - 4);
5395        pSMB->SetupCount = 1;
5396        pSMB->Reserved3 = 0;
5397        pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_FS_INFORMATION);
5398        pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_POSIX_FS_INFO);
5399        inc_rfc1001_len(pSMB, byte_count);
5400        pSMB->ByteCount = cpu_to_le16(byte_count);
5401
5402        rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
5403                         (struct smb_hdr *) pSMBr, &bytes_returned, 0);
5404        if (rc) {
5405                cifs_dbg(FYI, "Send error in QFSUnixInfo = %d\n", rc);
5406        } else {                /* decode response */
5407                rc = validate_t2((struct smb_t2_rsp *)pSMBr);
5408
5409                if (rc || get_bcc(&pSMBr->hdr) < 13) {
5410                        rc = -EIO;      /* bad smb */
5411                } else {
5412                        __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
5413                        response_data =
5414                            (FILE_SYSTEM_POSIX_INFO
5415                             *) (((char *) &pSMBr->hdr.Protocol) +
5416                                 data_offset);
5417                        FSData->f_bsize =
5418                                        le32_to_cpu(response_data->BlockSize);
5419                        /*
5420                         * much prefer larger but if server doesn't report
5421                         * a valid size than 4K is a reasonable minimum
5422                         */
5423                        if (FSData->f_bsize < 512)
5424                                FSData->f_bsize = 4096;
5425
5426                        FSData->f_blocks =
5427                                        le64_to_cpu(response_data->TotalBlocks);
5428                        FSData->f_bfree =
5429                            le64_to_cpu(response_data->BlocksAvail);
5430                        if (response_data->UserBlocksAvail == cpu_to_le64(-1)) {
5431                                FSData->f_bavail = FSData->f_bfree;
5432                        } else {
5433                                FSData->f_bavail =
5434                                    le64_to_cpu(response_data->UserBlocksAvail);
5435                        }
5436                        if (response_data->TotalFileNodes != cpu_to_le64(-1))
5437                                FSData->f_files =
5438                                     le64_to_cpu(response_data->TotalFileNodes);
5439                        if (response_data->FreeFileNodes != cpu_to_le64(-1))
5440                                FSData->f_ffree =
5441                                      le64_to_cpu(response_data->FreeFileNodes);
5442                }
5443        }
5444        cifs_buf_release(pSMB);
5445
5446        if (rc == -EAGAIN)
5447                goto QFSPosixRetry;
5448
5449        return rc;
5450}
5451
5452
5453/*
5454 * We can not use write of zero bytes trick to set file size due to need for
5455 * large file support. Also note that this SetPathInfo is preferred to
5456 * SetFileInfo based method in next routine which is only needed to work around
5457 * a sharing violation bugin Samba which this routine can run into.
5458 */
5459int
5460CIFSSMBSetEOF(const unsigned int xid, struct cifs_tcon *tcon,
5461              const char *file_name, __u64 size, struct cifs_sb_info *cifs_sb,
5462              bool set_allocation)
5463{
5464        struct smb_com_transaction2_spi_req *pSMB = NULL;
5465        struct smb_com_transaction2_spi_rsp *pSMBr = NULL;
5466        struct file_end_of_file_info *parm_data;
5467        int name_len;
5468        int rc = 0;
5469        int bytes_returned = 0;
5470        int remap = cifs_remap(cifs_sb);
5471
5472        __u16 params, byte_count, data_count, param_offset, offset;
5473
5474        cifs_dbg(FYI, "In SetEOF\n");
5475SetEOFRetry:
5476        rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
5477                      (void **) &pSMBr);
5478        if (rc)
5479                return rc;
5480
5481        if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
5482                name_len =
5483                    cifsConvertToUTF16((__le16 *) pSMB->FileName, file_name,
5484                                       PATH_MAX, cifs_sb->local_nls, remap);
5485                name_len++;     /* trailing null */
5486                name_len *= 2;
5487        } else {
5488                name_len = copy_path_name(pSMB->FileName, file_name);
5489        }
5490        params = 6 + name_len;
5491        data_count = sizeof(struct file_end_of_file_info);
5492        pSMB->MaxParameterCount = cpu_to_le16(2);
5493        pSMB->MaxDataCount = cpu_to_le16(4100);
5494        pSMB->MaxSetupCount = 0;
5495        pSMB->Reserved = 0;
5496        pSMB->Flags = 0;
5497        pSMB->Timeout = 0;
5498        pSMB->Reserved2 = 0;
5499        param_offset = offsetof(struct smb_com_transaction2_spi_req,
5500                                InformationLevel) - 4;
5501        offset = param_offset + params;
5502        if (set_allocation) {
5503                if (tcon->ses->capabilities & CAP_INFOLEVEL_PASSTHRU)
5504                        pSMB->InformationLevel =
5505                                cpu_to_le16(SMB_SET_FILE_ALLOCATION_INFO2);
5506                else
5507                        pSMB->InformationLevel =
5508                                cpu_to_le16(SMB_SET_FILE_ALLOCATION_INFO);
5509        } else /* Set File Size */  {
5510            if (tcon->ses->capabilities & CAP_INFOLEVEL_PASSTHRU)
5511                    pSMB->InformationLevel =
5512                                cpu_to_le16(SMB_SET_FILE_END_OF_FILE_INFO2);
5513            else
5514                    pSMB->InformationLevel =
5515                                cpu_to_le16(SMB_SET_FILE_END_OF_FILE_INFO);
5516        }
5517
5518        parm_data =
5519            (struct file_end_of_file_info *) (((char *) &pSMB->hdr.Protocol) +
5520                                       offset);
5521        pSMB->ParameterOffset = cpu_to_le16(param_offset);
5522        pSMB->DataOffset = cpu_to_le16(offset);
5523        pSMB->SetupCount = 1;
5524        pSMB->Reserved3 = 0;
5525        pSMB->SubCommand = cpu_to_le16(TRANS2_SET_PATH_INFORMATION);
5526        byte_count = 3 /* pad */  + params + data_count;
5527        pSMB->DataCount = cpu_to_le16(data_count);
5528        pSMB->TotalDataCount = pSMB->DataCount;
5529        pSMB->ParameterCount = cpu_to_le16(params);
5530        pSMB->TotalParameterCount = pSMB->ParameterCount;
5531        pSMB->Reserved4 = 0;
5532        inc_rfc1001_len(pSMB, byte_count);
5533        parm_data->FileSize = cpu_to_le64(size);
5534        pSMB->ByteCount = cpu_to_le16(byte_count);
5535        rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
5536                         (struct smb_hdr *) pSMBr, &bytes_returned, 0);
5537        if (rc)
5538                cifs_dbg(FYI, "SetPathInfo (file size) returned %d\n", rc);
5539
5540        cifs_buf_release(pSMB);
5541
5542        if (rc == -EAGAIN)
5543                goto SetEOFRetry;
5544
5545        return rc;
5546}
5547
5548int
5549CIFSSMBSetFileSize(const unsigned int xid, struct cifs_tcon *tcon,
5550                   struct cifsFileInfo *cfile, __u64 size, bool set_allocation)
5551{
5552        struct smb_com_transaction2_sfi_req *pSMB  = NULL;
5553        struct file_end_of_file_info *parm_data;
5554        int rc = 0;
5555        __u16 params, param_offset, offset, byte_count, count;
5556
5557        cifs_dbg(FYI, "SetFileSize (via SetFileInfo) %lld\n",
5558                 (long long)size);
5559        rc = small_smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB);
5560
5561        if (rc)
5562                return rc;
5563
5564        pSMB->hdr.Pid = cpu_to_le16((__u16)cfile->pid);
5565        pSMB->hdr.PidHigh = cpu_to_le16((__u16)(cfile->pid >> 16));
5566
5567        params = 6;
5568        pSMB->MaxSetupCount = 0;
5569        pSMB->Reserved = 0;
5570        pSMB->Flags = 0;
5571        pSMB->Timeout = 0;
5572        pSMB->Reserved2 = 0;
5573        param_offset = offsetof(struct smb_com_transaction2_sfi_req, Fid) - 4;
5574        offset = param_offset + params;
5575
5576        count = sizeof(struct file_end_of_file_info);
5577        pSMB->MaxParameterCount = cpu_to_le16(2);
5578        /* BB find exact max SMB PDU from sess structure BB */
5579        pSMB->MaxDataCount = cpu_to_le16(1000);
5580        pSMB->SetupCount = 1;
5581        pSMB->Reserved3 = 0;
5582        pSMB->SubCommand = cpu_to_le16(TRANS2_SET_FILE_INFORMATION);
5583        byte_count = 3 /* pad */  + params + count;
5584        pSMB->DataCount = cpu_to_le16(count);
5585        pSMB->ParameterCount = cpu_to_le16(params);
5586        pSMB->TotalDataCount = pSMB->DataCount;
5587        pSMB->TotalParameterCount = pSMB->ParameterCount;
5588        pSMB->ParameterOffset = cpu_to_le16(param_offset);
5589        /* SMB offsets are from the beginning of SMB which is 4 bytes in, after RFC1001 field */
5590        parm_data =
5591                (struct file_end_of_file_info *)(((char *)pSMB) + offset + 4);
5592        pSMB->DataOffset = cpu_to_le16(offset);
5593        parm_data->FileSize = cpu_to_le64(size);
5594        pSMB->Fid = cfile->fid.netfid;
5595        if (set_allocation) {
5596                if (tcon->ses->capabilities & CAP_INFOLEVEL_PASSTHRU)
5597                        pSMB->InformationLevel =
5598                                cpu_to_le16(SMB_SET_FILE_ALLOCATION_INFO2);
5599                else
5600                        pSMB->InformationLevel =
5601                                cpu_to_le16(SMB_SET_FILE_ALLOCATION_INFO);
5602        } else /* Set File Size */  {
5603            if (tcon->ses->capabilities & CAP_INFOLEVEL_PASSTHRU)
5604                    pSMB->InformationLevel =
5605                                cpu_to_le16(SMB_SET_FILE_END_OF_FILE_INFO2);
5606            else
5607                    pSMB->InformationLevel =
5608                                cpu_to_le16(SMB_SET_FILE_END_OF_FILE_INFO);
5609        }
5610        pSMB->Reserved4 = 0;
5611        inc_rfc1001_len(pSMB, byte_count);
5612        pSMB->ByteCount = cpu_to_le16(byte_count);
5613        rc = SendReceiveNoRsp(xid, tcon->ses, (char *) pSMB, 0);
5614        cifs_small_buf_release(pSMB);
5615        if (rc) {
5616                cifs_dbg(FYI, "Send error in SetFileInfo (SetFileSize) = %d\n",
5617                         rc);
5618        }
5619
5620        /* Note: On -EAGAIN error only caller can retry on handle based calls
5621                since file handle passed in no longer valid */
5622
5623        return rc;
5624}
5625
5626/* Some legacy servers such as NT4 require that the file times be set on
5627   an open handle, rather than by pathname - this is awkward due to
5628   potential access conflicts on the open, but it is unavoidable for these
5629   old servers since the only other choice is to go from 100 nanosecond DCE
5630   time and resort to the original setpathinfo level which takes the ancient
5631   DOS time format with 2 second granularity */
5632int
5633CIFSSMBSetFileInfo(const unsigned int xid, struct cifs_tcon *tcon,
5634                    const FILE_BASIC_INFO *data, __u16 fid, __u32 pid_of_opener)
5635{
5636        struct smb_com_transaction2_sfi_req *pSMB  = NULL;
5637        char *data_offset;
5638        int rc = 0;
5639        __u16 params, param_offset, offset, byte_count, count;
5640
5641        cifs_dbg(FYI, "Set Times (via SetFileInfo)\n");
5642        rc = small_smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB);
5643
5644        if (rc)
5645                return rc;
5646
5647        pSMB->hdr.Pid = cpu_to_le16((__u16)pid_of_opener);
5648        pSMB->hdr.PidHigh = cpu_to_le16((__u16)(pid_of_opener >> 16));
5649
5650        params = 6;
5651        pSMB->MaxSetupCount = 0;
5652        pSMB->Reserved = 0;
5653        pSMB->Flags = 0;
5654        pSMB->Timeout = 0;
5655        pSMB->Reserved2 = 0;
5656        param_offset = offsetof(struct smb_com_transaction2_sfi_req, Fid) - 4;
5657        offset = param_offset + params;
5658
5659        data_offset = (char *)pSMB +
5660                        offsetof(struct smb_hdr, Protocol) + offset;
5661
5662        count = sizeof(FILE_BASIC_INFO);
5663        pSMB->MaxParameterCount = cpu_to_le16(2);
5664        /* BB find max SMB PDU from sess */
5665        pSMB->MaxDataCount = cpu_to_le16(1000);
5666        pSMB->SetupCount = 1;
5667        pSMB->Reserved3 = 0;
5668        pSMB->SubCommand = cpu_to_le16(TRANS2_SET_FILE_INFORMATION);
5669        byte_count = 3 /* pad */  + params + count;
5670        pSMB->DataCount = cpu_to_le16(count);
5671        pSMB->ParameterCount = cpu_to_le16(params);
5672        pSMB->TotalDataCount = pSMB->DataCount;
5673        pSMB->TotalParameterCount = pSMB->ParameterCount;
5674        pSMB->ParameterOffset = cpu_to_le16(param_offset);
5675        pSMB->DataOffset = cpu_to_le16(offset);
5676        pSMB->Fid = fid;
5677        if (tcon->ses->capabilities & CAP_INFOLEVEL_PASSTHRU)
5678                pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_BASIC_INFO2);
5679        else
5680                pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_BASIC_INFO);
5681        pSMB->Reserved4 = 0;
5682        inc_rfc1001_len(pSMB, byte_count);
5683        pSMB->ByteCount = cpu_to_le16(byte_count);
5684        memcpy(data_offset, data, sizeof(FILE_BASIC_INFO));
5685        rc = SendReceiveNoRsp(xid, tcon->ses, (char *) pSMB, 0);
5686        cifs_small_buf_release(pSMB);
5687        if (rc)
5688                cifs_dbg(FYI, "Send error in Set Time (SetFileInfo) = %d\n",
5689                         rc);
5690
5691        /* Note: On -EAGAIN error only caller can retry on handle based calls
5692                since file handle passed in no longer valid */
5693
5694        return rc;
5695}
5696
5697int
5698CIFSSMBSetFileDisposition(const unsigned int xid, struct cifs_tcon *tcon,
5699                          bool delete_file, __u16 fid, __u32 pid_of_opener)
5700{
5701        struct smb_com_transaction2_sfi_req *pSMB  = NULL;
5702        char *data_offset;
5703        int rc = 0;
5704        __u16 params, param_offset, offset, byte_count, count;
5705
5706        cifs_dbg(FYI, "Set File Disposition (via SetFileInfo)\n");
5707        rc = small_smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB);
5708
5709        if (rc)
5710                return rc;
5711
5712        pSMB->hdr.Pid = cpu_to_le16((__u16)pid_of_opener);
5713        pSMB->hdr.PidHigh = cpu_to_le16((__u16)(pid_of_opener >> 16));
5714
5715        params = 6;
5716        pSMB->MaxSetupCount = 0;
5717        pSMB->Reserved = 0;
5718        pSMB->Flags = 0;
5719        pSMB->Timeout = 0;
5720        pSMB->Reserved2 = 0;
5721        param_offset = offsetof(struct smb_com_transaction2_sfi_req, Fid) - 4;
5722        offset = param_offset + params;
5723
5724        /* SMB offsets are from the beginning of SMB which is 4 bytes in, after RFC1001 field */
5725        data_offset = (char *)(pSMB) + offset + 4;
5726
5727        count = 1;
5728        pSMB->MaxParameterCount = cpu_to_le16(2);
5729        /* BB find max SMB PDU from sess */
5730        pSMB->MaxDataCount = cpu_to_le16(1000);
5731        pSMB->SetupCount = 1;
5732        pSMB->Reserved3 = 0;
5733        pSMB->SubCommand = cpu_to_le16(TRANS2_SET_FILE_INFORMATION);
5734        byte_count = 3 /* pad */  + params + count;
5735        pSMB->DataCount = cpu_to_le16(count);
5736        pSMB->ParameterCount = cpu_to_le16(params);
5737        pSMB->TotalDataCount = pSMB->DataCount;
5738        pSMB->TotalParameterCount = pSMB->ParameterCount;
5739        pSMB->ParameterOffset = cpu_to_le16(param_offset);
5740        pSMB->DataOffset = cpu_to_le16(offset);
5741        pSMB->Fid = fid;
5742        pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_DISPOSITION_INFO);
5743        pSMB->Reserved4 = 0;
5744        inc_rfc1001_len(pSMB, byte_count);
5745        pSMB->ByteCount = cpu_to_le16(byte_count);
5746        *data_offset = delete_file ? 1 : 0;
5747        rc = SendReceiveNoRsp(xid, tcon->ses, (char *) pSMB, 0);
5748        cifs_small_buf_release(pSMB);
5749        if (rc)
5750                cifs_dbg(FYI, "Send error in SetFileDisposition = %d\n", rc);
5751
5752        return rc;
5753}
5754
5755static int
5756CIFSSMBSetPathInfoFB(const unsigned int xid, struct cifs_tcon *tcon,
5757                     const char *fileName, const FILE_BASIC_INFO *data,
5758                     const struct nls_table *nls_codepage,
5759                     struct cifs_sb_info *cifs_sb)
5760{
5761        int oplock = 0;
5762        struct cifs_open_parms oparms;
5763        struct cifs_fid fid;
5764        int rc;
5765
5766        oparms.tcon = tcon;
5767        oparms.cifs_sb = cifs_sb;
5768        oparms.desired_access = GENERIC_WRITE;
5769        oparms.create_options = cifs_create_options(cifs_sb, 0);
5770        oparms.disposition = FILE_OPEN;
5771        oparms.path = fileName;
5772        oparms.fid = &fid;
5773        oparms.reconnect = false;
5774
5775        rc = CIFS_open(xid, &oparms, &oplock, NULL);
5776        if (rc)
5777                goto out;
5778
5779        rc = CIFSSMBSetFileInfo(xid, tcon, data, fid.netfid, current->tgid);
5780        CIFSSMBClose(xid, tcon, fid.netfid);
5781out:
5782
5783        return rc;
5784}
5785
5786int
5787CIFSSMBSetPathInfo(const unsigned int xid, struct cifs_tcon *tcon,
5788                   const char *fileName, const FILE_BASIC_INFO *data,
5789                   const struct nls_table *nls_codepage,
5790                     struct cifs_sb_info *cifs_sb)
5791{
5792        TRANSACTION2_SPI_REQ *pSMB = NULL;
5793        TRANSACTION2_SPI_RSP *pSMBr = NULL;
5794        int name_len;
5795        int rc = 0;
5796        int bytes_returned = 0;
5797        char *data_offset;
5798        __u16 params, param_offset, offset, byte_count, count;
5799        int remap = cifs_remap(cifs_sb);
5800
5801        cifs_dbg(FYI, "In SetTimes\n");
5802
5803SetTimesRetry:
5804        rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
5805                      (void **) &pSMBr);
5806        if (rc)
5807                return rc;
5808
5809        if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
5810                name_len =
5811                    cifsConvertToUTF16((__le16 *) pSMB->FileName, fileName,
5812                                       PATH_MAX, nls_codepage, remap);
5813                name_len++;     /* trailing null */
5814                name_len *= 2;
5815        } else {
5816                name_len = copy_path_name(pSMB->FileName, fileName);
5817        }
5818
5819        params = 6 + name_len;
5820        count = sizeof(FILE_BASIC_INFO);
5821        pSMB->MaxParameterCount = cpu_to_le16(2);
5822        /* BB find max SMB PDU from sess structure BB */
5823        pSMB->MaxDataCount = cpu_to_le16(1000);
5824        pSMB->MaxSetupCount = 0;
5825        pSMB->Reserved = 0;
5826        pSMB->Flags = 0;
5827        pSMB->Timeout = 0;
5828        pSMB->Reserved2 = 0;
5829        param_offset = offsetof(struct smb_com_transaction2_spi_req,
5830                                InformationLevel) - 4;
5831        offset = param_offset + params;
5832        data_offset = (char *) (&pSMB->hdr.Protocol) + offset;
5833        pSMB->ParameterOffset = cpu_to_le16(param_offset);
5834        pSMB->DataOffset = cpu_to_le16(offset);
5835        pSMB->SetupCount = 1;
5836        pSMB->Reserved3 = 0;
5837        pSMB->SubCommand = cpu_to_le16(TRANS2_SET_PATH_INFORMATION);
5838        byte_count = 3 /* pad */  + params + count;
5839
5840        pSMB->DataCount = cpu_to_le16(count);
5841        pSMB->ParameterCount = cpu_to_le16(params);
5842        pSMB->TotalDataCount = pSMB->DataCount;
5843        pSMB->TotalParameterCount = pSMB->ParameterCount;
5844        if (tcon->ses->capabilities & CAP_INFOLEVEL_PASSTHRU)
5845                pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_BASIC_INFO2);
5846        else
5847                pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_BASIC_INFO);
5848        pSMB->Reserved4 = 0;
5849        inc_rfc1001_len(pSMB, byte_count);
5850        memcpy(data_offset, data, sizeof(FILE_BASIC_INFO));
5851        pSMB->ByteCount = cpu_to_le16(byte_count);
5852        rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
5853                         (struct smb_hdr *) pSMBr, &bytes_returned, 0);
5854        if (rc)
5855                cifs_dbg(FYI, "SetPathInfo (times) returned %d\n", rc);
5856
5857        cifs_buf_release(pSMB);
5858
5859        if (rc == -EAGAIN)
5860                goto SetTimesRetry;
5861
5862        if (rc == -EOPNOTSUPP)
5863                return CIFSSMBSetPathInfoFB(xid, tcon, fileName, data,
5864                                            nls_codepage, cifs_sb);
5865
5866        return rc;
5867}
5868
5869static void
5870cifs_fill_unix_set_info(FILE_UNIX_BASIC_INFO *data_offset,
5871                        const struct cifs_unix_set_info_args *args)
5872{
5873        u64 uid = NO_CHANGE_64, gid = NO_CHANGE_64;
5874        u64 mode = args->mode;
5875
5876        if (uid_valid(args->uid))
5877                uid = from_kuid(&init_user_ns, args->uid);
5878        if (gid_valid(args->gid))
5879                gid = from_kgid(&init_user_ns, args->gid);
5880
5881        /*
5882         * Samba server ignores set of file size to zero due to bugs in some
5883         * older clients, but we should be precise - we use SetFileSize to
5884         * set file size and do not want to truncate file size to zero
5885         * accidentally as happened on one Samba server beta by putting
5886         * zero instead of -1 here
5887         */
5888        data_offset->EndOfFile = cpu_to_le64(NO_CHANGE_64);
5889        data_offset->NumOfBytes = cpu_to_le64(NO_CHANGE_64);
5890        data_offset->LastStatusChange = cpu_to_le64(args->ctime);
5891        data_offset->LastAccessTime = cpu_to_le64(args->atime);
5892        data_offset->LastModificationTime = cpu_to_le64(args->mtime);
5893        data_offset->Uid = cpu_to_le64(uid);
5894        data_offset->Gid = cpu_to_le64(gid);
5895        /* better to leave device as zero when it is  */
5896        data_offset->DevMajor = cpu_to_le64(MAJOR(args->device));
5897        data_offset->DevMinor = cpu_to_le64(MINOR(args->device));
5898        data_offset->Permissions = cpu_to_le64(mode);
5899
5900        if (S_ISREG(mode))
5901                data_offset->Type = cpu_to_le32(UNIX_FILE);
5902        else if (S_ISDIR(mode))
5903                data_offset->Type = cpu_to_le32(UNIX_DIR);
5904        else if (S_ISLNK(mode))
5905                data_offset->Type = cpu_to_le32(UNIX_SYMLINK);
5906        else if (S_ISCHR(mode))
5907                data_offset->Type = cpu_to_le32(UNIX_CHARDEV);
5908        else if (S_ISBLK(mode))
5909                data_offset->Type = cpu_to_le32(UNIX_BLOCKDEV);
5910        else if (S_ISFIFO(mode))
5911                data_offset->Type = cpu_to_le32(UNIX_FIFO);
5912        else if (S_ISSOCK(mode))
5913                data_offset->Type = cpu_to_le32(UNIX_SOCKET);
5914}
5915
5916int
5917CIFSSMBUnixSetFileInfo(const unsigned int xid, struct cifs_tcon *tcon,
5918                       const struct cifs_unix_set_info_args *args,
5919                       u16 fid, u32 pid_of_opener)
5920{
5921        struct smb_com_transaction2_sfi_req *pSMB  = NULL;
5922        char *data_offset;
5923        int rc = 0;
5924        u16 params, param_offset, offset, byte_count, count;
5925
5926        cifs_dbg(FYI, "Set Unix Info (via SetFileInfo)\n");
5927        rc = small_smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB);
5928
5929        if (rc)
5930                return rc;
5931
5932        pSMB->hdr.Pid = cpu_to_le16((__u16)pid_of_opener);
5933        pSMB->hdr.PidHigh = cpu_to_le16((__u16)(pid_of_opener >> 16));
5934
5935        params = 6;
5936        pSMB->MaxSetupCount = 0;
5937        pSMB->Reserved = 0;
5938        pSMB->Flags = 0;
5939        pSMB->Timeout = 0;
5940        pSMB->Reserved2 = 0;
5941        param_offset = offsetof(struct smb_com_transaction2_sfi_req, Fid) - 4;
5942        offset = param_offset + params;
5943
5944        data_offset = (char *)pSMB +
5945                        offsetof(struct smb_hdr, Protocol) + offset;
5946
5947        count = sizeof(FILE_UNIX_BASIC_INFO);
5948
5949        pSMB->MaxParameterCount = cpu_to_le16(2);
5950        /* BB find max SMB PDU from sess */
5951        pSMB->MaxDataCount = cpu_to_le16(1000);
5952        pSMB->SetupCount = 1;
5953        pSMB->Reserved3 = 0;
5954        pSMB->SubCommand = cpu_to_le16(TRANS2_SET_FILE_INFORMATION);
5955        byte_count = 3 /* pad */  + params + count;
5956        pSMB->DataCount = cpu_to_le16(count);
5957        pSMB->ParameterCount = cpu_to_le16(params);
5958        pSMB->TotalDataCount = pSMB->DataCount;
5959        pSMB->TotalParameterCount = pSMB->ParameterCount;
5960        pSMB->ParameterOffset = cpu_to_le16(param_offset);
5961        pSMB->DataOffset = cpu_to_le16(offset);
5962        pSMB->Fid = fid;
5963        pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_UNIX_BASIC);
5964        pSMB->Reserved4 = 0;
5965        inc_rfc1001_len(pSMB, byte_count);
5966        pSMB->ByteCount = cpu_to_le16(byte_count);
5967
5968        cifs_fill_unix_set_info((FILE_UNIX_BASIC_INFO *)data_offset, args);
5969
5970        rc = SendReceiveNoRsp(xid, tcon->ses, (char *) pSMB, 0);
5971        cifs_small_buf_release(pSMB);
5972        if (rc)
5973                cifs_dbg(FYI, "Send error in Set Time (SetFileInfo) = %d\n",
5974                         rc);
5975
5976        /* Note: On -EAGAIN error only caller can retry on handle based calls
5977                since file handle passed in no longer valid */
5978
5979        return rc;
5980}
5981
5982int
5983CIFSSMBUnixSetPathInfo(const unsigned int xid, struct cifs_tcon *tcon,
5984                       const char *file_name,
5985                       const struct cifs_unix_set_info_args *args,
5986                       const struct nls_table *nls_codepage, int remap)
5987{
5988        TRANSACTION2_SPI_REQ *pSMB = NULL;
5989        TRANSACTION2_SPI_RSP *pSMBr = NULL;
5990        int name_len;
5991        int rc = 0;
5992        int bytes_returned = 0;
5993        FILE_UNIX_BASIC_INFO *data_offset;
5994        __u16 params, param_offset, offset, count, byte_count;
5995
5996        cifs_dbg(FYI, "In SetUID/GID/Mode\n");
5997setPermsRetry:
5998        rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
5999                      (void **) &pSMBr);
6000        if (rc)
6001                return rc;
6002
6003        if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
6004                name_len =
6005                    cifsConvertToUTF16((__le16 *) pSMB->FileName, file_name,
6006                                       PATH_MAX, nls_codepage, remap);
6007                name_len++;     /* trailing null */
6008                name_len *= 2;
6009        } else {
6010                name_len = copy_path_name(pSMB->FileName, file_name);
6011        }
6012
6013        params = 6 + name_len;
6014        count = sizeof(FILE_UNIX_BASIC_INFO);
6015        pSMB->MaxParameterCount = cpu_to_le16(2);
6016        /* BB find max SMB PDU from sess structure BB */
6017        pSMB->MaxDataCount = cpu_to_le16(1000);
6018        pSMB->MaxSetupCount = 0;
6019        pSMB->Reserved = 0;
6020        pSMB->Flags = 0;
6021        pSMB->Timeout = 0;
6022        pSMB->Reserved2 = 0;
6023        param_offset = offsetof(struct smb_com_transaction2_spi_req,
6024                                InformationLevel) - 4;
6025        offset = param_offset + params;
6026        /* SMB offsets are from the beginning of SMB which is 4 bytes in, after RFC1001 field */
6027        data_offset = (FILE_UNIX_BASIC_INFO *)((char *) pSMB + offset + 4);
6028        memset(data_offset, 0, count);
6029        pSMB->DataOffset = cpu_to_le16(offset);
6030        pSMB->ParameterOffset = cpu_to_le16(param_offset);
6031        pSMB->SetupCount = 1;
6032        pSMB->Reserved3 = 0;
6033        pSMB->SubCommand = cpu_to_le16(TRANS2_SET_PATH_INFORMATION);
6034        byte_count = 3 /* pad */  + params + count;
6035        pSMB->ParameterCount = cpu_to_le16(params);
6036        pSMB->DataCount = cpu_to_le16(count);
6037        pSMB->TotalParameterCount = pSMB->ParameterCount;
6038        pSMB->TotalDataCount = pSMB->DataCount;
6039        pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_UNIX_BASIC);
6040        pSMB->Reserved4 = 0;
6041        inc_rfc1001_len(pSMB, byte_count);
6042
6043        cifs_fill_unix_set_info(data_offset, args);
6044
6045        pSMB->ByteCount = cpu_to_le16(byte_count);
6046        rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
6047                         (struct smb_hdr *) pSMBr, &bytes_returned, 0);
6048        if (rc)
6049                cifs_dbg(FYI, "SetPathInfo (perms) returned %d\n", rc);
6050
6051        cifs_buf_release(pSMB);
6052        if (rc == -EAGAIN)
6053                goto setPermsRetry;
6054        return rc;
6055}
6056
6057#ifdef CONFIG_CIFS_XATTR
6058/*
6059 * Do a path-based QUERY_ALL_EAS call and parse the result. This is a common
6060 * function used by listxattr and getxattr type calls. When ea_name is set,
6061 * it looks for that attribute name and stuffs that value into the EAData
6062 * buffer. When ea_name is NULL, it stuffs a list of attribute names into the
6063 * buffer. In both cases, the return value is either the length of the
6064 * resulting data or a negative error code. If EAData is a NULL pointer then
6065 * the data isn't copied to it, but the length is returned.
6066 */
6067ssize_t
6068CIFSSMBQAllEAs(const unsigned int xid, struct cifs_tcon *tcon,
6069                const unsigned char *searchName, const unsigned char *ea_name,
6070                char *EAData, size_t buf_size,
6071                struct cifs_sb_info *cifs_sb)
6072{
6073                /* BB assumes one setup word */
6074        TRANSACTION2_QPI_REQ *pSMB = NULL;
6075        TRANSACTION2_QPI_RSP *pSMBr = NULL;
6076        int remap = cifs_remap(cifs_sb);
6077        struct nls_table *nls_codepage = cifs_sb->local_nls;
6078        int rc = 0;
6079        int bytes_returned;
6080        int list_len;
6081        struct fealist *ea_response_data;
6082        struct fea *temp_fea;
6083        char *temp_ptr;
6084        char *end_of_smb;
6085        __u16 params, byte_count, data_offset;
6086        unsigned int ea_name_len = ea_name ? strlen(ea_name) : 0;
6087
6088        cifs_dbg(FYI, "In Query All EAs path %s\n", searchName);
6089QAllEAsRetry:
6090        rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
6091                      (void **) &pSMBr);
6092        if (rc)
6093                return rc;
6094
6095        if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
6096                list_len =
6097                    cifsConvertToUTF16((__le16 *) pSMB->FileName, searchName,
6098                                       PATH_MAX, nls_codepage, remap);
6099                list_len++;     /* trailing null */
6100                list_len *= 2;
6101        } else {
6102                list_len = copy_path_name(pSMB->FileName, searchName);
6103        }
6104
6105        params = 2 /* level */ + 4 /* reserved */ + list_len /* includes NUL */;
6106        pSMB->TotalDataCount = 0;
6107        pSMB->MaxParameterCount = cpu_to_le16(2);
6108        /* BB find exact max SMB PDU from sess structure BB */
6109        pSMB->MaxDataCount = cpu_to_le16(CIFSMaxBufSize);
6110        pSMB->MaxSetupCount = 0;
6111        pSMB->Reserved = 0;
6112        pSMB->Flags = 0;
6113        pSMB->Timeout = 0;
6114        pSMB->Reserved2 = 0;
6115        pSMB->ParameterOffset = cpu_to_le16(offsetof(
6116        struct smb_com_transaction2_qpi_req, InformationLevel) - 4);
6117        pSMB->DataCount = 0;
6118        pSMB->DataOffset = 0;
6119        pSMB->SetupCount = 1;
6120        pSMB->Reserved3 = 0;
6121        pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_PATH_INFORMATION);
6122        byte_count = params + 1 /* pad */ ;
6123        pSMB->TotalParameterCount = cpu_to_le16(params);
6124        pSMB->ParameterCount = pSMB->TotalParameterCount;
6125        pSMB->InformationLevel = cpu_to_le16(SMB_INFO_QUERY_ALL_EAS);
6126        pSMB->Reserved4 = 0;
6127        inc_rfc1001_len(pSMB, byte_count);
6128        pSMB->ByteCount = cpu_to_le16(byte_count);
6129
6130        rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
6131                         (struct smb_hdr *) pSMBr, &bytes_returned, 0);
6132        if (rc) {
6133                cifs_dbg(FYI, "Send error in QueryAllEAs = %d\n", rc);
6134                goto QAllEAsOut;
6135        }
6136
6137
6138        /* BB also check enough total bytes returned */
6139        /* BB we need to improve the validity checking
6140        of these trans2 responses */
6141
6142        rc = validate_t2((struct smb_t2_rsp *)pSMBr);
6143        if (rc || get_bcc(&pSMBr->hdr) < 4) {
6144                rc = -EIO;      /* bad smb */
6145                goto QAllEAsOut;
6146        }
6147
6148        /* check that length of list is not more than bcc */
6149        /* check that each entry does not go beyond length
6150           of list */
6151        /* check that each element of each entry does not
6152           go beyond end of list */
6153        /* validate_trans2_offsets() */
6154        /* BB check if start of smb + data_offset > &bcc+ bcc */
6155
6156        data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
6157        ea_response_data = (struct fealist *)
6158                                (((char *) &pSMBr->hdr.Protocol) + data_offset);
6159
6160        list_len = le32_to_cpu(ea_response_data->list_len);
6161        cifs_dbg(FYI, "ea length %d\n", list_len);
6162        if (list_len <= 8) {
6163                cifs_dbg(FYI, "empty EA list returned from server\n");
6164                /* didn't find the named attribute */
6165                if (ea_name)
6166                        rc = -ENODATA;
6167                goto QAllEAsOut;
6168        }
6169
6170        /* make sure list_len doesn't go past end of SMB */
6171        end_of_smb = (char *)pByteArea(&pSMBr->hdr) + get_bcc(&pSMBr->hdr);
6172        if ((char *)ea_response_data + list_len > end_of_smb) {
6173                cifs_dbg(FYI, "EA list appears to go beyond SMB\n");
6174                rc = -EIO;
6175                goto QAllEAsOut;
6176        }
6177
6178        /* account for ea list len */
6179        list_len -= 4;
6180        temp_fea = ea_response_data->list;
6181        temp_ptr = (char *)temp_fea;
6182        while (list_len > 0) {
6183                unsigned int name_len;
6184                __u16 value_len;
6185
6186                list_len -= 4;
6187                temp_ptr += 4;
6188                /* make sure we can read name_len and value_len */
6189                if (list_len < 0) {
6190                        cifs_dbg(FYI, "EA entry goes beyond length of list\n");
6191                        rc = -EIO;
6192                        goto QAllEAsOut;
6193                }
6194
6195                name_len = temp_fea->name_len;
6196                value_len = le16_to_cpu(temp_fea->value_len);
6197                list_len -= name_len + 1 + value_len;
6198                if (list_len < 0) {
6199                        cifs_dbg(FYI, "EA entry goes beyond length of list\n");
6200                        rc = -EIO;
6201                        goto QAllEAsOut;
6202                }
6203
6204                if (ea_name) {
6205                        if (ea_name_len == name_len &&
6206                            memcmp(ea_name, temp_ptr, name_len) == 0) {
6207                                temp_ptr += name_len + 1;
6208                                rc = value_len;
6209                                if (buf_size == 0)
6210                                        goto QAllEAsOut;
6211                                if ((size_t)value_len > buf_size) {
6212                                        rc = -ERANGE;
6213                                        goto QAllEAsOut;
6214                                }
6215                                memcpy(EAData, temp_ptr, value_len);
6216                                goto QAllEAsOut;
6217                        }
6218                } else {
6219                        /* account for prefix user. and trailing null */
6220                        rc += (5 + 1 + name_len);
6221                        if (rc < (int) buf_size) {
6222                                memcpy(EAData, "user.", 5);
6223                                EAData += 5;
6224                                memcpy(EAData, temp_ptr, name_len);
6225                                EAData += name_len;
6226                                /* null terminate name */
6227                                *EAData = 0;
6228                                ++EAData;
6229                        } else if (buf_size == 0) {
6230                                /* skip copy - calc size only */
6231                        } else {
6232                                /* stop before overrun buffer */
6233                                rc = -ERANGE;
6234                                break;
6235                        }
6236                }
6237                temp_ptr += name_len + 1 + value_len;
6238                temp_fea = (struct fea *)temp_ptr;
6239        }
6240
6241        /* didn't find the named attribute */
6242        if (ea_name)
6243                rc = -ENODATA;
6244
6245QAllEAsOut:
6246        cifs_buf_release(pSMB);
6247        if (rc == -EAGAIN)
6248                goto QAllEAsRetry;
6249
6250        return (ssize_t)rc;
6251}
6252
6253int
6254CIFSSMBSetEA(const unsigned int xid, struct cifs_tcon *tcon,
6255             const char *fileName, const char *ea_name, const void *ea_value,
6256             const __u16 ea_value_len, const struct nls_table *nls_codepage,
6257             struct cifs_sb_info *cifs_sb)
6258{
6259        struct smb_com_transaction2_spi_req *pSMB = NULL;
6260        struct smb_com_transaction2_spi_rsp *pSMBr = NULL;
6261        struct fealist *parm_data;
6262        int name_len;
6263        int rc = 0;
6264        int bytes_returned = 0;
6265        __u16 params, param_offset, byte_count, offset, count;
6266        int remap = cifs_remap(cifs_sb);
6267
6268        cifs_dbg(FYI, "In SetEA\n");
6269SetEARetry:
6270        rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
6271                      (void **) &pSMBr);
6272        if (rc)
6273                return rc;
6274
6275        if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
6276                name_len =
6277                    cifsConvertToUTF16((__le16 *) pSMB->FileName, fileName,
6278                                       PATH_MAX, nls_codepage, remap);
6279                name_len++;     /* trailing null */
6280                name_len *= 2;
6281        } else {
6282                name_len = copy_path_name(pSMB->FileName, fileName);
6283        }
6284
6285        params = 6 + name_len;
6286
6287        /* done calculating parms using name_len of file name,
6288        now use name_len to calculate length of ea name
6289        we are going to create in the inode xattrs */
6290        if (ea_name == NULL)
6291                name_len = 0;
6292        else
6293                name_len = strnlen(ea_name, 255);
6294
6295        count = sizeof(*parm_data) + ea_value_len + name_len;
6296        pSMB->MaxParameterCount = cpu_to_le16(2);
6297        /* BB find max SMB PDU from sess */
6298        pSMB->MaxDataCount = cpu_to_le16(1000);
6299        pSMB->MaxSetupCount = 0;
6300        pSMB->Reserved = 0;
6301        pSMB->Flags = 0;
6302        pSMB->Timeout = 0;
6303        pSMB->Reserved2 = 0;
6304        param_offset = offsetof(struct smb_com_transaction2_spi_req,
6305                                InformationLevel) - 4;
6306        offset = param_offset + params;
6307        pSMB->InformationLevel =
6308                cpu_to_le16(SMB_SET_FILE_EA);
6309
6310        parm_data = (void *)pSMB + offsetof(struct smb_hdr, Protocol) + offset;
6311        pSMB->ParameterOffset = cpu_to_le16(param_offset);
6312        pSMB->DataOffset = cpu_to_le16(offset);
6313        pSMB->SetupCount = 1;
6314        pSMB->Reserved3 = 0;
6315        pSMB->SubCommand = cpu_to_le16(TRANS2_SET_PATH_INFORMATION);
6316        byte_count = 3 /* pad */  + params + count;
6317        pSMB->DataCount = cpu_to_le16(count);
6318        parm_data->list_len = cpu_to_le32(count);
6319        parm_data->list[0].EA_flags = 0;
6320        /* we checked above that name len is less than 255 */
6321        parm_data->list[0].name_len = (__u8)name_len;
6322        /* EA names are always ASCII */
6323        if (ea_name)
6324                strncpy(parm_data->list[0].name, ea_name, name_len);
6325        parm_data->list[0].name[name_len] = 0;
6326        parm_data->list[0].value_len = cpu_to_le16(ea_value_len);
6327        /* caller ensures that ea_value_len is less than 64K but
6328        we need to ensure that it fits within the smb */
6329
6330        /*BB add length check to see if it would fit in
6331             negotiated SMB buffer size BB */
6332        /* if (ea_value_len > buffer_size - 512 (enough for header)) */
6333        if (ea_value_len)
6334                memcpy(parm_data->list[0].name+name_len+1,
6335                       ea_value, ea_value_len);
6336
6337        pSMB->TotalDataCount = pSMB->DataCount;
6338        pSMB->ParameterCount = cpu_to_le16(params);
6339        pSMB->TotalParameterCount = pSMB->ParameterCount;
6340        pSMB->Reserved4 = 0;
6341        inc_rfc1001_len(pSMB, byte_count);
6342        pSMB->ByteCount = cpu_to_le16(byte_count);
6343        rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
6344                         (struct smb_hdr *) pSMBr, &bytes_returned, 0);
6345        if (rc)
6346                cifs_dbg(FYI, "SetPathInfo (EA) returned %d\n", rc);
6347
6348        cifs_buf_release(pSMB);
6349
6350        if (rc == -EAGAIN)
6351                goto SetEARetry;
6352
6353        return rc;
6354}
6355#endif
6356