~ubuntu-branches/ubuntu/quantal/linux-linaro-mx51/quantal

« back to all changes in this revision

Viewing changes to fs/cifs/cifssmb.c

  • Committer: Package Import Robot
  • Author(s): John Rigby, John Rigby
  • Date: 2011-09-26 10:44:23 UTC
  • Revision ID: package-import@ubuntu.com-20110926104423-3o58a3c1bj7x00rs
Tags: 3.0.0-1007.9
[ John Rigby ]

Enable crypto modules and remove crypto-modules from
exclude-module files
LP: #826021

Show diffs side-by-side

added added

removed removed

Lines of Context:
32
32
#include <linux/vfs.h>
33
33
#include <linux/slab.h>
34
34
#include <linux/posix_acl_xattr.h>
 
35
#include <linux/pagemap.h>
35
36
#include <asm/uaccess.h>
36
37
#include "cifspdu.h"
37
38
#include "cifsglob.h"
84
85
 
85
86
/* Mark as invalid, all open files on tree connections since they
86
87
   were closed when session to server was lost */
87
 
static void mark_open_files_invalid(struct cifsTconInfo *pTcon)
 
88
static void mark_open_files_invalid(struct cifs_tcon *pTcon)
88
89
{
89
90
        struct cifsFileInfo *open_file = NULL;
90
91
        struct list_head *tmp;
104
105
 
105
106
/* reconnect the socket, tcon, and smb session if needed */
106
107
static int
107
 
cifs_reconnect_tcon(struct cifsTconInfo *tcon, int smb_command)
 
108
cifs_reconnect_tcon(struct cifs_tcon *tcon, int smb_command)
108
109
{
109
110
        int rc = 0;
110
 
        struct cifsSesInfo *ses;
 
111
        struct cifs_ses *ses;
111
112
        struct TCP_Server_Info *server;
112
113
        struct nls_table *nls_codepage;
113
114
 
226
227
   SMB information in the SMB header.  If the return code is zero, this
227
228
   function must have filled in request_buf pointer */
228
229
static int
229
 
small_smb_init(int smb_command, int wct, struct cifsTconInfo *tcon,
 
230
small_smb_init(int smb_command, int wct, struct cifs_tcon *tcon,
230
231
                void **request_buf)
231
232
{
232
233
        int rc;
252
253
 
253
254
int
254
255
small_smb_init_no_tc(const int smb_command, const int wct,
255
 
                     struct cifsSesInfo *ses, void **request_buf)
 
256
                     struct cifs_ses *ses, void **request_buf)
256
257
{
257
258
        int rc;
258
259
        struct smb_hdr *buffer;
278
279
 
279
280
/* If the return code is zero, this function must fill in request_buf pointer */
280
281
static int
281
 
__smb_init(int smb_command, int wct, struct cifsTconInfo *tcon,
 
282
__smb_init(int smb_command, int wct, struct cifs_tcon *tcon,
282
283
                        void **request_buf, void **response_buf)
283
284
{
284
285
        *request_buf = cifs_buf_get();
304
305
 
305
306
/* If the return code is zero, this function must fill in request_buf pointer */
306
307
static int
307
 
smb_init(int smb_command, int wct, struct cifsTconInfo *tcon,
 
308
smb_init(int smb_command, int wct, struct cifs_tcon *tcon,
308
309
         void **request_buf, void **response_buf)
309
310
{
310
311
        int rc;
317
318
}
318
319
 
319
320
static int
320
 
smb_init_no_reconnect(int smb_command, int wct, struct cifsTconInfo *tcon,
 
321
smb_init_no_reconnect(int smb_command, int wct, struct cifs_tcon *tcon,
321
322
                        void **request_buf, void **response_buf)
322
323
{
323
324
        if (tcon->ses->need_reconnect || tcon->need_reconnect)
339
340
            get_unaligned_le16(&pSMB->t2_rsp.DataOffset) > 1024)
340
341
                goto vt2_err;
341
342
 
342
 
        /* check that bcc is at least as big as parms + data */
343
 
        /* check that bcc is less than negotiated smb buffer */
344
343
        total_size = get_unaligned_le16(&pSMB->t2_rsp.ParameterCount);
345
344
        if (total_size >= 512)
346
345
                goto vt2_err;
347
346
 
 
347
        /* check that bcc is at least as big as parms + data, and that it is
 
348
         * less than negotiated smb buffer
 
349
         */
348
350
        total_size += get_unaligned_le16(&pSMB->t2_rsp.DataCount);
349
351
        if (total_size > get_bcc(&pSMB->hdr) ||
350
352
            total_size >= CIFSMaxBufSize + MAX_CIFS_HDR_SIZE)
357
359
        return -EINVAL;
358
360
}
359
361
 
 
362
static inline void inc_rfc1001_len(void *pSMB, int count)
 
363
{
 
364
        struct smb_hdr *hdr = (struct smb_hdr *)pSMB;
 
365
 
 
366
        be32_add_cpu(&hdr->smb_buf_length, count);
 
367
}
 
368
 
360
369
int
361
 
CIFSSMBNegotiate(unsigned int xid, struct cifsSesInfo *ses)
 
370
CIFSSMBNegotiate(unsigned int xid, struct cifs_ses *ses)
362
371
{
363
372
        NEGOTIATE_REQ *pSMB;
364
373
        NEGOTIATE_RSP *pSMBr;
409
418
                count += strlen(protocols[i].name) + 1;
410
419
                /* null at end of source and target buffers anyway */
411
420
        }
412
 
        pSMB->hdr.smb_buf_length += count;
 
421
        inc_rfc1001_len(pSMB, count);
413
422
        pSMB->ByteCount = cpu_to_le16(count);
414
423
 
415
424
        rc = SendReceive(xid, ses, (struct smb_hdr *) pSMB,
442
451
                        rc = -EOPNOTSUPP;
443
452
                        goto neg_err_exit;
444
453
                }
445
 
                server->secMode = (__u8)le16_to_cpu(rsp->SecurityMode);
 
454
                server->sec_mode = (__u8)le16_to_cpu(rsp->SecurityMode);
446
455
                server->maxReq = le16_to_cpu(rsp->MaxMpxCount);
447
456
                server->maxBuf = min((__u32)le16_to_cpu(rsp->MaxBufSize),
448
457
                                (__u32)CIFSMaxBufSize + MAX_CIFS_HDR_SIZE);
496
505
                                cpu_to_le16(CIFS_CRYPTO_KEY_SIZE)) {
497
506
                        memcpy(ses->server->cryptkey, rsp->EncryptionKey,
498
507
                                CIFS_CRYPTO_KEY_SIZE);
499
 
                } else if (server->secMode & SECMODE_PW_ENCRYPT) {
 
508
                } else if (server->sec_mode & SECMODE_PW_ENCRYPT) {
500
509
                        rc = -EIO; /* need cryptkey unless plain text */
501
510
                        goto neg_err_exit;
502
511
                }
518
527
                goto neg_err_exit;
519
528
        }
520
529
        /* else wct == 17 NTLM */
521
 
        server->secMode = pSMBr->SecurityMode;
522
 
        if ((server->secMode & SECMODE_USER) == 0)
 
530
        server->sec_mode = pSMBr->SecurityMode;
 
531
        if ((server->sec_mode & SECMODE_USER) == 0)
523
532
                cFYI(1, "share mode security");
524
533
 
525
 
        if ((server->secMode & SECMODE_PW_ENCRYPT) == 0)
 
534
        if ((server->sec_mode & SECMODE_PW_ENCRYPT) == 0)
526
535
#ifdef CONFIG_CIFS_WEAK_PW_HASH
527
536
                if ((secFlags & CIFSSEC_MAY_PLNTXT) == 0)
528
537
#endif /* CIFS_WEAK_PW_HASH */
541
550
                server->secType = RawNTLMSSP;
542
551
        else if (secFlags & CIFSSEC_MAY_LANMAN)
543
552
                server->secType = LANMAN;
544
 
/* #ifdef CONFIG_CIFS_EXPERIMENTAL
545
 
        else if (secFlags & CIFSSEC_MAY_PLNTXT)
546
 
                server->secType = ??
547
 
#endif */
548
553
        else {
549
554
                rc = -EOPNOTSUPP;
550
555
                cERROR(1, "Invalid security type");
566
571
        if (pSMBr->EncryptionKeyLength == CIFS_CRYPTO_KEY_SIZE) {
567
572
                memcpy(ses->server->cryptkey, pSMBr->u.EncryptionKey,
568
573
                       CIFS_CRYPTO_KEY_SIZE);
569
 
        } else if ((pSMBr->hdr.Flags2 & SMBFLG2_EXT_SEC)
570
 
                        && (pSMBr->EncryptionKeyLength == 0)) {
 
574
        } else if ((pSMBr->hdr.Flags2 & SMBFLG2_EXT_SEC ||
 
575
                        server->capabilities & CAP_EXTENDED_SECURITY) &&
 
576
                                (pSMBr->EncryptionKeyLength == 0)) {
571
577
                /* decode security blob */
572
 
        } else if (server->secMode & SECMODE_PW_ENCRYPT) {
573
 
                rc = -EIO; /* no crypt key only if plain text pwd */
574
 
                goto neg_err_exit;
575
 
        }
576
 
 
577
 
        /* BB might be helpful to save off the domain of server here */
578
 
 
579
 
        if ((pSMBr->hdr.Flags2 & SMBFLG2_EXT_SEC) &&
580
 
                (server->capabilities & CAP_EXTENDED_SECURITY)) {
581
 
                count = pSMBr->ByteCount;
 
578
                count = get_bcc(&pSMBr->hdr);
582
579
                if (count < 16) {
583
580
                        rc = -EIO;
584
581
                        goto neg_err_exit;
620
617
                        } else
621
618
                                        rc = -EOPNOTSUPP;
622
619
                }
 
620
        } else if (server->sec_mode & SECMODE_PW_ENCRYPT) {
 
621
                rc = -EIO; /* no crypt key only if plain text pwd */
 
622
                goto neg_err_exit;
623
623
        } else
624
624
                server->capabilities &= ~CAP_EXTENDED_SECURITY;
625
625
 
630
630
                /* MUST_SIGN already includes the MAY_SIGN FLAG
631
631
                   so if this is zero it means that signing is disabled */
632
632
                cFYI(1, "Signing disabled");
633
 
                if (server->secMode & SECMODE_SIGN_REQUIRED) {
 
633
                if (server->sec_mode & SECMODE_SIGN_REQUIRED) {
634
634
                        cERROR(1, "Server requires "
635
635
                                   "packet signing to be enabled in "
636
636
                                   "/proc/fs/cifs/SecurityFlags.");
637
637
                        rc = -EOPNOTSUPP;
638
638
                }
639
 
                server->secMode &=
 
639
                server->sec_mode &=
640
640
                        ~(SECMODE_SIGN_ENABLED | SECMODE_SIGN_REQUIRED);
641
641
        } else if ((secFlags & CIFSSEC_MUST_SIGN) == CIFSSEC_MUST_SIGN) {
642
642
                /* signing required */
643
643
                cFYI(1, "Must sign - secFlags 0x%x", secFlags);
644
 
                if ((server->secMode &
 
644
                if ((server->sec_mode &
645
645
                        (SECMODE_SIGN_ENABLED | SECMODE_SIGN_REQUIRED)) == 0) {
646
646
                        cERROR(1, "signing required but server lacks support");
647
647
                        rc = -EOPNOTSUPP;
648
648
                } else
649
 
                        server->secMode |= SECMODE_SIGN_REQUIRED;
 
649
                        server->sec_mode |= SECMODE_SIGN_REQUIRED;
650
650
        } else {
651
651
                /* signing optional ie CIFSSEC_MAY_SIGN */
652
 
                if ((server->secMode & SECMODE_SIGN_REQUIRED) == 0)
653
 
                        server->secMode &=
 
652
                if ((server->sec_mode & SECMODE_SIGN_REQUIRED) == 0)
 
653
                        server->sec_mode &=
654
654
                                ~(SECMODE_SIGN_ENABLED | SECMODE_SIGN_REQUIRED);
655
655
        }
656
656
 
662
662
}
663
663
 
664
664
int
665
 
CIFSSMBTDis(const int xid, struct cifsTconInfo *tcon)
 
665
CIFSSMBTDis(const int xid, struct cifs_tcon *tcon)
666
666
{
667
667
        struct smb_hdr *smb_buffer;
668
668
        int rc = 0;
721
721
{
722
722
        ECHO_REQ *smb;
723
723
        int rc = 0;
 
724
        struct kvec iov;
724
725
 
725
726
        cFYI(1, "In echo request");
726
727
 
732
733
        smb->hdr.Tid = 0xffff;
733
734
        smb->hdr.WordCount = 1;
734
735
        put_unaligned_le16(1, &smb->EchoCount);
735
 
        put_bcc_le(1, &smb->hdr);
 
736
        put_bcc(1, &smb->hdr);
736
737
        smb->Data[0] = 'a';
737
 
        smb->hdr.smb_buf_length += 3;
 
738
        inc_rfc1001_len(smb, 3);
 
739
        iov.iov_base = smb;
 
740
        iov.iov_len = be32_to_cpu(smb->hdr.smb_buf_length) + 4;
738
741
 
739
 
        rc = cifs_call_async(server, (struct smb_hdr *)smb,
740
 
                                cifs_echo_callback, server);
 
742
        rc = cifs_call_async(server, &iov, 1, cifs_echo_callback, server, true);
741
743
        if (rc)
742
744
                cFYI(1, "Echo request failed: %d", rc);
743
745
 
747
749
}
748
750
 
749
751
int
750
 
CIFSSMBLogoff(const int xid, struct cifsSesInfo *ses)
 
752
CIFSSMBLogoff(const int xid, struct cifs_ses *ses)
751
753
{
752
754
        LOGOFF_ANDX_REQ *pSMB;
753
755
        int rc = 0;
774
776
 
775
777
        pSMB->hdr.Mid = GetNextMid(ses->server);
776
778
 
777
 
        if (ses->server->secMode &
 
779
        if (ses->server->sec_mode &
778
780
                   (SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED))
779
781
                        pSMB->hdr.Flags2 |= SMBFLG2_SECURITY_SIGNATURE;
780
782
 
794
796
}
795
797
 
796
798
int
797
 
CIFSPOSIXDelFile(const int xid, struct cifsTconInfo *tcon, const char *fileName,
 
799
CIFSPOSIXDelFile(const int xid, struct cifs_tcon *tcon, const char *fileName,
798
800
                 __u16 type, const struct nls_table *nls_codepage, int remap)
799
801
{
800
802
        TRANSACTION2_SPI_REQ *pSMB = NULL;
852
854
        pSMB->TotalParameterCount = pSMB->ParameterCount;
853
855
        pSMB->InformationLevel = cpu_to_le16(SMB_POSIX_UNLINK);
854
856
        pSMB->Reserved4 = 0;
855
 
        pSMB->hdr.smb_buf_length += byte_count;
 
857
        inc_rfc1001_len(pSMB, byte_count);
856
858
        pSMB->ByteCount = cpu_to_le16(byte_count);
857
859
        rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
858
860
                         (struct smb_hdr *) pSMBr, &bytes_returned, 0);
869
871
}
870
872
 
871
873
int
872
 
CIFSSMBDelFile(const int xid, struct cifsTconInfo *tcon, const char *fileName,
 
874
CIFSSMBDelFile(const int xid, struct cifs_tcon *tcon, const char *fileName,
873
875
               const struct nls_table *nls_codepage, int remap)
874
876
{
875
877
        DELETE_FILE_REQ *pSMB = NULL;
898
900
        pSMB->SearchAttributes =
899
901
            cpu_to_le16(ATTR_READONLY | ATTR_HIDDEN | ATTR_SYSTEM);
900
902
        pSMB->BufferFormat = 0x04;
901
 
        pSMB->hdr.smb_buf_length += name_len + 1;
 
903
        inc_rfc1001_len(pSMB, name_len + 1);
902
904
        pSMB->ByteCount = cpu_to_le16(name_len + 1);
903
905
        rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
904
906
                         (struct smb_hdr *) pSMBr, &bytes_returned, 0);
914
916
}
915
917
 
916
918
int
917
 
CIFSSMBRmDir(const int xid, struct cifsTconInfo *tcon, const char *dirName,
 
919
CIFSSMBRmDir(const int xid, struct cifs_tcon *tcon, const char *dirName,
918
920
             const struct nls_table *nls_codepage, int remap)
919
921
{
920
922
        DELETE_DIRECTORY_REQ *pSMB = NULL;
942
944
        }
943
945
 
944
946
        pSMB->BufferFormat = 0x04;
945
 
        pSMB->hdr.smb_buf_length += name_len + 1;
 
947
        inc_rfc1001_len(pSMB, name_len + 1);
946
948
        pSMB->ByteCount = cpu_to_le16(name_len + 1);
947
949
        rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
948
950
                         (struct smb_hdr *) pSMBr, &bytes_returned, 0);
957
959
}
958
960
 
959
961
int
960
 
CIFSSMBMkDir(const int xid, struct cifsTconInfo *tcon,
 
962
CIFSSMBMkDir(const int xid, struct cifs_tcon *tcon,
961
963
             const char *name, const struct nls_table *nls_codepage, int remap)
962
964
{
963
965
        int rc = 0;
985
987
        }
986
988
 
987
989
        pSMB->BufferFormat = 0x04;
988
 
        pSMB->hdr.smb_buf_length += name_len + 1;
 
990
        inc_rfc1001_len(pSMB, name_len + 1);
989
991
        pSMB->ByteCount = cpu_to_le16(name_len + 1);
990
992
        rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
991
993
                         (struct smb_hdr *) pSMBr, &bytes_returned, 0);
1000
1002
}
1001
1003
 
1002
1004
int
1003
 
CIFSPOSIXCreate(const int xid, struct cifsTconInfo *tcon, __u32 posix_flags,
 
1005
CIFSPOSIXCreate(const int xid, struct cifs_tcon *tcon, __u32 posix_flags,
1004
1006
                __u64 mode, __u16 *netfid, FILE_UNIX_BASIC_INFO *pRetData,
1005
1007
                __u32 *pOplock, const char *name,
1006
1008
                const struct nls_table *nls_codepage, int remap)
1063
1065
        pSMB->TotalParameterCount = pSMB->ParameterCount;
1064
1066
        pSMB->InformationLevel = cpu_to_le16(SMB_POSIX_OPEN);
1065
1067
        pSMB->Reserved4 = 0;
1066
 
        pSMB->hdr.smb_buf_length += byte_count;
 
1068
        inc_rfc1001_len(pSMB, byte_count);
1067
1069
        pSMB->ByteCount = cpu_to_le16(byte_count);
1068
1070
        rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
1069
1071
                         (struct smb_hdr *) pSMBr, &bytes_returned, 0);
1075
1077
        cFYI(1, "copying inode info");
1076
1078
        rc = validate_t2((struct smb_t2_rsp *)pSMBr);
1077
1079
 
1078
 
        if (rc || (pSMBr->ByteCount < sizeof(OPEN_PSX_RSP))) {
 
1080
        if (rc || get_bcc(&pSMBr->hdr) < sizeof(OPEN_PSX_RSP)) {
1079
1081
                rc = -EIO;      /* bad smb */
1080
1082
                goto psx_create_err;
1081
1083
        }
1096
1098
                pRetData->Type = cpu_to_le32(-1); /* unknown */
1097
1099
                cFYI(DBG2, "unknown type");
1098
1100
        } else {
1099
 
                if (pSMBr->ByteCount < sizeof(OPEN_PSX_RSP)
 
1101
                if (get_bcc(&pSMBr->hdr) < sizeof(OPEN_PSX_RSP)
1100
1102
                                        + sizeof(FILE_UNIX_BASIC_INFO)) {
1101
1103
                        cERROR(1, "Open response data too small");
1102
1104
                        pRetData->Type = cpu_to_le32(-1);
1166
1168
}
1167
1169
 
1168
1170
int
1169
 
SMBLegacyOpen(const int xid, struct cifsTconInfo *tcon,
 
1171
SMBLegacyOpen(const int xid, struct cifs_tcon *tcon,
1170
1172
            const char *fileName, const int openDisposition,
1171
1173
            const int access_flags, const int create_options, __u16 *netfid,
1172
1174
            int *pOplock, FILE_ALL_INFO *pfile_info,
1228
1230
        pSMB->Sattr = cpu_to_le16(ATTR_HIDDEN | ATTR_SYSTEM | ATTR_DIRECTORY);
1229
1231
        pSMB->OpenFunction = cpu_to_le16(convert_disposition(openDisposition));
1230
1232
        count += name_len;
1231
 
        pSMB->hdr.smb_buf_length += count;
 
1233
        inc_rfc1001_len(pSMB, count);
1232
1234
 
1233
1235
        pSMB->ByteCount = cpu_to_le16(count);
1234
1236
        /* long_op set to 1 to allow for oplock break timeouts */
1273
1275
}
1274
1276
 
1275
1277
int
1276
 
CIFSSMBOpen(const int xid, struct cifsTconInfo *tcon,
 
1278
CIFSSMBOpen(const int xid, struct cifs_tcon *tcon,
1277
1279
            const char *fileName, const int openDisposition,
1278
1280
            const int access_flags, const int create_options, __u16 *netfid,
1279
1281
            int *pOplock, FILE_ALL_INFO *pfile_info,
1341
1343
            SECURITY_CONTEXT_TRACKING | SECURITY_EFFECTIVE_ONLY;
1342
1344
 
1343
1345
        count += name_len;
1344
 
        pSMB->hdr.smb_buf_length += count;
 
1346
        inc_rfc1001_len(pSMB, count);
1345
1347
 
1346
1348
        pSMB->ByteCount = cpu_to_le16(count);
1347
1349
        /* long_op set to 1 to allow for oplock break timeouts */
1375
1377
}
1376
1378
 
1377
1379
int
1378
 
CIFSSMBRead(const int xid, struct cifsTconInfo *tcon, const int netfid,
1379
 
            const unsigned int count, const __u64 lseek, unsigned int *nbytes,
 
1380
CIFSSMBRead(const int xid, struct cifs_io_parms *io_parms, unsigned int *nbytes,
1380
1381
            char **buf, int *pbuf_type)
1381
1382
{
1382
1383
        int rc = -EACCES;
1386
1387
        int wct;
1387
1388
        int resp_buf_type = 0;
1388
1389
        struct kvec iov[1];
 
1390
        __u32 pid = io_parms->pid;
 
1391
        __u16 netfid = io_parms->netfid;
 
1392
        __u64 offset = io_parms->offset;
 
1393
        struct cifs_tcon *tcon = io_parms->tcon;
 
1394
        unsigned int count = io_parms->length;
1389
1395
 
1390
1396
        cFYI(1, "Reading %d bytes on fid %d", count, netfid);
1391
1397
        if (tcon->ses->capabilities & CAP_LARGE_FILES)
1392
1398
                wct = 12;
1393
1399
        else {
1394
1400
                wct = 10; /* old style read */
1395
 
                if ((lseek >> 32) > 0)  {
 
1401
                if ((offset >> 32) > 0)  {
1396
1402
                        /* can not handle this big offset for old */
1397
1403
                        return -EIO;
1398
1404
                }
1403
1409
        if (rc)
1404
1410
                return rc;
1405
1411
 
 
1412
        pSMB->hdr.Pid = cpu_to_le16((__u16)pid);
 
1413
        pSMB->hdr.PidHigh = cpu_to_le16((__u16)(pid >> 16));
 
1414
 
1406
1415
        /* tcon and ses pointer are checked in smb_init */
1407
1416
        if (tcon->ses->server == NULL)
1408
1417
                return -ECONNABORTED;
1409
1418
 
1410
1419
        pSMB->AndXCommand = 0xFF;       /* none */
1411
1420
        pSMB->Fid = netfid;
1412
 
        pSMB->OffsetLow = cpu_to_le32(lseek & 0xFFFFFFFF);
 
1421
        pSMB->OffsetLow = cpu_to_le32(offset & 0xFFFFFFFF);
1413
1422
        if (wct == 12)
1414
 
                pSMB->OffsetHigh = cpu_to_le32(lseek >> 32);
 
1423
                pSMB->OffsetHigh = cpu_to_le32(offset >> 32);
1415
1424
 
1416
1425
        pSMB->Remaining = 0;
1417
1426
        pSMB->MaxCount = cpu_to_le16(count & 0xFFFF);
1426
1435
        }
1427
1436
 
1428
1437
        iov[0].iov_base = (char *)pSMB;
1429
 
        iov[0].iov_len = pSMB->hdr.smb_buf_length + 4;
 
1438
        iov[0].iov_len = be32_to_cpu(pSMB->hdr.smb_buf_length) + 4;
1430
1439
        rc = SendReceive2(xid, tcon->ses, iov, 1 /* num iovecs */,
1431
1440
                         &resp_buf_type, CIFS_LOG_ERROR);
1432
1441
        cifs_stats_inc(&tcon->num_reads);
1480
1489
 
1481
1490
 
1482
1491
int
1483
 
CIFSSMBWrite(const int xid, struct cifsTconInfo *tcon,
1484
 
             const int netfid, const unsigned int count,
1485
 
             const __u64 offset, unsigned int *nbytes, const char *buf,
 
1492
CIFSSMBWrite(const int xid, struct cifs_io_parms *io_parms,
 
1493
             unsigned int *nbytes, const char *buf,
1486
1494
             const char __user *ubuf, const int long_op)
1487
1495
{
1488
1496
        int rc = -EACCES;
1491
1499
        int bytes_returned, wct;
1492
1500
        __u32 bytes_sent;
1493
1501
        __u16 byte_count;
 
1502
        __u32 pid = io_parms->pid;
 
1503
        __u16 netfid = io_parms->netfid;
 
1504
        __u64 offset = io_parms->offset;
 
1505
        struct cifs_tcon *tcon = io_parms->tcon;
 
1506
        unsigned int count = io_parms->length;
1494
1507
 
1495
1508
        *nbytes = 0;
1496
1509
 
1512
1525
                      (void **) &pSMBr);
1513
1526
        if (rc)
1514
1527
                return rc;
 
1528
 
 
1529
        pSMB->hdr.Pid = cpu_to_le16((__u16)pid);
 
1530
        pSMB->hdr.PidHigh = cpu_to_le16((__u16)(pid >> 16));
 
1531
 
1515
1532
        /* tcon and ses pointer are checked in smb_init */
1516
1533
        if (tcon->ses->server == NULL)
1517
1534
                return -ECONNABORTED;
1560
1577
 
1561
1578
        pSMB->DataLengthLow = cpu_to_le16(bytes_sent & 0xFFFF);
1562
1579
        pSMB->DataLengthHigh = cpu_to_le16(bytes_sent >> 16);
1563
 
        pSMB->hdr.smb_buf_length += byte_count;
 
1580
        inc_rfc1001_len(pSMB, byte_count);
1564
1581
 
1565
1582
        if (wct == 14)
1566
1583
                pSMB->ByteCount = cpu_to_le16(byte_count);
1598
1615
        return rc;
1599
1616
}
1600
1617
 
1601
 
int
1602
 
CIFSSMBWrite2(const int xid, struct cifsTconInfo *tcon,
1603
 
             const int netfid, const unsigned int count,
1604
 
             const __u64 offset, unsigned int *nbytes, struct kvec *iov,
1605
 
             int n_vec, const int long_op)
 
1618
void
 
1619
cifs_writedata_release(struct kref *refcount)
 
1620
{
 
1621
        struct cifs_writedata *wdata = container_of(refcount,
 
1622
                                        struct cifs_writedata, refcount);
 
1623
 
 
1624
        if (wdata->cfile)
 
1625
                cifsFileInfo_put(wdata->cfile);
 
1626
 
 
1627
        kfree(wdata);
 
1628
}
 
1629
 
 
1630
/*
 
1631
 * Write failed with a retryable error. Resend the write request. It's also
 
1632
 * possible that the page was redirtied so re-clean the page.
 
1633
 */
 
1634
static void
 
1635
cifs_writev_requeue(struct cifs_writedata *wdata)
 
1636
{
 
1637
        int i, rc;
 
1638
        struct inode *inode = wdata->cfile->dentry->d_inode;
 
1639
 
 
1640
        for (i = 0; i < wdata->nr_pages; i++) {
 
1641
                lock_page(wdata->pages[i]);
 
1642
                clear_page_dirty_for_io(wdata->pages[i]);
 
1643
        }
 
1644
 
 
1645
        do {
 
1646
                rc = cifs_async_writev(wdata);
 
1647
        } while (rc == -EAGAIN);
 
1648
 
 
1649
        for (i = 0; i < wdata->nr_pages; i++) {
 
1650
                if (rc != 0)
 
1651
                        SetPageError(wdata->pages[i]);
 
1652
                unlock_page(wdata->pages[i]);
 
1653
        }
 
1654
 
 
1655
        mapping_set_error(inode->i_mapping, rc);
 
1656
        kref_put(&wdata->refcount, cifs_writedata_release);
 
1657
}
 
1658
 
 
1659
static void
 
1660
cifs_writev_complete(struct work_struct *work)
 
1661
{
 
1662
        struct cifs_writedata *wdata = container_of(work,
 
1663
                                                struct cifs_writedata, work);
 
1664
        struct inode *inode = wdata->cfile->dentry->d_inode;
 
1665
        int i = 0;
 
1666
 
 
1667
        if (wdata->result == 0) {
 
1668
                cifs_update_eof(CIFS_I(inode), wdata->offset, wdata->bytes);
 
1669
                cifs_stats_bytes_written(tlink_tcon(wdata->cfile->tlink),
 
1670
                                         wdata->bytes);
 
1671
        } else if (wdata->sync_mode == WB_SYNC_ALL && wdata->result == -EAGAIN)
 
1672
                return cifs_writev_requeue(wdata);
 
1673
 
 
1674
        for (i = 0; i < wdata->nr_pages; i++) {
 
1675
                struct page *page = wdata->pages[i];
 
1676
                if (wdata->result == -EAGAIN)
 
1677
                        __set_page_dirty_nobuffers(page);
 
1678
                else if (wdata->result < 0)
 
1679
                        SetPageError(page);
 
1680
                end_page_writeback(page);
 
1681
                page_cache_release(page);
 
1682
        }
 
1683
        if (wdata->result != -EAGAIN)
 
1684
                mapping_set_error(inode->i_mapping, wdata->result);
 
1685
        kref_put(&wdata->refcount, cifs_writedata_release);
 
1686
}
 
1687
 
 
1688
struct cifs_writedata *
 
1689
cifs_writedata_alloc(unsigned int nr_pages)
 
1690
{
 
1691
        struct cifs_writedata *wdata;
 
1692
 
 
1693
        /* this would overflow */
 
1694
        if (nr_pages == 0) {
 
1695
                cERROR(1, "%s: called with nr_pages == 0!", __func__);
 
1696
                return NULL;
 
1697
        }
 
1698
 
 
1699
        /* writedata + number of page pointers */
 
1700
        wdata = kzalloc(sizeof(*wdata) +
 
1701
                        sizeof(struct page *) * (nr_pages - 1), GFP_NOFS);
 
1702
        if (wdata != NULL) {
 
1703
                INIT_WORK(&wdata->work, cifs_writev_complete);
 
1704
                kref_init(&wdata->refcount);
 
1705
        }
 
1706
        return wdata;
 
1707
}
 
1708
 
 
1709
/*
 
1710
 * Check the midState and signature on received buffer (if any), and queue the
 
1711
 * workqueue completion task.
 
1712
 */
 
1713
static void
 
1714
cifs_writev_callback(struct mid_q_entry *mid)
 
1715
{
 
1716
        struct cifs_writedata *wdata = mid->callback_data;
 
1717
        struct cifs_tcon *tcon = tlink_tcon(wdata->cfile->tlink);
 
1718
        unsigned int written;
 
1719
        WRITE_RSP *smb = (WRITE_RSP *)mid->resp_buf;
 
1720
 
 
1721
        switch (mid->midState) {
 
1722
        case MID_RESPONSE_RECEIVED:
 
1723
                wdata->result = cifs_check_receive(mid, tcon->ses->server, 0);
 
1724
                if (wdata->result != 0)
 
1725
                        break;
 
1726
 
 
1727
                written = le16_to_cpu(smb->CountHigh);
 
1728
                written <<= 16;
 
1729
                written += le16_to_cpu(smb->Count);
 
1730
                /*
 
1731
                 * Mask off high 16 bits when bytes written as returned
 
1732
                 * by the server is greater than bytes requested by the
 
1733
                 * client. OS/2 servers are known to set incorrect
 
1734
                 * CountHigh values.
 
1735
                 */
 
1736
                if (written > wdata->bytes)
 
1737
                        written &= 0xFFFF;
 
1738
 
 
1739
                if (written < wdata->bytes)
 
1740
                        wdata->result = -ENOSPC;
 
1741
                else
 
1742
                        wdata->bytes = written;
 
1743
                break;
 
1744
        case MID_REQUEST_SUBMITTED:
 
1745
        case MID_RETRY_NEEDED:
 
1746
                wdata->result = -EAGAIN;
 
1747
                break;
 
1748
        default:
 
1749
                wdata->result = -EIO;
 
1750
                break;
 
1751
        }
 
1752
 
 
1753
        queue_work(system_nrt_wq, &wdata->work);
 
1754
        DeleteMidQEntry(mid);
 
1755
        atomic_dec(&tcon->ses->server->inFlight);
 
1756
        wake_up(&tcon->ses->server->request_q);
 
1757
}
 
1758
 
 
1759
/* cifs_async_writev - send an async write, and set up mid to handle result */
 
1760
int
 
1761
cifs_async_writev(struct cifs_writedata *wdata)
 
1762
{
 
1763
        int i, rc = -EACCES;
 
1764
        WRITE_REQ *smb = NULL;
 
1765
        int wct;
 
1766
        struct cifs_tcon *tcon = tlink_tcon(wdata->cfile->tlink);
 
1767
        struct inode *inode = wdata->cfile->dentry->d_inode;
 
1768
        struct kvec *iov = NULL;
 
1769
 
 
1770
        if (tcon->ses->capabilities & CAP_LARGE_FILES) {
 
1771
                wct = 14;
 
1772
        } else {
 
1773
                wct = 12;
 
1774
                if (wdata->offset >> 32 > 0) {
 
1775
                        /* can not handle big offset for old srv */
 
1776
                        return -EIO;
 
1777
                }
 
1778
        }
 
1779
 
 
1780
        rc = small_smb_init(SMB_COM_WRITE_ANDX, wct, tcon, (void **)&smb);
 
1781
        if (rc)
 
1782
                goto async_writev_out;
 
1783
 
 
1784
        /* 1 iov per page + 1 for header */
 
1785
        iov = kzalloc((wdata->nr_pages + 1) * sizeof(*iov), GFP_NOFS);
 
1786
        if (iov == NULL) {
 
1787
                rc = -ENOMEM;
 
1788
                goto async_writev_out;
 
1789
        }
 
1790
 
 
1791
        smb->hdr.Pid = cpu_to_le16((__u16)wdata->cfile->pid);
 
1792
        smb->hdr.PidHigh = cpu_to_le16((__u16)(wdata->cfile->pid >> 16));
 
1793
 
 
1794
        smb->AndXCommand = 0xFF;        /* none */
 
1795
        smb->Fid = wdata->cfile->netfid;
 
1796
        smb->OffsetLow = cpu_to_le32(wdata->offset & 0xFFFFFFFF);
 
1797
        if (wct == 14)
 
1798
                smb->OffsetHigh = cpu_to_le32(wdata->offset >> 32);
 
1799
        smb->Reserved = 0xFFFFFFFF;
 
1800
        smb->WriteMode = 0;
 
1801
        smb->Remaining = 0;
 
1802
 
 
1803
        smb->DataOffset =
 
1804
            cpu_to_le16(offsetof(struct smb_com_write_req, Data) - 4);
 
1805
 
 
1806
        /* 4 for RFC1001 length + 1 for BCC */
 
1807
        iov[0].iov_len = be32_to_cpu(smb->hdr.smb_buf_length) + 4 + 1;
 
1808
        iov[0].iov_base = smb;
 
1809
 
 
1810
        /* marshal up the pages into iov array */
 
1811
        wdata->bytes = 0;
 
1812
        for (i = 0; i < wdata->nr_pages; i++) {
 
1813
                iov[i + 1].iov_len = min(inode->i_size -
 
1814
                                      page_offset(wdata->pages[i]),
 
1815
                                        (loff_t)PAGE_CACHE_SIZE);
 
1816
                iov[i + 1].iov_base = kmap(wdata->pages[i]);
 
1817
                wdata->bytes += iov[i + 1].iov_len;
 
1818
        }
 
1819
 
 
1820
        cFYI(1, "async write at %llu %u bytes", wdata->offset, wdata->bytes);
 
1821
 
 
1822
        smb->DataLengthLow = cpu_to_le16(wdata->bytes & 0xFFFF);
 
1823
        smb->DataLengthHigh = cpu_to_le16(wdata->bytes >> 16);
 
1824
 
 
1825
        if (wct == 14) {
 
1826
                inc_rfc1001_len(&smb->hdr, wdata->bytes + 1);
 
1827
                put_bcc(wdata->bytes + 1, &smb->hdr);
 
1828
        } else {
 
1829
                /* wct == 12 */
 
1830
                struct smb_com_writex_req *smbw =
 
1831
                                (struct smb_com_writex_req *)smb;
 
1832
                inc_rfc1001_len(&smbw->hdr, wdata->bytes + 5);
 
1833
                put_bcc(wdata->bytes + 5, &smbw->hdr);
 
1834
                iov[0].iov_len += 4; /* pad bigger by four bytes */
 
1835
        }
 
1836
 
 
1837
        kref_get(&wdata->refcount);
 
1838
        rc = cifs_call_async(tcon->ses->server, iov, wdata->nr_pages + 1,
 
1839
                             cifs_writev_callback, wdata, false);
 
1840
 
 
1841
        if (rc == 0)
 
1842
                cifs_stats_inc(&tcon->num_writes);
 
1843
        else
 
1844
                kref_put(&wdata->refcount, cifs_writedata_release);
 
1845
 
 
1846
        /* send is done, unmap pages */
 
1847
        for (i = 0; i < wdata->nr_pages; i++)
 
1848
                kunmap(wdata->pages[i]);
 
1849
 
 
1850
async_writev_out:
 
1851
        cifs_small_buf_release(smb);
 
1852
        kfree(iov);
 
1853
        return rc;
 
1854
}
 
1855
 
 
1856
int
 
1857
CIFSSMBWrite2(const int xid, struct cifs_io_parms *io_parms,
 
1858
              unsigned int *nbytes, struct kvec *iov, int n_vec,
 
1859
              const int long_op)
1606
1860
{
1607
1861
        int rc = -EACCES;
1608
1862
        WRITE_REQ *pSMB = NULL;
1609
1863
        int wct;
1610
1864
        int smb_hdr_len;
1611
1865
        int resp_buf_type = 0;
 
1866
        __u32 pid = io_parms->pid;
 
1867
        __u16 netfid = io_parms->netfid;
 
1868
        __u64 offset = io_parms->offset;
 
1869
        struct cifs_tcon *tcon = io_parms->tcon;
 
1870
        unsigned int count = io_parms->length;
1612
1871
 
1613
1872
        *nbytes = 0;
1614
1873
 
1626
1885
        rc = small_smb_init(SMB_COM_WRITE_ANDX, wct, tcon, (void **) &pSMB);
1627
1886
        if (rc)
1628
1887
                return rc;
 
1888
 
 
1889
        pSMB->hdr.Pid = cpu_to_le16((__u16)pid);
 
1890
        pSMB->hdr.PidHigh = cpu_to_le16((__u16)(pid >> 16));
 
1891
 
1629
1892
        /* tcon and ses pointer are checked in smb_init */
1630
1893
        if (tcon->ses->server == NULL)
1631
1894
                return -ECONNABORTED;
1644
1907
 
1645
1908
        pSMB->DataLengthLow = cpu_to_le16(count & 0xFFFF);
1646
1909
        pSMB->DataLengthHigh = cpu_to_le16(count >> 16);
1647
 
        smb_hdr_len = pSMB->hdr.smb_buf_length + 1; /* hdr + 1 byte pad */
 
1910
        /* header + 1 byte pad */
 
1911
        smb_hdr_len = be32_to_cpu(pSMB->hdr.smb_buf_length) + 1;
1648
1912
        if (wct == 14)
1649
 
                pSMB->hdr.smb_buf_length += count+1;
 
1913
                inc_rfc1001_len(pSMB, count + 1);
1650
1914
        else /* wct == 12 */
1651
 
                pSMB->hdr.smb_buf_length += count+5; /* smb data starts later */
 
1915
                inc_rfc1001_len(pSMB, count + 5); /* smb data starts later */
1652
1916
        if (wct == 14)
1653
1917
                pSMB->ByteCount = cpu_to_le16(count + 1);
1654
1918
        else /* wct == 12 */ /* bigger pad, smaller smb hdr, keep offset ok */ {
1700
1964
 
1701
1965
 
1702
1966
int
1703
 
CIFSSMBLock(const int xid, struct cifsTconInfo *tcon,
 
1967
CIFSSMBLock(const int xid, struct cifs_tcon *tcon,
1704
1968
            const __u16 smb_file_id, const __u64 len,
1705
1969
            const __u64 offset, const __u32 numUnlock,
1706
1970
            const __u32 numLock, const __u8 lockType,
1748
2012
                /* oplock break */
1749
2013
                count = 0;
1750
2014
        }
1751
 
        pSMB->hdr.smb_buf_length += count;
 
2015
        inc_rfc1001_len(pSMB, count);
1752
2016
        pSMB->ByteCount = cpu_to_le16(count);
1753
2017
 
1754
2018
        if (waitFlag) {
1770
2034
}
1771
2035
 
1772
2036
int
1773
 
CIFSSMBPosixLock(const int xid, struct cifsTconInfo *tcon,
 
2037
CIFSSMBPosixLock(const int xid, struct cifs_tcon *tcon,
1774
2038
                const __u16 smb_file_id, const int get_flag, const __u64 len,
1775
2039
                struct file_lock *pLockData, const __u16 lock_type,
1776
2040
                const bool waitFlag)
1839
2103
        pSMB->Fid = smb_file_id;
1840
2104
        pSMB->InformationLevel = cpu_to_le16(SMB_SET_POSIX_LOCK);
1841
2105
        pSMB->Reserved4 = 0;
1842
 
        pSMB->hdr.smb_buf_length += byte_count;
 
2106
        inc_rfc1001_len(pSMB, byte_count);
1843
2107
        pSMB->ByteCount = cpu_to_le16(byte_count);
1844
2108
        if (waitFlag) {
1845
2109
                rc = SendReceiveBlockingLock(xid, tcon, (struct smb_hdr *) pSMB,
1846
2110
                        (struct smb_hdr *) pSMBr, &bytes_returned);
1847
2111
        } else {
1848
2112
                iov[0].iov_base = (char *)pSMB;
1849
 
                iov[0].iov_len = pSMB->hdr.smb_buf_length + 4;
 
2113
                iov[0].iov_len = be32_to_cpu(pSMB->hdr.smb_buf_length) + 4;
1850
2114
                rc = SendReceive2(xid, tcon->ses, iov, 1 /* num iovecs */,
1851
2115
                                &resp_buf_type, timeout);
1852
2116
                pSMB = NULL; /* request buf already freed by SendReceive2. Do
1862
2126
                __u16 data_count;
1863
2127
                rc = validate_t2((struct smb_t2_rsp *)pSMBr);
1864
2128
 
1865
 
                if (rc || (pSMBr->ByteCount < sizeof(struct cifs_posix_lock))) {
 
2129
                if (rc || get_bcc(&pSMBr->hdr) < sizeof(*parm_data)) {
1866
2130
                        rc = -EIO;      /* bad smb */
1867
2131
                        goto plk_err_exit;
1868
2132
                }
1908
2172
 
1909
2173
 
1910
2174
int
1911
 
CIFSSMBClose(const int xid, struct cifsTconInfo *tcon, int smb_file_id)
 
2175
CIFSSMBClose(const int xid, struct cifs_tcon *tcon, int smb_file_id)
1912
2176
{
1913
2177
        int rc = 0;
1914
2178
        CLOSE_REQ *pSMB = NULL;
1941
2205
}
1942
2206
 
1943
2207
int
1944
 
CIFSSMBFlush(const int xid, struct cifsTconInfo *tcon, int smb_file_id)
 
2208
CIFSSMBFlush(const int xid, struct cifs_tcon *tcon, int smb_file_id)
1945
2209
{
1946
2210
        int rc = 0;
1947
2211
        FLUSH_REQ *pSMB = NULL;
1962
2226
}
1963
2227
 
1964
2228
int
1965
 
CIFSSMBRename(const int xid, struct cifsTconInfo *tcon,
 
2229
CIFSSMBRename(const int xid, struct cifs_tcon *tcon,
1966
2230
              const char *fromName, const char *toName,
1967
2231
              const struct nls_table *nls_codepage, int remap)
1968
2232
{
2012
2276
        }
2013
2277
 
2014
2278
        count = 1 /* 1st signature byte */  + name_len + name_len2;
2015
 
        pSMB->hdr.smb_buf_length += count;
 
2279
        inc_rfc1001_len(pSMB, count);
2016
2280
        pSMB->ByteCount = cpu_to_le16(count);
2017
2281
 
2018
2282
        rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
2029
2293
        return rc;
2030
2294
}
2031
2295
 
2032
 
int CIFSSMBRenameOpenFile(const int xid, struct cifsTconInfo *pTcon,
 
2296
int CIFSSMBRenameOpenFile(const int xid, struct cifs_tcon *pTcon,
2033
2297
                int netfid, const char *target_name,
2034
2298
                const struct nls_table *nls_codepage, int remap)
2035
2299
{
2092
2356
        pSMB->InformationLevel =
2093
2357
                cpu_to_le16(SMB_SET_FILE_RENAME_INFORMATION);
2094
2358
        pSMB->Reserved4 = 0;
2095
 
        pSMB->hdr.smb_buf_length += byte_count;
 
2359
        inc_rfc1001_len(pSMB, byte_count);
2096
2360
        pSMB->ByteCount = cpu_to_le16(byte_count);
2097
2361
        rc = SendReceive(xid, pTcon->ses, (struct smb_hdr *) pSMB,
2098
2362
                         (struct smb_hdr *) pSMBr, &bytes_returned, 0);
2109
2373
}
2110
2374
 
2111
2375
int
2112
 
CIFSSMBCopy(const int xid, struct cifsTconInfo *tcon, const char *fromName,
 
2376
CIFSSMBCopy(const int xid, struct cifs_tcon *tcon, const char *fromName,
2113
2377
            const __u16 target_tid, const char *toName, const int flags,
2114
2378
            const struct nls_table *nls_codepage, int remap)
2115
2379
{
2159
2423
        }
2160
2424
 
2161
2425
        count = 1 /* 1st signature byte */  + name_len + name_len2;
2162
 
        pSMB->hdr.smb_buf_length += count;
 
2426
        inc_rfc1001_len(pSMB, count);
2163
2427
        pSMB->ByteCount = cpu_to_le16(count);
2164
2428
 
2165
2429
        rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
2177
2441
}
2178
2442
 
2179
2443
int
2180
 
CIFSUnixCreateSymLink(const int xid, struct cifsTconInfo *tcon,
 
2444
CIFSUnixCreateSymLink(const int xid, struct cifs_tcon *tcon,
2181
2445
                      const char *fromName, const char *toName,
2182
2446
                      const struct nls_table *nls_codepage)
2183
2447
{
2249
2513
        pSMB->DataOffset = cpu_to_le16(offset);
2250
2514
        pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_UNIX_LINK);
2251
2515
        pSMB->Reserved4 = 0;
2252
 
        pSMB->hdr.smb_buf_length += byte_count;
 
2516
        inc_rfc1001_len(pSMB, byte_count);
2253
2517
        pSMB->ByteCount = cpu_to_le16(byte_count);
2254
2518
        rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
2255
2519
                         (struct smb_hdr *) pSMBr, &bytes_returned, 0);
2266
2530
}
2267
2531
 
2268
2532
int
2269
 
CIFSUnixCreateHardLink(const int xid, struct cifsTconInfo *tcon,
 
2533
CIFSUnixCreateHardLink(const int xid, struct cifs_tcon *tcon,
2270
2534
                       const char *fromName, const char *toName,
2271
2535
                       const struct nls_table *nls_codepage, int remap)
2272
2536
{
2335
2599
        pSMB->DataOffset = cpu_to_le16(offset);
2336
2600
        pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_UNIX_HLINK);
2337
2601
        pSMB->Reserved4 = 0;
2338
 
        pSMB->hdr.smb_buf_length += byte_count;
 
2602
        inc_rfc1001_len(pSMB, byte_count);
2339
2603
        pSMB->ByteCount = cpu_to_le16(byte_count);
2340
2604
        rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
2341
2605
                         (struct smb_hdr *) pSMBr, &bytes_returned, 0);
2351
2615
}
2352
2616
 
2353
2617
int
2354
 
CIFSCreateHardLink(const int xid, struct cifsTconInfo *tcon,
 
2618
CIFSCreateHardLink(const int xid, struct cifs_tcon *tcon,
2355
2619
                   const char *fromName, const char *toName,
2356
2620
                   const struct nls_table *nls_codepage, int remap)
2357
2621
{
2406
2670
        }
2407
2671
 
2408
2672
        count = 1 /* string type byte */  + name_len + name_len2;
2409
 
        pSMB->hdr.smb_buf_length += count;
 
2673
        inc_rfc1001_len(pSMB, count);
2410
2674
        pSMB->ByteCount = cpu_to_le16(count);
2411
2675
 
2412
2676
        rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
2423
2687
}
2424
2688
 
2425
2689
int
2426
 
CIFSSMBUnixQuerySymLink(const int xid, struct cifsTconInfo *tcon,
 
2690
CIFSSMBUnixQuerySymLink(const int xid, struct cifs_tcon *tcon,
2427
2691
                        const unsigned char *searchName, char **symlinkinfo,
2428
2692
                        const struct nls_table *nls_codepage)
2429
2693
{
2477
2741
        pSMB->ParameterCount = pSMB->TotalParameterCount;
2478
2742
        pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FILE_UNIX_LINK);
2479
2743
        pSMB->Reserved4 = 0;
2480
 
        pSMB->hdr.smb_buf_length += byte_count;
 
2744
        inc_rfc1001_len(pSMB, byte_count);
2481
2745
        pSMB->ByteCount = cpu_to_le16(byte_count);
2482
2746
 
2483
2747
        rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
2489
2753
 
2490
2754
                rc = validate_t2((struct smb_t2_rsp *)pSMBr);
2491
2755
                /* BB also check enough total bytes returned */
2492
 
                if (rc || (pSMBr->ByteCount < 2))
 
2756
                if (rc || get_bcc(&pSMBr->hdr) < 2)
2493
2757
                        rc = -EIO;
2494
2758
                else {
2495
2759
                        bool is_unicode;
2516
2780
        return rc;
2517
2781
}
2518
2782
 
2519
 
#ifdef CONFIG_CIFS_EXPERIMENTAL
 
2783
#ifdef CONFIG_CIFS_SYMLINK_EXPERIMENTAL
 
2784
/*
 
2785
 *      Recent Windows versions now create symlinks more frequently
 
2786
 *      and they use the "reparse point" mechanism below.  We can of course
 
2787
 *      do symlinks nicely to Samba and other servers which support the
 
2788
 *      CIFS Unix Extensions and we can also do SFU symlinks and "client only"
 
2789
 *      "MF" symlinks optionally, but for recent Windows we really need to
 
2790
 *      reenable the code below and fix the cifs_symlink callers to handle this.
 
2791
 *      In the interim this code has been moved to its own config option so
 
2792
 *      it is not compiled in by default until callers fixed up and more tested.
 
2793
 */
2520
2794
int
2521
 
CIFSSMBQueryReparseLinkInfo(const int xid, struct cifsTconInfo *tcon,
 
2795
CIFSSMBQueryReparseLinkInfo(const int xid, struct cifs_tcon *tcon,
2522
2796
                        const unsigned char *searchName,
2523
2797
                        char *symlinkinfo, const int buflen, __u16 fid,
2524
2798
                        const struct nls_table *nls_codepage)
2561
2835
        } else {                /* decode response */
2562
2836
                __u32 data_offset = le32_to_cpu(pSMBr->DataOffset);
2563
2837
                __u32 data_count = le32_to_cpu(pSMBr->DataCount);
2564
 
                if ((pSMBr->ByteCount < 2) || (data_offset > 512)) {
2565
 
                /* BB also check enough total bytes returned */
 
2838
                if (get_bcc(&pSMBr->hdr) < 2 || data_offset > 512) {
 
2839
                        /* BB also check enough total bytes returned */
2566
2840
                        rc = -EIO;      /* bad smb */
2567
2841
                        goto qreparse_out;
2568
2842
                }
2569
2843
                if (data_count && (data_count < 2048)) {
2570
2844
                        char *end_of_smb = 2 /* sizeof byte count */ +
2571
 
                                pSMBr->ByteCount + (char *)&pSMBr->ByteCount;
 
2845
                               get_bcc(&pSMBr->hdr) + (char *)&pSMBr->ByteCount;
2572
2846
 
2573
2847
                        struct reparse_data *reparse_buf =
2574
2848
                                                (struct reparse_data *)
2618
2892
 
2619
2893
        return rc;
2620
2894
}
2621
 
#endif /* CIFS_EXPERIMENTAL */
 
2895
#endif /* CIFS_SYMLINK_EXPERIMENTAL */ /* BB temporarily unused */
2622
2896
 
2623
2897
#ifdef CONFIG_CIFS_POSIX
2624
2898
 
2756
3030
}
2757
3031
 
2758
3032
int
2759
 
CIFSSMBGetPosixACL(const int xid, struct cifsTconInfo *tcon,
 
3033
CIFSSMBGetPosixACL(const int xid, struct cifs_tcon *tcon,
2760
3034
                   const unsigned char *searchName,
2761
3035
                   char *acl_inf, const int buflen, const int acl_type,
2762
3036
                   const struct nls_table *nls_codepage, int remap)
2814
3088
        pSMB->ParameterCount = pSMB->TotalParameterCount;
2815
3089
        pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_POSIX_ACL);
2816
3090
        pSMB->Reserved4 = 0;
2817
 
        pSMB->hdr.smb_buf_length += byte_count;
 
3091
        inc_rfc1001_len(pSMB, byte_count);
2818
3092
        pSMB->ByteCount = cpu_to_le16(byte_count);
2819
3093
 
2820
3094
        rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
2826
3100
                /* decode response */
2827
3101
 
2828
3102
                rc = validate_t2((struct smb_t2_rsp *)pSMBr);
2829
 
                if (rc || (pSMBr->ByteCount < 2))
2830
3103
                /* BB also check enough total bytes returned */
 
3104
                if (rc || get_bcc(&pSMBr->hdr) < 2)
2831
3105
                        rc = -EIO;      /* bad smb */
2832
3106
                else {
2833
3107
                        __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
2844
3118
}
2845
3119
 
2846
3120
int
2847
 
CIFSSMBSetPosixACL(const int xid, struct cifsTconInfo *tcon,
 
3121
CIFSSMBSetPosixACL(const int xid, struct cifs_tcon *tcon,
2848
3122
                   const unsigned char *fileName,
2849
3123
                   const char *local_acl, const int buflen,
2850
3124
                   const int acl_type,
2908
3182
        pSMB->ParameterCount = cpu_to_le16(params);
2909
3183
        pSMB->TotalParameterCount = pSMB->ParameterCount;
2910
3184
        pSMB->Reserved4 = 0;
2911
 
        pSMB->hdr.smb_buf_length += byte_count;
 
3185
        inc_rfc1001_len(pSMB, byte_count);
2912
3186
        pSMB->ByteCount = cpu_to_le16(byte_count);
2913
3187
        rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
2914
3188
                         (struct smb_hdr *) pSMBr, &bytes_returned, 0);
2924
3198
 
2925
3199
/* BB fix tabs in this function FIXME BB */
2926
3200
int
2927
 
CIFSGetExtAttr(const int xid, struct cifsTconInfo *tcon,
 
3201
CIFSGetExtAttr(const int xid, struct cifs_tcon *tcon,
2928
3202
               const int netfid, __u64 *pExtAttrBits, __u64 *pMask)
2929
3203
{
2930
3204
        int rc = 0;
2966
3240
        pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_ATTR_FLAGS);
2967
3241
        pSMB->Pad = 0;
2968
3242
        pSMB->Fid = netfid;
2969
 
        pSMB->hdr.smb_buf_length += byte_count;
 
3243
        inc_rfc1001_len(pSMB, byte_count);
2970
3244
        pSMB->t2.ByteCount = cpu_to_le16(byte_count);
2971
3245
 
2972
3246
        rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
2976
3250
        } else {
2977
3251
                /* decode response */
2978
3252
                rc = validate_t2((struct smb_t2_rsp *)pSMBr);
2979
 
                if (rc || (pSMBr->ByteCount < 2))
2980
3253
                /* BB also check enough total bytes returned */
 
3254
                if (rc || get_bcc(&pSMBr->hdr) < 2)
2981
3255
                        /* If rc should we check for EOPNOSUPP and
2982
3256
                           disable the srvino flag? or in caller? */
2983
3257
                        rc = -EIO;      /* bad smb */
3017
3291
 */
3018
3292
static int
3019
3293
smb_init_nttransact(const __u16 sub_command, const int setup_count,
3020
 
                   const int parm_len, struct cifsTconInfo *tcon,
 
3294
                   const int parm_len, struct cifs_tcon *tcon,
3021
3295
                   void **ret_buf)
3022
3296
{
3023
3297
        int rc;
3052
3326
        char *end_of_smb;
3053
3327
        __u32 data_count, data_offset, parm_count, parm_offset;
3054
3328
        struct smb_com_ntransact_rsp *pSMBr;
 
3329
        u16 bcc;
3055
3330
 
3056
3331
        *pdatalen = 0;
3057
3332
        *pparmlen = 0;
3061
3336
 
3062
3337
        pSMBr = (struct smb_com_ntransact_rsp *)buf;
3063
3338
 
3064
 
        /* ByteCount was converted from little endian in SendReceive */
3065
 
        end_of_smb = 2 /* sizeof byte count */ + pSMBr->ByteCount +
 
3339
        bcc = get_bcc(&pSMBr->hdr);
 
3340
        end_of_smb = 2 /* sizeof byte count */ + bcc +
3066
3341
                        (char *)&pSMBr->ByteCount;
3067
3342
 
3068
3343
        data_offset = le32_to_cpu(pSMBr->DataOffset);
3088
3363
                        *ppdata, data_count, (data_count + *ppdata),
3089
3364
                        end_of_smb, pSMBr);
3090
3365
                return -EINVAL;
3091
 
        } else if (parm_count + data_count > pSMBr->ByteCount) {
 
3366
        } else if (parm_count + data_count > bcc) {
3092
3367
                cFYI(1, "parm count and data count larger than SMB");
3093
3368
                return -EINVAL;
3094
3369
        }
3099
3374
 
3100
3375
/* Get Security Descriptor (by handle) from remote server for a file or dir */
3101
3376
int
3102
 
CIFSSMBGetCIFSACL(const int xid, struct cifsTconInfo *tcon, __u16 fid,
 
3377
CIFSSMBGetCIFSACL(const int xid, struct cifs_tcon *tcon, __u16 fid,
3103
3378
                  struct cifs_ntsd **acl_inf, __u32 *pbuflen)
3104
3379
{
3105
3380
        int rc = 0;
3124
3399
        pSMB->AclFlags = cpu_to_le32(CIFS_ACL_OWNER | CIFS_ACL_GROUP |
3125
3400
                                     CIFS_ACL_DACL);
3126
3401
        pSMB->ByteCount = cpu_to_le16(11); /* 3 bytes pad + 8 bytes parm */
3127
 
        pSMB->hdr.smb_buf_length += 11;
 
3402
        inc_rfc1001_len(pSMB, 11);
3128
3403
        iov[0].iov_base = (char *)pSMB;
3129
 
        iov[0].iov_len = pSMB->hdr.smb_buf_length + 4;
 
3404
        iov[0].iov_len = be32_to_cpu(pSMB->hdr.smb_buf_length) + 4;
3130
3405
 
3131
3406
        rc = SendReceive2(xid, tcon->ses, iov, 1 /* num iovec */, &buf_type,
3132
3407
                         0);
3191
3466
}
3192
3467
 
3193
3468
int
3194
 
CIFSSMBSetCIFSACL(const int xid, struct cifsTconInfo *tcon, __u16 fid,
 
3469
CIFSSMBSetCIFSACL(const int xid, struct cifs_tcon *tcon, __u16 fid,
3195
3470
                        struct cifs_ntsd *pntsd, __u32 acllen)
3196
3471
{
3197
3472
        __u16 byte_count, param_count, data_count, param_offset, data_offset;
3235
3510
                memcpy((char *) &pSMBr->hdr.Protocol + data_offset,
3236
3511
                        (char *) pntsd,
3237
3512
                        acllen);
3238
 
                pSMB->hdr.smb_buf_length += (byte_count + data_count);
3239
 
 
 
3513
                inc_rfc1001_len(pSMB, byte_count + data_count);
3240
3514
        } else
3241
 
                pSMB->hdr.smb_buf_length += byte_count;
 
3515
                inc_rfc1001_len(pSMB, byte_count);
3242
3516
 
3243
3517
        rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
3244
3518
                (struct smb_hdr *) pSMBr, &bytes_returned, 0);
3258
3532
 
3259
3533
/* Legacy Query Path Information call for lookup to old servers such
3260
3534
   as Win9x/WinME */
3261
 
int SMBQueryInformation(const int xid, struct cifsTconInfo *tcon,
 
3535
int SMBQueryInformation(const int xid, struct cifs_tcon *tcon,
3262
3536
                        const unsigned char *searchName,
3263
3537
                        FILE_ALL_INFO *pFinfo,
3264
3538
                        const struct nls_table *nls_codepage, int remap)
3289
3563
        }
3290
3564
        pSMB->BufferFormat = 0x04;
3291
3565
        name_len++; /* account for buffer type byte */
3292
 
        pSMB->hdr.smb_buf_length += (__u16) name_len;
 
3566
        inc_rfc1001_len(pSMB, (__u16)name_len);
3293
3567
        pSMB->ByteCount = cpu_to_le16(name_len);
3294
3568
 
3295
3569
        rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
3326
3600
}
3327
3601
 
3328
3602
int
3329
 
CIFSSMBQFileInfo(const int xid, struct cifsTconInfo *tcon,
 
3603
CIFSSMBQFileInfo(const int xid, struct cifs_tcon *tcon,
3330
3604
                 u16 netfid, FILE_ALL_INFO *pFindData)
3331
3605
{
3332
3606
        struct smb_t2_qfi_req *pSMB = NULL;
3364
3638
        pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FILE_ALL_INFO);
3365
3639
        pSMB->Pad = 0;
3366
3640
        pSMB->Fid = netfid;
3367
 
        pSMB->hdr.smb_buf_length += byte_count;
 
3641
        inc_rfc1001_len(pSMB, byte_count);
3368
3642
 
3369
3643
        rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
3370
3644
                         (struct smb_hdr *) pSMBr, &bytes_returned, 0);
3375
3649
 
3376
3650
                if (rc) /* BB add auto retry on EOPNOTSUPP? */
3377
3651
                        rc = -EIO;
3378
 
                else if (pSMBr->ByteCount < 40)
 
3652
                else if (get_bcc(&pSMBr->hdr) < 40)
3379
3653
                        rc = -EIO;      /* bad smb */
3380
3654
                else if (pFindData) {
3381
3655
                        __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
3393
3667
}
3394
3668
 
3395
3669
int
3396
 
CIFSSMBQPathInfo(const int xid, struct cifsTconInfo *tcon,
 
3670
CIFSSMBQPathInfo(const int xid, struct cifs_tcon *tcon,
3397
3671
                 const unsigned char *searchName,
3398
3672
                 FILE_ALL_INFO *pFindData,
3399
3673
                 int legacy /* old style infolevel */,
3451
3725
        else
3452
3726
                pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FILE_ALL_INFO);
3453
3727
        pSMB->Reserved4 = 0;
3454
 
        pSMB->hdr.smb_buf_length += byte_count;
 
3728
        inc_rfc1001_len(pSMB, byte_count);
3455
3729
        pSMB->ByteCount = cpu_to_le16(byte_count);
3456
3730
 
3457
3731
        rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
3463
3737
 
3464
3738
                if (rc) /* BB add auto retry on EOPNOTSUPP? */
3465
3739
                        rc = -EIO;
3466
 
                else if (!legacy && (pSMBr->ByteCount < 40))
 
3740
                else if (!legacy && get_bcc(&pSMBr->hdr) < 40)
3467
3741
                        rc = -EIO;      /* bad smb */
3468
 
                else if (legacy && (pSMBr->ByteCount < 24))
 
3742
                else if (legacy && get_bcc(&pSMBr->hdr) < 24)
3469
3743
                        rc = -EIO;  /* 24 or 26 expected but we do not read
3470
3744
                                        last field */
3471
3745
                else if (pFindData) {
3494
3768
}
3495
3769
 
3496
3770
int
3497
 
CIFSSMBUnixQFileInfo(const int xid, struct cifsTconInfo *tcon,
 
3771
CIFSSMBUnixQFileInfo(const int xid, struct cifs_tcon *tcon,
3498
3772
                 u16 netfid, FILE_UNIX_BASIC_INFO *pFindData)
3499
3773
{
3500
3774
        struct smb_t2_qfi_req *pSMB = NULL;
3532
3806
        pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FILE_UNIX_BASIC);
3533
3807
        pSMB->Pad = 0;
3534
3808
        pSMB->Fid = netfid;
3535
 
        pSMB->hdr.smb_buf_length += byte_count;
 
3809
        inc_rfc1001_len(pSMB, byte_count);
3536
3810
 
3537
3811
        rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
3538
3812
                         (struct smb_hdr *) pSMBr, &bytes_returned, 0);
3541
3815
        } else {                /* decode response */
3542
3816
                rc = validate_t2((struct smb_t2_rsp *)pSMBr);
3543
3817
 
3544
 
                if (rc || (pSMBr->ByteCount < sizeof(FILE_UNIX_BASIC_INFO))) {
 
3818
                if (rc || get_bcc(&pSMBr->hdr) < sizeof(FILE_UNIX_BASIC_INFO)) {
3545
3819
                        cERROR(1, "Malformed FILE_UNIX_BASIC_INFO response.\n"
3546
3820
                                   "Unix Extensions can be disabled on mount "
3547
3821
                                   "by specifying the nosfu mount option.");
3563
3837
}
3564
3838
 
3565
3839
int
3566
 
CIFSSMBUnixQPathInfo(const int xid, struct cifsTconInfo *tcon,
 
3840
CIFSSMBUnixQPathInfo(const int xid, struct cifs_tcon *tcon,
3567
3841
                     const unsigned char *searchName,
3568
3842
                     FILE_UNIX_BASIC_INFO *pFindData,
3569
3843
                     const struct nls_table *nls_codepage, int remap)
3617
3891
        pSMB->ParameterCount = pSMB->TotalParameterCount;
3618
3892
        pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FILE_UNIX_BASIC);
3619
3893
        pSMB->Reserved4 = 0;
3620
 
        pSMB->hdr.smb_buf_length += byte_count;
 
3894
        inc_rfc1001_len(pSMB, byte_count);
3621
3895
        pSMB->ByteCount = cpu_to_le16(byte_count);
3622
3896
 
3623
3897
        rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
3627
3901
        } else {                /* decode response */
3628
3902
                rc = validate_t2((struct smb_t2_rsp *)pSMBr);
3629
3903
 
3630
 
                if (rc || (pSMBr->ByteCount < sizeof(FILE_UNIX_BASIC_INFO))) {
 
3904
                if (rc || get_bcc(&pSMBr->hdr) < sizeof(FILE_UNIX_BASIC_INFO)) {
3631
3905
                        cERROR(1, "Malformed FILE_UNIX_BASIC_INFO response.\n"
3632
3906
                                   "Unix Extensions can be disabled on mount "
3633
3907
                                   "by specifying the nosfu mount option.");
3649
3923
 
3650
3924
/* xid, tcon, searchName and codepage are input parms, rest are returned */
3651
3925
int
3652
 
CIFSFindFirst(const int xid, struct cifsTconInfo *tcon,
 
3926
CIFSFindFirst(const int xid, struct cifs_tcon *tcon,
3653
3927
              const char *searchName,
3654
3928
              const struct nls_table *nls_codepage,
3655
3929
              __u16 *pnetfid,
3731
4005
 
3732
4006
        /* BB what should we set StorageType to? Does it matter? BB */
3733
4007
        pSMB->SearchStorageType = 0;
3734
 
        pSMB->hdr.smb_buf_length += byte_count;
 
4008
        inc_rfc1001_len(pSMB, byte_count);
3735
4009
        pSMB->ByteCount = cpu_to_le16(byte_count);
3736
4010
 
3737
4011
        rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
3797
4071
        return rc;
3798
4072
}
3799
4073
 
3800
 
int CIFSFindNext(const int xid, struct cifsTconInfo *tcon,
 
4074
int CIFSFindNext(const int xid, struct cifs_tcon *tcon,
3801
4075
                 __u16 searchHandle, struct cifs_search_info *psrch_inf)
3802
4076
{
3803
4077
        TRANSACTION2_FNEXT_REQ *pSMB = NULL;
3860
4134
        byte_count = params + 1 /* pad */ ;
3861
4135
        pSMB->TotalParameterCount = cpu_to_le16(params);
3862
4136
        pSMB->ParameterCount = pSMB->TotalParameterCount;
3863
 
        pSMB->hdr.smb_buf_length += byte_count;
 
4137
        inc_rfc1001_len(pSMB, byte_count);
3864
4138
        pSMB->ByteCount = cpu_to_le16(byte_count);
3865
4139
 
3866
4140
        rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
3935
4209
}
3936
4210
 
3937
4211
int
3938
 
CIFSFindClose(const int xid, struct cifsTconInfo *tcon,
 
4212
CIFSFindClose(const int xid, struct cifs_tcon *tcon,
3939
4213
              const __u16 searchHandle)
3940
4214
{
3941
4215
        int rc = 0;
3967
4241
}
3968
4242
 
3969
4243
int
3970
 
CIFSGetSrvInodeNumber(const int xid, struct cifsTconInfo *tcon,
 
4244
CIFSGetSrvInodeNumber(const int xid, struct cifs_tcon *tcon,
3971
4245
                      const unsigned char *searchName,
3972
4246
                      __u64 *inode_number,
3973
4247
                      const struct nls_table *nls_codepage, int remap)
4022
4296
        pSMB->ParameterCount = pSMB->TotalParameterCount;
4023
4297
        pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FILE_INTERNAL_INFO);
4024
4298
        pSMB->Reserved4 = 0;
4025
 
        pSMB->hdr.smb_buf_length += byte_count;
 
4299
        inc_rfc1001_len(pSMB, byte_count);
4026
4300
        pSMB->ByteCount = cpu_to_le16(byte_count);
4027
4301
 
4028
4302
        rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
4032
4306
        } else {
4033
4307
                /* decode response */
4034
4308
                rc = validate_t2((struct smb_t2_rsp *)pSMBr);
4035
 
                if (rc || (pSMBr->ByteCount < 2))
4036
4309
                /* BB also check enough total bytes returned */
 
4310
                if (rc || get_bcc(&pSMBr->hdr) < 2)
4037
4311
                        /* If rc should we check for EOPNOSUPP and
4038
4312
                        disable the srvino flag? or in caller? */
4039
4313
                        rc = -EIO;      /* bad smb */
4169
4443
}
4170
4444
 
4171
4445
int
4172
 
CIFSGetDFSRefer(const int xid, struct cifsSesInfo *ses,
 
4446
CIFSGetDFSRefer(const int xid, struct cifs_ses *ses,
4173
4447
                const unsigned char *searchName,
4174
4448
                struct dfs_info3_param **target_nodes,
4175
4449
                unsigned int *num_of_nodes,
4218
4492
        }
4219
4493
 
4220
4494
        if (ses->server) {
4221
 
                if (ses->server->secMode &
 
4495
                if (ses->server->sec_mode &
4222
4496
                   (SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED))
4223
4497
                        pSMB->hdr.Flags2 |= SMBFLG2_SECURITY_SIGNATURE;
4224
4498
        }
4246
4520
        pSMB->ParameterCount = cpu_to_le16(params);
4247
4521
        pSMB->TotalParameterCount = pSMB->ParameterCount;
4248
4522
        pSMB->MaxReferralLevel = cpu_to_le16(3);
4249
 
        pSMB->hdr.smb_buf_length += byte_count;
 
4523
        inc_rfc1001_len(pSMB, byte_count);
4250
4524
        pSMB->ByteCount = cpu_to_le16(byte_count);
4251
4525
 
4252
4526
        rc = SendReceive(xid, ses, (struct smb_hdr *) pSMB,
4258
4532
        rc = validate_t2((struct smb_t2_rsp *)pSMBr);
4259
4533
 
4260
4534
        /* BB Also check if enough total bytes returned? */
4261
 
        if (rc || (pSMBr->ByteCount < 17)) {
 
4535
        if (rc || get_bcc(&pSMBr->hdr) < 17) {
4262
4536
                rc = -EIO;      /* bad smb */
4263
4537
                goto GetDFSRefExit;
4264
4538
        }
4265
4539
 
4266
4540
        cFYI(1, "Decoding GetDFSRefer response BCC: %d  Offset %d",
4267
 
                                pSMBr->ByteCount,
 
4541
                                get_bcc(&pSMBr->hdr),
4268
4542
                                le16_to_cpu(pSMBr->t2.DataOffset));
4269
4543
 
4270
4544
        /* parse returned result into more usable form */
4283
4557
 
4284
4558
/* Query File System Info such as free space to old servers such as Win 9x */
4285
4559
int
4286
 
SMBOldQFSInfo(const int xid, struct cifsTconInfo *tcon, struct kstatfs *FSData)
 
4560
SMBOldQFSInfo(const int xid, struct cifs_tcon *tcon, struct kstatfs *FSData)
4287
4561
{
4288
4562
/* level 0x01 SMB_QUERY_FILE_SYSTEM_INFO */
4289
4563
        TRANSACTION2_QFSI_REQ *pSMB = NULL;
4320
4594
        pSMB->Reserved3 = 0;
4321
4595
        pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_FS_INFORMATION);
4322
4596
        pSMB->InformationLevel = cpu_to_le16(SMB_INFO_ALLOCATION);
4323
 
        pSMB->hdr.smb_buf_length += byte_count;
 
4597
        inc_rfc1001_len(pSMB, byte_count);
4324
4598
        pSMB->ByteCount = cpu_to_le16(byte_count);
4325
4599
 
4326
4600
        rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
4330
4604
        } else {                /* decode response */
4331
4605
                rc = validate_t2((struct smb_t2_rsp *)pSMBr);
4332
4606
 
4333
 
                if (rc || (pSMBr->ByteCount < 18))
 
4607
                if (rc || get_bcc(&pSMBr->hdr) < 18)
4334
4608
                        rc = -EIO;      /* bad smb */
4335
4609
                else {
4336
4610
                        __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
4337
4611
                        cFYI(1, "qfsinf resp BCC: %d  Offset %d",
4338
 
                                 pSMBr->ByteCount, data_offset);
 
4612
                                 get_bcc(&pSMBr->hdr), data_offset);
4339
4613
 
4340
4614
                        response_data = (FILE_SYSTEM_ALLOC_INFO *)
4341
4615
                                (((char *) &pSMBr->hdr.Protocol) + data_offset);
4362
4636
}
4363
4637
 
4364
4638
int
4365
 
CIFSSMBQFSInfo(const int xid, struct cifsTconInfo *tcon, struct kstatfs *FSData)
 
4639
CIFSSMBQFSInfo(const int xid, struct cifs_tcon *tcon, struct kstatfs *FSData)
4366
4640
{
4367
4641
/* level 0x103 SMB_QUERY_FILE_SYSTEM_INFO */
4368
4642
        TRANSACTION2_QFSI_REQ *pSMB = NULL;
4399
4673
        pSMB->Reserved3 = 0;
4400
4674
        pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_FS_INFORMATION);
4401
4675
        pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FS_SIZE_INFO);
4402
 
        pSMB->hdr.smb_buf_length += byte_count;
 
4676
        inc_rfc1001_len(pSMB, byte_count);
4403
4677
        pSMB->ByteCount = cpu_to_le16(byte_count);
4404
4678
 
4405
4679
        rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
4409
4683
        } else {                /* decode response */
4410
4684
                rc = validate_t2((struct smb_t2_rsp *)pSMBr);
4411
4685
 
4412
 
                if (rc || (pSMBr->ByteCount < 24))
 
4686
                if (rc || get_bcc(&pSMBr->hdr) < 24)
4413
4687
                        rc = -EIO;      /* bad smb */
4414
4688
                else {
4415
4689
                        __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
4441
4715
}
4442
4716
 
4443
4717
int
4444
 
CIFSSMBQFSAttributeInfo(const int xid, struct cifsTconInfo *tcon)
 
4718
CIFSSMBQFSAttributeInfo(const int xid, struct cifs_tcon *tcon)
4445
4719
{
4446
4720
/* level 0x105  SMB_QUERY_FILE_SYSTEM_INFO */
4447
4721
        TRANSACTION2_QFSI_REQ *pSMB = NULL;
4479
4753
        pSMB->Reserved3 = 0;
4480
4754
        pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_FS_INFORMATION);
4481
4755
        pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FS_ATTRIBUTE_INFO);
4482
 
        pSMB->hdr.smb_buf_length += byte_count;
 
4756
        inc_rfc1001_len(pSMB, byte_count);
4483
4757
        pSMB->ByteCount = cpu_to_le16(byte_count);
4484
4758
 
4485
4759
        rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
4489
4763
        } else {                /* decode response */
4490
4764
                rc = validate_t2((struct smb_t2_rsp *)pSMBr);
4491
4765
 
4492
 
                if (rc || (pSMBr->ByteCount < 13)) {
 
4766
                if (rc || get_bcc(&pSMBr->hdr) < 13) {
4493
4767
                        /* BB also check if enough bytes returned */
4494
4768
                        rc = -EIO;      /* bad smb */
4495
4769
                } else {
4511
4785
}
4512
4786
 
4513
4787
int
4514
 
CIFSSMBQFSDeviceInfo(const int xid, struct cifsTconInfo *tcon)
 
4788
CIFSSMBQFSDeviceInfo(const int xid, struct cifs_tcon *tcon)
4515
4789
{
4516
4790
/* level 0x104 SMB_QUERY_FILE_SYSTEM_INFO */
4517
4791
        TRANSACTION2_QFSI_REQ *pSMB = NULL;
4550
4824
        pSMB->Reserved3 = 0;
4551
4825
        pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_FS_INFORMATION);
4552
4826
        pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FS_DEVICE_INFO);
4553
 
        pSMB->hdr.smb_buf_length += byte_count;
 
4827
        inc_rfc1001_len(pSMB, byte_count);
4554
4828
        pSMB->ByteCount = cpu_to_le16(byte_count);
4555
4829
 
4556
4830
        rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
4560
4834
        } else {                /* decode response */
4561
4835
                rc = validate_t2((struct smb_t2_rsp *)pSMBr);
4562
4836
 
4563
 
                if (rc || (pSMBr->ByteCount < sizeof(FILE_SYSTEM_DEVICE_INFO)))
 
4837
                if (rc || get_bcc(&pSMBr->hdr) <
 
4838
                          sizeof(FILE_SYSTEM_DEVICE_INFO))
4564
4839
                        rc = -EIO;      /* bad smb */
4565
4840
                else {
4566
4841
                        __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
4581
4856
}
4582
4857
 
4583
4858
int
4584
 
CIFSSMBQFSUnixInfo(const int xid, struct cifsTconInfo *tcon)
 
4859
CIFSSMBQFSUnixInfo(const int xid, struct cifs_tcon *tcon)
4585
4860
{
4586
4861
/* level 0x200  SMB_QUERY_CIFS_UNIX_INFO */
4587
4862
        TRANSACTION2_QFSI_REQ *pSMB = NULL;
4619
4894
        pSMB->Reserved3 = 0;
4620
4895
        pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_FS_INFORMATION);
4621
4896
        pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_CIFS_UNIX_INFO);
4622
 
        pSMB->hdr.smb_buf_length += byte_count;
 
4897
        inc_rfc1001_len(pSMB, byte_count);
4623
4898
        pSMB->ByteCount = cpu_to_le16(byte_count);
4624
4899
 
4625
4900
        rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
4629
4904
        } else {                /* decode response */
4630
4905
                rc = validate_t2((struct smb_t2_rsp *)pSMBr);
4631
4906
 
4632
 
                if (rc || (pSMBr->ByteCount < 13)) {
 
4907
                if (rc || get_bcc(&pSMBr->hdr) < 13) {
4633
4908
                        rc = -EIO;      /* bad smb */
4634
4909
                } else {
4635
4910
                        __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
4651
4926
}
4652
4927
 
4653
4928
int
4654
 
CIFSSMBSetFSUnixInfo(const int xid, struct cifsTconInfo *tcon, __u64 cap)
 
4929
CIFSSMBSetFSUnixInfo(const int xid, struct cifs_tcon *tcon, __u64 cap)
4655
4930
{
4656
4931
/* level 0x200  SMB_SET_CIFS_UNIX_INFO */
4657
4932
        TRANSACTION2_SETFSI_REQ *pSMB = NULL;
4702
4977
        pSMB->ClientUnixMinor = cpu_to_le16(CIFS_UNIX_MINOR_VERSION);
4703
4978
        pSMB->ClientUnixCap = cpu_to_le64(cap);
4704
4979
 
4705
 
        pSMB->hdr.smb_buf_length += byte_count;
 
4980
        inc_rfc1001_len(pSMB, byte_count);
4706
4981
        pSMB->ByteCount = cpu_to_le16(byte_count);
4707
4982
 
4708
4983
        rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
4725
5000
 
4726
5001
 
4727
5002
int
4728
 
CIFSSMBQFSPosixInfo(const int xid, struct cifsTconInfo *tcon,
 
5003
CIFSSMBQFSPosixInfo(const int xid, struct cifs_tcon *tcon,
4729
5004
                   struct kstatfs *FSData)
4730
5005
{
4731
5006
/* level 0x201  SMB_QUERY_CIFS_POSIX_INFO */
4764
5039
        pSMB->Reserved3 = 0;
4765
5040
        pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_FS_INFORMATION);
4766
5041
        pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_POSIX_FS_INFO);
4767
 
        pSMB->hdr.smb_buf_length += byte_count;
 
5042
        inc_rfc1001_len(pSMB, byte_count);
4768
5043
        pSMB->ByteCount = cpu_to_le16(byte_count);
4769
5044
 
4770
5045
        rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
4774
5049
        } else {                /* decode response */
4775
5050
                rc = validate_t2((struct smb_t2_rsp *)pSMBr);
4776
5051
 
4777
 
                if (rc || (pSMBr->ByteCount < 13)) {
 
5052
                if (rc || get_bcc(&pSMBr->hdr) < 13) {
4778
5053
                        rc = -EIO;      /* bad smb */
4779
5054
                } else {
4780
5055
                        __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
4818
5093
   in Samba which this routine can run into */
4819
5094
 
4820
5095
int
4821
 
CIFSSMBSetEOF(const int xid, struct cifsTconInfo *tcon, const char *fileName,
 
5096
CIFSSMBSetEOF(const int xid, struct cifs_tcon *tcon, const char *fileName,
4822
5097
              __u64 size, bool SetAllocation,
4823
5098
              const struct nls_table *nls_codepage, int remap)
4824
5099
{
4890
5165
        pSMB->ParameterCount = cpu_to_le16(params);
4891
5166
        pSMB->TotalParameterCount = pSMB->ParameterCount;
4892
5167
        pSMB->Reserved4 = 0;
4893
 
        pSMB->hdr.smb_buf_length += byte_count;
 
5168
        inc_rfc1001_len(pSMB, byte_count);
4894
5169
        parm_data->FileSize = cpu_to_le64(size);
4895
5170
        pSMB->ByteCount = cpu_to_le16(byte_count);
4896
5171
        rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
4907
5182
}
4908
5183
 
4909
5184
int
4910
 
CIFSSMBSetFileSize(const int xid, struct cifsTconInfo *tcon, __u64 size,
 
5185
CIFSSMBSetFileSize(const int xid, struct cifs_tcon *tcon, __u64 size,
4911
5186
                   __u16 fid, __u32 pid_of_opener, bool SetAllocation)
4912
5187
{
4913
5188
        struct smb_com_transaction2_sfi_req *pSMB  = NULL;
4969
5244
                                cpu_to_le16(SMB_SET_FILE_END_OF_FILE_INFO);
4970
5245
        }
4971
5246
        pSMB->Reserved4 = 0;
4972
 
        pSMB->hdr.smb_buf_length += byte_count;
 
5247
        inc_rfc1001_len(pSMB, byte_count);
4973
5248
        pSMB->ByteCount = cpu_to_le16(byte_count);
4974
5249
        rc = SendReceiveNoRsp(xid, tcon->ses, (struct smb_hdr *) pSMB, 0);
4975
5250
        if (rc) {
4989
5264
   time and resort to the original setpathinfo level which takes the ancient
4990
5265
   DOS time format with 2 second granularity */
4991
5266
int
4992
 
CIFSSMBSetFileInfo(const int xid, struct cifsTconInfo *tcon,
 
5267
CIFSSMBSetFileInfo(const int xid, struct cifs_tcon *tcon,
4993
5268
                    const FILE_BASIC_INFO *data, __u16 fid, __u32 pid_of_opener)
4994
5269
{
4995
5270
        struct smb_com_transaction2_sfi_req *pSMB  = NULL;
5037
5312
        else
5038
5313
                pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_BASIC_INFO);
5039
5314
        pSMB->Reserved4 = 0;
5040
 
        pSMB->hdr.smb_buf_length += byte_count;
 
5315
        inc_rfc1001_len(pSMB, byte_count);
5041
5316
        pSMB->ByteCount = cpu_to_le16(byte_count);
5042
5317
        memcpy(data_offset, data, sizeof(FILE_BASIC_INFO));
5043
5318
        rc = SendReceiveNoRsp(xid, tcon->ses, (struct smb_hdr *) pSMB, 0);
5051
5326
}
5052
5327
 
5053
5328
int
5054
 
CIFSSMBSetFileDisposition(const int xid, struct cifsTconInfo *tcon,
 
5329
CIFSSMBSetFileDisposition(const int xid, struct cifs_tcon *tcon,
5055
5330
                          bool delete_file, __u16 fid, __u32 pid_of_opener)
5056
5331
{
5057
5332
        struct smb_com_transaction2_sfi_req *pSMB  = NULL;
5096
5371
        pSMB->Fid = fid;
5097
5372
        pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_DISPOSITION_INFO);
5098
5373
        pSMB->Reserved4 = 0;
5099
 
        pSMB->hdr.smb_buf_length += byte_count;
 
5374
        inc_rfc1001_len(pSMB, byte_count);
5100
5375
        pSMB->ByteCount = cpu_to_le16(byte_count);
5101
5376
        *data_offset = delete_file ? 1 : 0;
5102
5377
        rc = SendReceiveNoRsp(xid, tcon->ses, (struct smb_hdr *) pSMB, 0);
5107
5382
}
5108
5383
 
5109
5384
int
5110
 
CIFSSMBSetPathInfo(const int xid, struct cifsTconInfo *tcon,
 
5385
CIFSSMBSetPathInfo(const int xid, struct cifs_tcon *tcon,
5111
5386
                   const char *fileName, const FILE_BASIC_INFO *data,
5112
5387
                   const struct nls_table *nls_codepage, int remap)
5113
5388
{
5169
5444
        else
5170
5445
                pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_BASIC_INFO);
5171
5446
        pSMB->Reserved4 = 0;
5172
 
        pSMB->hdr.smb_buf_length += byte_count;
 
5447
        inc_rfc1001_len(pSMB, byte_count);
5173
5448
        memcpy(data_offset, data, sizeof(FILE_BASIC_INFO));
5174
5449
        pSMB->ByteCount = cpu_to_le16(byte_count);
5175
5450
        rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
5191
5466
          handling it anyway and NT4 was what we thought it would be needed for
5192
5467
          Do not delete it until we prove whether needed for Win9x though */
5193
5468
int
5194
 
CIFSSMBSetAttrLegacy(int xid, struct cifsTconInfo *tcon, char *fileName,
 
5469
CIFSSMBSetAttrLegacy(int xid, struct cifs_tcon *tcon, char *fileName,
5195
5470
                __u16 dos_attrs, const struct nls_table *nls_codepage)
5196
5471
{
5197
5472
        SETATTR_REQ *pSMB = NULL;
5221
5496
        }
5222
5497
        pSMB->attr = cpu_to_le16(dos_attrs);
5223
5498
        pSMB->BufferFormat = 0x04;
5224
 
        pSMB->hdr.smb_buf_length += name_len + 1;
 
5499
        inc_rfc1001_len(pSMB, name_len + 1);
5225
5500
        pSMB->ByteCount = cpu_to_le16(name_len + 1);
5226
5501
        rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
5227
5502
                         (struct smb_hdr *) pSMBr, &bytes_returned, 0);
5279
5554
}
5280
5555
 
5281
5556
int
5282
 
CIFSSMBUnixSetFileInfo(const int xid, struct cifsTconInfo *tcon,
 
5557
CIFSSMBUnixSetFileInfo(const int xid, struct cifs_tcon *tcon,
5283
5558
                       const struct cifs_unix_set_info_args *args,
5284
5559
                       u16 fid, u32 pid_of_opener)
5285
5560
{
5326
5601
        pSMB->Fid = fid;
5327
5602
        pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_UNIX_BASIC);
5328
5603
        pSMB->Reserved4 = 0;
5329
 
        pSMB->hdr.smb_buf_length += byte_count;
 
5604
        inc_rfc1001_len(pSMB, byte_count);
5330
5605
        pSMB->ByteCount = cpu_to_le16(byte_count);
5331
5606
 
5332
5607
        cifs_fill_unix_set_info(data_offset, args);
5342
5617
}
5343
5618
 
5344
5619
int
5345
 
CIFSSMBUnixSetPathInfo(const int xid, struct cifsTconInfo *tcon, char *fileName,
 
5620
CIFSSMBUnixSetPathInfo(const int xid, struct cifs_tcon *tcon, char *fileName,
5346
5621
                       const struct cifs_unix_set_info_args *args,
5347
5622
                       const struct nls_table *nls_codepage, int remap)
5348
5623
{
5402
5677
        pSMB->TotalDataCount = pSMB->DataCount;
5403
5678
        pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_UNIX_BASIC);
5404
5679
        pSMB->Reserved4 = 0;
5405
 
        pSMB->hdr.smb_buf_length += byte_count;
 
5680
        inc_rfc1001_len(pSMB, byte_count);
5406
5681
 
5407
5682
        cifs_fill_unix_set_info(data_offset, args);
5408
5683
 
5418
5693
        return rc;
5419
5694
}
5420
5695
 
5421
 
int CIFSSMBNotify(const int xid, struct cifsTconInfo *tcon,
5422
 
                  const int notify_subdirs, const __u16 netfid,
5423
 
                  __u32 filter, struct file *pfile, int multishot,
5424
 
                  const struct nls_table *nls_codepage)
5425
 
{
5426
 
        int rc = 0;
5427
 
        struct smb_com_transaction_change_notify_req *pSMB = NULL;
5428
 
        struct smb_com_ntransaction_change_notify_rsp *pSMBr = NULL;
5429
 
        struct dir_notify_req *dnotify_req;
5430
 
        int bytes_returned;
5431
 
 
5432
 
        cFYI(1, "In CIFSSMBNotify for file handle %d", (int)netfid);
5433
 
        rc = smb_init(SMB_COM_NT_TRANSACT, 23, tcon, (void **) &pSMB,
5434
 
                      (void **) &pSMBr);
5435
 
        if (rc)
5436
 
                return rc;
5437
 
 
5438
 
        pSMB->TotalParameterCount = 0 ;
5439
 
        pSMB->TotalDataCount = 0;
5440
 
        pSMB->MaxParameterCount = cpu_to_le32(2);
5441
 
        /* BB find exact data count max from sess structure BB */
5442
 
        pSMB->MaxDataCount = 0; /* same in little endian or be */
5443
 
/* BB VERIFY verify which is correct for above BB */
5444
 
        pSMB->MaxDataCount = cpu_to_le32((tcon->ses->server->maxBuf -
5445
 
                                             MAX_CIFS_HDR_SIZE) & 0xFFFFFF00);
5446
 
 
5447
 
        pSMB->MaxSetupCount = 4;
5448
 
        pSMB->Reserved = 0;
5449
 
        pSMB->ParameterOffset = 0;
5450
 
        pSMB->DataCount = 0;
5451
 
        pSMB->DataOffset = 0;
5452
 
        pSMB->SetupCount = 4; /* single byte does not need le conversion */
5453
 
        pSMB->SubCommand = cpu_to_le16(NT_TRANSACT_NOTIFY_CHANGE);
5454
 
        pSMB->ParameterCount = pSMB->TotalParameterCount;
5455
 
        if (notify_subdirs)
5456
 
                pSMB->WatchTree = 1; /* one byte - no le conversion needed */
5457
 
        pSMB->Reserved2 = 0;
5458
 
        pSMB->CompletionFilter = cpu_to_le32(filter);
5459
 
        pSMB->Fid = netfid; /* file handle always le */
5460
 
        pSMB->ByteCount = 0;
5461
 
 
5462
 
        rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
5463
 
                         (struct smb_hdr *)pSMBr, &bytes_returned,
5464
 
                         CIFS_ASYNC_OP);
5465
 
        if (rc) {
5466
 
                cFYI(1, "Error in Notify = %d", rc);
5467
 
        } else {
5468
 
                /* Add file to outstanding requests */
5469
 
                /* BB change to kmem cache alloc */
5470
 
                dnotify_req = kmalloc(
5471
 
                                                sizeof(struct dir_notify_req),
5472
 
                                                 GFP_KERNEL);
5473
 
                if (dnotify_req) {
5474
 
                        dnotify_req->Pid = pSMB->hdr.Pid;
5475
 
                        dnotify_req->PidHigh = pSMB->hdr.PidHigh;
5476
 
                        dnotify_req->Mid = pSMB->hdr.Mid;
5477
 
                        dnotify_req->Tid = pSMB->hdr.Tid;
5478
 
                        dnotify_req->Uid = pSMB->hdr.Uid;
5479
 
                        dnotify_req->netfid = netfid;
5480
 
                        dnotify_req->pfile = pfile;
5481
 
                        dnotify_req->filter = filter;
5482
 
                        dnotify_req->multishot = multishot;
5483
 
                        spin_lock(&GlobalMid_Lock);
5484
 
                        list_add_tail(&dnotify_req->lhead,
5485
 
                                        &GlobalDnotifyReqList);
5486
 
                        spin_unlock(&GlobalMid_Lock);
5487
 
                } else
5488
 
                        rc = -ENOMEM;
5489
 
        }
5490
 
        cifs_buf_release(pSMB);
5491
 
        return rc;
5492
 
}
5493
 
 
5494
5696
#ifdef CONFIG_CIFS_XATTR
5495
5697
/*
5496
5698
 * Do a path-based QUERY_ALL_EAS call and parse the result. This is a common
5502
5704
 * the data isn't copied to it, but the length is returned.
5503
5705
 */
5504
5706
ssize_t
5505
 
CIFSSMBQAllEAs(const int xid, struct cifsTconInfo *tcon,
 
5707
CIFSSMBQAllEAs(const int xid, struct cifs_tcon *tcon,
5506
5708
                const unsigned char *searchName, const unsigned char *ea_name,
5507
5709
                char *EAData, size_t buf_size,
5508
5710
                const struct nls_table *nls_codepage, int remap)
5560
5762
        pSMB->ParameterCount = pSMB->TotalParameterCount;
5561
5763
        pSMB->InformationLevel = cpu_to_le16(SMB_INFO_QUERY_ALL_EAS);
5562
5764
        pSMB->Reserved4 = 0;
5563
 
        pSMB->hdr.smb_buf_length += byte_count;
 
5765
        inc_rfc1001_len(pSMB, byte_count);
5564
5766
        pSMB->ByteCount = cpu_to_le16(byte_count);
5565
5767
 
5566
5768
        rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
5576
5778
        of these trans2 responses */
5577
5779
 
5578
5780
        rc = validate_t2((struct smb_t2_rsp *)pSMBr);
5579
 
        if (rc || (pSMBr->ByteCount < 4)) {
 
5781
        if (rc || get_bcc(&pSMBr->hdr) < 4) {
5580
5782
                rc = -EIO;      /* bad smb */
5581
5783
                goto QAllEAsOut;
5582
5784
        }
5683
5885
}
5684
5886
 
5685
5887
int
5686
 
CIFSSMBSetEA(const int xid, struct cifsTconInfo *tcon, const char *fileName,
 
5888
CIFSSMBSetEA(const int xid, struct cifs_tcon *tcon, const char *fileName,
5687
5889
             const char *ea_name, const void *ea_value,
5688
5890
             const __u16 ea_value_len, const struct nls_table *nls_codepage,
5689
5891
             int remap)
5773
5975
        pSMB->ParameterCount = cpu_to_le16(params);
5774
5976
        pSMB->TotalParameterCount = pSMB->ParameterCount;
5775
5977
        pSMB->Reserved4 = 0;
5776
 
        pSMB->hdr.smb_buf_length += byte_count;
 
5978
        inc_rfc1001_len(pSMB, byte_count);
5777
5979
        pSMB->ByteCount = cpu_to_le16(byte_count);
5778
5980
        rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
5779
5981
                         (struct smb_hdr *) pSMBr, &bytes_returned, 0);
5787
5989
 
5788
5990
        return rc;
5789
5991
}
5790
 
 
5791
5992
#endif
 
5993
 
 
5994
#ifdef CONFIG_CIFS_DNOTIFY_EXPERIMENTAL /* BB unused temporarily */
 
5995
/*
 
5996
 *      Years ago the kernel added a "dnotify" function for Samba server,
 
5997
 *      to allow network clients (such as Windows) to display updated
 
5998
 *      lists of files in directory listings automatically when
 
5999
 *      files are added by one user when another user has the
 
6000
 *      same directory open on their desktop.  The Linux cifs kernel
 
6001
 *      client hooked into the kernel side of this interface for
 
6002
 *      the same reason, but ironically when the VFS moved from
 
6003
 *      "dnotify" to "inotify" it became harder to plug in Linux
 
6004
 *      network file system clients (the most obvious use case
 
6005
 *      for notify interfaces is when multiple users can update
 
6006
 *      the contents of the same directory - exactly what network
 
6007
 *      file systems can do) although the server (Samba) could
 
6008
 *      still use it.  For the short term we leave the worker
 
6009
 *      function ifdeffed out (below) until inotify is fixed
 
6010
 *      in the VFS to make it easier to plug in network file
 
6011
 *      system clients.  If inotify turns out to be permanently
 
6012
 *      incompatible for network fs clients, we could instead simply
 
6013
 *      expose this config flag by adding a future cifs (and smb2) notify ioctl.
 
6014
 */
 
6015
int CIFSSMBNotify(const int xid, struct cifs_tcon *tcon,
 
6016
                  const int notify_subdirs, const __u16 netfid,
 
6017
                  __u32 filter, struct file *pfile, int multishot,
 
6018
                  const struct nls_table *nls_codepage)
 
6019
{
 
6020
        int rc = 0;
 
6021
        struct smb_com_transaction_change_notify_req *pSMB = NULL;
 
6022
        struct smb_com_ntransaction_change_notify_rsp *pSMBr = NULL;
 
6023
        struct dir_notify_req *dnotify_req;
 
6024
        int bytes_returned;
 
6025
 
 
6026
        cFYI(1, "In CIFSSMBNotify for file handle %d", (int)netfid);
 
6027
        rc = smb_init(SMB_COM_NT_TRANSACT, 23, tcon, (void **) &pSMB,
 
6028
                      (void **) &pSMBr);
 
6029
        if (rc)
 
6030
                return rc;
 
6031
 
 
6032
        pSMB->TotalParameterCount = 0 ;
 
6033
        pSMB->TotalDataCount = 0;
 
6034
        pSMB->MaxParameterCount = cpu_to_le32(2);
 
6035
        /* BB find exact data count max from sess structure BB */
 
6036
        pSMB->MaxDataCount = 0; /* same in little endian or be */
 
6037
/* BB VERIFY verify which is correct for above BB */
 
6038
        pSMB->MaxDataCount = cpu_to_le32((tcon->ses->server->maxBuf -
 
6039
                                             MAX_CIFS_HDR_SIZE) & 0xFFFFFF00);
 
6040
 
 
6041
        pSMB->MaxSetupCount = 4;
 
6042
        pSMB->Reserved = 0;
 
6043
        pSMB->ParameterOffset = 0;
 
6044
        pSMB->DataCount = 0;
 
6045
        pSMB->DataOffset = 0;
 
6046
        pSMB->SetupCount = 4; /* single byte does not need le conversion */
 
6047
        pSMB->SubCommand = cpu_to_le16(NT_TRANSACT_NOTIFY_CHANGE);
 
6048
        pSMB->ParameterCount = pSMB->TotalParameterCount;
 
6049
        if (notify_subdirs)
 
6050
                pSMB->WatchTree = 1; /* one byte - no le conversion needed */
 
6051
        pSMB->Reserved2 = 0;
 
6052
        pSMB->CompletionFilter = cpu_to_le32(filter);
 
6053
        pSMB->Fid = netfid; /* file handle always le */
 
6054
        pSMB->ByteCount = 0;
 
6055
 
 
6056
        rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
 
6057
                         (struct smb_hdr *)pSMBr, &bytes_returned,
 
6058
                         CIFS_ASYNC_OP);
 
6059
        if (rc) {
 
6060
                cFYI(1, "Error in Notify = %d", rc);
 
6061
        } else {
 
6062
                /* Add file to outstanding requests */
 
6063
                /* BB change to kmem cache alloc */
 
6064
                dnotify_req = kmalloc(
 
6065
                                                sizeof(struct dir_notify_req),
 
6066
                                                 GFP_KERNEL);
 
6067
                if (dnotify_req) {
 
6068
                        dnotify_req->Pid = pSMB->hdr.Pid;
 
6069
                        dnotify_req->PidHigh = pSMB->hdr.PidHigh;
 
6070
                        dnotify_req->Mid = pSMB->hdr.Mid;
 
6071
                        dnotify_req->Tid = pSMB->hdr.Tid;
 
6072
                        dnotify_req->Uid = pSMB->hdr.Uid;
 
6073
                        dnotify_req->netfid = netfid;
 
6074
                        dnotify_req->pfile = pfile;
 
6075
                        dnotify_req->filter = filter;
 
6076
                        dnotify_req->multishot = multishot;
 
6077
                        spin_lock(&GlobalMid_Lock);
 
6078
                        list_add_tail(&dnotify_req->lhead,
 
6079
                                        &GlobalDnotifyReqList);
 
6080
                        spin_unlock(&GlobalMid_Lock);
 
6081
                } else
 
6082
                        rc = -ENOMEM;
 
6083
        }
 
6084
        cifs_buf_release(pSMB);
 
6085
        return rc;
 
6086
}
 
6087
#endif /* was needed for dnotify, and will be needed for inotify when VFS fix */