linux/fs/cifs/smb2misc.c
<<
>>
Prefs
   1/*
   2 *   fs/cifs/smb2misc.c
   3 *
   4 *   Copyright (C) International Business Machines  Corp., 2002,2011
   5 *                 Etersoft, 2012
   6 *   Author(s): Steve French (sfrench@us.ibm.com)
   7 *              Pavel Shilovsky (pshilovsky@samba.org) 2012
   8 *
   9 *   This library is free software; you can redistribute it and/or modify
  10 *   it under the terms of the GNU Lesser General Public License as published
  11 *   by the Free Software Foundation; either version 2.1 of the License, or
  12 *   (at your option) any later version.
  13 *
  14 *   This library is distributed in the hope that it will be useful,
  15 *   but WITHOUT ANY WARRANTY; without even the implied warranty of
  16 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
  17 *   the GNU Lesser General Public License for more details.
  18 *
  19 *   You should have received a copy of the GNU Lesser General Public License
  20 *   along with this library; if not, write to the Free Software
  21 *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  22 */
  23#include <linux/ctype.h>
  24#include "smb2pdu.h"
  25#include "cifsglob.h"
  26#include "cifsproto.h"
  27#include "smb2proto.h"
  28#include "cifs_debug.h"
  29#include "cifs_unicode.h"
  30#include "smb2status.h"
  31#include "smb2glob.h"
  32
  33static int
  34check_smb2_hdr(struct smb2_sync_hdr *shdr, __u64 mid)
  35{
  36        __u64 wire_mid = le64_to_cpu(shdr->MessageId);
  37
  38        /*
  39         * Make sure that this really is an SMB, that it is a response,
  40         * and that the message ids match.
  41         */
  42        if ((shdr->ProtocolId == SMB2_PROTO_NUMBER) &&
  43            (mid == wire_mid)) {
  44                if (shdr->Flags & SMB2_FLAGS_SERVER_TO_REDIR)
  45                        return 0;
  46                else {
  47                        /* only one valid case where server sends us request */
  48                        if (shdr->Command == SMB2_OPLOCK_BREAK)
  49                                return 0;
  50                        else
  51                                cifs_dbg(VFS, "Received Request not response\n");
  52                }
  53        } else { /* bad signature or mid */
  54                if (shdr->ProtocolId != SMB2_PROTO_NUMBER)
  55                        cifs_dbg(VFS, "Bad protocol string signature header %x\n",
  56                                 le32_to_cpu(shdr->ProtocolId));
  57                if (mid != wire_mid)
  58                        cifs_dbg(VFS, "Mids do not match: %llu and %llu\n",
  59                                 mid, wire_mid);
  60        }
  61        cifs_dbg(VFS, "Bad SMB detected. The Mid=%llu\n", wire_mid);
  62        return 1;
  63}
  64
  65/*
  66 *  The following table defines the expected "StructureSize" of SMB2 responses
  67 *  in order by SMB2 command.  This is similar to "wct" in SMB/CIFS responses.
  68 *
  69 *  Note that commands are defined in smb2pdu.h in le16 but the array below is
  70 *  indexed by command in host byte order
  71 */
  72static const __le16 smb2_rsp_struct_sizes[NUMBER_OF_SMB2_COMMANDS] = {
  73        /* SMB2_NEGOTIATE */ cpu_to_le16(65),
  74        /* SMB2_SESSION_SETUP */ cpu_to_le16(9),
  75        /* SMB2_LOGOFF */ cpu_to_le16(4),
  76        /* SMB2_TREE_CONNECT */ cpu_to_le16(16),
  77        /* SMB2_TREE_DISCONNECT */ cpu_to_le16(4),
  78        /* SMB2_CREATE */ cpu_to_le16(89),
  79        /* SMB2_CLOSE */ cpu_to_le16(60),
  80        /* SMB2_FLUSH */ cpu_to_le16(4),
  81        /* SMB2_READ */ cpu_to_le16(17),
  82        /* SMB2_WRITE */ cpu_to_le16(17),
  83        /* SMB2_LOCK */ cpu_to_le16(4),
  84        /* SMB2_IOCTL */ cpu_to_le16(49),
  85        /* BB CHECK this ... not listed in documentation */
  86        /* SMB2_CANCEL */ cpu_to_le16(0),
  87        /* SMB2_ECHO */ cpu_to_le16(4),
  88        /* SMB2_QUERY_DIRECTORY */ cpu_to_le16(9),
  89        /* SMB2_CHANGE_NOTIFY */ cpu_to_le16(9),
  90        /* SMB2_QUERY_INFO */ cpu_to_le16(9),
  91        /* SMB2_SET_INFO */ cpu_to_le16(2),
  92        /* BB FIXME can also be 44 for lease break */
  93        /* SMB2_OPLOCK_BREAK */ cpu_to_le16(24)
  94};
  95
  96int
  97smb2_check_message(char *buf, unsigned int length, struct TCP_Server_Info *srvr)
  98{
  99        struct smb2_pdu *pdu = (struct smb2_pdu *)buf;
 100        struct smb2_hdr *hdr = &pdu->hdr;
 101        struct smb2_sync_hdr *shdr = get_sync_hdr(buf);
 102        __u64 mid;
 103        __u32 len = get_rfc1002_length(buf);
 104        __u32 clc_len;  /* calculated length */
 105        int command;
 106
 107        /* BB disable following printk later */
 108        cifs_dbg(FYI, "%s length: 0x%x, smb_buf_length: 0x%x\n",
 109                 __func__, length, len);
 110
 111        /*
 112         * Add function to do table lookup of StructureSize by command
 113         * ie Validate the wct via smb2_struct_sizes table above
 114         */
 115
 116        if (shdr->ProtocolId == SMB2_TRANSFORM_PROTO_NUM) {
 117                struct smb2_transform_hdr *thdr =
 118                        (struct smb2_transform_hdr *)buf;
 119                struct cifs_ses *ses = NULL;
 120                struct list_head *tmp;
 121
 122                /* decrypt frame now that it is completely read in */
 123                spin_lock(&cifs_tcp_ses_lock);
 124                list_for_each(tmp, &srvr->smb_ses_list) {
 125                        ses = list_entry(tmp, struct cifs_ses, smb_ses_list);
 126                        if (ses->Suid == thdr->SessionId)
 127                                break;
 128
 129                        ses = NULL;
 130                }
 131                spin_unlock(&cifs_tcp_ses_lock);
 132                if (ses == NULL) {
 133                        cifs_dbg(VFS, "no decryption - session id not found\n");
 134                        return 1;
 135                }
 136        }
 137
 138        mid = le64_to_cpu(shdr->MessageId);
 139        if (length < sizeof(struct smb2_pdu)) {
 140                if ((length >= sizeof(struct smb2_hdr))
 141                    && (shdr->Status != 0)) {
 142                        pdu->StructureSize2 = 0;
 143                        /*
 144                         * As with SMB/CIFS, on some error cases servers may
 145                         * not return wct properly
 146                         */
 147                        return 0;
 148                } else {
 149                        cifs_dbg(VFS, "Length less than SMB header size\n");
 150                }
 151                return 1;
 152        }
 153        if (len > CIFSMaxBufSize + MAX_SMB2_HDR_SIZE - 4) {
 154                cifs_dbg(VFS, "SMB length greater than maximum, mid=%llu\n",
 155                         mid);
 156                return 1;
 157        }
 158
 159        if (check_smb2_hdr(shdr, mid))
 160                return 1;
 161
 162        if (shdr->StructureSize != SMB2_HEADER_STRUCTURE_SIZE) {
 163                cifs_dbg(VFS, "Illegal structure size %u\n",
 164                         le16_to_cpu(shdr->StructureSize));
 165                return 1;
 166        }
 167
 168        command = le16_to_cpu(shdr->Command);
 169        if (command >= NUMBER_OF_SMB2_COMMANDS) {
 170                cifs_dbg(VFS, "Illegal SMB2 command %d\n", command);
 171                return 1;
 172        }
 173
 174        if (smb2_rsp_struct_sizes[command] != pdu->StructureSize2) {
 175                if (command != SMB2_OPLOCK_BREAK_HE && (shdr->Status == 0 ||
 176                    pdu->StructureSize2 != SMB2_ERROR_STRUCTURE_SIZE2)) {
 177                        /* error packets have 9 byte structure size */
 178                        cifs_dbg(VFS, "Illegal response size %u for command %d\n",
 179                                 le16_to_cpu(pdu->StructureSize2), command);
 180                        return 1;
 181                } else if (command == SMB2_OPLOCK_BREAK_HE
 182                           && (shdr->Status == 0)
 183                           && (le16_to_cpu(pdu->StructureSize2) != 44)
 184                           && (le16_to_cpu(pdu->StructureSize2) != 36)) {
 185                        /* special case for SMB2.1 lease break message */
 186                        cifs_dbg(VFS, "Illegal response size %d for oplock break\n",
 187                                 le16_to_cpu(pdu->StructureSize2));
 188                        return 1;
 189                }
 190        }
 191
 192        if (4 + len != length) {
 193                cifs_dbg(VFS, "Total length %u RFC1002 length %u mismatch mid %llu\n",
 194                         length, 4 + len, mid);
 195                return 1;
 196        }
 197
 198        clc_len = smb2_calc_size(hdr);
 199
 200        if (4 + len != clc_len) {
 201                cifs_dbg(FYI, "Calculated size %u length %u mismatch mid %llu\n",
 202                         clc_len, 4 + len, mid);
 203                /* create failed on symlink */
 204                if (command == SMB2_CREATE_HE &&
 205                    shdr->Status == STATUS_STOPPED_ON_SYMLINK)
 206                        return 0;
 207                /* Windows 7 server returns 24 bytes more */
 208                if (clc_len + 20 == len && command == SMB2_OPLOCK_BREAK_HE)
 209                        return 0;
 210                /* server can return one byte more due to implied bcc[0] */
 211                if (clc_len == 4 + len + 1)
 212                        return 0;
 213
 214                /*
 215                 * MacOS server pads after SMB2.1 write response with 3 bytes
 216                 * of junk. Other servers match RFC1001 len to actual
 217                 * SMB2/SMB3 frame length (header + smb2 response specific data)
 218                 * Log the server error (once), but allow it and continue
 219                 * since the frame is parseable.
 220                 */
 221                if (clc_len < 4 /* RFC1001 header size */ + len) {
 222                        printk_once(KERN_WARNING
 223                                "SMB2 server sent bad RFC1001 len %d not %d\n",
 224                                len, clc_len - 4);
 225                        return 0;
 226                }
 227
 228                return 1;
 229        }
 230        return 0;
 231}
 232
 233/*
 234 * The size of the variable area depends on the offset and length fields
 235 * located in different fields for various SMB2 responses. SMB2 responses
 236 * with no variable length info, show an offset of zero for the offset field.
 237 */
 238static const bool has_smb2_data_area[NUMBER_OF_SMB2_COMMANDS] = {
 239        /* SMB2_NEGOTIATE */ true,
 240        /* SMB2_SESSION_SETUP */ true,
 241        /* SMB2_LOGOFF */ false,
 242        /* SMB2_TREE_CONNECT */ false,
 243        /* SMB2_TREE_DISCONNECT */ false,
 244        /* SMB2_CREATE */ true,
 245        /* SMB2_CLOSE */ false,
 246        /* SMB2_FLUSH */ false,
 247        /* SMB2_READ */ true,
 248        /* SMB2_WRITE */ false,
 249        /* SMB2_LOCK */ false,
 250        /* SMB2_IOCTL */ true,
 251        /* SMB2_CANCEL */ false, /* BB CHECK this not listed in documentation */
 252        /* SMB2_ECHO */ false,
 253        /* SMB2_QUERY_DIRECTORY */ true,
 254        /* SMB2_CHANGE_NOTIFY */ true,
 255        /* SMB2_QUERY_INFO */ true,
 256        /* SMB2_SET_INFO */ false,
 257        /* SMB2_OPLOCK_BREAK */ false
 258};
 259
 260/*
 261 * Returns the pointer to the beginning of the data area. Length of the data
 262 * area and the offset to it (from the beginning of the smb are also returned.
 263 */
 264char *
 265smb2_get_data_area_len(int *off, int *len, struct smb2_hdr *hdr)
 266{
 267        struct smb2_sync_hdr *shdr = get_sync_hdr(hdr);
 268        *off = 0;
 269        *len = 0;
 270
 271        /* error responses do not have data area */
 272        if (shdr->Status && shdr->Status != STATUS_MORE_PROCESSING_REQUIRED &&
 273            (((struct smb2_err_rsp *)hdr)->StructureSize) ==
 274                                                SMB2_ERROR_STRUCTURE_SIZE2)
 275                return NULL;
 276
 277        /*
 278         * Following commands have data areas so we have to get the location
 279         * of the data buffer offset and data buffer length for the particular
 280         * command.
 281         */
 282        switch (shdr->Command) {
 283        case SMB2_NEGOTIATE:
 284                *off = le16_to_cpu(
 285                    ((struct smb2_negotiate_rsp *)hdr)->SecurityBufferOffset);
 286                *len = le16_to_cpu(
 287                    ((struct smb2_negotiate_rsp *)hdr)->SecurityBufferLength);
 288                break;
 289        case SMB2_SESSION_SETUP:
 290                *off = le16_to_cpu(
 291                    ((struct smb2_sess_setup_rsp *)hdr)->SecurityBufferOffset);
 292                *len = le16_to_cpu(
 293                    ((struct smb2_sess_setup_rsp *)hdr)->SecurityBufferLength);
 294                break;
 295        case SMB2_CREATE:
 296                *off = le32_to_cpu(
 297                    ((struct smb2_create_rsp *)hdr)->CreateContextsOffset);
 298                *len = le32_to_cpu(
 299                    ((struct smb2_create_rsp *)hdr)->CreateContextsLength);
 300                break;
 301        case SMB2_QUERY_INFO:
 302                *off = le16_to_cpu(
 303                    ((struct smb2_query_info_rsp *)hdr)->OutputBufferOffset);
 304                *len = le32_to_cpu(
 305                    ((struct smb2_query_info_rsp *)hdr)->OutputBufferLength);
 306                break;
 307        case SMB2_READ:
 308                *off = ((struct smb2_read_rsp *)hdr)->DataOffset;
 309                *len = le32_to_cpu(((struct smb2_read_rsp *)hdr)->DataLength);
 310                break;
 311        case SMB2_QUERY_DIRECTORY:
 312                *off = le16_to_cpu(
 313                  ((struct smb2_query_directory_rsp *)hdr)->OutputBufferOffset);
 314                *len = le32_to_cpu(
 315                  ((struct smb2_query_directory_rsp *)hdr)->OutputBufferLength);
 316                break;
 317        case SMB2_IOCTL:
 318                *off = le32_to_cpu(
 319                  ((struct smb2_ioctl_rsp *)hdr)->OutputOffset);
 320                *len = le32_to_cpu(((struct smb2_ioctl_rsp *)hdr)->OutputCount);
 321                break;
 322        case SMB2_CHANGE_NOTIFY:
 323        default:
 324                /* BB FIXME for unimplemented cases above */
 325                cifs_dbg(VFS, "no length check for command\n");
 326                break;
 327        }
 328
 329        /*
 330         * Invalid length or offset probably means data area is invalid, but
 331         * we have little choice but to ignore the data area in this case.
 332         */
 333        if (*off > 4096) {
 334                cifs_dbg(VFS, "offset %d too large, data area ignored\n", *off);
 335                *len = 0;
 336                *off = 0;
 337        } else if (*off < 0) {
 338                cifs_dbg(VFS, "negative offset %d to data invalid ignore data area\n",
 339                         *off);
 340                *off = 0;
 341                *len = 0;
 342        } else if (*len < 0) {
 343                cifs_dbg(VFS, "negative data length %d invalid, data area ignored\n",
 344                         *len);
 345                *len = 0;
 346        } else if (*len > 128 * 1024) {
 347                cifs_dbg(VFS, "data area larger than 128K: %d\n", *len);
 348                *len = 0;
 349        }
 350
 351        /* return pointer to beginning of data area, ie offset from SMB start */
 352        if ((*off != 0) && (*len != 0))
 353                return (char *)shdr + *off;
 354        else
 355                return NULL;
 356}
 357
 358/*
 359 * Calculate the size of the SMB message based on the fixed header
 360 * portion, the number of word parameters and the data portion of the message.
 361 */
 362unsigned int
 363smb2_calc_size(void *buf)
 364{
 365        struct smb2_pdu *pdu = (struct smb2_pdu *)buf;
 366        struct smb2_hdr *hdr = &pdu->hdr;
 367        struct smb2_sync_hdr *shdr = get_sync_hdr(hdr);
 368        int offset; /* the offset from the beginning of SMB to data area */
 369        int data_length; /* the length of the variable length data area */
 370        /* Structure Size has already been checked to make sure it is 64 */
 371        int len = 4 + le16_to_cpu(shdr->StructureSize);
 372
 373        /*
 374         * StructureSize2, ie length of fixed parameter area has already
 375         * been checked to make sure it is the correct length.
 376         */
 377        len += le16_to_cpu(pdu->StructureSize2);
 378
 379        if (has_smb2_data_area[le16_to_cpu(shdr->Command)] == false)
 380                goto calc_size_exit;
 381
 382        smb2_get_data_area_len(&offset, &data_length, hdr);
 383        cifs_dbg(FYI, "SMB2 data length %d offset %d\n", data_length, offset);
 384
 385        if (data_length > 0) {
 386                /*
 387                 * Check to make sure that data area begins after fixed area,
 388                 * Note that last byte of the fixed area is part of data area
 389                 * for some commands, typically those with odd StructureSize,
 390                 * so we must add one to the calculation (and 4 to account for
 391                 * the size of the RFC1001 hdr.
 392                 */
 393                if (offset + 4 + 1 < len) {
 394                        cifs_dbg(VFS, "data area offset %d overlaps SMB2 header %d\n",
 395                                 offset + 4 + 1, len);
 396                        data_length = 0;
 397                } else {
 398                        len = 4 + offset + data_length;
 399                }
 400        }
 401calc_size_exit:
 402        cifs_dbg(FYI, "SMB2 len %d\n", len);
 403        return len;
 404}
 405
 406/* Note: caller must free return buffer */
 407__le16 *
 408cifs_convert_path_to_utf16(const char *from, struct cifs_sb_info *cifs_sb)
 409{
 410        int len;
 411        const char *start_of_path;
 412        __le16 *to;
 413        int map_type;
 414
 415        if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SFM_CHR)
 416                map_type = SFM_MAP_UNI_RSVD;
 417        else if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR)
 418                map_type = SFU_MAP_UNI_RSVD;
 419        else
 420                map_type = NO_MAP_UNI_RSVD;
 421
 422        /* Windows doesn't allow paths beginning with \ */
 423        if (from[0] == '\\')
 424                start_of_path = from + 1;
 425        else
 426                start_of_path = from;
 427        to = cifs_strndup_to_utf16(start_of_path, PATH_MAX, &len,
 428                                   cifs_sb->local_nls, map_type);
 429        return to;
 430}
 431
 432__le32
 433smb2_get_lease_state(struct cifsInodeInfo *cinode)
 434{
 435        __le32 lease = 0;
 436
 437        if (CIFS_CACHE_WRITE(cinode))
 438                lease |= SMB2_LEASE_WRITE_CACHING;
 439        if (CIFS_CACHE_HANDLE(cinode))
 440                lease |= SMB2_LEASE_HANDLE_CACHING;
 441        if (CIFS_CACHE_READ(cinode))
 442                lease |= SMB2_LEASE_READ_CACHING;
 443        return lease;
 444}
 445
 446struct smb2_lease_break_work {
 447        struct work_struct lease_break;
 448        struct tcon_link *tlink;
 449        __u8 lease_key[16];
 450        __le32 lease_state;
 451};
 452
 453static void
 454cifs_ses_oplock_break(struct work_struct *work)
 455{
 456        struct smb2_lease_break_work *lw = container_of(work,
 457                                struct smb2_lease_break_work, lease_break);
 458        int rc;
 459
 460        rc = SMB2_lease_break(0, tlink_tcon(lw->tlink), lw->lease_key,
 461                              lw->lease_state);
 462        cifs_dbg(FYI, "Lease release rc %d\n", rc);
 463        cifs_put_tlink(lw->tlink);
 464        kfree(lw);
 465}
 466
 467static bool
 468smb2_tcon_has_lease(struct cifs_tcon *tcon, struct smb2_lease_break *rsp,
 469                    struct smb2_lease_break_work *lw)
 470{
 471        bool found;
 472        __u8 lease_state;
 473        struct list_head *tmp;
 474        struct cifsFileInfo *cfile;
 475        struct TCP_Server_Info *server = tcon->ses->server;
 476        struct cifs_pending_open *open;
 477        struct cifsInodeInfo *cinode;
 478        int ack_req = le32_to_cpu(rsp->Flags &
 479                                  SMB2_NOTIFY_BREAK_LEASE_FLAG_ACK_REQUIRED);
 480
 481        lease_state = le32_to_cpu(rsp->NewLeaseState);
 482
 483        list_for_each(tmp, &tcon->openFileList) {
 484                cfile = list_entry(tmp, struct cifsFileInfo, tlist);
 485                cinode = CIFS_I(d_inode(cfile->dentry));
 486
 487                if (memcmp(cinode->lease_key, rsp->LeaseKey,
 488                                                        SMB2_LEASE_KEY_SIZE))
 489                        continue;
 490
 491                cifs_dbg(FYI, "found in the open list\n");
 492                cifs_dbg(FYI, "lease key match, lease break 0x%x\n",
 493                         le32_to_cpu(rsp->NewLeaseState));
 494
 495                server->ops->set_oplock_level(cinode, lease_state, 0, NULL);
 496
 497                if (ack_req)
 498                        cfile->oplock_break_cancelled = false;
 499                else
 500                        cfile->oplock_break_cancelled = true;
 501
 502                queue_work(cifsoplockd_wq, &cfile->oplock_break);
 503                kfree(lw);
 504                return true;
 505        }
 506
 507        found = false;
 508        list_for_each_entry(open, &tcon->pending_opens, olist) {
 509                if (memcmp(open->lease_key, rsp->LeaseKey,
 510                           SMB2_LEASE_KEY_SIZE))
 511                        continue;
 512
 513                if (!found && ack_req) {
 514                        found = true;
 515                        memcpy(lw->lease_key, open->lease_key,
 516                               SMB2_LEASE_KEY_SIZE);
 517                        lw->tlink = cifs_get_tlink(open->tlink);
 518                        queue_work(cifsiod_wq, &lw->lease_break);
 519                }
 520
 521                cifs_dbg(FYI, "found in the pending open list\n");
 522                cifs_dbg(FYI, "lease key match, lease break 0x%x\n",
 523                         le32_to_cpu(rsp->NewLeaseState));
 524
 525                open->oplock = lease_state;
 526        }
 527        return found;
 528}
 529
 530static bool
 531smb2_is_valid_lease_break(char *buffer)
 532{
 533        struct smb2_lease_break *rsp = (struct smb2_lease_break *)buffer;
 534        struct list_head *tmp, *tmp1, *tmp2;
 535        struct TCP_Server_Info *server;
 536        struct cifs_ses *ses;
 537        struct cifs_tcon *tcon;
 538        struct smb2_lease_break_work *lw;
 539
 540        lw = kmalloc(sizeof(struct smb2_lease_break_work), GFP_KERNEL);
 541        if (!lw)
 542                return false;
 543
 544        INIT_WORK(&lw->lease_break, cifs_ses_oplock_break);
 545        lw->lease_state = rsp->NewLeaseState;
 546
 547        cifs_dbg(FYI, "Checking for lease break\n");
 548
 549        /* look up tcon based on tid & uid */
 550        spin_lock(&cifs_tcp_ses_lock);
 551        list_for_each(tmp, &cifs_tcp_ses_list) {
 552                server = list_entry(tmp, struct TCP_Server_Info, tcp_ses_list);
 553
 554                list_for_each(tmp1, &server->smb_ses_list) {
 555                        ses = list_entry(tmp1, struct cifs_ses, smb_ses_list);
 556
 557                        list_for_each(tmp2, &ses->tcon_list) {
 558                                tcon = list_entry(tmp2, struct cifs_tcon,
 559                                                  tcon_list);
 560                                spin_lock(&tcon->open_file_lock);
 561                                cifs_stats_inc(
 562                                    &tcon->stats.cifs_stats.num_oplock_brks);
 563                                if (smb2_tcon_has_lease(tcon, rsp, lw)) {
 564                                        spin_unlock(&tcon->open_file_lock);
 565                                        spin_unlock(&cifs_tcp_ses_lock);
 566                                        return true;
 567                                }
 568                                spin_unlock(&tcon->open_file_lock);
 569                        }
 570                }
 571        }
 572        spin_unlock(&cifs_tcp_ses_lock);
 573        kfree(lw);
 574        cifs_dbg(FYI, "Can not process lease break - no lease matched\n");
 575        return false;
 576}
 577
 578bool
 579smb2_is_valid_oplock_break(char *buffer, struct TCP_Server_Info *server)
 580{
 581        struct smb2_oplock_break_rsp *rsp = (struct smb2_oplock_break_rsp *)buffer;
 582        struct list_head *tmp, *tmp1, *tmp2;
 583        struct cifs_ses *ses;
 584        struct cifs_tcon *tcon;
 585        struct cifsInodeInfo *cinode;
 586        struct cifsFileInfo *cfile;
 587
 588        cifs_dbg(FYI, "Checking for oplock break\n");
 589
 590        if (rsp->hdr.sync_hdr.Command != SMB2_OPLOCK_BREAK)
 591                return false;
 592
 593        if (rsp->StructureSize !=
 594                                smb2_rsp_struct_sizes[SMB2_OPLOCK_BREAK_HE]) {
 595                if (le16_to_cpu(rsp->StructureSize) == 44)
 596                        return smb2_is_valid_lease_break(buffer);
 597                else
 598                        return false;
 599        }
 600
 601        cifs_dbg(FYI, "oplock level 0x%x\n", rsp->OplockLevel);
 602
 603        /* look up tcon based on tid & uid */
 604        spin_lock(&cifs_tcp_ses_lock);
 605        list_for_each(tmp, &server->smb_ses_list) {
 606                ses = list_entry(tmp, struct cifs_ses, smb_ses_list);
 607                list_for_each(tmp1, &ses->tcon_list) {
 608                        tcon = list_entry(tmp1, struct cifs_tcon, tcon_list);
 609
 610                        cifs_stats_inc(&tcon->stats.cifs_stats.num_oplock_brks);
 611                        spin_lock(&tcon->open_file_lock);
 612                        list_for_each(tmp2, &tcon->openFileList) {
 613                                cfile = list_entry(tmp2, struct cifsFileInfo,
 614                                                     tlist);
 615                                if (rsp->PersistentFid !=
 616                                    cfile->fid.persistent_fid ||
 617                                    rsp->VolatileFid !=
 618                                    cfile->fid.volatile_fid)
 619                                        continue;
 620
 621                                cifs_dbg(FYI, "file id match, oplock break\n");
 622                                cinode = CIFS_I(d_inode(cfile->dentry));
 623                                spin_lock(&cfile->file_info_lock);
 624                                if (!CIFS_CACHE_WRITE(cinode) &&
 625                                    rsp->OplockLevel == SMB2_OPLOCK_LEVEL_NONE)
 626                                        cfile->oplock_break_cancelled = true;
 627                                else
 628                                        cfile->oplock_break_cancelled = false;
 629
 630                                set_bit(CIFS_INODE_PENDING_OPLOCK_BREAK,
 631                                        &cinode->flags);
 632
 633                                /*
 634                                 * Set flag if the server downgrades the oplock
 635                                 * to L2 else clear.
 636                                 */
 637                                if (rsp->OplockLevel)
 638                                        set_bit(
 639                                           CIFS_INODE_DOWNGRADE_OPLOCK_TO_L2,
 640                                           &cinode->flags);
 641                                else
 642                                        clear_bit(
 643                                           CIFS_INODE_DOWNGRADE_OPLOCK_TO_L2,
 644                                           &cinode->flags);
 645                                spin_unlock(&cfile->file_info_lock);
 646                                queue_work(cifsoplockd_wq,
 647                                           &cfile->oplock_break);
 648
 649                                spin_unlock(&tcon->open_file_lock);
 650                                spin_unlock(&cifs_tcp_ses_lock);
 651                                return true;
 652                        }
 653                        spin_unlock(&tcon->open_file_lock);
 654                        spin_unlock(&cifs_tcp_ses_lock);
 655                        cifs_dbg(FYI, "No matching file for oplock break\n");
 656                        return true;
 657                }
 658        }
 659        spin_unlock(&cifs_tcp_ses_lock);
 660        cifs_dbg(FYI, "Can not process oplock break for non-existent connection\n");
 661        return false;
 662}
 663
 664void
 665smb2_cancelled_close_fid(struct work_struct *work)
 666{
 667        struct close_cancelled_open *cancelled = container_of(work,
 668                                        struct close_cancelled_open, work);
 669
 670        cifs_dbg(VFS, "Close unmatched open\n");
 671
 672        SMB2_close(0, cancelled->tcon, cancelled->fid.persistent_fid,
 673                   cancelled->fid.volatile_fid);
 674        cifs_put_tcon(cancelled->tcon);
 675        kfree(cancelled);
 676}
 677
 678int
 679smb2_handle_cancelled_mid(char *buffer, struct TCP_Server_Info *server)
 680{
 681        struct smb2_sync_hdr *sync_hdr = get_sync_hdr(buffer);
 682        struct smb2_create_rsp *rsp = (struct smb2_create_rsp *)buffer;
 683        struct cifs_tcon *tcon;
 684        struct close_cancelled_open *cancelled;
 685
 686        if (sync_hdr->Command != SMB2_CREATE ||
 687            sync_hdr->Status != STATUS_SUCCESS)
 688                return 0;
 689
 690        cancelled = kzalloc(sizeof(*cancelled), GFP_KERNEL);
 691        if (!cancelled)
 692                return -ENOMEM;
 693
 694        tcon = smb2_find_smb_tcon(server, sync_hdr->SessionId,
 695                                  sync_hdr->TreeId);
 696        if (!tcon) {
 697                kfree(cancelled);
 698                return -ENOENT;
 699        }
 700
 701        cancelled->fid.persistent_fid = rsp->PersistentFileId;
 702        cancelled->fid.volatile_fid = rsp->VolatileFileId;
 703        cancelled->tcon = tcon;
 704        INIT_WORK(&cancelled->work, smb2_cancelled_close_fid);
 705        queue_work(cifsiod_wq, &cancelled->work);
 706
 707        return 0;
 708}
 709