linux/fs/cifs/misc.c
<<
>>
Prefs
   1/*
   2 *   fs/cifs/misc.c
   3 *
   4 *   Copyright (C) International Business Machines  Corp., 2002,2008
   5 *   Author(s): Steve French (sfrench@us.ibm.com)
   6 *
   7 *   This library is free software; you can redistribute it and/or modify
   8 *   it under the terms of the GNU Lesser General Public License as published
   9 *   by the Free Software Foundation; either version 2.1 of the License, or
  10 *   (at your option) any later version.
  11 *
  12 *   This library is distributed in the hope that it will be useful,
  13 *   but WITHOUT ANY WARRANTY; without even the implied warranty of
  14 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
  15 *   the GNU Lesser General Public License for more details.
  16 *
  17 *   You should have received a copy of the GNU Lesser General Public License
  18 *   along with this library; if not, write to the Free Software
  19 *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  20 */
  21
  22#include <linux/slab.h>
  23#include <linux/ctype.h>
  24#include <linux/mempool.h>
  25#include "cifspdu.h"
  26#include "cifsglob.h"
  27#include "cifsproto.h"
  28#include "cifs_debug.h"
  29#include "smberr.h"
  30#include "nterr.h"
  31#include "cifs_unicode.h"
  32
  33extern mempool_t *cifs_sm_req_poolp;
  34extern mempool_t *cifs_req_poolp;
  35
  36/* The xid serves as a useful identifier for each incoming vfs request,
  37   in a similar way to the mid which is useful to track each sent smb,
  38   and CurrentXid can also provide a running counter (although it
  39   will eventually wrap past zero) of the total vfs operations handled
  40   since the cifs fs was mounted */
  41
  42unsigned int
  43_GetXid(void)
  44{
  45        unsigned int xid;
  46
  47        spin_lock(&GlobalMid_Lock);
  48        GlobalTotalActiveXid++;
  49
  50        /* keep high water mark for number of simultaneous ops in filesystem */
  51        if (GlobalTotalActiveXid > GlobalMaxActiveXid)
  52                GlobalMaxActiveXid = GlobalTotalActiveXid;
  53        if (GlobalTotalActiveXid > 65000)
  54                cFYI(1, ("warning: more than 65000 requests active"));
  55        xid = GlobalCurrentXid++;
  56        spin_unlock(&GlobalMid_Lock);
  57        return xid;
  58}
  59
  60void
  61_FreeXid(unsigned int xid)
  62{
  63        spin_lock(&GlobalMid_Lock);
  64        /* if (GlobalTotalActiveXid == 0)
  65                BUG(); */
  66        GlobalTotalActiveXid--;
  67        spin_unlock(&GlobalMid_Lock);
  68}
  69
  70struct cifsSesInfo *
  71sesInfoAlloc(void)
  72{
  73        struct cifsSesInfo *ret_buf;
  74
  75        ret_buf = kzalloc(sizeof(struct cifsSesInfo), GFP_KERNEL);
  76        if (ret_buf) {
  77                atomic_inc(&sesInfoAllocCount);
  78                ret_buf->status = CifsNew;
  79                ++ret_buf->ses_count;
  80                INIT_LIST_HEAD(&ret_buf->smb_ses_list);
  81                INIT_LIST_HEAD(&ret_buf->tcon_list);
  82                init_MUTEX(&ret_buf->sesSem);
  83        }
  84        return ret_buf;
  85}
  86
  87void
  88sesInfoFree(struct cifsSesInfo *buf_to_free)
  89{
  90        if (buf_to_free == NULL) {
  91                cFYI(1, ("Null buffer passed to sesInfoFree"));
  92                return;
  93        }
  94
  95        atomic_dec(&sesInfoAllocCount);
  96        kfree(buf_to_free->serverOS);
  97        kfree(buf_to_free->serverDomain);
  98        kfree(buf_to_free->serverNOS);
  99        if (buf_to_free->password) {
 100                memset(buf_to_free->password, 0, strlen(buf_to_free->password));
 101                kfree(buf_to_free->password);
 102        }
 103        kfree(buf_to_free->domainName);
 104        kfree(buf_to_free);
 105}
 106
 107struct cifsTconInfo *
 108tconInfoAlloc(void)
 109{
 110        struct cifsTconInfo *ret_buf;
 111        ret_buf = kzalloc(sizeof(struct cifsTconInfo), GFP_KERNEL);
 112        if (ret_buf) {
 113                atomic_inc(&tconInfoAllocCount);
 114                ret_buf->tidStatus = CifsNew;
 115                ++ret_buf->tc_count;
 116                INIT_LIST_HEAD(&ret_buf->openFileList);
 117                INIT_LIST_HEAD(&ret_buf->tcon_list);
 118#ifdef CONFIG_CIFS_STATS
 119                spin_lock_init(&ret_buf->stat_lock);
 120#endif
 121        }
 122        return ret_buf;
 123}
 124
 125void
 126tconInfoFree(struct cifsTconInfo *buf_to_free)
 127{
 128        if (buf_to_free == NULL) {
 129                cFYI(1, ("Null buffer passed to tconInfoFree"));
 130                return;
 131        }
 132        atomic_dec(&tconInfoAllocCount);
 133        kfree(buf_to_free->nativeFileSystem);
 134        if (buf_to_free->password) {
 135                memset(buf_to_free->password, 0, strlen(buf_to_free->password));
 136                kfree(buf_to_free->password);
 137        }
 138        kfree(buf_to_free);
 139}
 140
 141struct smb_hdr *
 142cifs_buf_get(void)
 143{
 144        struct smb_hdr *ret_buf = NULL;
 145
 146/* We could use negotiated size instead of max_msgsize -
 147   but it may be more efficient to always alloc same size
 148   albeit slightly larger than necessary and maxbuffersize
 149   defaults to this and can not be bigger */
 150        ret_buf = mempool_alloc(cifs_req_poolp, GFP_NOFS);
 151
 152        /* clear the first few header bytes */
 153        /* for most paths, more is cleared in header_assemble */
 154        if (ret_buf) {
 155                memset(ret_buf, 0, sizeof(struct smb_hdr) + 3);
 156                atomic_inc(&bufAllocCount);
 157#ifdef CONFIG_CIFS_STATS2
 158                atomic_inc(&totBufAllocCount);
 159#endif /* CONFIG_CIFS_STATS2 */
 160        }
 161
 162        return ret_buf;
 163}
 164
 165void
 166cifs_buf_release(void *buf_to_free)
 167{
 168        if (buf_to_free == NULL) {
 169                /* cFYI(1, ("Null buffer passed to cifs_buf_release"));*/
 170                return;
 171        }
 172        mempool_free(buf_to_free, cifs_req_poolp);
 173
 174        atomic_dec(&bufAllocCount);
 175        return;
 176}
 177
 178struct smb_hdr *
 179cifs_small_buf_get(void)
 180{
 181        struct smb_hdr *ret_buf = NULL;
 182
 183/* We could use negotiated size instead of max_msgsize -
 184   but it may be more efficient to always alloc same size
 185   albeit slightly larger than necessary and maxbuffersize
 186   defaults to this and can not be bigger */
 187        ret_buf = mempool_alloc(cifs_sm_req_poolp, GFP_NOFS);
 188        if (ret_buf) {
 189        /* No need to clear memory here, cleared in header assemble */
 190        /*      memset(ret_buf, 0, sizeof(struct smb_hdr) + 27);*/
 191                atomic_inc(&smBufAllocCount);
 192#ifdef CONFIG_CIFS_STATS2
 193                atomic_inc(&totSmBufAllocCount);
 194#endif /* CONFIG_CIFS_STATS2 */
 195
 196        }
 197        return ret_buf;
 198}
 199
 200void
 201cifs_small_buf_release(void *buf_to_free)
 202{
 203
 204        if (buf_to_free == NULL) {
 205                cFYI(1, ("Null buffer passed to cifs_small_buf_release"));
 206                return;
 207        }
 208        mempool_free(buf_to_free, cifs_sm_req_poolp);
 209
 210        atomic_dec(&smBufAllocCount);
 211        return;
 212}
 213
 214/*
 215        Find a free multiplex id (SMB mid). Otherwise there could be
 216        mid collisions which might cause problems, demultiplexing the
 217        wrong response to this request. Multiplex ids could collide if
 218        one of a series requests takes much longer than the others, or
 219        if a very large number of long lived requests (byte range
 220        locks or FindNotify requests) are pending.  No more than
 221        64K-1 requests can be outstanding at one time.  If no
 222        mids are available, return zero.  A future optimization
 223        could make the combination of mids and uid the key we use
 224        to demultiplex on (rather than mid alone).
 225        In addition to the above check, the cifs demultiplex
 226        code already used the command code as a secondary
 227        check of the frame and if signing is negotiated the
 228        response would be discarded if the mid were the same
 229        but the signature was wrong.  Since the mid is not put in the
 230        pending queue until later (when it is about to be dispatched)
 231        we do have to limit the number of outstanding requests
 232        to somewhat less than 64K-1 although it is hard to imagine
 233        so many threads being in the vfs at one time.
 234*/
 235__u16 GetNextMid(struct TCP_Server_Info *server)
 236{
 237        __u16 mid = 0;
 238        __u16 last_mid;
 239        int   collision;
 240
 241        if (server == NULL)
 242                return mid;
 243
 244        spin_lock(&GlobalMid_Lock);
 245        last_mid = server->CurrentMid; /* we do not want to loop forever */
 246        server->CurrentMid++;
 247        /* This nested loop looks more expensive than it is.
 248        In practice the list of pending requests is short,
 249        fewer than 50, and the mids are likely to be unique
 250        on the first pass through the loop unless some request
 251        takes longer than the 64 thousand requests before it
 252        (and it would also have to have been a request that
 253         did not time out) */
 254        while (server->CurrentMid != last_mid) {
 255                struct list_head *tmp;
 256                struct mid_q_entry *mid_entry;
 257
 258                collision = 0;
 259                if (server->CurrentMid == 0)
 260                        server->CurrentMid++;
 261
 262                list_for_each(tmp, &server->pending_mid_q) {
 263                        mid_entry = list_entry(tmp, struct mid_q_entry, qhead);
 264
 265                        if ((mid_entry->mid == server->CurrentMid) &&
 266                            (mid_entry->midState == MID_REQUEST_SUBMITTED)) {
 267                                /* This mid is in use, try a different one */
 268                                collision = 1;
 269                                break;
 270                        }
 271                }
 272                if (collision == 0) {
 273                        mid = server->CurrentMid;
 274                        break;
 275                }
 276                server->CurrentMid++;
 277        }
 278        spin_unlock(&GlobalMid_Lock);
 279        return mid;
 280}
 281
 282/* NB: MID can not be set if treeCon not passed in, in that
 283   case it is responsbility of caller to set the mid */
 284void
 285header_assemble(struct smb_hdr *buffer, char smb_command /* command */ ,
 286                const struct cifsTconInfo *treeCon, int word_count
 287                /* length of fixed section (word count) in two byte units  */)
 288{
 289        struct list_head *temp_item;
 290        struct cifsSesInfo *ses;
 291        char *temp = (char *) buffer;
 292
 293        memset(temp, 0, 256); /* bigger than MAX_CIFS_HDR_SIZE */
 294
 295        buffer->smb_buf_length =
 296            (2 * word_count) + sizeof(struct smb_hdr) -
 297            4 /*  RFC 1001 length field does not count */  +
 298            2 /* for bcc field itself */ ;
 299        /* Note that this is the only network field that has to be converted
 300           to big endian and it is done just before we send it */
 301
 302        buffer->Protocol[0] = 0xFF;
 303        buffer->Protocol[1] = 'S';
 304        buffer->Protocol[2] = 'M';
 305        buffer->Protocol[3] = 'B';
 306        buffer->Command = smb_command;
 307        buffer->Flags = 0x00;   /* case sensitive */
 308        buffer->Flags2 = SMBFLG2_KNOWS_LONG_NAMES;
 309        buffer->Pid = cpu_to_le16((__u16)current->tgid);
 310        buffer->PidHigh = cpu_to_le16((__u16)(current->tgid >> 16));
 311        if (treeCon) {
 312                buffer->Tid = treeCon->tid;
 313                if (treeCon->ses) {
 314                        if (treeCon->ses->capabilities & CAP_UNICODE)
 315                                buffer->Flags2 |= SMBFLG2_UNICODE;
 316                        if (treeCon->ses->capabilities & CAP_STATUS32)
 317                                buffer->Flags2 |= SMBFLG2_ERR_STATUS;
 318
 319                        /* Uid is not converted */
 320                        buffer->Uid = treeCon->ses->Suid;
 321                        buffer->Mid = GetNextMid(treeCon->ses->server);
 322                        if (multiuser_mount != 0) {
 323                /* For the multiuser case, there are few obvious technically  */
 324                /* possible mechanisms to match the local linux user (uid)    */
 325                /* to a valid remote smb user (smb_uid):                      */
 326                /*      1) Query Winbind (or other local pam/nss daemon       */
 327                /*        for userid/password/logon_domain or credential      */
 328                /*      2) Query Winbind for uid to sid to username mapping   */
 329                /*         and see if we have a matching password for existing*/
 330                /*         session for that user perhas getting password by   */
 331                /*         adding a new pam_cifs module that stores passwords */
 332                /*         so that the cifs vfs can get at that for all logged*/
 333                /*         on users                                           */
 334                /*      3) (Which is the mechanism we have chosen)            */
 335                /*         Search through sessions to the same server for a   */
 336                /*         a match on the uid that was passed in on mount     */
 337                /*         with the current processes uid (or euid?) and use  */
 338                /*         that smb uid.   If no existing smb session for     */
 339                /*         that uid found, use the default smb session ie     */
 340                /*         the smb session for the volume mounted which is    */
 341                /*         the same as would be used if the multiuser mount   */
 342                /*         flag were disabled.  */
 343
 344                /*  BB Add support for establishing new tCon and SMB Session  */
 345                /*      with userid/password pairs found on the smb session   */
 346                /*      for other target tcp/ip addresses               BB    */
 347                                if (current_fsuid() != treeCon->ses->linux_uid) {
 348                                        cFYI(1, ("Multiuser mode and UID "
 349                                                 "did not match tcon uid"));
 350                                        read_lock(&cifs_tcp_ses_lock);
 351                                        list_for_each(temp_item, &treeCon->ses->server->smb_ses_list) {
 352                                                ses = list_entry(temp_item, struct cifsSesInfo, smb_ses_list);
 353                                                if (ses->linux_uid == current_fsuid()) {
 354                                                        if (ses->server == treeCon->ses->server) {
 355                                                                cFYI(1, ("found matching uid substitute right smb_uid"));
 356                                                                buffer->Uid = ses->Suid;
 357                                                                break;
 358                                                        } else {
 359                                /* BB eventually call cifs_setup_session here */
 360                                                                cFYI(1, ("local UID found but no smb sess with this server exists"));
 361                                                        }
 362                                                }
 363                                        }
 364                                        read_unlock(&cifs_tcp_ses_lock);
 365                                }
 366                        }
 367                }
 368                if (treeCon->Flags & SMB_SHARE_IS_IN_DFS)
 369                        buffer->Flags2 |= SMBFLG2_DFS;
 370                if (treeCon->nocase)
 371                        buffer->Flags  |= SMBFLG_CASELESS;
 372                if ((treeCon->ses) && (treeCon->ses->server))
 373                        if (treeCon->ses->server->secMode &
 374                          (SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED))
 375                                buffer->Flags2 |= SMBFLG2_SECURITY_SIGNATURE;
 376        }
 377
 378/*  endian conversion of flags is now done just before sending */
 379        buffer->WordCount = (char) word_count;
 380        return;
 381}
 382
 383static int
 384checkSMBhdr(struct smb_hdr *smb, __u16 mid)
 385{
 386        /* Make sure that this really is an SMB, that it is a response,
 387           and that the message ids match */
 388        if ((*(__le32 *) smb->Protocol == cpu_to_le32(0x424d53ff)) &&
 389                (mid == smb->Mid)) {
 390                if (smb->Flags & SMBFLG_RESPONSE)
 391                        return 0;
 392                else {
 393                /* only one valid case where server sends us request */
 394                        if (smb->Command == SMB_COM_LOCKING_ANDX)
 395                                return 0;
 396                        else
 397                                cERROR(1, ("Received Request not response"));
 398                }
 399        } else { /* bad signature or mid */
 400                if (*(__le32 *) smb->Protocol != cpu_to_le32(0x424d53ff))
 401                        cERROR(1,
 402                               ("Bad protocol string signature header %x",
 403                                *(unsigned int *) smb->Protocol));
 404                if (mid != smb->Mid)
 405                        cERROR(1, ("Mids do not match"));
 406        }
 407        cERROR(1, ("bad smb detected. The Mid=%d", smb->Mid));
 408        return 1;
 409}
 410
 411int
 412checkSMB(struct smb_hdr *smb, __u16 mid, unsigned int length)
 413{
 414        __u32 len = smb->smb_buf_length;
 415        __u32 clc_len;  /* calculated length */
 416        cFYI(0, ("checkSMB Length: 0x%x, smb_buf_length: 0x%x", length, len));
 417
 418        if (length < 2 + sizeof(struct smb_hdr)) {
 419                if ((length >= sizeof(struct smb_hdr) - 1)
 420                            && (smb->Status.CifsError != 0)) {
 421                        smb->WordCount = 0;
 422                        /* some error cases do not return wct and bcc */
 423                        return 0;
 424                } else if ((length == sizeof(struct smb_hdr) + 1) &&
 425                                (smb->WordCount == 0)) {
 426                        char *tmp = (char *)smb;
 427                        /* Need to work around a bug in two servers here */
 428                        /* First, check if the part of bcc they sent was zero */
 429                        if (tmp[sizeof(struct smb_hdr)] == 0) {
 430                                /* some servers return only half of bcc
 431                                 * on simple responses (wct, bcc both zero)
 432                                 * in particular have seen this on
 433                                 * ulogoffX and FindClose. This leaves
 434                                 * one byte of bcc potentially unitialized
 435                                 */
 436                                /* zero rest of bcc */
 437                                tmp[sizeof(struct smb_hdr)+1] = 0;
 438                                return 0;
 439                        }
 440                        cERROR(1, ("rcvd invalid byte count (bcc)"));
 441                } else {
 442                        cERROR(1, ("Length less than smb header size"));
 443                }
 444                return 1;
 445        }
 446        if (len > CIFSMaxBufSize + MAX_CIFS_HDR_SIZE - 4) {
 447                cERROR(1, ("smb length greater than MaxBufSize, mid=%d",
 448                                   smb->Mid));
 449                return 1;
 450        }
 451
 452        if (checkSMBhdr(smb, mid))
 453                return 1;
 454        clc_len = smbCalcSize_LE(smb);
 455
 456        if (4 + len != length) {
 457                cERROR(1, ("Length read does not match RFC1001 length %d",
 458                           len));
 459                return 1;
 460        }
 461
 462        if (4 + len != clc_len) {
 463                /* check if bcc wrapped around for large read responses */
 464                if ((len > 64 * 1024) && (len > clc_len)) {
 465                        /* check if lengths match mod 64K */
 466                        if (((4 + len) & 0xFFFF) == (clc_len & 0xFFFF))
 467                                return 0; /* bcc wrapped */
 468                }
 469                cFYI(1, ("Calculated size %d vs length %d mismatch for mid %d",
 470                                clc_len, 4 + len, smb->Mid));
 471                /* Windows XP can return a few bytes too much, presumably
 472                an illegal pad, at the end of byte range lock responses
 473                so we allow for that three byte pad, as long as actual
 474                received length is as long or longer than calculated length */
 475                /* We have now had to extend this more, since there is a
 476                case in which it needs to be bigger still to handle a
 477                malformed response to transact2 findfirst from WinXP when
 478                access denied is returned and thus bcc and wct are zero
 479                but server says length is 0x21 bytes too long as if the server
 480                forget to reset the smb rfc1001 length when it reset the
 481                wct and bcc to minimum size and drop the t2 parms and data */
 482                if ((4+len > clc_len) && (len <= clc_len + 512))
 483                        return 0;
 484                else {
 485                        cERROR(1, ("RFC1001 size %d bigger than SMB for Mid=%d",
 486                                        len, smb->Mid));
 487                        return 1;
 488                }
 489        }
 490        return 0;
 491}
 492
 493bool
 494is_valid_oplock_break(struct smb_hdr *buf, struct TCP_Server_Info *srv)
 495{
 496        struct smb_com_lock_req *pSMB = (struct smb_com_lock_req *)buf;
 497        struct list_head *tmp, *tmp1, *tmp2;
 498        struct cifsSesInfo *ses;
 499        struct cifsTconInfo *tcon;
 500        struct cifsInodeInfo *pCifsInode;
 501        struct cifsFileInfo *netfile;
 502        int rc;
 503
 504        cFYI(1, ("Checking for oplock break or dnotify response"));
 505        if ((pSMB->hdr.Command == SMB_COM_NT_TRANSACT) &&
 506           (pSMB->hdr.Flags & SMBFLG_RESPONSE)) {
 507                struct smb_com_transaction_change_notify_rsp *pSMBr =
 508                        (struct smb_com_transaction_change_notify_rsp *)buf;
 509                struct file_notify_information *pnotify;
 510                __u32 data_offset = 0;
 511                if (pSMBr->ByteCount > sizeof(struct file_notify_information)) {
 512                        data_offset = le32_to_cpu(pSMBr->DataOffset);
 513
 514                        pnotify = (struct file_notify_information *)
 515                                ((char *)&pSMBr->hdr.Protocol + data_offset);
 516                        cFYI(1, ("dnotify on %s Action: 0x%x",
 517                                 pnotify->FileName, pnotify->Action));
 518                        /*   cifs_dump_mem("Rcvd notify Data: ",buf,
 519                                sizeof(struct smb_hdr)+60); */
 520                        return true;
 521                }
 522                if (pSMBr->hdr.Status.CifsError) {
 523                        cFYI(1, ("notify err 0x%d",
 524                                pSMBr->hdr.Status.CifsError));
 525                        return true;
 526                }
 527                return false;
 528        }
 529        if (pSMB->hdr.Command != SMB_COM_LOCKING_ANDX)
 530                return false;
 531        if (pSMB->hdr.Flags & SMBFLG_RESPONSE) {
 532                /* no sense logging error on invalid handle on oplock
 533                   break - harmless race between close request and oplock
 534                   break response is expected from time to time writing out
 535                   large dirty files cached on the client */
 536                if ((NT_STATUS_INVALID_HANDLE) ==
 537                   le32_to_cpu(pSMB->hdr.Status.CifsError)) {
 538                        cFYI(1, ("invalid handle on oplock break"));
 539                        return true;
 540                } else if (ERRbadfid ==
 541                   le16_to_cpu(pSMB->hdr.Status.DosError.Error)) {
 542                        return true;
 543                } else {
 544                        return false; /* on valid oplock brk we get "request" */
 545                }
 546        }
 547        if (pSMB->hdr.WordCount != 8)
 548                return false;
 549
 550        cFYI(1, ("oplock type 0x%d level 0x%d",
 551                 pSMB->LockType, pSMB->OplockLevel));
 552        if (!(pSMB->LockType & LOCKING_ANDX_OPLOCK_RELEASE))
 553                return false;
 554
 555        /* look up tcon based on tid & uid */
 556        read_lock(&cifs_tcp_ses_lock);
 557        list_for_each(tmp, &srv->smb_ses_list) {
 558                ses = list_entry(tmp, struct cifsSesInfo, smb_ses_list);
 559                list_for_each(tmp1, &ses->tcon_list) {
 560                        tcon = list_entry(tmp1, struct cifsTconInfo, tcon_list);
 561                        if (tcon->tid != buf->Tid)
 562                                continue;
 563
 564                        cifs_stats_inc(&tcon->num_oplock_brks);
 565                        read_lock(&GlobalSMBSeslock);
 566                        list_for_each(tmp2, &tcon->openFileList) {
 567                                netfile = list_entry(tmp2, struct cifsFileInfo,
 568                                                     tlist);
 569                                if (pSMB->Fid != netfile->netfid)
 570                                        continue;
 571
 572                                /*
 573                                 * don't do anything if file is about to be
 574                                 * closed anyway.
 575                                 */
 576                                if (netfile->closePend) {
 577                                        read_unlock(&GlobalSMBSeslock);
 578                                        read_unlock(&cifs_tcp_ses_lock);
 579                                        return true;
 580                                }
 581
 582                                cFYI(1, ("file id match, oplock break"));
 583                                pCifsInode = CIFS_I(netfile->pInode);
 584                                pCifsInode->clientCanCacheAll = false;
 585                                if (pSMB->OplockLevel == 0)
 586                                        pCifsInode->clientCanCacheRead = false;
 587                                rc = slow_work_enqueue(&netfile->oplock_break);
 588                                if (rc) {
 589                                        cERROR(1, ("failed to enqueue oplock "
 590                                                   "break: %d\n", rc));
 591                                } else {
 592                                        netfile->oplock_break_cancelled = false;
 593                                }
 594                                read_unlock(&GlobalSMBSeslock);
 595                                read_unlock(&cifs_tcp_ses_lock);
 596                                return true;
 597                        }
 598                        read_unlock(&GlobalSMBSeslock);
 599                        read_unlock(&cifs_tcp_ses_lock);
 600                        cFYI(1, ("No matching file for oplock break"));
 601                        return true;
 602                }
 603        }
 604        read_unlock(&cifs_tcp_ses_lock);
 605        cFYI(1, ("Can not process oplock break for non-existent connection"));
 606        return true;
 607}
 608
 609void
 610dump_smb(struct smb_hdr *smb_buf, int smb_buf_length)
 611{
 612        int i, j;
 613        char debug_line[17];
 614        unsigned char *buffer;
 615
 616        if (traceSMB == 0)
 617                return;
 618
 619        buffer = (unsigned char *) smb_buf;
 620        for (i = 0, j = 0; i < smb_buf_length; i++, j++) {
 621                if (i % 8 == 0) {
 622                        /* have reached the beginning of line */
 623                        printk(KERN_DEBUG "| ");
 624                        j = 0;
 625                }
 626                printk("%0#4x ", buffer[i]);
 627                debug_line[2 * j] = ' ';
 628                if (isprint(buffer[i]))
 629                        debug_line[1 + (2 * j)] = buffer[i];
 630                else
 631                        debug_line[1 + (2 * j)] = '_';
 632
 633                if (i % 8 == 7) {
 634                        /* reached end of line, time to print ascii */
 635                        debug_line[16] = 0;
 636                        printk(" | %s\n", debug_line);
 637                }
 638        }
 639        for (; j < 8; j++) {
 640                printk("     ");
 641                debug_line[2 * j] = ' ';
 642                debug_line[1 + (2 * j)] = ' ';
 643        }
 644        printk(" | %s\n", debug_line);
 645        return;
 646}
 647
 648/* Convert 16 bit Unicode pathname to wire format from string in current code
 649   page.  Conversion may involve remapping up the seven characters that are
 650   only legal in POSIX-like OS (if they are present in the string). Path
 651   names are little endian 16 bit Unicode on the wire */
 652int
 653cifsConvertToUCS(__le16 *target, const char *source, int maxlen,
 654                 const struct nls_table *cp, int mapChars)
 655{
 656        int i, j, charlen;
 657        int len_remaining = maxlen;
 658        char src_char;
 659        __u16 temp;
 660
 661        if (!mapChars)
 662                return cifs_strtoUCS(target, source, PATH_MAX, cp);
 663
 664        for (i = 0, j = 0; i < maxlen; j++) {
 665                src_char = source[i];
 666                switch (src_char) {
 667                        case 0:
 668                                target[j] = 0;
 669                                goto ctoUCS_out;
 670                        case ':':
 671                                target[j] = cpu_to_le16(UNI_COLON);
 672                                break;
 673                        case '*':
 674                                target[j] = cpu_to_le16(UNI_ASTERIK);
 675                                break;
 676                        case '?':
 677                                target[j] = cpu_to_le16(UNI_QUESTION);
 678                                break;
 679                        case '<':
 680                                target[j] = cpu_to_le16(UNI_LESSTHAN);
 681                                break;
 682                        case '>':
 683                                target[j] = cpu_to_le16(UNI_GRTRTHAN);
 684                                break;
 685                        case '|':
 686                                target[j] = cpu_to_le16(UNI_PIPE);
 687                                break;
 688                        /* BB We can not handle remapping slash until
 689                           all the calls to build_path_from_dentry
 690                           are modified, as they use slash as separator BB */
 691                        /* case '\\':
 692                                target[j] = cpu_to_le16(UNI_SLASH);
 693                                break;*/
 694                        default:
 695                                charlen = cp->char2uni(source+i,
 696                                        len_remaining, &temp);
 697                                /* if no match, use question mark, which
 698                                at least in some cases servers as wild card */
 699                                if (charlen < 1) {
 700                                        target[j] = cpu_to_le16(0x003f);
 701                                        charlen = 1;
 702                                } else
 703                                        target[j] = cpu_to_le16(temp);
 704                                len_remaining -= charlen;
 705                                /* character may take more than one byte in the
 706                                   the source string, but will take exactly two
 707                                   bytes in the target string */
 708                                i += charlen;
 709                                continue;
 710                }
 711                i++; /* move to next char in source string */
 712                len_remaining--;
 713        }
 714
 715ctoUCS_out:
 716        return i;
 717}
 718
 719void
 720cifs_autodisable_serverino(struct cifs_sb_info *cifs_sb)
 721{
 722        if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SERVER_INUM) {
 723                cifs_sb->mnt_cifs_flags &= ~CIFS_MOUNT_SERVER_INUM;
 724                cERROR(1, ("Autodisabling the use of server inode numbers on "
 725                           "%s. This server doesn't seem to support them "
 726                           "properly. Hardlinks will not be recognized on this "
 727                           "mount. Consider mounting with the \"noserverino\" "
 728                           "option to silence this message.",
 729                           cifs_sb->tcon->treeName));
 730        }
 731}
 732