linux/fs/cifs/smb2ops.c
<<
>>
Prefs
   1/*
   2 *  SMB2 version specific operations
   3 *
   4 *  Copyright (c) 2012, Jeff Layton <jlayton@redhat.com>
   5 *
   6 *  This library is free software; you can redistribute it and/or modify
   7 *  it under the terms of the GNU General Public License v2 as published
   8 *  by the Free Software Foundation.
   9 *
  10 *  This library is distributed in the hope that it will be useful,
  11 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
  12 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
  13 *  the GNU Lesser General Public License for more details.
  14 *
  15 *  You should have received a copy of the GNU Lesser General Public License
  16 *  along with this library; if not, write to the Free Software
  17 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  18 */
  19
  20#include <linux/pagemap.h>
  21#include <linux/vfs.h>
  22#include "cifsglob.h"
  23#include "smb2pdu.h"
  24#include "smb2proto.h"
  25#include "cifsproto.h"
  26#include "cifs_debug.h"
  27#include "cifs_unicode.h"
  28#include "smb2status.h"
  29#include "smb2glob.h"
  30
  31static int
  32change_conf(struct TCP_Server_Info *server)
  33{
  34        server->credits += server->echo_credits + server->oplock_credits;
  35        server->oplock_credits = server->echo_credits = 0;
  36        switch (server->credits) {
  37        case 0:
  38                return -1;
  39        case 1:
  40                server->echoes = false;
  41                server->oplocks = false;
  42                cifs_dbg(VFS, "disabling echoes and oplocks\n");
  43                break;
  44        case 2:
  45                server->echoes = true;
  46                server->oplocks = false;
  47                server->echo_credits = 1;
  48                cifs_dbg(FYI, "disabling oplocks\n");
  49                break;
  50        default:
  51                server->echoes = true;
  52                server->oplocks = true;
  53                server->echo_credits = 1;
  54                server->oplock_credits = 1;
  55        }
  56        server->credits -= server->echo_credits + server->oplock_credits;
  57        return 0;
  58}
  59
  60static void
  61smb2_add_credits(struct TCP_Server_Info *server, const unsigned int add,
  62                 const int optype)
  63{
  64        int *val, rc = 0;
  65        spin_lock(&server->req_lock);
  66        val = server->ops->get_credits_field(server, optype);
  67        *val += add;
  68        server->in_flight--;
  69        if (server->in_flight == 0 && (optype & CIFS_OP_MASK) != CIFS_NEG_OP)
  70                rc = change_conf(server);
  71        /*
  72         * Sometimes server returns 0 credits on oplock break ack - we need to
  73         * rebalance credits in this case.
  74         */
  75        else if (server->in_flight > 0 && server->oplock_credits == 0 &&
  76                 server->oplocks) {
  77                if (server->credits > 1) {
  78                        server->credits--;
  79                        server->oplock_credits++;
  80                }
  81        }
  82        spin_unlock(&server->req_lock);
  83        wake_up(&server->request_q);
  84        if (rc)
  85                cifs_reconnect(server);
  86}
  87
  88static void
  89smb2_set_credits(struct TCP_Server_Info *server, const int val)
  90{
  91        spin_lock(&server->req_lock);
  92        server->credits = val;
  93        spin_unlock(&server->req_lock);
  94}
  95
  96static int *
  97smb2_get_credits_field(struct TCP_Server_Info *server, const int optype)
  98{
  99        switch (optype) {
 100        case CIFS_ECHO_OP:
 101                return &server->echo_credits;
 102        case CIFS_OBREAK_OP:
 103                return &server->oplock_credits;
 104        default:
 105                return &server->credits;
 106        }
 107}
 108
 109static unsigned int
 110smb2_get_credits(struct mid_q_entry *mid)
 111{
 112        return le16_to_cpu(((struct smb2_hdr *)mid->resp_buf)->CreditRequest);
 113}
 114
 115static __u64
 116smb2_get_next_mid(struct TCP_Server_Info *server)
 117{
 118        __u64 mid;
 119        /* for SMB2 we need the current value */
 120        spin_lock(&GlobalMid_Lock);
 121        mid = server->CurrentMid++;
 122        spin_unlock(&GlobalMid_Lock);
 123        return mid;
 124}
 125
 126static struct mid_q_entry *
 127smb2_find_mid(struct TCP_Server_Info *server, char *buf)
 128{
 129        struct mid_q_entry *mid;
 130        struct smb2_hdr *hdr = (struct smb2_hdr *)buf;
 131
 132        spin_lock(&GlobalMid_Lock);
 133        list_for_each_entry(mid, &server->pending_mid_q, qhead) {
 134                if ((mid->mid == hdr->MessageId) &&
 135                    (mid->mid_state == MID_REQUEST_SUBMITTED) &&
 136                    (mid->command == hdr->Command)) {
 137                        spin_unlock(&GlobalMid_Lock);
 138                        return mid;
 139                }
 140        }
 141        spin_unlock(&GlobalMid_Lock);
 142        return NULL;
 143}
 144
 145static void
 146smb2_dump_detail(void *buf)
 147{
 148#ifdef CONFIG_CIFS_DEBUG2
 149        struct smb2_hdr *smb = (struct smb2_hdr *)buf;
 150
 151        cifs_dbg(VFS, "Cmd: %d Err: 0x%x Flags: 0x%x Mid: %llu Pid: %d\n",
 152                 smb->Command, smb->Status, smb->Flags, smb->MessageId,
 153                 smb->ProcessId);
 154        cifs_dbg(VFS, "smb buf %p len %u\n", smb, smb2_calc_size(smb));
 155#endif
 156}
 157
 158static bool
 159smb2_need_neg(struct TCP_Server_Info *server)
 160{
 161        return server->max_read == 0;
 162}
 163
 164static int
 165smb2_negotiate(const unsigned int xid, struct cifs_ses *ses)
 166{
 167        int rc;
 168        ses->server->CurrentMid = 0;
 169        rc = SMB2_negotiate(xid, ses);
 170        /* BB we probably don't need to retry with modern servers */
 171        if (rc == -EAGAIN)
 172                rc = -EHOSTDOWN;
 173        return rc;
 174}
 175
 176static unsigned int
 177smb2_negotiate_wsize(struct cifs_tcon *tcon, struct smb_vol *volume_info)
 178{
 179        struct TCP_Server_Info *server = tcon->ses->server;
 180        unsigned int wsize;
 181
 182        /* start with specified wsize, or default */
 183        wsize = volume_info->wsize ? volume_info->wsize : CIFS_DEFAULT_IOSIZE;
 184        wsize = min_t(unsigned int, wsize, server->max_write);
 185        /*
 186         * limit write size to 2 ** 16, because we don't support multicredit
 187         * requests now.
 188         */
 189        wsize = min_t(unsigned int, wsize, 2 << 15);
 190
 191        return wsize;
 192}
 193
 194static unsigned int
 195smb2_negotiate_rsize(struct cifs_tcon *tcon, struct smb_vol *volume_info)
 196{
 197        struct TCP_Server_Info *server = tcon->ses->server;
 198        unsigned int rsize;
 199
 200        /* start with specified rsize, or default */
 201        rsize = volume_info->rsize ? volume_info->rsize : CIFS_DEFAULT_IOSIZE;
 202        rsize = min_t(unsigned int, rsize, server->max_read);
 203        /*
 204         * limit write size to 2 ** 16, because we don't support multicredit
 205         * requests now.
 206         */
 207        rsize = min_t(unsigned int, rsize, 2 << 15);
 208
 209        return rsize;
 210}
 211
 212#ifdef CONFIG_CIFS_STATS2
 213static int
 214SMB3_request_interfaces(const unsigned int xid, struct cifs_tcon *tcon)
 215{
 216        int rc;
 217        unsigned int ret_data_len = 0;
 218        struct network_interface_info_ioctl_rsp *out_buf;
 219
 220        rc = SMB2_ioctl(xid, tcon, NO_FILE_ID, NO_FILE_ID,
 221                        FSCTL_QUERY_NETWORK_INTERFACE_INFO, true /* is_fsctl */,
 222                        NULL /* no data input */, 0 /* no data input */,
 223                        (char **)&out_buf, &ret_data_len);
 224
 225        if ((rc == 0)  && (ret_data_len > 0)) {
 226                /* Dump info on first interface */
 227                cifs_dbg(FYI, "Adapter Capability 0x%x\t",
 228                        le32_to_cpu(out_buf->Capability));
 229                cifs_dbg(FYI, "Link Speed %lld\n",
 230                        le64_to_cpu(out_buf->LinkSpeed));
 231        } else
 232                cifs_dbg(VFS, "error %d on ioctl to get interface list\n", rc);
 233
 234        return rc;
 235}
 236#endif /* STATS2 */
 237
 238static void
 239smb3_qfs_tcon(const unsigned int xid, struct cifs_tcon *tcon)
 240{
 241        int rc;
 242        __le16 srch_path = 0; /* Null - open root of share */
 243        u8 oplock = SMB2_OPLOCK_LEVEL_NONE;
 244        struct cifs_open_parms oparms;
 245        struct cifs_fid fid;
 246
 247        oparms.tcon = tcon;
 248        oparms.desired_access = FILE_READ_ATTRIBUTES;
 249        oparms.disposition = FILE_OPEN;
 250        oparms.create_options = 0;
 251        oparms.fid = &fid;
 252        oparms.reconnect = false;
 253
 254        rc = SMB2_open(xid, &oparms, &srch_path, &oplock, NULL, NULL);
 255        if (rc)
 256                return;
 257
 258#ifdef CONFIG_CIFS_STATS2
 259        SMB3_request_interfaces(xid, tcon);
 260#endif /* STATS2 */
 261
 262        SMB2_QFS_attr(xid, tcon, fid.persistent_fid, fid.volatile_fid,
 263                        FS_ATTRIBUTE_INFORMATION);
 264        SMB2_QFS_attr(xid, tcon, fid.persistent_fid, fid.volatile_fid,
 265                        FS_DEVICE_INFORMATION);
 266        SMB2_QFS_attr(xid, tcon, fid.persistent_fid, fid.volatile_fid,
 267                        FS_SECTOR_SIZE_INFORMATION); /* SMB3 specific */
 268        SMB2_close(xid, tcon, fid.persistent_fid, fid.volatile_fid);
 269        return;
 270}
 271
 272static void
 273smb2_qfs_tcon(const unsigned int xid, struct cifs_tcon *tcon)
 274{
 275        int rc;
 276        __le16 srch_path = 0; /* Null - open root of share */
 277        u8 oplock = SMB2_OPLOCK_LEVEL_NONE;
 278        struct cifs_open_parms oparms;
 279        struct cifs_fid fid;
 280
 281        oparms.tcon = tcon;
 282        oparms.desired_access = FILE_READ_ATTRIBUTES;
 283        oparms.disposition = FILE_OPEN;
 284        oparms.create_options = 0;
 285        oparms.fid = &fid;
 286        oparms.reconnect = false;
 287
 288        rc = SMB2_open(xid, &oparms, &srch_path, &oplock, NULL, NULL);
 289        if (rc)
 290                return;
 291
 292        SMB2_QFS_attr(xid, tcon, fid.persistent_fid, fid.volatile_fid,
 293                        FS_ATTRIBUTE_INFORMATION);
 294        SMB2_QFS_attr(xid, tcon, fid.persistent_fid, fid.volatile_fid,
 295                        FS_DEVICE_INFORMATION);
 296        SMB2_close(xid, tcon, fid.persistent_fid, fid.volatile_fid);
 297        return;
 298}
 299
 300static int
 301smb2_is_path_accessible(const unsigned int xid, struct cifs_tcon *tcon,
 302                        struct cifs_sb_info *cifs_sb, const char *full_path)
 303{
 304        int rc;
 305        __le16 *utf16_path;
 306        __u8 oplock = SMB2_OPLOCK_LEVEL_NONE;
 307        struct cifs_open_parms oparms;
 308        struct cifs_fid fid;
 309
 310        utf16_path = cifs_convert_path_to_utf16(full_path, cifs_sb);
 311        if (!utf16_path)
 312                return -ENOMEM;
 313
 314        oparms.tcon = tcon;
 315        oparms.desired_access = FILE_READ_ATTRIBUTES;
 316        oparms.disposition = FILE_OPEN;
 317        oparms.create_options = 0;
 318        oparms.fid = &fid;
 319        oparms.reconnect = false;
 320
 321        rc = SMB2_open(xid, &oparms, utf16_path, &oplock, NULL, NULL);
 322        if (rc) {
 323                kfree(utf16_path);
 324                return rc;
 325        }
 326
 327        rc = SMB2_close(xid, tcon, fid.persistent_fid, fid.volatile_fid);
 328        kfree(utf16_path);
 329        return rc;
 330}
 331
 332static int
 333smb2_get_srv_inum(const unsigned int xid, struct cifs_tcon *tcon,
 334                  struct cifs_sb_info *cifs_sb, const char *full_path,
 335                  u64 *uniqueid, FILE_ALL_INFO *data)
 336{
 337        *uniqueid = le64_to_cpu(data->IndexNumber);
 338        return 0;
 339}
 340
 341static int
 342smb2_query_file_info(const unsigned int xid, struct cifs_tcon *tcon,
 343                     struct cifs_fid *fid, FILE_ALL_INFO *data)
 344{
 345        int rc;
 346        struct smb2_file_all_info *smb2_data;
 347
 348        smb2_data = kzalloc(sizeof(struct smb2_file_all_info) + MAX_NAME * 2,
 349                            GFP_KERNEL);
 350        if (smb2_data == NULL)
 351                return -ENOMEM;
 352
 353        rc = SMB2_query_info(xid, tcon, fid->persistent_fid, fid->volatile_fid,
 354                             smb2_data);
 355        if (!rc)
 356                move_smb2_info_to_cifs(data, smb2_data);
 357        kfree(smb2_data);
 358        return rc;
 359}
 360
 361static bool
 362smb2_can_echo(struct TCP_Server_Info *server)
 363{
 364        return server->echoes;
 365}
 366
 367static void
 368smb2_clear_stats(struct cifs_tcon *tcon)
 369{
 370#ifdef CONFIG_CIFS_STATS
 371        int i;
 372        for (i = 0; i < NUMBER_OF_SMB2_COMMANDS; i++) {
 373                atomic_set(&tcon->stats.smb2_stats.smb2_com_sent[i], 0);
 374                atomic_set(&tcon->stats.smb2_stats.smb2_com_failed[i], 0);
 375        }
 376#endif
 377}
 378
 379static void
 380smb2_dump_share_caps(struct seq_file *m, struct cifs_tcon *tcon)
 381{
 382        seq_puts(m, "\n\tShare Capabilities:");
 383        if (tcon->capabilities & SMB2_SHARE_CAP_DFS)
 384                seq_puts(m, " DFS,");
 385        if (tcon->capabilities & SMB2_SHARE_CAP_CONTINUOUS_AVAILABILITY)
 386                seq_puts(m, " CONTINUOUS AVAILABILITY,");
 387        if (tcon->capabilities & SMB2_SHARE_CAP_SCALEOUT)
 388                seq_puts(m, " SCALEOUT,");
 389        if (tcon->capabilities & SMB2_SHARE_CAP_CLUSTER)
 390                seq_puts(m, " CLUSTER,");
 391        if (tcon->capabilities & SMB2_SHARE_CAP_ASYMMETRIC)
 392                seq_puts(m, " ASYMMETRIC,");
 393        if (tcon->capabilities == 0)
 394                seq_puts(m, " None");
 395        if (tcon->ss_flags & SSINFO_FLAGS_ALIGNED_DEVICE)
 396                seq_puts(m, " Aligned,");
 397        if (tcon->ss_flags & SSINFO_FLAGS_PARTITION_ALIGNED_ON_DEVICE)
 398                seq_puts(m, " Partition Aligned,");
 399        if (tcon->ss_flags & SSINFO_FLAGS_NO_SEEK_PENALTY)
 400                seq_puts(m, " SSD,");
 401        if (tcon->ss_flags & SSINFO_FLAGS_TRIM_ENABLED)
 402                seq_puts(m, " TRIM-support,");
 403
 404        seq_printf(m, "\tShare Flags: 0x%x", tcon->share_flags);
 405        if (tcon->perf_sector_size)
 406                seq_printf(m, "\tOptimal sector size: 0x%x",
 407                           tcon->perf_sector_size);
 408}
 409
 410static void
 411smb2_print_stats(struct seq_file *m, struct cifs_tcon *tcon)
 412{
 413#ifdef CONFIG_CIFS_STATS
 414        atomic_t *sent = tcon->stats.smb2_stats.smb2_com_sent;
 415        atomic_t *failed = tcon->stats.smb2_stats.smb2_com_failed;
 416        seq_printf(m, "\nNegotiates: %d sent %d failed",
 417                   atomic_read(&sent[SMB2_NEGOTIATE_HE]),
 418                   atomic_read(&failed[SMB2_NEGOTIATE_HE]));
 419        seq_printf(m, "\nSessionSetups: %d sent %d failed",
 420                   atomic_read(&sent[SMB2_SESSION_SETUP_HE]),
 421                   atomic_read(&failed[SMB2_SESSION_SETUP_HE]));
 422        seq_printf(m, "\nLogoffs: %d sent %d failed",
 423                   atomic_read(&sent[SMB2_LOGOFF_HE]),
 424                   atomic_read(&failed[SMB2_LOGOFF_HE]));
 425        seq_printf(m, "\nTreeConnects: %d sent %d failed",
 426                   atomic_read(&sent[SMB2_TREE_CONNECT_HE]),
 427                   atomic_read(&failed[SMB2_TREE_CONNECT_HE]));
 428        seq_printf(m, "\nTreeDisconnects: %d sent %d failed",
 429                   atomic_read(&sent[SMB2_TREE_DISCONNECT_HE]),
 430                   atomic_read(&failed[SMB2_TREE_DISCONNECT_HE]));
 431        seq_printf(m, "\nCreates: %d sent %d failed",
 432                   atomic_read(&sent[SMB2_CREATE_HE]),
 433                   atomic_read(&failed[SMB2_CREATE_HE]));
 434        seq_printf(m, "\nCloses: %d sent %d failed",
 435                   atomic_read(&sent[SMB2_CLOSE_HE]),
 436                   atomic_read(&failed[SMB2_CLOSE_HE]));
 437        seq_printf(m, "\nFlushes: %d sent %d failed",
 438                   atomic_read(&sent[SMB2_FLUSH_HE]),
 439                   atomic_read(&failed[SMB2_FLUSH_HE]));
 440        seq_printf(m, "\nReads: %d sent %d failed",
 441                   atomic_read(&sent[SMB2_READ_HE]),
 442                   atomic_read(&failed[SMB2_READ_HE]));
 443        seq_printf(m, "\nWrites: %d sent %d failed",
 444                   atomic_read(&sent[SMB2_WRITE_HE]),
 445                   atomic_read(&failed[SMB2_WRITE_HE]));
 446        seq_printf(m, "\nLocks: %d sent %d failed",
 447                   atomic_read(&sent[SMB2_LOCK_HE]),
 448                   atomic_read(&failed[SMB2_LOCK_HE]));
 449        seq_printf(m, "\nIOCTLs: %d sent %d failed",
 450                   atomic_read(&sent[SMB2_IOCTL_HE]),
 451                   atomic_read(&failed[SMB2_IOCTL_HE]));
 452        seq_printf(m, "\nCancels: %d sent %d failed",
 453                   atomic_read(&sent[SMB2_CANCEL_HE]),
 454                   atomic_read(&failed[SMB2_CANCEL_HE]));
 455        seq_printf(m, "\nEchos: %d sent %d failed",
 456                   atomic_read(&sent[SMB2_ECHO_HE]),
 457                   atomic_read(&failed[SMB2_ECHO_HE]));
 458        seq_printf(m, "\nQueryDirectories: %d sent %d failed",
 459                   atomic_read(&sent[SMB2_QUERY_DIRECTORY_HE]),
 460                   atomic_read(&failed[SMB2_QUERY_DIRECTORY_HE]));
 461        seq_printf(m, "\nChangeNotifies: %d sent %d failed",
 462                   atomic_read(&sent[SMB2_CHANGE_NOTIFY_HE]),
 463                   atomic_read(&failed[SMB2_CHANGE_NOTIFY_HE]));
 464        seq_printf(m, "\nQueryInfos: %d sent %d failed",
 465                   atomic_read(&sent[SMB2_QUERY_INFO_HE]),
 466                   atomic_read(&failed[SMB2_QUERY_INFO_HE]));
 467        seq_printf(m, "\nSetInfos: %d sent %d failed",
 468                   atomic_read(&sent[SMB2_SET_INFO_HE]),
 469                   atomic_read(&failed[SMB2_SET_INFO_HE]));
 470        seq_printf(m, "\nOplockBreaks: %d sent %d failed",
 471                   atomic_read(&sent[SMB2_OPLOCK_BREAK_HE]),
 472                   atomic_read(&failed[SMB2_OPLOCK_BREAK_HE]));
 473#endif
 474}
 475
 476static void
 477smb2_set_fid(struct cifsFileInfo *cfile, struct cifs_fid *fid, __u32 oplock)
 478{
 479        struct cifsInodeInfo *cinode = CIFS_I(cfile->dentry->d_inode);
 480        struct TCP_Server_Info *server = tlink_tcon(cfile->tlink)->ses->server;
 481
 482        cfile->fid.persistent_fid = fid->persistent_fid;
 483        cfile->fid.volatile_fid = fid->volatile_fid;
 484        server->ops->set_oplock_level(cinode, oplock, fid->epoch,
 485                                      &fid->purge_cache);
 486        cinode->can_cache_brlcks = CIFS_CACHE_WRITE(cinode);
 487}
 488
 489static void
 490smb2_close_file(const unsigned int xid, struct cifs_tcon *tcon,
 491                struct cifs_fid *fid)
 492{
 493        SMB2_close(xid, tcon, fid->persistent_fid, fid->volatile_fid);
 494}
 495
 496static int
 497SMB2_request_res_key(const unsigned int xid, struct cifs_tcon *tcon,
 498                     u64 persistent_fid, u64 volatile_fid,
 499                     struct copychunk_ioctl *pcchunk)
 500{
 501        int rc;
 502        unsigned int ret_data_len;
 503        struct resume_key_req *res_key;
 504
 505        rc = SMB2_ioctl(xid, tcon, persistent_fid, volatile_fid,
 506                        FSCTL_SRV_REQUEST_RESUME_KEY, true /* is_fsctl */,
 507                        NULL, 0 /* no input */,
 508                        (char **)&res_key, &ret_data_len);
 509
 510        if (rc) {
 511                cifs_dbg(VFS, "refcpy ioctl error %d getting resume key\n", rc);
 512                goto req_res_key_exit;
 513        }
 514        if (ret_data_len < sizeof(struct resume_key_req)) {
 515                cifs_dbg(VFS, "Invalid refcopy resume key length\n");
 516                rc = -EINVAL;
 517                goto req_res_key_exit;
 518        }
 519        memcpy(pcchunk->SourceKey, res_key->ResumeKey, COPY_CHUNK_RES_KEY_SIZE);
 520
 521req_res_key_exit:
 522        kfree(res_key);
 523        return rc;
 524}
 525
 526static int
 527smb2_clone_range(const unsigned int xid,
 528                        struct cifsFileInfo *srcfile,
 529                        struct cifsFileInfo *trgtfile, u64 src_off,
 530                        u64 len, u64 dest_off)
 531{
 532        int rc;
 533        unsigned int ret_data_len;
 534        struct copychunk_ioctl *pcchunk;
 535        struct copychunk_ioctl_rsp *retbuf = NULL;
 536        struct cifs_tcon *tcon;
 537        int chunks_copied = 0;
 538        bool chunk_sizes_updated = false;
 539
 540        pcchunk = kmalloc(sizeof(struct copychunk_ioctl), GFP_KERNEL);
 541
 542        if (pcchunk == NULL)
 543                return -ENOMEM;
 544
 545        cifs_dbg(FYI, "in smb2_clone_range - about to call request res key\n");
 546        /* Request a key from the server to identify the source of the copy */
 547        rc = SMB2_request_res_key(xid, tlink_tcon(srcfile->tlink),
 548                                srcfile->fid.persistent_fid,
 549                                srcfile->fid.volatile_fid, pcchunk);
 550
 551        /* Note: request_res_key sets res_key null only if rc !=0 */
 552        if (rc)
 553                goto cchunk_out;
 554
 555        /* For now array only one chunk long, will make more flexible later */
 556        pcchunk->ChunkCount = __constant_cpu_to_le32(1);
 557        pcchunk->Reserved = 0;
 558        pcchunk->Reserved2 = 0;
 559
 560        tcon = tlink_tcon(trgtfile->tlink);
 561
 562        while (len > 0) {
 563                pcchunk->SourceOffset = cpu_to_le64(src_off);
 564                pcchunk->TargetOffset = cpu_to_le64(dest_off);
 565                pcchunk->Length =
 566                        cpu_to_le32(min_t(u32, len, tcon->max_bytes_chunk));
 567
 568                /* Request server copy to target from src identified by key */
 569                rc = SMB2_ioctl(xid, tcon, trgtfile->fid.persistent_fid,
 570                        trgtfile->fid.volatile_fid, FSCTL_SRV_COPYCHUNK_WRITE,
 571                        true /* is_fsctl */, (char *)pcchunk,
 572                        sizeof(struct copychunk_ioctl), (char **)&retbuf,
 573                        &ret_data_len);
 574                if (rc == 0) {
 575                        if (ret_data_len !=
 576                                        sizeof(struct copychunk_ioctl_rsp)) {
 577                                cifs_dbg(VFS, "invalid cchunk response size\n");
 578                                rc = -EIO;
 579                                goto cchunk_out;
 580                        }
 581                        if (retbuf->TotalBytesWritten == 0) {
 582                                cifs_dbg(FYI, "no bytes copied\n");
 583                                rc = -EIO;
 584                                goto cchunk_out;
 585                        }
 586                        /*
 587                         * Check if server claimed to write more than we asked
 588                         */
 589                        if (le32_to_cpu(retbuf->TotalBytesWritten) >
 590                            le32_to_cpu(pcchunk->Length)) {
 591                                cifs_dbg(VFS, "invalid copy chunk response\n");
 592                                rc = -EIO;
 593                                goto cchunk_out;
 594                        }
 595                        if (le32_to_cpu(retbuf->ChunksWritten) != 1) {
 596                                cifs_dbg(VFS, "invalid num chunks written\n");
 597                                rc = -EIO;
 598                                goto cchunk_out;
 599                        }
 600                        chunks_copied++;
 601
 602                        src_off += le32_to_cpu(retbuf->TotalBytesWritten);
 603                        dest_off += le32_to_cpu(retbuf->TotalBytesWritten);
 604                        len -= le32_to_cpu(retbuf->TotalBytesWritten);
 605
 606                        cifs_dbg(FYI, "Chunks %d PartialChunk %d Total %d\n",
 607                                le32_to_cpu(retbuf->ChunksWritten),
 608                                le32_to_cpu(retbuf->ChunkBytesWritten),
 609                                le32_to_cpu(retbuf->TotalBytesWritten));
 610                } else if (rc == -EINVAL) {
 611                        if (ret_data_len != sizeof(struct copychunk_ioctl_rsp))
 612                                goto cchunk_out;
 613
 614                        cifs_dbg(FYI, "MaxChunks %d BytesChunk %d MaxCopy %d\n",
 615                                le32_to_cpu(retbuf->ChunksWritten),
 616                                le32_to_cpu(retbuf->ChunkBytesWritten),
 617                                le32_to_cpu(retbuf->TotalBytesWritten));
 618
 619                        /*
 620                         * Check if this is the first request using these sizes,
 621                         * (ie check if copy succeed once with original sizes
 622                         * and check if the server gave us different sizes after
 623                         * we already updated max sizes on previous request).
 624                         * if not then why is the server returning an error now
 625                         */
 626                        if ((chunks_copied != 0) || chunk_sizes_updated)
 627                                goto cchunk_out;
 628
 629                        /* Check that server is not asking us to grow size */
 630                        if (le32_to_cpu(retbuf->ChunkBytesWritten) <
 631                                        tcon->max_bytes_chunk)
 632                                tcon->max_bytes_chunk =
 633                                        le32_to_cpu(retbuf->ChunkBytesWritten);
 634                        else
 635                                goto cchunk_out; /* server gave us bogus size */
 636
 637                        /* No need to change MaxChunks since already set to 1 */
 638                        chunk_sizes_updated = true;
 639                }
 640        }
 641
 642cchunk_out:
 643        kfree(pcchunk);
 644        return rc;
 645}
 646
 647static int
 648smb2_flush_file(const unsigned int xid, struct cifs_tcon *tcon,
 649                struct cifs_fid *fid)
 650{
 651        return SMB2_flush(xid, tcon, fid->persistent_fid, fid->volatile_fid);
 652}
 653
 654static unsigned int
 655smb2_read_data_offset(char *buf)
 656{
 657        struct smb2_read_rsp *rsp = (struct smb2_read_rsp *)buf;
 658        return rsp->DataOffset;
 659}
 660
 661static unsigned int
 662smb2_read_data_length(char *buf)
 663{
 664        struct smb2_read_rsp *rsp = (struct smb2_read_rsp *)buf;
 665        return le32_to_cpu(rsp->DataLength);
 666}
 667
 668
 669static int
 670smb2_sync_read(const unsigned int xid, struct cifsFileInfo *cfile,
 671               struct cifs_io_parms *parms, unsigned int *bytes_read,
 672               char **buf, int *buf_type)
 673{
 674        parms->persistent_fid = cfile->fid.persistent_fid;
 675        parms->volatile_fid = cfile->fid.volatile_fid;
 676        return SMB2_read(xid, parms, bytes_read, buf, buf_type);
 677}
 678
 679static int
 680smb2_sync_write(const unsigned int xid, struct cifsFileInfo *cfile,
 681                struct cifs_io_parms *parms, unsigned int *written,
 682                struct kvec *iov, unsigned long nr_segs)
 683{
 684
 685        parms->persistent_fid = cfile->fid.persistent_fid;
 686        parms->volatile_fid = cfile->fid.volatile_fid;
 687        return SMB2_write(xid, parms, written, iov, nr_segs);
 688}
 689
 690static int
 691smb2_set_file_size(const unsigned int xid, struct cifs_tcon *tcon,
 692                   struct cifsFileInfo *cfile, __u64 size, bool set_alloc)
 693{
 694        __le64 eof = cpu_to_le64(size);
 695        return SMB2_set_eof(xid, tcon, cfile->fid.persistent_fid,
 696                            cfile->fid.volatile_fid, cfile->pid, &eof);
 697}
 698
 699static int
 700smb2_set_compression(const unsigned int xid, struct cifs_tcon *tcon,
 701                   struct cifsFileInfo *cfile)
 702{
 703        return SMB2_set_compression(xid, tcon, cfile->fid.persistent_fid,
 704                            cfile->fid.volatile_fid);
 705}
 706
 707static int
 708smb2_query_dir_first(const unsigned int xid, struct cifs_tcon *tcon,
 709                     const char *path, struct cifs_sb_info *cifs_sb,
 710                     struct cifs_fid *fid, __u16 search_flags,
 711                     struct cifs_search_info *srch_inf)
 712{
 713        __le16 *utf16_path;
 714        int rc;
 715        __u8 oplock = SMB2_OPLOCK_LEVEL_NONE;
 716        struct cifs_open_parms oparms;
 717
 718        utf16_path = cifs_convert_path_to_utf16(path, cifs_sb);
 719        if (!utf16_path)
 720                return -ENOMEM;
 721
 722        oparms.tcon = tcon;
 723        oparms.desired_access = FILE_READ_ATTRIBUTES | FILE_READ_DATA;
 724        oparms.disposition = FILE_OPEN;
 725        oparms.create_options = 0;
 726        oparms.fid = fid;
 727        oparms.reconnect = false;
 728
 729        rc = SMB2_open(xid, &oparms, utf16_path, &oplock, NULL, NULL);
 730        kfree(utf16_path);
 731        if (rc) {
 732                cifs_dbg(VFS, "open dir failed\n");
 733                return rc;
 734        }
 735
 736        srch_inf->entries_in_buffer = 0;
 737        srch_inf->index_of_last_entry = 0;
 738
 739        rc = SMB2_query_directory(xid, tcon, fid->persistent_fid,
 740                                  fid->volatile_fid, 0, srch_inf);
 741        if (rc) {
 742                cifs_dbg(VFS, "query directory failed\n");
 743                SMB2_close(xid, tcon, fid->persistent_fid, fid->volatile_fid);
 744        }
 745        return rc;
 746}
 747
 748static int
 749smb2_query_dir_next(const unsigned int xid, struct cifs_tcon *tcon,
 750                    struct cifs_fid *fid, __u16 search_flags,
 751                    struct cifs_search_info *srch_inf)
 752{
 753        return SMB2_query_directory(xid, tcon, fid->persistent_fid,
 754                                    fid->volatile_fid, 0, srch_inf);
 755}
 756
 757static int
 758smb2_close_dir(const unsigned int xid, struct cifs_tcon *tcon,
 759               struct cifs_fid *fid)
 760{
 761        return SMB2_close(xid, tcon, fid->persistent_fid, fid->volatile_fid);
 762}
 763
 764/*
 765* If we negotiate SMB2 protocol and get STATUS_PENDING - update
 766* the number of credits and return true. Otherwise - return false.
 767*/
 768static bool
 769smb2_is_status_pending(char *buf, struct TCP_Server_Info *server, int length)
 770{
 771        struct smb2_hdr *hdr = (struct smb2_hdr *)buf;
 772
 773        if (hdr->Status != STATUS_PENDING)
 774                return false;
 775
 776        if (!length) {
 777                spin_lock(&server->req_lock);
 778                server->credits += le16_to_cpu(hdr->CreditRequest);
 779                spin_unlock(&server->req_lock);
 780                wake_up(&server->request_q);
 781        }
 782
 783        return true;
 784}
 785
 786static int
 787smb2_oplock_response(struct cifs_tcon *tcon, struct cifs_fid *fid,
 788                     struct cifsInodeInfo *cinode)
 789{
 790        if (tcon->ses->server->capabilities & SMB2_GLOBAL_CAP_LEASING)
 791                return SMB2_lease_break(0, tcon, cinode->lease_key,
 792                                        smb2_get_lease_state(cinode));
 793
 794        return SMB2_oplock_break(0, tcon, fid->persistent_fid,
 795                                 fid->volatile_fid,
 796                                 CIFS_CACHE_READ(cinode) ? 1 : 0);
 797}
 798
 799static int
 800smb2_queryfs(const unsigned int xid, struct cifs_tcon *tcon,
 801             struct kstatfs *buf)
 802{
 803        int rc;
 804        __le16 srch_path = 0; /* Null - open root of share */
 805        u8 oplock = SMB2_OPLOCK_LEVEL_NONE;
 806        struct cifs_open_parms oparms;
 807        struct cifs_fid fid;
 808
 809        oparms.tcon = tcon;
 810        oparms.desired_access = FILE_READ_ATTRIBUTES;
 811        oparms.disposition = FILE_OPEN;
 812        oparms.create_options = 0;
 813        oparms.fid = &fid;
 814        oparms.reconnect = false;
 815
 816        rc = SMB2_open(xid, &oparms, &srch_path, &oplock, NULL, NULL);
 817        if (rc)
 818                return rc;
 819        buf->f_type = SMB2_MAGIC_NUMBER;
 820        rc = SMB2_QFS_info(xid, tcon, fid.persistent_fid, fid.volatile_fid,
 821                           buf);
 822        SMB2_close(xid, tcon, fid.persistent_fid, fid.volatile_fid);
 823        return rc;
 824}
 825
 826static bool
 827smb2_compare_fids(struct cifsFileInfo *ob1, struct cifsFileInfo *ob2)
 828{
 829        return ob1->fid.persistent_fid == ob2->fid.persistent_fid &&
 830               ob1->fid.volatile_fid == ob2->fid.volatile_fid;
 831}
 832
 833static int
 834smb2_mand_lock(const unsigned int xid, struct cifsFileInfo *cfile, __u64 offset,
 835               __u64 length, __u32 type, int lock, int unlock, bool wait)
 836{
 837        if (unlock && !lock)
 838                type = SMB2_LOCKFLAG_UNLOCK;
 839        return SMB2_lock(xid, tlink_tcon(cfile->tlink),
 840                         cfile->fid.persistent_fid, cfile->fid.volatile_fid,
 841                         current->tgid, length, offset, type, wait);
 842}
 843
 844static void
 845smb2_get_lease_key(struct inode *inode, struct cifs_fid *fid)
 846{
 847        memcpy(fid->lease_key, CIFS_I(inode)->lease_key, SMB2_LEASE_KEY_SIZE);
 848}
 849
 850static void
 851smb2_set_lease_key(struct inode *inode, struct cifs_fid *fid)
 852{
 853        memcpy(CIFS_I(inode)->lease_key, fid->lease_key, SMB2_LEASE_KEY_SIZE);
 854}
 855
 856static void
 857smb2_new_lease_key(struct cifs_fid *fid)
 858{
 859        get_random_bytes(fid->lease_key, SMB2_LEASE_KEY_SIZE);
 860}
 861
 862static int
 863smb2_query_symlink(const unsigned int xid, struct cifs_tcon *tcon,
 864                   const char *full_path, char **target_path,
 865                   struct cifs_sb_info *cifs_sb)
 866{
 867        int rc;
 868        __le16 *utf16_path;
 869        __u8 oplock = SMB2_OPLOCK_LEVEL_NONE;
 870        struct cifs_open_parms oparms;
 871        struct cifs_fid fid;
 872        struct smb2_err_rsp *err_buf = NULL;
 873        struct smb2_symlink_err_rsp *symlink;
 874        unsigned int sub_len, sub_offset;
 875
 876        cifs_dbg(FYI, "%s: path: %s\n", __func__, full_path);
 877
 878        utf16_path = cifs_convert_path_to_utf16(full_path, cifs_sb);
 879        if (!utf16_path)
 880                return -ENOMEM;
 881
 882        oparms.tcon = tcon;
 883        oparms.desired_access = FILE_READ_ATTRIBUTES;
 884        oparms.disposition = FILE_OPEN;
 885        oparms.create_options = 0;
 886        oparms.fid = &fid;
 887        oparms.reconnect = false;
 888
 889        rc = SMB2_open(xid, &oparms, utf16_path, &oplock, NULL, &err_buf);
 890
 891        if (!rc || !err_buf) {
 892                kfree(utf16_path);
 893                return -ENOENT;
 894        }
 895        /* open must fail on symlink - reset rc */
 896        rc = 0;
 897        symlink = (struct smb2_symlink_err_rsp *)err_buf->ErrorData;
 898        sub_len = le16_to_cpu(symlink->SubstituteNameLength);
 899        sub_offset = le16_to_cpu(symlink->SubstituteNameOffset);
 900        *target_path = cifs_strndup_from_utf16(
 901                                (char *)symlink->PathBuffer + sub_offset,
 902                                sub_len, true, cifs_sb->local_nls);
 903        if (!(*target_path)) {
 904                kfree(utf16_path);
 905                return -ENOMEM;
 906        }
 907        convert_delimiter(*target_path, '/');
 908        cifs_dbg(FYI, "%s: target path: %s\n", __func__, *target_path);
 909        kfree(utf16_path);
 910        return rc;
 911}
 912
 913static void
 914smb2_set_oplock_level(struct cifsInodeInfo *cinode, __u32 oplock,
 915                      unsigned int epoch, bool *purge_cache)
 916{
 917        oplock &= 0xFF;
 918        if (oplock == SMB2_OPLOCK_LEVEL_NOCHANGE)
 919                return;
 920        if (oplock == SMB2_OPLOCK_LEVEL_BATCH) {
 921                cinode->oplock = CIFS_CACHE_RHW_FLG;
 922                cifs_dbg(FYI, "Batch Oplock granted on inode %p\n",
 923                         &cinode->vfs_inode);
 924        } else if (oplock == SMB2_OPLOCK_LEVEL_EXCLUSIVE) {
 925                cinode->oplock = CIFS_CACHE_RW_FLG;
 926                cifs_dbg(FYI, "Exclusive Oplock granted on inode %p\n",
 927                         &cinode->vfs_inode);
 928        } else if (oplock == SMB2_OPLOCK_LEVEL_II) {
 929                cinode->oplock = CIFS_CACHE_READ_FLG;
 930                cifs_dbg(FYI, "Level II Oplock granted on inode %p\n",
 931                         &cinode->vfs_inode);
 932        } else
 933                cinode->oplock = 0;
 934}
 935
 936static void
 937smb21_set_oplock_level(struct cifsInodeInfo *cinode, __u32 oplock,
 938                       unsigned int epoch, bool *purge_cache)
 939{
 940        char message[5] = {0};
 941
 942        oplock &= 0xFF;
 943        if (oplock == SMB2_OPLOCK_LEVEL_NOCHANGE)
 944                return;
 945
 946        cinode->oplock = 0;
 947        if (oplock & SMB2_LEASE_READ_CACHING_HE) {
 948                cinode->oplock |= CIFS_CACHE_READ_FLG;
 949                strcat(message, "R");
 950        }
 951        if (oplock & SMB2_LEASE_HANDLE_CACHING_HE) {
 952                cinode->oplock |= CIFS_CACHE_HANDLE_FLG;
 953                strcat(message, "H");
 954        }
 955        if (oplock & SMB2_LEASE_WRITE_CACHING_HE) {
 956                cinode->oplock |= CIFS_CACHE_WRITE_FLG;
 957                strcat(message, "W");
 958        }
 959        if (!cinode->oplock)
 960                strcat(message, "None");
 961        cifs_dbg(FYI, "%s Lease granted on inode %p\n", message,
 962                 &cinode->vfs_inode);
 963}
 964
 965static void
 966smb3_set_oplock_level(struct cifsInodeInfo *cinode, __u32 oplock,
 967                      unsigned int epoch, bool *purge_cache)
 968{
 969        unsigned int old_oplock = cinode->oplock;
 970
 971        smb21_set_oplock_level(cinode, oplock, epoch, purge_cache);
 972
 973        if (purge_cache) {
 974                *purge_cache = false;
 975                if (old_oplock == CIFS_CACHE_READ_FLG) {
 976                        if (cinode->oplock == CIFS_CACHE_READ_FLG &&
 977                            (epoch - cinode->epoch > 0))
 978                                *purge_cache = true;
 979                        else if (cinode->oplock == CIFS_CACHE_RH_FLG &&
 980                                 (epoch - cinode->epoch > 1))
 981                                *purge_cache = true;
 982                        else if (cinode->oplock == CIFS_CACHE_RHW_FLG &&
 983                                 (epoch - cinode->epoch > 1))
 984                                *purge_cache = true;
 985                        else if (cinode->oplock == 0 &&
 986                                 (epoch - cinode->epoch > 0))
 987                                *purge_cache = true;
 988                } else if (old_oplock == CIFS_CACHE_RH_FLG) {
 989                        if (cinode->oplock == CIFS_CACHE_RH_FLG &&
 990                            (epoch - cinode->epoch > 0))
 991                                *purge_cache = true;
 992                        else if (cinode->oplock == CIFS_CACHE_RHW_FLG &&
 993                                 (epoch - cinode->epoch > 1))
 994                                *purge_cache = true;
 995                }
 996                cinode->epoch = epoch;
 997        }
 998}
 999
1000static bool
1001smb2_is_read_op(__u32 oplock)
1002{
1003        return oplock == SMB2_OPLOCK_LEVEL_II;
1004}
1005
1006static bool
1007smb21_is_read_op(__u32 oplock)
1008{
1009        return (oplock & SMB2_LEASE_READ_CACHING_HE) &&
1010               !(oplock & SMB2_LEASE_WRITE_CACHING_HE);
1011}
1012
1013static __le32
1014map_oplock_to_lease(u8 oplock)
1015{
1016        if (oplock == SMB2_OPLOCK_LEVEL_EXCLUSIVE)
1017                return SMB2_LEASE_WRITE_CACHING | SMB2_LEASE_READ_CACHING;
1018        else if (oplock == SMB2_OPLOCK_LEVEL_II)
1019                return SMB2_LEASE_READ_CACHING;
1020        else if (oplock == SMB2_OPLOCK_LEVEL_BATCH)
1021                return SMB2_LEASE_HANDLE_CACHING | SMB2_LEASE_READ_CACHING |
1022                       SMB2_LEASE_WRITE_CACHING;
1023        return 0;
1024}
1025
1026static char *
1027smb2_create_lease_buf(u8 *lease_key, u8 oplock)
1028{
1029        struct create_lease *buf;
1030
1031        buf = kzalloc(sizeof(struct create_lease), GFP_KERNEL);
1032        if (!buf)
1033                return NULL;
1034
1035        buf->lcontext.LeaseKeyLow = cpu_to_le64(*((u64 *)lease_key));
1036        buf->lcontext.LeaseKeyHigh = cpu_to_le64(*((u64 *)(lease_key + 8)));
1037        buf->lcontext.LeaseState = map_oplock_to_lease(oplock);
1038
1039        buf->ccontext.DataOffset = cpu_to_le16(offsetof
1040                                        (struct create_lease, lcontext));
1041        buf->ccontext.DataLength = cpu_to_le32(sizeof(struct lease_context));
1042        buf->ccontext.NameOffset = cpu_to_le16(offsetof
1043                                (struct create_lease, Name));
1044        buf->ccontext.NameLength = cpu_to_le16(4);
1045        buf->Name[0] = 'R';
1046        buf->Name[1] = 'q';
1047        buf->Name[2] = 'L';
1048        buf->Name[3] = 's';
1049        return (char *)buf;
1050}
1051
1052static char *
1053smb3_create_lease_buf(u8 *lease_key, u8 oplock)
1054{
1055        struct create_lease_v2 *buf;
1056
1057        buf = kzalloc(sizeof(struct create_lease_v2), GFP_KERNEL);
1058        if (!buf)
1059                return NULL;
1060
1061        buf->lcontext.LeaseKeyLow = cpu_to_le64(*((u64 *)lease_key));
1062        buf->lcontext.LeaseKeyHigh = cpu_to_le64(*((u64 *)(lease_key + 8)));
1063        buf->lcontext.LeaseState = map_oplock_to_lease(oplock);
1064
1065        buf->ccontext.DataOffset = cpu_to_le16(offsetof
1066                                        (struct create_lease_v2, lcontext));
1067        buf->ccontext.DataLength = cpu_to_le32(sizeof(struct lease_context_v2));
1068        buf->ccontext.NameOffset = cpu_to_le16(offsetof
1069                                (struct create_lease_v2, Name));
1070        buf->ccontext.NameLength = cpu_to_le16(4);
1071        buf->Name[0] = 'R';
1072        buf->Name[1] = 'q';
1073        buf->Name[2] = 'L';
1074        buf->Name[3] = 's';
1075        return (char *)buf;
1076}
1077
1078static __u8
1079smb2_parse_lease_buf(void *buf, unsigned int *epoch)
1080{
1081        struct create_lease *lc = (struct create_lease *)buf;
1082
1083        *epoch = 0; /* not used */
1084        if (lc->lcontext.LeaseFlags & SMB2_LEASE_FLAG_BREAK_IN_PROGRESS)
1085                return SMB2_OPLOCK_LEVEL_NOCHANGE;
1086        return le32_to_cpu(lc->lcontext.LeaseState);
1087}
1088
1089static __u8
1090smb3_parse_lease_buf(void *buf, unsigned int *epoch)
1091{
1092        struct create_lease_v2 *lc = (struct create_lease_v2 *)buf;
1093
1094        *epoch = le16_to_cpu(lc->lcontext.Epoch);
1095        if (lc->lcontext.LeaseFlags & SMB2_LEASE_FLAG_BREAK_IN_PROGRESS)
1096                return SMB2_OPLOCK_LEVEL_NOCHANGE;
1097        return le32_to_cpu(lc->lcontext.LeaseState);
1098}
1099
1100struct smb_version_operations smb20_operations = {
1101        .compare_fids = smb2_compare_fids,
1102        .setup_request = smb2_setup_request,
1103        .setup_async_request = smb2_setup_async_request,
1104        .check_receive = smb2_check_receive,
1105        .add_credits = smb2_add_credits,
1106        .set_credits = smb2_set_credits,
1107        .get_credits_field = smb2_get_credits_field,
1108        .get_credits = smb2_get_credits,
1109        .get_next_mid = smb2_get_next_mid,
1110        .read_data_offset = smb2_read_data_offset,
1111        .read_data_length = smb2_read_data_length,
1112        .map_error = map_smb2_to_linux_error,
1113        .find_mid = smb2_find_mid,
1114        .check_message = smb2_check_message,
1115        .dump_detail = smb2_dump_detail,
1116        .clear_stats = smb2_clear_stats,
1117        .print_stats = smb2_print_stats,
1118        .is_oplock_break = smb2_is_valid_oplock_break,
1119        .need_neg = smb2_need_neg,
1120        .negotiate = smb2_negotiate,
1121        .negotiate_wsize = smb2_negotiate_wsize,
1122        .negotiate_rsize = smb2_negotiate_rsize,
1123        .sess_setup = SMB2_sess_setup,
1124        .logoff = SMB2_logoff,
1125        .tree_connect = SMB2_tcon,
1126        .tree_disconnect = SMB2_tdis,
1127        .qfs_tcon = smb2_qfs_tcon,
1128        .is_path_accessible = smb2_is_path_accessible,
1129        .can_echo = smb2_can_echo,
1130        .echo = SMB2_echo,
1131        .query_path_info = smb2_query_path_info,
1132        .get_srv_inum = smb2_get_srv_inum,
1133        .query_file_info = smb2_query_file_info,
1134        .set_path_size = smb2_set_path_size,
1135        .set_file_size = smb2_set_file_size,
1136        .set_file_info = smb2_set_file_info,
1137        .set_compression = smb2_set_compression,
1138        .mkdir = smb2_mkdir,
1139        .mkdir_setinfo = smb2_mkdir_setinfo,
1140        .rmdir = smb2_rmdir,
1141        .unlink = smb2_unlink,
1142        .rename = smb2_rename_path,
1143        .create_hardlink = smb2_create_hardlink,
1144        .query_symlink = smb2_query_symlink,
1145        .open = smb2_open_file,
1146        .set_fid = smb2_set_fid,
1147        .close = smb2_close_file,
1148        .flush = smb2_flush_file,
1149        .async_readv = smb2_async_readv,
1150        .async_writev = smb2_async_writev,
1151        .sync_read = smb2_sync_read,
1152        .sync_write = smb2_sync_write,
1153        .query_dir_first = smb2_query_dir_first,
1154        .query_dir_next = smb2_query_dir_next,
1155        .close_dir = smb2_close_dir,
1156        .calc_smb_size = smb2_calc_size,
1157        .is_status_pending = smb2_is_status_pending,
1158        .oplock_response = smb2_oplock_response,
1159        .queryfs = smb2_queryfs,
1160        .mand_lock = smb2_mand_lock,
1161        .mand_unlock_range = smb2_unlock_range,
1162        .push_mand_locks = smb2_push_mandatory_locks,
1163        .get_lease_key = smb2_get_lease_key,
1164        .set_lease_key = smb2_set_lease_key,
1165        .new_lease_key = smb2_new_lease_key,
1166        .calc_signature = smb2_calc_signature,
1167        .is_read_op = smb2_is_read_op,
1168        .set_oplock_level = smb2_set_oplock_level,
1169        .create_lease_buf = smb2_create_lease_buf,
1170        .parse_lease_buf = smb2_parse_lease_buf,
1171        .clone_range = smb2_clone_range,
1172};
1173
1174struct smb_version_operations smb21_operations = {
1175        .compare_fids = smb2_compare_fids,
1176        .setup_request = smb2_setup_request,
1177        .setup_async_request = smb2_setup_async_request,
1178        .check_receive = smb2_check_receive,
1179        .add_credits = smb2_add_credits,
1180        .set_credits = smb2_set_credits,
1181        .get_credits_field = smb2_get_credits_field,
1182        .get_credits = smb2_get_credits,
1183        .get_next_mid = smb2_get_next_mid,
1184        .read_data_offset = smb2_read_data_offset,
1185        .read_data_length = smb2_read_data_length,
1186        .map_error = map_smb2_to_linux_error,
1187        .find_mid = smb2_find_mid,
1188        .check_message = smb2_check_message,
1189        .dump_detail = smb2_dump_detail,
1190        .clear_stats = smb2_clear_stats,
1191        .print_stats = smb2_print_stats,
1192        .is_oplock_break = smb2_is_valid_oplock_break,
1193        .need_neg = smb2_need_neg,
1194        .negotiate = smb2_negotiate,
1195        .negotiate_wsize = smb2_negotiate_wsize,
1196        .negotiate_rsize = smb2_negotiate_rsize,
1197        .sess_setup = SMB2_sess_setup,
1198        .logoff = SMB2_logoff,
1199        .tree_connect = SMB2_tcon,
1200        .tree_disconnect = SMB2_tdis,
1201        .qfs_tcon = smb2_qfs_tcon,
1202        .is_path_accessible = smb2_is_path_accessible,
1203        .can_echo = smb2_can_echo,
1204        .echo = SMB2_echo,
1205        .query_path_info = smb2_query_path_info,
1206        .get_srv_inum = smb2_get_srv_inum,
1207        .query_file_info = smb2_query_file_info,
1208        .set_path_size = smb2_set_path_size,
1209        .set_file_size = smb2_set_file_size,
1210        .set_file_info = smb2_set_file_info,
1211        .set_compression = smb2_set_compression,
1212        .mkdir = smb2_mkdir,
1213        .mkdir_setinfo = smb2_mkdir_setinfo,
1214        .rmdir = smb2_rmdir,
1215        .unlink = smb2_unlink,
1216        .rename = smb2_rename_path,
1217        .create_hardlink = smb2_create_hardlink,
1218        .query_symlink = smb2_query_symlink,
1219        .open = smb2_open_file,
1220        .set_fid = smb2_set_fid,
1221        .close = smb2_close_file,
1222        .flush = smb2_flush_file,
1223        .async_readv = smb2_async_readv,
1224        .async_writev = smb2_async_writev,
1225        .sync_read = smb2_sync_read,
1226        .sync_write = smb2_sync_write,
1227        .query_dir_first = smb2_query_dir_first,
1228        .query_dir_next = smb2_query_dir_next,
1229        .close_dir = smb2_close_dir,
1230        .calc_smb_size = smb2_calc_size,
1231        .is_status_pending = smb2_is_status_pending,
1232        .oplock_response = smb2_oplock_response,
1233        .queryfs = smb2_queryfs,
1234        .mand_lock = smb2_mand_lock,
1235        .mand_unlock_range = smb2_unlock_range,
1236        .push_mand_locks = smb2_push_mandatory_locks,
1237        .get_lease_key = smb2_get_lease_key,
1238        .set_lease_key = smb2_set_lease_key,
1239        .new_lease_key = smb2_new_lease_key,
1240        .calc_signature = smb2_calc_signature,
1241        .is_read_op = smb21_is_read_op,
1242        .set_oplock_level = smb21_set_oplock_level,
1243        .create_lease_buf = smb2_create_lease_buf,
1244        .parse_lease_buf = smb2_parse_lease_buf,
1245        .clone_range = smb2_clone_range,
1246};
1247
1248struct smb_version_operations smb30_operations = {
1249        .compare_fids = smb2_compare_fids,
1250        .setup_request = smb2_setup_request,
1251        .setup_async_request = smb2_setup_async_request,
1252        .check_receive = smb2_check_receive,
1253        .add_credits = smb2_add_credits,
1254        .set_credits = smb2_set_credits,
1255        .get_credits_field = smb2_get_credits_field,
1256        .get_credits = smb2_get_credits,
1257        .get_next_mid = smb2_get_next_mid,
1258        .read_data_offset = smb2_read_data_offset,
1259        .read_data_length = smb2_read_data_length,
1260        .map_error = map_smb2_to_linux_error,
1261        .find_mid = smb2_find_mid,
1262        .check_message = smb2_check_message,
1263        .dump_detail = smb2_dump_detail,
1264        .clear_stats = smb2_clear_stats,
1265        .print_stats = smb2_print_stats,
1266        .dump_share_caps = smb2_dump_share_caps,
1267        .is_oplock_break = smb2_is_valid_oplock_break,
1268        .need_neg = smb2_need_neg,
1269        .negotiate = smb2_negotiate,
1270        .negotiate_wsize = smb2_negotiate_wsize,
1271        .negotiate_rsize = smb2_negotiate_rsize,
1272        .sess_setup = SMB2_sess_setup,
1273        .logoff = SMB2_logoff,
1274        .tree_connect = SMB2_tcon,
1275        .tree_disconnect = SMB2_tdis,
1276        .qfs_tcon = smb3_qfs_tcon,
1277        .is_path_accessible = smb2_is_path_accessible,
1278        .can_echo = smb2_can_echo,
1279        .echo = SMB2_echo,
1280        .query_path_info = smb2_query_path_info,
1281        .get_srv_inum = smb2_get_srv_inum,
1282        .query_file_info = smb2_query_file_info,
1283        .set_path_size = smb2_set_path_size,
1284        .set_file_size = smb2_set_file_size,
1285        .set_file_info = smb2_set_file_info,
1286        .set_compression = smb2_set_compression,
1287        .mkdir = smb2_mkdir,
1288        .mkdir_setinfo = smb2_mkdir_setinfo,
1289        .rmdir = smb2_rmdir,
1290        .unlink = smb2_unlink,
1291        .rename = smb2_rename_path,
1292        .create_hardlink = smb2_create_hardlink,
1293        .query_symlink = smb2_query_symlink,
1294        .open = smb2_open_file,
1295        .set_fid = smb2_set_fid,
1296        .close = smb2_close_file,
1297        .flush = smb2_flush_file,
1298        .async_readv = smb2_async_readv,
1299        .async_writev = smb2_async_writev,
1300        .sync_read = smb2_sync_read,
1301        .sync_write = smb2_sync_write,
1302        .query_dir_first = smb2_query_dir_first,
1303        .query_dir_next = smb2_query_dir_next,
1304        .close_dir = smb2_close_dir,
1305        .calc_smb_size = smb2_calc_size,
1306        .is_status_pending = smb2_is_status_pending,
1307        .oplock_response = smb2_oplock_response,
1308        .queryfs = smb2_queryfs,
1309        .mand_lock = smb2_mand_lock,
1310        .mand_unlock_range = smb2_unlock_range,
1311        .push_mand_locks = smb2_push_mandatory_locks,
1312        .get_lease_key = smb2_get_lease_key,
1313        .set_lease_key = smb2_set_lease_key,
1314        .new_lease_key = smb2_new_lease_key,
1315        .generate_signingkey = generate_smb3signingkey,
1316        .calc_signature = smb3_calc_signature,
1317        .is_read_op = smb21_is_read_op,
1318        .set_oplock_level = smb3_set_oplock_level,
1319        .create_lease_buf = smb3_create_lease_buf,
1320        .parse_lease_buf = smb3_parse_lease_buf,
1321        .clone_range = smb2_clone_range,
1322        .validate_negotiate = smb3_validate_negotiate,
1323};
1324
1325struct smb_version_values smb20_values = {
1326        .version_string = SMB20_VERSION_STRING,
1327        .protocol_id = SMB20_PROT_ID,
1328        .req_capabilities = 0, /* MBZ */
1329        .large_lock_type = 0,
1330        .exclusive_lock_type = SMB2_LOCKFLAG_EXCLUSIVE_LOCK,
1331        .shared_lock_type = SMB2_LOCKFLAG_SHARED_LOCK,
1332        .unlock_lock_type = SMB2_LOCKFLAG_UNLOCK,
1333        .header_size = sizeof(struct smb2_hdr),
1334        .max_header_size = MAX_SMB2_HDR_SIZE,
1335        .read_rsp_size = sizeof(struct smb2_read_rsp) - 1,
1336        .lock_cmd = SMB2_LOCK,
1337        .cap_unix = 0,
1338        .cap_nt_find = SMB2_NT_FIND,
1339        .cap_large_files = SMB2_LARGE_FILES,
1340        .signing_enabled = SMB2_NEGOTIATE_SIGNING_ENABLED | SMB2_NEGOTIATE_SIGNING_REQUIRED,
1341        .signing_required = SMB2_NEGOTIATE_SIGNING_REQUIRED,
1342        .create_lease_size = sizeof(struct create_lease),
1343};
1344
1345struct smb_version_values smb21_values = {
1346        .version_string = SMB21_VERSION_STRING,
1347        .protocol_id = SMB21_PROT_ID,
1348        .req_capabilities = 0, /* MBZ on negotiate req until SMB3 dialect */
1349        .large_lock_type = 0,
1350        .exclusive_lock_type = SMB2_LOCKFLAG_EXCLUSIVE_LOCK,
1351        .shared_lock_type = SMB2_LOCKFLAG_SHARED_LOCK,
1352        .unlock_lock_type = SMB2_LOCKFLAG_UNLOCK,
1353        .header_size = sizeof(struct smb2_hdr),
1354        .max_header_size = MAX_SMB2_HDR_SIZE,
1355        .read_rsp_size = sizeof(struct smb2_read_rsp) - 1,
1356        .lock_cmd = SMB2_LOCK,
1357        .cap_unix = 0,
1358        .cap_nt_find = SMB2_NT_FIND,
1359        .cap_large_files = SMB2_LARGE_FILES,
1360        .signing_enabled = SMB2_NEGOTIATE_SIGNING_ENABLED | SMB2_NEGOTIATE_SIGNING_REQUIRED,
1361        .signing_required = SMB2_NEGOTIATE_SIGNING_REQUIRED,
1362        .create_lease_size = sizeof(struct create_lease),
1363};
1364
1365struct smb_version_values smb30_values = {
1366        .version_string = SMB30_VERSION_STRING,
1367        .protocol_id = SMB30_PROT_ID,
1368        .req_capabilities = SMB2_GLOBAL_CAP_DFS | SMB2_GLOBAL_CAP_LEASING | SMB2_GLOBAL_CAP_LARGE_MTU,
1369        .large_lock_type = 0,
1370        .exclusive_lock_type = SMB2_LOCKFLAG_EXCLUSIVE_LOCK,
1371        .shared_lock_type = SMB2_LOCKFLAG_SHARED_LOCK,
1372        .unlock_lock_type = SMB2_LOCKFLAG_UNLOCK,
1373        .header_size = sizeof(struct smb2_hdr),
1374        .max_header_size = MAX_SMB2_HDR_SIZE,
1375        .read_rsp_size = sizeof(struct smb2_read_rsp) - 1,
1376        .lock_cmd = SMB2_LOCK,
1377        .cap_unix = 0,
1378        .cap_nt_find = SMB2_NT_FIND,
1379        .cap_large_files = SMB2_LARGE_FILES,
1380        .signing_enabled = SMB2_NEGOTIATE_SIGNING_ENABLED | SMB2_NEGOTIATE_SIGNING_REQUIRED,
1381        .signing_required = SMB2_NEGOTIATE_SIGNING_REQUIRED,
1382        .create_lease_size = sizeof(struct create_lease_v2),
1383};
1384
1385struct smb_version_values smb302_values = {
1386        .version_string = SMB302_VERSION_STRING,
1387        .protocol_id = SMB302_PROT_ID,
1388        .req_capabilities = SMB2_GLOBAL_CAP_DFS | SMB2_GLOBAL_CAP_LEASING | SMB2_GLOBAL_CAP_LARGE_MTU,
1389        .large_lock_type = 0,
1390        .exclusive_lock_type = SMB2_LOCKFLAG_EXCLUSIVE_LOCK,
1391        .shared_lock_type = SMB2_LOCKFLAG_SHARED_LOCK,
1392        .unlock_lock_type = SMB2_LOCKFLAG_UNLOCK,
1393        .header_size = sizeof(struct smb2_hdr),
1394        .max_header_size = MAX_SMB2_HDR_SIZE,
1395        .read_rsp_size = sizeof(struct smb2_read_rsp) - 1,
1396        .lock_cmd = SMB2_LOCK,
1397        .cap_unix = 0,
1398        .cap_nt_find = SMB2_NT_FIND,
1399        .cap_large_files = SMB2_LARGE_FILES,
1400        .signing_enabled = SMB2_NEGOTIATE_SIGNING_ENABLED | SMB2_NEGOTIATE_SIGNING_REQUIRED,
1401        .signing_required = SMB2_NEGOTIATE_SIGNING_REQUIRED,
1402        .create_lease_size = sizeof(struct create_lease_v2),
1403};
1404