aboutsummaryrefslogtreecommitdiffstats
path: root/fs/cifs/cifssmb.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/cifs/cifssmb.c')
-rw-r--r--fs/cifs/cifssmb.c1171
1 files changed, 753 insertions, 418 deletions
diff --git a/fs/cifs/cifssmb.c b/fs/cifs/cifssmb.c
index 7e83b356cc9e..1a9fe7f816d1 100644
--- a/fs/cifs/cifssmb.c
+++ b/fs/cifs/cifssmb.c
@@ -32,6 +32,7 @@
32#include <linux/vfs.h> 32#include <linux/vfs.h>
33#include <linux/slab.h> 33#include <linux/slab.h>
34#include <linux/posix_acl_xattr.h> 34#include <linux/posix_acl_xattr.h>
35#include <linux/pagemap.h>
35#include <asm/uaccess.h> 36#include <asm/uaccess.h>
36#include "cifspdu.h" 37#include "cifspdu.h"
37#include "cifsglob.h" 38#include "cifsglob.h"
@@ -84,30 +85,30 @@ static struct {
84 85
85/* Mark as invalid, all open files on tree connections since they 86/* Mark as invalid, all open files on tree connections since they
86 were closed when session to server was lost */ 87 were closed when session to server was lost */
87static void mark_open_files_invalid(struct cifsTconInfo *pTcon) 88static void mark_open_files_invalid(struct cifs_tcon *pTcon)
88{ 89{
89 struct cifsFileInfo *open_file = NULL; 90 struct cifsFileInfo *open_file = NULL;
90 struct list_head *tmp; 91 struct list_head *tmp;
91 struct list_head *tmp1; 92 struct list_head *tmp1;
92 93
93/* list all files open on tree connection and mark them invalid */ 94/* list all files open on tree connection and mark them invalid */
94 write_lock(&GlobalSMBSeslock); 95 spin_lock(&cifs_file_list_lock);
95 list_for_each_safe(tmp, tmp1, &pTcon->openFileList) { 96 list_for_each_safe(tmp, tmp1, &pTcon->openFileList) {
96 open_file = list_entry(tmp, struct cifsFileInfo, tlist); 97 open_file = list_entry(tmp, struct cifsFileInfo, tlist);
97 open_file->invalidHandle = true; 98 open_file->invalidHandle = true;
98 open_file->oplock_break_cancelled = true; 99 open_file->oplock_break_cancelled = true;
99 } 100 }
100 write_unlock(&GlobalSMBSeslock); 101 spin_unlock(&cifs_file_list_lock);
101 /* BB Add call to invalidate_inodes(sb) for all superblocks mounted 102 /* BB Add call to invalidate_inodes(sb) for all superblocks mounted
102 to this tcon */ 103 to this tcon */
103} 104}
104 105
105/* reconnect the socket, tcon, and smb session if needed */ 106/* reconnect the socket, tcon, and smb session if needed */
106static int 107static int
107cifs_reconnect_tcon(struct cifsTconInfo *tcon, int smb_command) 108cifs_reconnect_tcon(struct cifs_tcon *tcon, int smb_command)
108{ 109{
109 int rc = 0; 110 int rc = 0;
110 struct cifsSesInfo *ses; 111 struct cifs_ses *ses;
111 struct TCP_Server_Info *server; 112 struct TCP_Server_Info *server;
112 struct nls_table *nls_codepage; 113 struct nls_table *nls_codepage;
113 114
@@ -136,18 +137,15 @@ cifs_reconnect_tcon(struct cifsTconInfo *tcon, int smb_command)
136 } 137 }
137 } 138 }
138 139
139 if (ses->status == CifsExiting)
140 return -EIO;
141
142 /* 140 /*
143 * Give demultiplex thread up to 10 seconds to reconnect, should be 141 * Give demultiplex thread up to 10 seconds to reconnect, should be
144 * greater than cifs socket timeout which is 7 seconds 142 * greater than cifs socket timeout which is 7 seconds
145 */ 143 */
146 while (server->tcpStatus == CifsNeedReconnect) { 144 while (server->tcpStatus == CifsNeedReconnect) {
147 wait_event_interruptible_timeout(server->response_q, 145 wait_event_interruptible_timeout(server->response_q,
148 (server->tcpStatus == CifsGood), 10 * HZ); 146 (server->tcpStatus != CifsNeedReconnect), 10 * HZ);
149 147
150 /* is TCP session is reestablished now ?*/ 148 /* are we still trying to reconnect? */
151 if (server->tcpStatus != CifsNeedReconnect) 149 if (server->tcpStatus != CifsNeedReconnect)
152 break; 150 break;
153 151
@@ -156,7 +154,7 @@ cifs_reconnect_tcon(struct cifsTconInfo *tcon, int smb_command)
156 * retrying until process is killed or server comes 154 * retrying until process is killed or server comes
157 * back on-line 155 * back on-line
158 */ 156 */
159 if (!tcon->retry || ses->status == CifsExiting) { 157 if (!tcon->retry) {
160 cFYI(1, "gave up waiting on reconnect in smb_init"); 158 cFYI(1, "gave up waiting on reconnect in smb_init");
161 return -EHOSTDOWN; 159 return -EHOSTDOWN;
162 } 160 }
@@ -229,7 +227,7 @@ out:
229 SMB information in the SMB header. If the return code is zero, this 227 SMB information in the SMB header. If the return code is zero, this
230 function must have filled in request_buf pointer */ 228 function must have filled in request_buf pointer */
231static int 229static int
232small_smb_init(int smb_command, int wct, struct cifsTconInfo *tcon, 230small_smb_init(int smb_command, int wct, struct cifs_tcon *tcon,
233 void **request_buf) 231 void **request_buf)
234{ 232{
235 int rc; 233 int rc;
@@ -255,7 +253,7 @@ small_smb_init(int smb_command, int wct, struct cifsTconInfo *tcon,
255 253
256int 254int
257small_smb_init_no_tc(const int smb_command, const int wct, 255small_smb_init_no_tc(const int smb_command, const int wct,
258 struct cifsSesInfo *ses, void **request_buf) 256 struct cifs_ses *ses, void **request_buf)
259{ 257{
260 int rc; 258 int rc;
261 struct smb_hdr *buffer; 259 struct smb_hdr *buffer;
@@ -281,7 +279,7 @@ small_smb_init_no_tc(const int smb_command, const int wct,
281 279
282/* If the return code is zero, this function must fill in request_buf pointer */ 280/* If the return code is zero, this function must fill in request_buf pointer */
283static int 281static int
284__smb_init(int smb_command, int wct, struct cifsTconInfo *tcon, 282__smb_init(int smb_command, int wct, struct cifs_tcon *tcon,
285 void **request_buf, void **response_buf) 283 void **request_buf, void **response_buf)
286{ 284{
287 *request_buf = cifs_buf_get(); 285 *request_buf = cifs_buf_get();
@@ -307,7 +305,7 @@ __smb_init(int smb_command, int wct, struct cifsTconInfo *tcon,
307 305
308/* If the return code is zero, this function must fill in request_buf pointer */ 306/* If the return code is zero, this function must fill in request_buf pointer */
309static int 307static int
310smb_init(int smb_command, int wct, struct cifsTconInfo *tcon, 308smb_init(int smb_command, int wct, struct cifs_tcon *tcon,
311 void **request_buf, void **response_buf) 309 void **request_buf, void **response_buf)
312{ 310{
313 int rc; 311 int rc;
@@ -320,7 +318,7 @@ smb_init(int smb_command, int wct, struct cifsTconInfo *tcon,
320} 318}
321 319
322static int 320static int
323smb_init_no_reconnect(int smb_command, int wct, struct cifsTconInfo *tcon, 321smb_init_no_reconnect(int smb_command, int wct, struct cifs_tcon *tcon,
324 void **request_buf, void **response_buf) 322 void **request_buf, void **response_buf)
325{ 323{
326 if (tcon->ses->need_reconnect || tcon->need_reconnect) 324 if (tcon->ses->need_reconnect || tcon->need_reconnect)
@@ -331,39 +329,45 @@ smb_init_no_reconnect(int smb_command, int wct, struct cifsTconInfo *tcon,
331 329
332static int validate_t2(struct smb_t2_rsp *pSMB) 330static int validate_t2(struct smb_t2_rsp *pSMB)
333{ 331{
334 int rc = -EINVAL; 332 unsigned int total_size;
335 int total_size; 333
336 char *pBCC; 334 /* check for plausible wct */
335 if (pSMB->hdr.WordCount < 10)
336 goto vt2_err;
337 337
338 /* check for plausible wct, bcc and t2 data and parm sizes */
339 /* check for parm and data offset going beyond end of smb */ 338 /* check for parm and data offset going beyond end of smb */
340 if (pSMB->hdr.WordCount >= 10) { 339 if (get_unaligned_le16(&pSMB->t2_rsp.ParameterOffset) > 1024 ||
341 if ((le16_to_cpu(pSMB->t2_rsp.ParameterOffset) <= 1024) && 340 get_unaligned_le16(&pSMB->t2_rsp.DataOffset) > 1024)
342 (le16_to_cpu(pSMB->t2_rsp.DataOffset) <= 1024)) { 341 goto vt2_err;
343 /* check that bcc is at least as big as parms + data */ 342
344 /* check that bcc is less than negotiated smb buffer */ 343 total_size = get_unaligned_le16(&pSMB->t2_rsp.ParameterCount);
345 total_size = le16_to_cpu(pSMB->t2_rsp.ParameterCount); 344 if (total_size >= 512)
346 if (total_size < 512) { 345 goto vt2_err;
347 total_size += 346
348 le16_to_cpu(pSMB->t2_rsp.DataCount); 347 /* check that bcc is at least as big as parms + data, and that it is
349 /* BCC le converted in SendReceive */ 348 * less than negotiated smb buffer
350 pBCC = (pSMB->hdr.WordCount * 2) + 349 */
351 sizeof(struct smb_hdr) + 350 total_size += get_unaligned_le16(&pSMB->t2_rsp.DataCount);
352 (char *)pSMB; 351 if (total_size > get_bcc(&pSMB->hdr) ||
353 if ((total_size <= (*(u16 *)pBCC)) && 352 total_size >= CIFSMaxBufSize + MAX_CIFS_HDR_SIZE)
354 (total_size < 353 goto vt2_err;
355 CIFSMaxBufSize+MAX_CIFS_HDR_SIZE)) { 354
356 return 0; 355 return 0;
357 } 356vt2_err:
358 }
359 }
360 }
361 cifs_dump_mem("Invalid transact2 SMB: ", (char *)pSMB, 357 cifs_dump_mem("Invalid transact2 SMB: ", (char *)pSMB,
362 sizeof(struct smb_t2_rsp) + 16); 358 sizeof(struct smb_t2_rsp) + 16);
363 return rc; 359 return -EINVAL;
364} 360}
361
362static 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
365int 369int
366CIFSSMBNegotiate(unsigned int xid, struct cifsSesInfo *ses) 370CIFSSMBNegotiate(unsigned int xid, struct cifs_ses *ses)
367{ 371{
368 NEGOTIATE_REQ *pSMB; 372 NEGOTIATE_REQ *pSMB;
369 NEGOTIATE_RSP *pSMBr; 373 NEGOTIATE_RSP *pSMBr;
@@ -401,15 +405,12 @@ CIFSSMBNegotiate(unsigned int xid, struct cifsSesInfo *ses)
401 else if ((secFlags & CIFSSEC_AUTH_MASK) == CIFSSEC_MAY_KRB5) { 405 else if ((secFlags & CIFSSEC_AUTH_MASK) == CIFSSEC_MAY_KRB5) {
402 cFYI(1, "Kerberos only mechanism, enable extended security"); 406 cFYI(1, "Kerberos only mechanism, enable extended security");
403 pSMB->hdr.Flags2 |= SMBFLG2_EXT_SEC; 407 pSMB->hdr.Flags2 |= SMBFLG2_EXT_SEC;
404 } 408 } else if ((secFlags & CIFSSEC_MUST_NTLMSSP) == CIFSSEC_MUST_NTLMSSP)
405#ifdef CONFIG_CIFS_EXPERIMENTAL
406 else if ((secFlags & CIFSSEC_MUST_NTLMSSP) == CIFSSEC_MUST_NTLMSSP)
407 pSMB->hdr.Flags2 |= SMBFLG2_EXT_SEC; 409 pSMB->hdr.Flags2 |= SMBFLG2_EXT_SEC;
408 else if ((secFlags & CIFSSEC_AUTH_MASK) == CIFSSEC_MAY_NTLMSSP) { 410 else if ((secFlags & CIFSSEC_AUTH_MASK) == CIFSSEC_MAY_NTLMSSP) {
409 cFYI(1, "NTLMSSP only mechanism, enable extended security"); 411 cFYI(1, "NTLMSSP only mechanism, enable extended security");
410 pSMB->hdr.Flags2 |= SMBFLG2_EXT_SEC; 412 pSMB->hdr.Flags2 |= SMBFLG2_EXT_SEC;
411 } 413 }
412#endif
413 414
414 count = 0; 415 count = 0;
415 for (i = 0; i < CIFS_NUM_PROT; i++) { 416 for (i = 0; i < CIFS_NUM_PROT; i++) {
@@ -417,7 +418,7 @@ CIFSSMBNegotiate(unsigned int xid, struct cifsSesInfo *ses)
417 count += strlen(protocols[i].name) + 1; 418 count += strlen(protocols[i].name) + 1;
418 /* null at end of source and target buffers anyway */ 419 /* null at end of source and target buffers anyway */
419 } 420 }
420 pSMB->hdr.smb_buf_length += count; 421 inc_rfc1001_len(pSMB, count);
421 pSMB->ByteCount = cpu_to_le16(count); 422 pSMB->ByteCount = cpu_to_le16(count);
422 423
423 rc = SendReceive(xid, ses, (struct smb_hdr *) pSMB, 424 rc = SendReceive(xid, ses, (struct smb_hdr *) pSMB,
@@ -450,12 +451,11 @@ CIFSSMBNegotiate(unsigned int xid, struct cifsSesInfo *ses)
450 rc = -EOPNOTSUPP; 451 rc = -EOPNOTSUPP;
451 goto neg_err_exit; 452 goto neg_err_exit;
452 } 453 }
453 server->secMode = (__u8)le16_to_cpu(rsp->SecurityMode); 454 server->sec_mode = (__u8)le16_to_cpu(rsp->SecurityMode);
454 server->maxReq = le16_to_cpu(rsp->MaxMpxCount); 455 server->maxReq = le16_to_cpu(rsp->MaxMpxCount);
455 server->maxBuf = min((__u32)le16_to_cpu(rsp->MaxBufSize), 456 server->maxBuf = min((__u32)le16_to_cpu(rsp->MaxBufSize),
456 (__u32)CIFSMaxBufSize + MAX_CIFS_HDR_SIZE); 457 (__u32)CIFSMaxBufSize + MAX_CIFS_HDR_SIZE);
457 server->max_vcs = le16_to_cpu(rsp->MaxNumberVcs); 458 server->max_vcs = le16_to_cpu(rsp->MaxNumberVcs);
458 GETU32(server->sessid) = le32_to_cpu(rsp->SessionKey);
459 /* even though we do not use raw we might as well set this 459 /* even though we do not use raw we might as well set this
460 accurately, in case we ever find a need for it */ 460 accurately, in case we ever find a need for it */
461 if ((le16_to_cpu(rsp->RawMode) & RAW_ENABLE) == RAW_ENABLE) { 461 if ((le16_to_cpu(rsp->RawMode) & RAW_ENABLE) == RAW_ENABLE) {
@@ -503,9 +503,9 @@ CIFSSMBNegotiate(unsigned int xid, struct cifsSesInfo *ses)
503 503
504 if (rsp->EncryptionKeyLength == 504 if (rsp->EncryptionKeyLength ==
505 cpu_to_le16(CIFS_CRYPTO_KEY_SIZE)) { 505 cpu_to_le16(CIFS_CRYPTO_KEY_SIZE)) {
506 memcpy(server->cryptKey, rsp->EncryptionKey, 506 memcpy(ses->server->cryptkey, rsp->EncryptionKey,
507 CIFS_CRYPTO_KEY_SIZE); 507 CIFS_CRYPTO_KEY_SIZE);
508 } else if (server->secMode & SECMODE_PW_ENCRYPT) { 508 } else if (server->sec_mode & SECMODE_PW_ENCRYPT) {
509 rc = -EIO; /* need cryptkey unless plain text */ 509 rc = -EIO; /* need cryptkey unless plain text */
510 goto neg_err_exit; 510 goto neg_err_exit;
511 } 511 }
@@ -527,11 +527,11 @@ CIFSSMBNegotiate(unsigned int xid, struct cifsSesInfo *ses)
527 goto neg_err_exit; 527 goto neg_err_exit;
528 } 528 }
529 /* else wct == 17 NTLM */ 529 /* else wct == 17 NTLM */
530 server->secMode = pSMBr->SecurityMode; 530 server->sec_mode = pSMBr->SecurityMode;
531 if ((server->secMode & SECMODE_USER) == 0) 531 if ((server->sec_mode & SECMODE_USER) == 0)
532 cFYI(1, "share mode security"); 532 cFYI(1, "share mode security");
533 533
534 if ((server->secMode & SECMODE_PW_ENCRYPT) == 0) 534 if ((server->sec_mode & SECMODE_PW_ENCRYPT) == 0)
535#ifdef CONFIG_CIFS_WEAK_PW_HASH 535#ifdef CONFIG_CIFS_WEAK_PW_HASH
536 if ((secFlags & CIFSSEC_MAY_PLNTXT) == 0) 536 if ((secFlags & CIFSSEC_MAY_PLNTXT) == 0)
537#endif /* CIFS_WEAK_PW_HASH */ 537#endif /* CIFS_WEAK_PW_HASH */
@@ -550,10 +550,6 @@ CIFSSMBNegotiate(unsigned int xid, struct cifsSesInfo *ses)
550 server->secType = RawNTLMSSP; 550 server->secType = RawNTLMSSP;
551 else if (secFlags & CIFSSEC_MAY_LANMAN) 551 else if (secFlags & CIFSSEC_MAY_LANMAN)
552 server->secType = LANMAN; 552 server->secType = LANMAN;
553/* #ifdef CONFIG_CIFS_EXPERIMENTAL
554 else if (secFlags & CIFSSEC_MAY_PLNTXT)
555 server->secType = ??
556#endif */
557 else { 553 else {
558 rc = -EOPNOTSUPP; 554 rc = -EOPNOTSUPP;
559 cERROR(1, "Invalid security type"); 555 cERROR(1, "Invalid security type");
@@ -569,33 +565,24 @@ CIFSSMBNegotiate(unsigned int xid, struct cifsSesInfo *ses)
569 (__u32) CIFSMaxBufSize + MAX_CIFS_HDR_SIZE); 565 (__u32) CIFSMaxBufSize + MAX_CIFS_HDR_SIZE);
570 server->max_rw = le32_to_cpu(pSMBr->MaxRawSize); 566 server->max_rw = le32_to_cpu(pSMBr->MaxRawSize);
571 cFYI(DBG2, "Max buf = %d", ses->server->maxBuf); 567 cFYI(DBG2, "Max buf = %d", ses->server->maxBuf);
572 GETU32(ses->server->sessid) = le32_to_cpu(pSMBr->SessionKey);
573 server->capabilities = le32_to_cpu(pSMBr->Capabilities); 568 server->capabilities = le32_to_cpu(pSMBr->Capabilities);
574 server->timeAdj = (int)(__s16)le16_to_cpu(pSMBr->ServerTimeZone); 569 server->timeAdj = (int)(__s16)le16_to_cpu(pSMBr->ServerTimeZone);
575 server->timeAdj *= 60; 570 server->timeAdj *= 60;
576 if (pSMBr->EncryptionKeyLength == CIFS_CRYPTO_KEY_SIZE) { 571 if (pSMBr->EncryptionKeyLength == CIFS_CRYPTO_KEY_SIZE) {
577 memcpy(server->cryptKey, pSMBr->u.EncryptionKey, 572 memcpy(ses->server->cryptkey, pSMBr->u.EncryptionKey,
578 CIFS_CRYPTO_KEY_SIZE); 573 CIFS_CRYPTO_KEY_SIZE);
579 } else if ((pSMBr->hdr.Flags2 & SMBFLG2_EXT_SEC) 574 } else if ((pSMBr->hdr.Flags2 & SMBFLG2_EXT_SEC ||
580 && (pSMBr->EncryptionKeyLength == 0)) { 575 server->capabilities & CAP_EXTENDED_SECURITY) &&
576 (pSMBr->EncryptionKeyLength == 0)) {
581 /* decode security blob */ 577 /* decode security blob */
582 } else if (server->secMode & SECMODE_PW_ENCRYPT) { 578 count = get_bcc(&pSMBr->hdr);
583 rc = -EIO; /* no crypt key only if plain text pwd */
584 goto neg_err_exit;
585 }
586
587 /* BB might be helpful to save off the domain of server here */
588
589 if ((pSMBr->hdr.Flags2 & SMBFLG2_EXT_SEC) &&
590 (server->capabilities & CAP_EXTENDED_SECURITY)) {
591 count = pSMBr->ByteCount;
592 if (count < 16) { 579 if (count < 16) {
593 rc = -EIO; 580 rc = -EIO;
594 goto neg_err_exit; 581 goto neg_err_exit;
595 } 582 }
596 read_lock(&cifs_tcp_ses_lock); 583 spin_lock(&cifs_tcp_ses_lock);
597 if (server->srv_count > 1) { 584 if (server->srv_count > 1) {
598 read_unlock(&cifs_tcp_ses_lock); 585 spin_unlock(&cifs_tcp_ses_lock);
599 if (memcmp(server->server_GUID, 586 if (memcmp(server->server_GUID,
600 pSMBr->u.extended_response. 587 pSMBr->u.extended_response.
601 GUID, 16) != 0) { 588 GUID, 16) != 0) {
@@ -605,7 +592,7 @@ CIFSSMBNegotiate(unsigned int xid, struct cifsSesInfo *ses)
605 16); 592 16);
606 } 593 }
607 } else { 594 } else {
608 read_unlock(&cifs_tcp_ses_lock); 595 spin_unlock(&cifs_tcp_ses_lock);
609 memcpy(server->server_GUID, 596 memcpy(server->server_GUID,
610 pSMBr->u.extended_response.GUID, 16); 597 pSMBr->u.extended_response.GUID, 16);
611 } 598 }
@@ -620,14 +607,19 @@ CIFSSMBNegotiate(unsigned int xid, struct cifsSesInfo *ses)
620 rc = 0; 607 rc = 0;
621 else 608 else
622 rc = -EINVAL; 609 rc = -EINVAL;
623 610 if (server->secType == Kerberos) {
624 if (server->sec_kerberos || server->sec_mskerberos) 611 if (!server->sec_kerberos &&
625 server->secType = Kerberos; 612 !server->sec_mskerberos)
626 else if (server->sec_ntlmssp) 613 rc = -EOPNOTSUPP;
627 server->secType = RawNTLMSSP; 614 } else if (server->secType == RawNTLMSSP) {
628 else 615 if (!server->sec_ntlmssp)
629 rc = -EOPNOTSUPP; 616 rc = -EOPNOTSUPP;
617 } else
618 rc = -EOPNOTSUPP;
630 } 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;
631 } else 623 } else
632 server->capabilities &= ~CAP_EXTENDED_SECURITY; 624 server->capabilities &= ~CAP_EXTENDED_SECURITY;
633 625
@@ -638,27 +630,27 @@ signing_check:
638 /* MUST_SIGN already includes the MAY_SIGN FLAG 630 /* MUST_SIGN already includes the MAY_SIGN FLAG
639 so if this is zero it means that signing is disabled */ 631 so if this is zero it means that signing is disabled */
640 cFYI(1, "Signing disabled"); 632 cFYI(1, "Signing disabled");
641 if (server->secMode & SECMODE_SIGN_REQUIRED) { 633 if (server->sec_mode & SECMODE_SIGN_REQUIRED) {
642 cERROR(1, "Server requires " 634 cERROR(1, "Server requires "
643 "packet signing to be enabled in " 635 "packet signing to be enabled in "
644 "/proc/fs/cifs/SecurityFlags."); 636 "/proc/fs/cifs/SecurityFlags.");
645 rc = -EOPNOTSUPP; 637 rc = -EOPNOTSUPP;
646 } 638 }
647 server->secMode &= 639 server->sec_mode &=
648 ~(SECMODE_SIGN_ENABLED | SECMODE_SIGN_REQUIRED); 640 ~(SECMODE_SIGN_ENABLED | SECMODE_SIGN_REQUIRED);
649 } else if ((secFlags & CIFSSEC_MUST_SIGN) == CIFSSEC_MUST_SIGN) { 641 } else if ((secFlags & CIFSSEC_MUST_SIGN) == CIFSSEC_MUST_SIGN) {
650 /* signing required */ 642 /* signing required */
651 cFYI(1, "Must sign - secFlags 0x%x", secFlags); 643 cFYI(1, "Must sign - secFlags 0x%x", secFlags);
652 if ((server->secMode & 644 if ((server->sec_mode &
653 (SECMODE_SIGN_ENABLED | SECMODE_SIGN_REQUIRED)) == 0) { 645 (SECMODE_SIGN_ENABLED | SECMODE_SIGN_REQUIRED)) == 0) {
654 cERROR(1, "signing required but server lacks support"); 646 cERROR(1, "signing required but server lacks support");
655 rc = -EOPNOTSUPP; 647 rc = -EOPNOTSUPP;
656 } else 648 } else
657 server->secMode |= SECMODE_SIGN_REQUIRED; 649 server->sec_mode |= SECMODE_SIGN_REQUIRED;
658 } else { 650 } else {
659 /* signing optional ie CIFSSEC_MAY_SIGN */ 651 /* signing optional ie CIFSSEC_MAY_SIGN */
660 if ((server->secMode & SECMODE_SIGN_REQUIRED) == 0) 652 if ((server->sec_mode & SECMODE_SIGN_REQUIRED) == 0)
661 server->secMode &= 653 server->sec_mode &=
662 ~(SECMODE_SIGN_ENABLED | SECMODE_SIGN_REQUIRED); 654 ~(SECMODE_SIGN_ENABLED | SECMODE_SIGN_REQUIRED);
663 } 655 }
664 656
@@ -670,7 +662,7 @@ neg_err_exit:
670} 662}
671 663
672int 664int
673CIFSSMBTDis(const int xid, struct cifsTconInfo *tcon) 665CIFSSMBTDis(const int xid, struct cifs_tcon *tcon)
674{ 666{
675 struct smb_hdr *smb_buffer; 667 struct smb_hdr *smb_buffer;
676 int rc = 0; 668 int rc = 0;
@@ -707,8 +699,57 @@ CIFSSMBTDis(const int xid, struct cifsTconInfo *tcon)
707 return rc; 699 return rc;
708} 700}
709 701
702/*
703 * This is a no-op for now. We're not really interested in the reply, but
704 * rather in the fact that the server sent one and that server->lstrp
705 * gets updated.
706 *
707 * FIXME: maybe we should consider checking that the reply matches request?
708 */
709static void
710cifs_echo_callback(struct mid_q_entry *mid)
711{
712 struct TCP_Server_Info *server = mid->callback_data;
713
714 DeleteMidQEntry(mid);
715 atomic_dec(&server->inFlight);
716 wake_up(&server->request_q);
717}
718
719int
720CIFSSMBEcho(struct TCP_Server_Info *server)
721{
722 ECHO_REQ *smb;
723 int rc = 0;
724 struct kvec iov;
725
726 cFYI(1, "In echo request");
727
728 rc = small_smb_init(SMB_COM_ECHO, 0, NULL, (void **)&smb);
729 if (rc)
730 return rc;
731
732 /* set up echo request */
733 smb->hdr.Tid = 0xffff;
734 smb->hdr.WordCount = 1;
735 put_unaligned_le16(1, &smb->EchoCount);
736 put_bcc(1, &smb->hdr);
737 smb->Data[0] = 'a';
738 inc_rfc1001_len(smb, 3);
739 iov.iov_base = smb;
740 iov.iov_len = be32_to_cpu(smb->hdr.smb_buf_length) + 4;
741
742 rc = cifs_call_async(server, &iov, 1, cifs_echo_callback, server, true);
743 if (rc)
744 cFYI(1, "Echo request failed: %d", rc);
745
746 cifs_small_buf_release(smb);
747
748 return rc;
749}
750
710int 751int
711CIFSSMBLogoff(const int xid, struct cifsSesInfo *ses) 752CIFSSMBLogoff(const int xid, struct cifs_ses *ses)
712{ 753{
713 LOGOFF_ANDX_REQ *pSMB; 754 LOGOFF_ANDX_REQ *pSMB;
714 int rc = 0; 755 int rc = 0;
@@ -735,7 +776,7 @@ CIFSSMBLogoff(const int xid, struct cifsSesInfo *ses)
735 776
736 pSMB->hdr.Mid = GetNextMid(ses->server); 777 pSMB->hdr.Mid = GetNextMid(ses->server);
737 778
738 if (ses->server->secMode & 779 if (ses->server->sec_mode &
739 (SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED)) 780 (SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED))
740 pSMB->hdr.Flags2 |= SMBFLG2_SECURITY_SIGNATURE; 781 pSMB->hdr.Flags2 |= SMBFLG2_SECURITY_SIGNATURE;
741 782
@@ -755,7 +796,7 @@ session_already_dead:
755} 796}
756 797
757int 798int
758CIFSPOSIXDelFile(const int xid, struct cifsTconInfo *tcon, const char *fileName, 799CIFSPOSIXDelFile(const int xid, struct cifs_tcon *tcon, const char *fileName,
759 __u16 type, const struct nls_table *nls_codepage, int remap) 800 __u16 type, const struct nls_table *nls_codepage, int remap)
760{ 801{
761 TRANSACTION2_SPI_REQ *pSMB = NULL; 802 TRANSACTION2_SPI_REQ *pSMB = NULL;
@@ -813,7 +854,7 @@ PsxDelete:
813 pSMB->TotalParameterCount = pSMB->ParameterCount; 854 pSMB->TotalParameterCount = pSMB->ParameterCount;
814 pSMB->InformationLevel = cpu_to_le16(SMB_POSIX_UNLINK); 855 pSMB->InformationLevel = cpu_to_le16(SMB_POSIX_UNLINK);
815 pSMB->Reserved4 = 0; 856 pSMB->Reserved4 = 0;
816 pSMB->hdr.smb_buf_length += byte_count; 857 inc_rfc1001_len(pSMB, byte_count);
817 pSMB->ByteCount = cpu_to_le16(byte_count); 858 pSMB->ByteCount = cpu_to_le16(byte_count);
818 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, 859 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
819 (struct smb_hdr *) pSMBr, &bytes_returned, 0); 860 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
@@ -830,7 +871,7 @@ PsxDelete:
830} 871}
831 872
832int 873int
833CIFSSMBDelFile(const int xid, struct cifsTconInfo *tcon, const char *fileName, 874CIFSSMBDelFile(const int xid, struct cifs_tcon *tcon, const char *fileName,
834 const struct nls_table *nls_codepage, int remap) 875 const struct nls_table *nls_codepage, int remap)
835{ 876{
836 DELETE_FILE_REQ *pSMB = NULL; 877 DELETE_FILE_REQ *pSMB = NULL;
@@ -859,7 +900,7 @@ DelFileRetry:
859 pSMB->SearchAttributes = 900 pSMB->SearchAttributes =
860 cpu_to_le16(ATTR_READONLY | ATTR_HIDDEN | ATTR_SYSTEM); 901 cpu_to_le16(ATTR_READONLY | ATTR_HIDDEN | ATTR_SYSTEM);
861 pSMB->BufferFormat = 0x04; 902 pSMB->BufferFormat = 0x04;
862 pSMB->hdr.smb_buf_length += name_len + 1; 903 inc_rfc1001_len(pSMB, name_len + 1);
863 pSMB->ByteCount = cpu_to_le16(name_len + 1); 904 pSMB->ByteCount = cpu_to_le16(name_len + 1);
864 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, 905 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
865 (struct smb_hdr *) pSMBr, &bytes_returned, 0); 906 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
@@ -875,7 +916,7 @@ DelFileRetry:
875} 916}
876 917
877int 918int
878CIFSSMBRmDir(const int xid, struct cifsTconInfo *tcon, const char *dirName, 919CIFSSMBRmDir(const int xid, struct cifs_tcon *tcon, const char *dirName,
879 const struct nls_table *nls_codepage, int remap) 920 const struct nls_table *nls_codepage, int remap)
880{ 921{
881 DELETE_DIRECTORY_REQ *pSMB = NULL; 922 DELETE_DIRECTORY_REQ *pSMB = NULL;
@@ -903,7 +944,7 @@ RmDirRetry:
903 } 944 }
904 945
905 pSMB->BufferFormat = 0x04; 946 pSMB->BufferFormat = 0x04;
906 pSMB->hdr.smb_buf_length += name_len + 1; 947 inc_rfc1001_len(pSMB, name_len + 1);
907 pSMB->ByteCount = cpu_to_le16(name_len + 1); 948 pSMB->ByteCount = cpu_to_le16(name_len + 1);
908 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, 949 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
909 (struct smb_hdr *) pSMBr, &bytes_returned, 0); 950 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
@@ -918,7 +959,7 @@ RmDirRetry:
918} 959}
919 960
920int 961int
921CIFSSMBMkDir(const int xid, struct cifsTconInfo *tcon, 962CIFSSMBMkDir(const int xid, struct cifs_tcon *tcon,
922 const char *name, const struct nls_table *nls_codepage, int remap) 963 const char *name, const struct nls_table *nls_codepage, int remap)
923{ 964{
924 int rc = 0; 965 int rc = 0;
@@ -946,7 +987,7 @@ MkDirRetry:
946 } 987 }
947 988
948 pSMB->BufferFormat = 0x04; 989 pSMB->BufferFormat = 0x04;
949 pSMB->hdr.smb_buf_length += name_len + 1; 990 inc_rfc1001_len(pSMB, name_len + 1);
950 pSMB->ByteCount = cpu_to_le16(name_len + 1); 991 pSMB->ByteCount = cpu_to_le16(name_len + 1);
951 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, 992 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
952 (struct smb_hdr *) pSMBr, &bytes_returned, 0); 993 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
@@ -961,7 +1002,7 @@ MkDirRetry:
961} 1002}
962 1003
963int 1004int
964CIFSPOSIXCreate(const int xid, struct cifsTconInfo *tcon, __u32 posix_flags, 1005CIFSPOSIXCreate(const int xid, struct cifs_tcon *tcon, __u32 posix_flags,
965 __u64 mode, __u16 *netfid, FILE_UNIX_BASIC_INFO *pRetData, 1006 __u64 mode, __u16 *netfid, FILE_UNIX_BASIC_INFO *pRetData,
966 __u32 *pOplock, const char *name, 1007 __u32 *pOplock, const char *name,
967 const struct nls_table *nls_codepage, int remap) 1008 const struct nls_table *nls_codepage, int remap)
@@ -1024,7 +1065,7 @@ PsxCreat:
1024 pSMB->TotalParameterCount = pSMB->ParameterCount; 1065 pSMB->TotalParameterCount = pSMB->ParameterCount;
1025 pSMB->InformationLevel = cpu_to_le16(SMB_POSIX_OPEN); 1066 pSMB->InformationLevel = cpu_to_le16(SMB_POSIX_OPEN);
1026 pSMB->Reserved4 = 0; 1067 pSMB->Reserved4 = 0;
1027 pSMB->hdr.smb_buf_length += byte_count; 1068 inc_rfc1001_len(pSMB, byte_count);
1028 pSMB->ByteCount = cpu_to_le16(byte_count); 1069 pSMB->ByteCount = cpu_to_le16(byte_count);
1029 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, 1070 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
1030 (struct smb_hdr *) pSMBr, &bytes_returned, 0); 1071 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
@@ -1036,7 +1077,7 @@ PsxCreat:
1036 cFYI(1, "copying inode info"); 1077 cFYI(1, "copying inode info");
1037 rc = validate_t2((struct smb_t2_rsp *)pSMBr); 1078 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
1038 1079
1039 if (rc || (pSMBr->ByteCount < sizeof(OPEN_PSX_RSP))) { 1080 if (rc || get_bcc(&pSMBr->hdr) < sizeof(OPEN_PSX_RSP)) {
1040 rc = -EIO; /* bad smb */ 1081 rc = -EIO; /* bad smb */
1041 goto psx_create_err; 1082 goto psx_create_err;
1042 } 1083 }
@@ -1057,7 +1098,7 @@ PsxCreat:
1057 pRetData->Type = cpu_to_le32(-1); /* unknown */ 1098 pRetData->Type = cpu_to_le32(-1); /* unknown */
1058 cFYI(DBG2, "unknown type"); 1099 cFYI(DBG2, "unknown type");
1059 } else { 1100 } else {
1060 if (pSMBr->ByteCount < sizeof(OPEN_PSX_RSP) 1101 if (get_bcc(&pSMBr->hdr) < sizeof(OPEN_PSX_RSP)
1061 + sizeof(FILE_UNIX_BASIC_INFO)) { 1102 + sizeof(FILE_UNIX_BASIC_INFO)) {
1062 cERROR(1, "Open response data too small"); 1103 cERROR(1, "Open response data too small");
1063 pRetData->Type = cpu_to_le32(-1); 1104 pRetData->Type = cpu_to_le32(-1);
@@ -1127,7 +1168,7 @@ access_flags_to_smbopen_mode(const int access_flags)
1127} 1168}
1128 1169
1129int 1170int
1130SMBLegacyOpen(const int xid, struct cifsTconInfo *tcon, 1171SMBLegacyOpen(const int xid, struct cifs_tcon *tcon,
1131 const char *fileName, const int openDisposition, 1172 const char *fileName, const int openDisposition,
1132 const int access_flags, const int create_options, __u16 *netfid, 1173 const int access_flags, const int create_options, __u16 *netfid,
1133 int *pOplock, FILE_ALL_INFO *pfile_info, 1174 int *pOplock, FILE_ALL_INFO *pfile_info,
@@ -1189,12 +1230,12 @@ OldOpenRetry:
1189 pSMB->Sattr = cpu_to_le16(ATTR_HIDDEN | ATTR_SYSTEM | ATTR_DIRECTORY); 1230 pSMB->Sattr = cpu_to_le16(ATTR_HIDDEN | ATTR_SYSTEM | ATTR_DIRECTORY);
1190 pSMB->OpenFunction = cpu_to_le16(convert_disposition(openDisposition)); 1231 pSMB->OpenFunction = cpu_to_le16(convert_disposition(openDisposition));
1191 count += name_len; 1232 count += name_len;
1192 pSMB->hdr.smb_buf_length += count; 1233 inc_rfc1001_len(pSMB, count);
1193 1234
1194 pSMB->ByteCount = cpu_to_le16(count); 1235 pSMB->ByteCount = cpu_to_le16(count);
1195 /* long_op set to 1 to allow for oplock break timeouts */ 1236 /* long_op set to 1 to allow for oplock break timeouts */
1196 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, 1237 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
1197 (struct smb_hdr *)pSMBr, &bytes_returned, CIFS_LONG_OP); 1238 (struct smb_hdr *)pSMBr, &bytes_returned, 0);
1198 cifs_stats_inc(&tcon->num_opens); 1239 cifs_stats_inc(&tcon->num_opens);
1199 if (rc) { 1240 if (rc) {
1200 cFYI(1, "Error in Open = %d", rc); 1241 cFYI(1, "Error in Open = %d", rc);
@@ -1234,7 +1275,7 @@ OldOpenRetry:
1234} 1275}
1235 1276
1236int 1277int
1237CIFSSMBOpen(const int xid, struct cifsTconInfo *tcon, 1278CIFSSMBOpen(const int xid, struct cifs_tcon *tcon,
1238 const char *fileName, const int openDisposition, 1279 const char *fileName, const int openDisposition,
1239 const int access_flags, const int create_options, __u16 *netfid, 1280 const int access_flags, const int create_options, __u16 *netfid,
1240 int *pOplock, FILE_ALL_INFO *pfile_info, 1281 int *pOplock, FILE_ALL_INFO *pfile_info,
@@ -1302,12 +1343,12 @@ openRetry:
1302 SECURITY_CONTEXT_TRACKING | SECURITY_EFFECTIVE_ONLY; 1343 SECURITY_CONTEXT_TRACKING | SECURITY_EFFECTIVE_ONLY;
1303 1344
1304 count += name_len; 1345 count += name_len;
1305 pSMB->hdr.smb_buf_length += count; 1346 inc_rfc1001_len(pSMB, count);
1306 1347
1307 pSMB->ByteCount = cpu_to_le16(count); 1348 pSMB->ByteCount = cpu_to_le16(count);
1308 /* long_op set to 1 to allow for oplock break timeouts */ 1349 /* long_op set to 1 to allow for oplock break timeouts */
1309 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, 1350 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
1310 (struct smb_hdr *)pSMBr, &bytes_returned, CIFS_LONG_OP); 1351 (struct smb_hdr *)pSMBr, &bytes_returned, 0);
1311 cifs_stats_inc(&tcon->num_opens); 1352 cifs_stats_inc(&tcon->num_opens);
1312 if (rc) { 1353 if (rc) {
1313 cFYI(1, "Error in Open = %d", rc); 1354 cFYI(1, "Error in Open = %d", rc);
@@ -1336,8 +1377,7 @@ openRetry:
1336} 1377}
1337 1378
1338int 1379int
1339CIFSSMBRead(const int xid, struct cifsTconInfo *tcon, const int netfid, 1380CIFSSMBRead(const int xid, struct cifs_io_parms *io_parms, unsigned int *nbytes,
1340 const unsigned int count, const __u64 lseek, unsigned int *nbytes,
1341 char **buf, int *pbuf_type) 1381 char **buf, int *pbuf_type)
1342{ 1382{
1343 int rc = -EACCES; 1383 int rc = -EACCES;
@@ -1347,13 +1387,18 @@ CIFSSMBRead(const int xid, struct cifsTconInfo *tcon, const int netfid,
1347 int wct; 1387 int wct;
1348 int resp_buf_type = 0; 1388 int resp_buf_type = 0;
1349 struct kvec iov[1]; 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;
1350 1395
1351 cFYI(1, "Reading %d bytes on fid %d", count, netfid); 1396 cFYI(1, "Reading %d bytes on fid %d", count, netfid);
1352 if (tcon->ses->capabilities & CAP_LARGE_FILES) 1397 if (tcon->ses->capabilities & CAP_LARGE_FILES)
1353 wct = 12; 1398 wct = 12;
1354 else { 1399 else {
1355 wct = 10; /* old style read */ 1400 wct = 10; /* old style read */
1356 if ((lseek >> 32) > 0) { 1401 if ((offset >> 32) > 0) {
1357 /* can not handle this big offset for old */ 1402 /* can not handle this big offset for old */
1358 return -EIO; 1403 return -EIO;
1359 } 1404 }
@@ -1364,15 +1409,18 @@ CIFSSMBRead(const int xid, struct cifsTconInfo *tcon, const int netfid,
1364 if (rc) 1409 if (rc)
1365 return rc; 1410 return rc;
1366 1411
1412 pSMB->hdr.Pid = cpu_to_le16((__u16)pid);
1413 pSMB->hdr.PidHigh = cpu_to_le16((__u16)(pid >> 16));
1414
1367 /* tcon and ses pointer are checked in smb_init */ 1415 /* tcon and ses pointer are checked in smb_init */
1368 if (tcon->ses->server == NULL) 1416 if (tcon->ses->server == NULL)
1369 return -ECONNABORTED; 1417 return -ECONNABORTED;
1370 1418
1371 pSMB->AndXCommand = 0xFF; /* none */ 1419 pSMB->AndXCommand = 0xFF; /* none */
1372 pSMB->Fid = netfid; 1420 pSMB->Fid = netfid;
1373 pSMB->OffsetLow = cpu_to_le32(lseek & 0xFFFFFFFF); 1421 pSMB->OffsetLow = cpu_to_le32(offset & 0xFFFFFFFF);
1374 if (wct == 12) 1422 if (wct == 12)
1375 pSMB->OffsetHigh = cpu_to_le32(lseek >> 32); 1423 pSMB->OffsetHigh = cpu_to_le32(offset >> 32);
1376 1424
1377 pSMB->Remaining = 0; 1425 pSMB->Remaining = 0;
1378 pSMB->MaxCount = cpu_to_le16(count & 0xFFFF); 1426 pSMB->MaxCount = cpu_to_le16(count & 0xFFFF);
@@ -1387,9 +1435,9 @@ CIFSSMBRead(const int xid, struct cifsTconInfo *tcon, const int netfid,
1387 } 1435 }
1388 1436
1389 iov[0].iov_base = (char *)pSMB; 1437 iov[0].iov_base = (char *)pSMB;
1390 iov[0].iov_len = pSMB->hdr.smb_buf_length + 4; 1438 iov[0].iov_len = be32_to_cpu(pSMB->hdr.smb_buf_length) + 4;
1391 rc = SendReceive2(xid, tcon->ses, iov, 1 /* num iovecs */, 1439 rc = SendReceive2(xid, tcon->ses, iov, 1 /* num iovecs */,
1392 &resp_buf_type, CIFS_STD_OP | CIFS_LOG_ERROR); 1440 &resp_buf_type, CIFS_LOG_ERROR);
1393 cifs_stats_inc(&tcon->num_reads); 1441 cifs_stats_inc(&tcon->num_reads);
1394 pSMBr = (READ_RSP *)iov[0].iov_base; 1442 pSMBr = (READ_RSP *)iov[0].iov_base;
1395 if (rc) { 1443 if (rc) {
@@ -1441,9 +1489,8 @@ CIFSSMBRead(const int xid, struct cifsTconInfo *tcon, const int netfid,
1441 1489
1442 1490
1443int 1491int
1444CIFSSMBWrite(const int xid, struct cifsTconInfo *tcon, 1492CIFSSMBWrite(const int xid, struct cifs_io_parms *io_parms,
1445 const int netfid, const unsigned int count, 1493 unsigned int *nbytes, const char *buf,
1446 const __u64 offset, unsigned int *nbytes, const char *buf,
1447 const char __user *ubuf, const int long_op) 1494 const char __user *ubuf, const int long_op)
1448{ 1495{
1449 int rc = -EACCES; 1496 int rc = -EACCES;
@@ -1452,6 +1499,11 @@ CIFSSMBWrite(const int xid, struct cifsTconInfo *tcon,
1452 int bytes_returned, wct; 1499 int bytes_returned, wct;
1453 __u32 bytes_sent; 1500 __u32 bytes_sent;
1454 __u16 byte_count; 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;
1455 1507
1456 *nbytes = 0; 1508 *nbytes = 0;
1457 1509
@@ -1473,6 +1525,10 @@ CIFSSMBWrite(const int xid, struct cifsTconInfo *tcon,
1473 (void **) &pSMBr); 1525 (void **) &pSMBr);
1474 if (rc) 1526 if (rc)
1475 return rc; 1527 return rc;
1528
1529 pSMB->hdr.Pid = cpu_to_le16((__u16)pid);
1530 pSMB->hdr.PidHigh = cpu_to_le16((__u16)(pid >> 16));
1531
1476 /* tcon and ses pointer are checked in smb_init */ 1532 /* tcon and ses pointer are checked in smb_init */
1477 if (tcon->ses->server == NULL) 1533 if (tcon->ses->server == NULL)
1478 return -ECONNABORTED; 1534 return -ECONNABORTED;
@@ -1521,7 +1577,7 @@ CIFSSMBWrite(const int xid, struct cifsTconInfo *tcon,
1521 1577
1522 pSMB->DataLengthLow = cpu_to_le16(bytes_sent & 0xFFFF); 1578 pSMB->DataLengthLow = cpu_to_le16(bytes_sent & 0xFFFF);
1523 pSMB->DataLengthHigh = cpu_to_le16(bytes_sent >> 16); 1579 pSMB->DataLengthHigh = cpu_to_le16(bytes_sent >> 16);
1524 pSMB->hdr.smb_buf_length += byte_count; 1580 inc_rfc1001_len(pSMB, byte_count);
1525 1581
1526 if (wct == 14) 1582 if (wct == 14)
1527 pSMB->ByteCount = cpu_to_le16(byte_count); 1583 pSMB->ByteCount = cpu_to_le16(byte_count);
@@ -1559,17 +1615,259 @@ CIFSSMBWrite(const int xid, struct cifsTconInfo *tcon,
1559 return rc; 1615 return rc;
1560} 1616}
1561 1617
1618void
1619cifs_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 */
1634static void
1635cifs_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
1659static void
1660cifs_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
1688struct cifs_writedata *
1689cifs_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 */
1713static void
1714cifs_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 */
1760int
1761cifs_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
1850async_writev_out:
1851 cifs_small_buf_release(smb);
1852 kfree(iov);
1853 return rc;
1854}
1855
1562int 1856int
1563CIFSSMBWrite2(const int xid, struct cifsTconInfo *tcon, 1857CIFSSMBWrite2(const int xid, struct cifs_io_parms *io_parms,
1564 const int netfid, const unsigned int count, 1858 unsigned int *nbytes, struct kvec *iov, int n_vec,
1565 const __u64 offset, unsigned int *nbytes, struct kvec *iov, 1859 const int long_op)
1566 int n_vec, const int long_op)
1567{ 1860{
1568 int rc = -EACCES; 1861 int rc = -EACCES;
1569 WRITE_REQ *pSMB = NULL; 1862 WRITE_REQ *pSMB = NULL;
1570 int wct; 1863 int wct;
1571 int smb_hdr_len; 1864 int smb_hdr_len;
1572 int resp_buf_type = 0; 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;
1573 1871
1574 *nbytes = 0; 1872 *nbytes = 0;
1575 1873
@@ -1587,6 +1885,10 @@ CIFSSMBWrite2(const int xid, struct cifsTconInfo *tcon,
1587 rc = small_smb_init(SMB_COM_WRITE_ANDX, wct, tcon, (void **) &pSMB); 1885 rc = small_smb_init(SMB_COM_WRITE_ANDX, wct, tcon, (void **) &pSMB);
1588 if (rc) 1886 if (rc)
1589 return rc; 1887 return rc;
1888
1889 pSMB->hdr.Pid = cpu_to_le16((__u16)pid);
1890 pSMB->hdr.PidHigh = cpu_to_le16((__u16)(pid >> 16));
1891
1590 /* tcon and ses pointer are checked in smb_init */ 1892 /* tcon and ses pointer are checked in smb_init */
1591 if (tcon->ses->server == NULL) 1893 if (tcon->ses->server == NULL)
1592 return -ECONNABORTED; 1894 return -ECONNABORTED;
@@ -1605,11 +1907,12 @@ CIFSSMBWrite2(const int xid, struct cifsTconInfo *tcon,
1605 1907
1606 pSMB->DataLengthLow = cpu_to_le16(count & 0xFFFF); 1908 pSMB->DataLengthLow = cpu_to_le16(count & 0xFFFF);
1607 pSMB->DataLengthHigh = cpu_to_le16(count >> 16); 1909 pSMB->DataLengthHigh = cpu_to_le16(count >> 16);
1608 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;
1609 if (wct == 14) 1912 if (wct == 14)
1610 pSMB->hdr.smb_buf_length += count+1; 1913 inc_rfc1001_len(pSMB, count + 1);
1611 else /* wct == 12 */ 1914 else /* wct == 12 */
1612 pSMB->hdr.smb_buf_length += count+5; /* smb data starts later */ 1915 inc_rfc1001_len(pSMB, count + 5); /* smb data starts later */
1613 if (wct == 14) 1916 if (wct == 14)
1614 pSMB->ByteCount = cpu_to_le16(count + 1); 1917 pSMB->ByteCount = cpu_to_le16(count + 1);
1615 else /* wct == 12 */ /* bigger pad, smaller smb hdr, keep offset ok */ { 1918 else /* wct == 12 */ /* bigger pad, smaller smb hdr, keep offset ok */ {
@@ -1661,10 +1964,11 @@ CIFSSMBWrite2(const int xid, struct cifsTconInfo *tcon,
1661 1964
1662 1965
1663int 1966int
1664CIFSSMBLock(const int xid, struct cifsTconInfo *tcon, 1967CIFSSMBLock(const int xid, struct cifs_tcon *tcon,
1665 const __u16 smb_file_id, const __u64 len, 1968 const __u16 smb_file_id, const __u64 len,
1666 const __u64 offset, const __u32 numUnlock, 1969 const __u64 offset, const __u32 numUnlock,
1667 const __u32 numLock, const __u8 lockType, const bool waitFlag) 1970 const __u32 numLock, const __u8 lockType,
1971 const bool waitFlag, const __u8 oplock_level)
1668{ 1972{
1669 int rc = 0; 1973 int rc = 0;
1670 LOCK_REQ *pSMB = NULL; 1974 LOCK_REQ *pSMB = NULL;
@@ -1692,6 +1996,7 @@ CIFSSMBLock(const int xid, struct cifsTconInfo *tcon,
1692 pSMB->NumberOfLocks = cpu_to_le16(numLock); 1996 pSMB->NumberOfLocks = cpu_to_le16(numLock);
1693 pSMB->NumberOfUnlocks = cpu_to_le16(numUnlock); 1997 pSMB->NumberOfUnlocks = cpu_to_le16(numUnlock);
1694 pSMB->LockType = lockType; 1998 pSMB->LockType = lockType;
1999 pSMB->OplockLevel = oplock_level;
1695 pSMB->AndXCommand = 0xFF; /* none */ 2000 pSMB->AndXCommand = 0xFF; /* none */
1696 pSMB->Fid = smb_file_id; /* netfid stays le */ 2001 pSMB->Fid = smb_file_id; /* netfid stays le */
1697 2002
@@ -1707,7 +2012,7 @@ CIFSSMBLock(const int xid, struct cifsTconInfo *tcon,
1707 /* oplock break */ 2012 /* oplock break */
1708 count = 0; 2013 count = 0;
1709 } 2014 }
1710 pSMB->hdr.smb_buf_length += count; 2015 inc_rfc1001_len(pSMB, count);
1711 pSMB->ByteCount = cpu_to_le16(count); 2016 pSMB->ByteCount = cpu_to_le16(count);
1712 2017
1713 if (waitFlag) { 2018 if (waitFlag) {
@@ -1729,7 +2034,7 @@ CIFSSMBLock(const int xid, struct cifsTconInfo *tcon,
1729} 2034}
1730 2035
1731int 2036int
1732CIFSSMBPosixLock(const int xid, struct cifsTconInfo *tcon, 2037CIFSSMBPosixLock(const int xid, struct cifs_tcon *tcon,
1733 const __u16 smb_file_id, const int get_flag, const __u64 len, 2038 const __u16 smb_file_id, const int get_flag, const __u64 len,
1734 struct file_lock *pLockData, const __u16 lock_type, 2039 struct file_lock *pLockData, const __u16 lock_type,
1735 const bool waitFlag) 2040 const bool waitFlag)
@@ -1798,14 +2103,14 @@ CIFSSMBPosixLock(const int xid, struct cifsTconInfo *tcon,
1798 pSMB->Fid = smb_file_id; 2103 pSMB->Fid = smb_file_id;
1799 pSMB->InformationLevel = cpu_to_le16(SMB_SET_POSIX_LOCK); 2104 pSMB->InformationLevel = cpu_to_le16(SMB_SET_POSIX_LOCK);
1800 pSMB->Reserved4 = 0; 2105 pSMB->Reserved4 = 0;
1801 pSMB->hdr.smb_buf_length += byte_count; 2106 inc_rfc1001_len(pSMB, byte_count);
1802 pSMB->ByteCount = cpu_to_le16(byte_count); 2107 pSMB->ByteCount = cpu_to_le16(byte_count);
1803 if (waitFlag) { 2108 if (waitFlag) {
1804 rc = SendReceiveBlockingLock(xid, tcon, (struct smb_hdr *) pSMB, 2109 rc = SendReceiveBlockingLock(xid, tcon, (struct smb_hdr *) pSMB,
1805 (struct smb_hdr *) pSMBr, &bytes_returned); 2110 (struct smb_hdr *) pSMBr, &bytes_returned);
1806 } else { 2111 } else {
1807 iov[0].iov_base = (char *)pSMB; 2112 iov[0].iov_base = (char *)pSMB;
1808 iov[0].iov_len = pSMB->hdr.smb_buf_length + 4; 2113 iov[0].iov_len = be32_to_cpu(pSMB->hdr.smb_buf_length) + 4;
1809 rc = SendReceive2(xid, tcon->ses, iov, 1 /* num iovecs */, 2114 rc = SendReceive2(xid, tcon->ses, iov, 1 /* num iovecs */,
1810 &resp_buf_type, timeout); 2115 &resp_buf_type, timeout);
1811 pSMB = NULL; /* request buf already freed by SendReceive2. Do 2116 pSMB = NULL; /* request buf already freed by SendReceive2. Do
@@ -1821,7 +2126,7 @@ CIFSSMBPosixLock(const int xid, struct cifsTconInfo *tcon,
1821 __u16 data_count; 2126 __u16 data_count;
1822 rc = validate_t2((struct smb_t2_rsp *)pSMBr); 2127 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
1823 2128
1824 if (rc || (pSMBr->ByteCount < sizeof(struct cifs_posix_lock))) { 2129 if (rc || get_bcc(&pSMBr->hdr) < sizeof(*parm_data)) {
1825 rc = -EIO; /* bad smb */ 2130 rc = -EIO; /* bad smb */
1826 goto plk_err_exit; 2131 goto plk_err_exit;
1827 } 2132 }
@@ -1843,10 +2148,10 @@ CIFSSMBPosixLock(const int xid, struct cifsTconInfo *tcon,
1843 __constant_cpu_to_le16(CIFS_WRLCK)) 2148 __constant_cpu_to_le16(CIFS_WRLCK))
1844 pLockData->fl_type = F_WRLCK; 2149 pLockData->fl_type = F_WRLCK;
1845 2150
1846 pLockData->fl_start = parm_data->start; 2151 pLockData->fl_start = le64_to_cpu(parm_data->start);
1847 pLockData->fl_end = parm_data->start + 2152 pLockData->fl_end = pLockData->fl_start +
1848 parm_data->length - 1; 2153 le64_to_cpu(parm_data->length) - 1;
1849 pLockData->fl_pid = parm_data->pid; 2154 pLockData->fl_pid = le32_to_cpu(parm_data->pid);
1850 } 2155 }
1851 } 2156 }
1852 2157
@@ -1867,7 +2172,7 @@ plk_err_exit:
1867 2172
1868 2173
1869int 2174int
1870CIFSSMBClose(const int xid, struct cifsTconInfo *tcon, int smb_file_id) 2175CIFSSMBClose(const int xid, struct cifs_tcon *tcon, int smb_file_id)
1871{ 2176{
1872 int rc = 0; 2177 int rc = 0;
1873 CLOSE_REQ *pSMB = NULL; 2178 CLOSE_REQ *pSMB = NULL;
@@ -1900,7 +2205,7 @@ CIFSSMBClose(const int xid, struct cifsTconInfo *tcon, int smb_file_id)
1900} 2205}
1901 2206
1902int 2207int
1903CIFSSMBFlush(const int xid, struct cifsTconInfo *tcon, int smb_file_id) 2208CIFSSMBFlush(const int xid, struct cifs_tcon *tcon, int smb_file_id)
1904{ 2209{
1905 int rc = 0; 2210 int rc = 0;
1906 FLUSH_REQ *pSMB = NULL; 2211 FLUSH_REQ *pSMB = NULL;
@@ -1921,7 +2226,7 @@ CIFSSMBFlush(const int xid, struct cifsTconInfo *tcon, int smb_file_id)
1921} 2226}
1922 2227
1923int 2228int
1924CIFSSMBRename(const int xid, struct cifsTconInfo *tcon, 2229CIFSSMBRename(const int xid, struct cifs_tcon *tcon,
1925 const char *fromName, const char *toName, 2230 const char *fromName, const char *toName,
1926 const struct nls_table *nls_codepage, int remap) 2231 const struct nls_table *nls_codepage, int remap)
1927{ 2232{
@@ -1971,7 +2276,7 @@ renameRetry:
1971 } 2276 }
1972 2277
1973 count = 1 /* 1st signature byte */ + name_len + name_len2; 2278 count = 1 /* 1st signature byte */ + name_len + name_len2;
1974 pSMB->hdr.smb_buf_length += count; 2279 inc_rfc1001_len(pSMB, count);
1975 pSMB->ByteCount = cpu_to_le16(count); 2280 pSMB->ByteCount = cpu_to_le16(count);
1976 2281
1977 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, 2282 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
@@ -1988,7 +2293,7 @@ renameRetry:
1988 return rc; 2293 return rc;
1989} 2294}
1990 2295
1991int CIFSSMBRenameOpenFile(const int xid, struct cifsTconInfo *pTcon, 2296int CIFSSMBRenameOpenFile(const int xid, struct cifs_tcon *pTcon,
1992 int netfid, const char *target_name, 2297 int netfid, const char *target_name,
1993 const struct nls_table *nls_codepage, int remap) 2298 const struct nls_table *nls_codepage, int remap)
1994{ 2299{
@@ -2051,7 +2356,7 @@ int CIFSSMBRenameOpenFile(const int xid, struct cifsTconInfo *pTcon,
2051 pSMB->InformationLevel = 2356 pSMB->InformationLevel =
2052 cpu_to_le16(SMB_SET_FILE_RENAME_INFORMATION); 2357 cpu_to_le16(SMB_SET_FILE_RENAME_INFORMATION);
2053 pSMB->Reserved4 = 0; 2358 pSMB->Reserved4 = 0;
2054 pSMB->hdr.smb_buf_length += byte_count; 2359 inc_rfc1001_len(pSMB, byte_count);
2055 pSMB->ByteCount = cpu_to_le16(byte_count); 2360 pSMB->ByteCount = cpu_to_le16(byte_count);
2056 rc = SendReceive(xid, pTcon->ses, (struct smb_hdr *) pSMB, 2361 rc = SendReceive(xid, pTcon->ses, (struct smb_hdr *) pSMB,
2057 (struct smb_hdr *) pSMBr, &bytes_returned, 0); 2362 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
@@ -2068,7 +2373,7 @@ int CIFSSMBRenameOpenFile(const int xid, struct cifsTconInfo *pTcon,
2068} 2373}
2069 2374
2070int 2375int
2071CIFSSMBCopy(const int xid, struct cifsTconInfo *tcon, const char *fromName, 2376CIFSSMBCopy(const int xid, struct cifs_tcon *tcon, const char *fromName,
2072 const __u16 target_tid, const char *toName, const int flags, 2377 const __u16 target_tid, const char *toName, const int flags,
2073 const struct nls_table *nls_codepage, int remap) 2378 const struct nls_table *nls_codepage, int remap)
2074{ 2379{
@@ -2118,7 +2423,7 @@ copyRetry:
2118 } 2423 }
2119 2424
2120 count = 1 /* 1st signature byte */ + name_len + name_len2; 2425 count = 1 /* 1st signature byte */ + name_len + name_len2;
2121 pSMB->hdr.smb_buf_length += count; 2426 inc_rfc1001_len(pSMB, count);
2122 pSMB->ByteCount = cpu_to_le16(count); 2427 pSMB->ByteCount = cpu_to_le16(count);
2123 2428
2124 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, 2429 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
@@ -2136,7 +2441,7 @@ copyRetry:
2136} 2441}
2137 2442
2138int 2443int
2139CIFSUnixCreateSymLink(const int xid, struct cifsTconInfo *tcon, 2444CIFSUnixCreateSymLink(const int xid, struct cifs_tcon *tcon,
2140 const char *fromName, const char *toName, 2445 const char *fromName, const char *toName,
2141 const struct nls_table *nls_codepage) 2446 const struct nls_table *nls_codepage)
2142{ 2447{
@@ -2208,7 +2513,7 @@ createSymLinkRetry:
2208 pSMB->DataOffset = cpu_to_le16(offset); 2513 pSMB->DataOffset = cpu_to_le16(offset);
2209 pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_UNIX_LINK); 2514 pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_UNIX_LINK);
2210 pSMB->Reserved4 = 0; 2515 pSMB->Reserved4 = 0;
2211 pSMB->hdr.smb_buf_length += byte_count; 2516 inc_rfc1001_len(pSMB, byte_count);
2212 pSMB->ByteCount = cpu_to_le16(byte_count); 2517 pSMB->ByteCount = cpu_to_le16(byte_count);
2213 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, 2518 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
2214 (struct smb_hdr *) pSMBr, &bytes_returned, 0); 2519 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
@@ -2225,7 +2530,7 @@ createSymLinkRetry:
2225} 2530}
2226 2531
2227int 2532int
2228CIFSUnixCreateHardLink(const int xid, struct cifsTconInfo *tcon, 2533CIFSUnixCreateHardLink(const int xid, struct cifs_tcon *tcon,
2229 const char *fromName, const char *toName, 2534 const char *fromName, const char *toName,
2230 const struct nls_table *nls_codepage, int remap) 2535 const struct nls_table *nls_codepage, int remap)
2231{ 2536{
@@ -2294,7 +2599,7 @@ createHardLinkRetry:
2294 pSMB->DataOffset = cpu_to_le16(offset); 2599 pSMB->DataOffset = cpu_to_le16(offset);
2295 pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_UNIX_HLINK); 2600 pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_UNIX_HLINK);
2296 pSMB->Reserved4 = 0; 2601 pSMB->Reserved4 = 0;
2297 pSMB->hdr.smb_buf_length += byte_count; 2602 inc_rfc1001_len(pSMB, byte_count);
2298 pSMB->ByteCount = cpu_to_le16(byte_count); 2603 pSMB->ByteCount = cpu_to_le16(byte_count);
2299 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, 2604 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
2300 (struct smb_hdr *) pSMBr, &bytes_returned, 0); 2605 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
@@ -2310,7 +2615,7 @@ createHardLinkRetry:
2310} 2615}
2311 2616
2312int 2617int
2313CIFSCreateHardLink(const int xid, struct cifsTconInfo *tcon, 2618CIFSCreateHardLink(const int xid, struct cifs_tcon *tcon,
2314 const char *fromName, const char *toName, 2619 const char *fromName, const char *toName,
2315 const struct nls_table *nls_codepage, int remap) 2620 const struct nls_table *nls_codepage, int remap)
2316{ 2621{
@@ -2365,7 +2670,7 @@ winCreateHardLinkRetry:
2365 } 2670 }
2366 2671
2367 count = 1 /* string type byte */ + name_len + name_len2; 2672 count = 1 /* string type byte */ + name_len + name_len2;
2368 pSMB->hdr.smb_buf_length += count; 2673 inc_rfc1001_len(pSMB, count);
2369 pSMB->ByteCount = cpu_to_le16(count); 2674 pSMB->ByteCount = cpu_to_le16(count);
2370 2675
2371 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, 2676 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
@@ -2382,7 +2687,7 @@ winCreateHardLinkRetry:
2382} 2687}
2383 2688
2384int 2689int
2385CIFSSMBUnixQuerySymLink(const int xid, struct cifsTconInfo *tcon, 2690CIFSSMBUnixQuerySymLink(const int xid, struct cifs_tcon *tcon,
2386 const unsigned char *searchName, char **symlinkinfo, 2691 const unsigned char *searchName, char **symlinkinfo,
2387 const struct nls_table *nls_codepage) 2692 const struct nls_table *nls_codepage)
2388{ 2693{
@@ -2436,7 +2741,7 @@ querySymLinkRetry:
2436 pSMB->ParameterCount = pSMB->TotalParameterCount; 2741 pSMB->ParameterCount = pSMB->TotalParameterCount;
2437 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FILE_UNIX_LINK); 2742 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FILE_UNIX_LINK);
2438 pSMB->Reserved4 = 0; 2743 pSMB->Reserved4 = 0;
2439 pSMB->hdr.smb_buf_length += byte_count; 2744 inc_rfc1001_len(pSMB, byte_count);
2440 pSMB->ByteCount = cpu_to_le16(byte_count); 2745 pSMB->ByteCount = cpu_to_le16(byte_count);
2441 2746
2442 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, 2747 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
@@ -2448,7 +2753,7 @@ querySymLinkRetry:
2448 2753
2449 rc = validate_t2((struct smb_t2_rsp *)pSMBr); 2754 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
2450 /* BB also check enough total bytes returned */ 2755 /* BB also check enough total bytes returned */
2451 if (rc || (pSMBr->ByteCount < 2)) 2756 if (rc || get_bcc(&pSMBr->hdr) < 2)
2452 rc = -EIO; 2757 rc = -EIO;
2453 else { 2758 else {
2454 bool is_unicode; 2759 bool is_unicode;
@@ -2475,98 +2780,19 @@ querySymLinkRetry:
2475 return rc; 2780 return rc;
2476} 2781}
2477 2782
2478#ifdef CONFIG_CIFS_EXPERIMENTAL 2783#ifdef CONFIG_CIFS_SYMLINK_EXPERIMENTAL
2479/* Initialize NT TRANSACT SMB into small smb request buffer. 2784/*
2480 This assumes that all NT TRANSACTS that we init here have 2785 * Recent Windows versions now create symlinks more frequently
2481 total parm and data under about 400 bytes (to fit in small cifs 2786 * and they use the "reparse point" mechanism below. We can of course
2482 buffer size), which is the case so far, it easily fits. NB: 2787 * do symlinks nicely to Samba and other servers which support the
2483 Setup words themselves and ByteCount 2788 * CIFS Unix Extensions and we can also do SFU symlinks and "client only"
2484 MaxSetupCount (size of returned setup area) and 2789 * "MF" symlinks optionally, but for recent Windows we really need to
2485 MaxParameterCount (returned parms size) must be set by caller */ 2790 * reenable the code below and fix the cifs_symlink callers to handle this.
2486static int 2791 * In the interim this code has been moved to its own config option so
2487smb_init_nttransact(const __u16 sub_command, const int setup_count, 2792 * it is not compiled in by default until callers fixed up and more tested.
2488 const int parm_len, struct cifsTconInfo *tcon, 2793 */
2489 void **ret_buf)
2490{
2491 int rc;
2492 __u32 temp_offset;
2493 struct smb_com_ntransact_req *pSMB;
2494
2495 rc = small_smb_init(SMB_COM_NT_TRANSACT, 19 + setup_count, tcon,
2496 (void **)&pSMB);
2497 if (rc)
2498 return rc;
2499 *ret_buf = (void *)pSMB;
2500 pSMB->Reserved = 0;
2501 pSMB->TotalParameterCount = cpu_to_le32(parm_len);
2502 pSMB->TotalDataCount = 0;
2503 pSMB->MaxDataCount = cpu_to_le32((tcon->ses->server->maxBuf -
2504 MAX_CIFS_HDR_SIZE) & 0xFFFFFF00);
2505 pSMB->ParameterCount = pSMB->TotalParameterCount;
2506 pSMB->DataCount = pSMB->TotalDataCount;
2507 temp_offset = offsetof(struct smb_com_ntransact_req, Parms) +
2508 (setup_count * 2) - 4 /* for rfc1001 length itself */;
2509 pSMB->ParameterOffset = cpu_to_le32(temp_offset);
2510 pSMB->DataOffset = cpu_to_le32(temp_offset + parm_len);
2511 pSMB->SetupCount = setup_count; /* no need to le convert byte fields */
2512 pSMB->SubCommand = cpu_to_le16(sub_command);
2513 return 0;
2514}
2515
2516static int
2517validate_ntransact(char *buf, char **ppparm, char **ppdata,
2518 __u32 *pparmlen, __u32 *pdatalen)
2519{
2520 char *end_of_smb;
2521 __u32 data_count, data_offset, parm_count, parm_offset;
2522 struct smb_com_ntransact_rsp *pSMBr;
2523
2524 *pdatalen = 0;
2525 *pparmlen = 0;
2526
2527 if (buf == NULL)
2528 return -EINVAL;
2529
2530 pSMBr = (struct smb_com_ntransact_rsp *)buf;
2531
2532 /* ByteCount was converted from little endian in SendReceive */
2533 end_of_smb = 2 /* sizeof byte count */ + pSMBr->ByteCount +
2534 (char *)&pSMBr->ByteCount;
2535
2536 data_offset = le32_to_cpu(pSMBr->DataOffset);
2537 data_count = le32_to_cpu(pSMBr->DataCount);
2538 parm_offset = le32_to_cpu(pSMBr->ParameterOffset);
2539 parm_count = le32_to_cpu(pSMBr->ParameterCount);
2540
2541 *ppparm = (char *)&pSMBr->hdr.Protocol + parm_offset;
2542 *ppdata = (char *)&pSMBr->hdr.Protocol + data_offset;
2543
2544 /* should we also check that parm and data areas do not overlap? */
2545 if (*ppparm > end_of_smb) {
2546 cFYI(1, "parms start after end of smb");
2547 return -EINVAL;
2548 } else if (parm_count + *ppparm > end_of_smb) {
2549 cFYI(1, "parm end after end of smb");
2550 return -EINVAL;
2551 } else if (*ppdata > end_of_smb) {
2552 cFYI(1, "data starts after end of smb");
2553 return -EINVAL;
2554 } else if (data_count + *ppdata > end_of_smb) {
2555 cFYI(1, "data %p + count %d (%p) past smb end %p start %p",
2556 *ppdata, data_count, (data_count + *ppdata),
2557 end_of_smb, pSMBr);
2558 return -EINVAL;
2559 } else if (parm_count + data_count > pSMBr->ByteCount) {
2560 cFYI(1, "parm count and data count larger than SMB");
2561 return -EINVAL;
2562 }
2563 *pdatalen = data_count;
2564 *pparmlen = parm_count;
2565 return 0;
2566}
2567
2568int 2794int
2569CIFSSMBQueryReparseLinkInfo(const int xid, struct cifsTconInfo *tcon, 2795CIFSSMBQueryReparseLinkInfo(const int xid, struct cifs_tcon *tcon,
2570 const unsigned char *searchName, 2796 const unsigned char *searchName,
2571 char *symlinkinfo, const int buflen, __u16 fid, 2797 char *symlinkinfo, const int buflen, __u16 fid,
2572 const struct nls_table *nls_codepage) 2798 const struct nls_table *nls_codepage)
@@ -2609,14 +2835,14 @@ CIFSSMBQueryReparseLinkInfo(const int xid, struct cifsTconInfo *tcon,
2609 } else { /* decode response */ 2835 } else { /* decode response */
2610 __u32 data_offset = le32_to_cpu(pSMBr->DataOffset); 2836 __u32 data_offset = le32_to_cpu(pSMBr->DataOffset);
2611 __u32 data_count = le32_to_cpu(pSMBr->DataCount); 2837 __u32 data_count = le32_to_cpu(pSMBr->DataCount);
2612 if ((pSMBr->ByteCount < 2) || (data_offset > 512)) { 2838 if (get_bcc(&pSMBr->hdr) < 2 || data_offset > 512) {
2613 /* BB also check enough total bytes returned */ 2839 /* BB also check enough total bytes returned */
2614 rc = -EIO; /* bad smb */ 2840 rc = -EIO; /* bad smb */
2615 goto qreparse_out; 2841 goto qreparse_out;
2616 } 2842 }
2617 if (data_count && (data_count < 2048)) { 2843 if (data_count && (data_count < 2048)) {
2618 char *end_of_smb = 2 /* sizeof byte count */ + 2844 char *end_of_smb = 2 /* sizeof byte count */ +
2619 pSMBr->ByteCount + (char *)&pSMBr->ByteCount; 2845 get_bcc(&pSMBr->hdr) + (char *)&pSMBr->ByteCount;
2620 2846
2621 struct reparse_data *reparse_buf = 2847 struct reparse_data *reparse_buf =
2622 (struct reparse_data *) 2848 (struct reparse_data *)
@@ -2666,7 +2892,7 @@ qreparse_out:
2666 2892
2667 return rc; 2893 return rc;
2668} 2894}
2669#endif /* CIFS_EXPERIMENTAL */ 2895#endif /* CIFS_SYMLINK_EXPERIMENTAL */ /* BB temporarily unused */
2670 2896
2671#ifdef CONFIG_CIFS_POSIX 2897#ifdef CONFIG_CIFS_POSIX
2672 2898
@@ -2804,7 +3030,7 @@ static __u16 ACL_to_cifs_posix(char *parm_data, const char *pACL,
2804} 3030}
2805 3031
2806int 3032int
2807CIFSSMBGetPosixACL(const int xid, struct cifsTconInfo *tcon, 3033CIFSSMBGetPosixACL(const int xid, struct cifs_tcon *tcon,
2808 const unsigned char *searchName, 3034 const unsigned char *searchName,
2809 char *acl_inf, const int buflen, const int acl_type, 3035 char *acl_inf, const int buflen, const int acl_type,
2810 const struct nls_table *nls_codepage, int remap) 3036 const struct nls_table *nls_codepage, int remap)
@@ -2862,7 +3088,7 @@ queryAclRetry:
2862 pSMB->ParameterCount = pSMB->TotalParameterCount; 3088 pSMB->ParameterCount = pSMB->TotalParameterCount;
2863 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_POSIX_ACL); 3089 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_POSIX_ACL);
2864 pSMB->Reserved4 = 0; 3090 pSMB->Reserved4 = 0;
2865 pSMB->hdr.smb_buf_length += byte_count; 3091 inc_rfc1001_len(pSMB, byte_count);
2866 pSMB->ByteCount = cpu_to_le16(byte_count); 3092 pSMB->ByteCount = cpu_to_le16(byte_count);
2867 3093
2868 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, 3094 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
@@ -2874,8 +3100,8 @@ queryAclRetry:
2874 /* decode response */ 3100 /* decode response */
2875 3101
2876 rc = validate_t2((struct smb_t2_rsp *)pSMBr); 3102 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
2877 if (rc || (pSMBr->ByteCount < 2))
2878 /* BB also check enough total bytes returned */ 3103 /* BB also check enough total bytes returned */
3104 if (rc || get_bcc(&pSMBr->hdr) < 2)
2879 rc = -EIO; /* bad smb */ 3105 rc = -EIO; /* bad smb */
2880 else { 3106 else {
2881 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset); 3107 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
@@ -2892,7 +3118,7 @@ queryAclRetry:
2892} 3118}
2893 3119
2894int 3120int
2895CIFSSMBSetPosixACL(const int xid, struct cifsTconInfo *tcon, 3121CIFSSMBSetPosixACL(const int xid, struct cifs_tcon *tcon,
2896 const unsigned char *fileName, 3122 const unsigned char *fileName,
2897 const char *local_acl, const int buflen, 3123 const char *local_acl, const int buflen,
2898 const int acl_type, 3124 const int acl_type,
@@ -2956,7 +3182,7 @@ setAclRetry:
2956 pSMB->ParameterCount = cpu_to_le16(params); 3182 pSMB->ParameterCount = cpu_to_le16(params);
2957 pSMB->TotalParameterCount = pSMB->ParameterCount; 3183 pSMB->TotalParameterCount = pSMB->ParameterCount;
2958 pSMB->Reserved4 = 0; 3184 pSMB->Reserved4 = 0;
2959 pSMB->hdr.smb_buf_length += byte_count; 3185 inc_rfc1001_len(pSMB, byte_count);
2960 pSMB->ByteCount = cpu_to_le16(byte_count); 3186 pSMB->ByteCount = cpu_to_le16(byte_count);
2961 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, 3187 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
2962 (struct smb_hdr *) pSMBr, &bytes_returned, 0); 3188 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
@@ -2972,7 +3198,7 @@ setACLerrorExit:
2972 3198
2973/* BB fix tabs in this function FIXME BB */ 3199/* BB fix tabs in this function FIXME BB */
2974int 3200int
2975CIFSGetExtAttr(const int xid, struct cifsTconInfo *tcon, 3201CIFSGetExtAttr(const int xid, struct cifs_tcon *tcon,
2976 const int netfid, __u64 *pExtAttrBits, __u64 *pMask) 3202 const int netfid, __u64 *pExtAttrBits, __u64 *pMask)
2977{ 3203{
2978 int rc = 0; 3204 int rc = 0;
@@ -3014,7 +3240,7 @@ GetExtAttrRetry:
3014 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_ATTR_FLAGS); 3240 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_ATTR_FLAGS);
3015 pSMB->Pad = 0; 3241 pSMB->Pad = 0;
3016 pSMB->Fid = netfid; 3242 pSMB->Fid = netfid;
3017 pSMB->hdr.smb_buf_length += byte_count; 3243 inc_rfc1001_len(pSMB, byte_count);
3018 pSMB->t2.ByteCount = cpu_to_le16(byte_count); 3244 pSMB->t2.ByteCount = cpu_to_le16(byte_count);
3019 3245
3020 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, 3246 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
@@ -3024,8 +3250,8 @@ GetExtAttrRetry:
3024 } else { 3250 } else {
3025 /* decode response */ 3251 /* decode response */
3026 rc = validate_t2((struct smb_t2_rsp *)pSMBr); 3252 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
3027 if (rc || (pSMBr->ByteCount < 2))
3028 /* BB also check enough total bytes returned */ 3253 /* BB also check enough total bytes returned */
3254 if (rc || get_bcc(&pSMBr->hdr) < 2)
3029 /* If rc should we check for EOPNOSUPP and 3255 /* If rc should we check for EOPNOSUPP and
3030 disable the srvino flag? or in caller? */ 3256 disable the srvino flag? or in caller? */
3031 rc = -EIO; /* bad smb */ 3257 rc = -EIO; /* bad smb */
@@ -3054,10 +3280,101 @@ GetExtAttrOut:
3054 3280
3055#endif /* CONFIG_POSIX */ 3281#endif /* CONFIG_POSIX */
3056 3282
3057#ifdef CONFIG_CIFS_EXPERIMENTAL 3283#ifdef CONFIG_CIFS_ACL
3284/*
3285 * Initialize NT TRANSACT SMB into small smb request buffer. This assumes that
3286 * all NT TRANSACTS that we init here have total parm and data under about 400
3287 * bytes (to fit in small cifs buffer size), which is the case so far, it
3288 * easily fits. NB: Setup words themselves and ByteCount MaxSetupCount (size of
3289 * returned setup area) and MaxParameterCount (returned parms size) must be set
3290 * by caller
3291 */
3292static int
3293smb_init_nttransact(const __u16 sub_command, const int setup_count,
3294 const int parm_len, struct cifs_tcon *tcon,
3295 void **ret_buf)
3296{
3297 int rc;
3298 __u32 temp_offset;
3299 struct smb_com_ntransact_req *pSMB;
3300
3301 rc = small_smb_init(SMB_COM_NT_TRANSACT, 19 + setup_count, tcon,
3302 (void **)&pSMB);
3303 if (rc)
3304 return rc;
3305 *ret_buf = (void *)pSMB;
3306 pSMB->Reserved = 0;
3307 pSMB->TotalParameterCount = cpu_to_le32(parm_len);
3308 pSMB->TotalDataCount = 0;
3309 pSMB->MaxDataCount = cpu_to_le32((tcon->ses->server->maxBuf -
3310 MAX_CIFS_HDR_SIZE) & 0xFFFFFF00);
3311 pSMB->ParameterCount = pSMB->TotalParameterCount;
3312 pSMB->DataCount = pSMB->TotalDataCount;
3313 temp_offset = offsetof(struct smb_com_ntransact_req, Parms) +
3314 (setup_count * 2) - 4 /* for rfc1001 length itself */;
3315 pSMB->ParameterOffset = cpu_to_le32(temp_offset);
3316 pSMB->DataOffset = cpu_to_le32(temp_offset + parm_len);
3317 pSMB->SetupCount = setup_count; /* no need to le convert byte fields */
3318 pSMB->SubCommand = cpu_to_le16(sub_command);
3319 return 0;
3320}
3321
3322static int
3323validate_ntransact(char *buf, char **ppparm, char **ppdata,
3324 __u32 *pparmlen, __u32 *pdatalen)
3325{
3326 char *end_of_smb;
3327 __u32 data_count, data_offset, parm_count, parm_offset;
3328 struct smb_com_ntransact_rsp *pSMBr;
3329 u16 bcc;
3330
3331 *pdatalen = 0;
3332 *pparmlen = 0;
3333
3334 if (buf == NULL)
3335 return -EINVAL;
3336
3337 pSMBr = (struct smb_com_ntransact_rsp *)buf;
3338
3339 bcc = get_bcc(&pSMBr->hdr);
3340 end_of_smb = 2 /* sizeof byte count */ + bcc +
3341 (char *)&pSMBr->ByteCount;
3342
3343 data_offset = le32_to_cpu(pSMBr->DataOffset);
3344 data_count = le32_to_cpu(pSMBr->DataCount);
3345 parm_offset = le32_to_cpu(pSMBr->ParameterOffset);
3346 parm_count = le32_to_cpu(pSMBr->ParameterCount);
3347
3348 *ppparm = (char *)&pSMBr->hdr.Protocol + parm_offset;
3349 *ppdata = (char *)&pSMBr->hdr.Protocol + data_offset;
3350
3351 /* should we also check that parm and data areas do not overlap? */
3352 if (*ppparm > end_of_smb) {
3353 cFYI(1, "parms start after end of smb");
3354 return -EINVAL;
3355 } else if (parm_count + *ppparm > end_of_smb) {
3356 cFYI(1, "parm end after end of smb");
3357 return -EINVAL;
3358 } else if (*ppdata > end_of_smb) {
3359 cFYI(1, "data starts after end of smb");
3360 return -EINVAL;
3361 } else if (data_count + *ppdata > end_of_smb) {
3362 cFYI(1, "data %p + count %d (%p) past smb end %p start %p",
3363 *ppdata, data_count, (data_count + *ppdata),
3364 end_of_smb, pSMBr);
3365 return -EINVAL;
3366 } else if (parm_count + data_count > bcc) {
3367 cFYI(1, "parm count and data count larger than SMB");
3368 return -EINVAL;
3369 }
3370 *pdatalen = data_count;
3371 *pparmlen = parm_count;
3372 return 0;
3373}
3374
3058/* Get Security Descriptor (by handle) from remote server for a file or dir */ 3375/* Get Security Descriptor (by handle) from remote server for a file or dir */
3059int 3376int
3060CIFSSMBGetCIFSACL(const int xid, struct cifsTconInfo *tcon, __u16 fid, 3377CIFSSMBGetCIFSACL(const int xid, struct cifs_tcon *tcon, __u16 fid,
3061 struct cifs_ntsd **acl_inf, __u32 *pbuflen) 3378 struct cifs_ntsd **acl_inf, __u32 *pbuflen)
3062{ 3379{
3063 int rc = 0; 3380 int rc = 0;
@@ -3082,12 +3399,12 @@ CIFSSMBGetCIFSACL(const int xid, struct cifsTconInfo *tcon, __u16 fid,
3082 pSMB->AclFlags = cpu_to_le32(CIFS_ACL_OWNER | CIFS_ACL_GROUP | 3399 pSMB->AclFlags = cpu_to_le32(CIFS_ACL_OWNER | CIFS_ACL_GROUP |
3083 CIFS_ACL_DACL); 3400 CIFS_ACL_DACL);
3084 pSMB->ByteCount = cpu_to_le16(11); /* 3 bytes pad + 8 bytes parm */ 3401 pSMB->ByteCount = cpu_to_le16(11); /* 3 bytes pad + 8 bytes parm */
3085 pSMB->hdr.smb_buf_length += 11; 3402 inc_rfc1001_len(pSMB, 11);
3086 iov[0].iov_base = (char *)pSMB; 3403 iov[0].iov_base = (char *)pSMB;
3087 iov[0].iov_len = pSMB->hdr.smb_buf_length + 4; 3404 iov[0].iov_len = be32_to_cpu(pSMB->hdr.smb_buf_length) + 4;
3088 3405
3089 rc = SendReceive2(xid, tcon->ses, iov, 1 /* num iovec */, &buf_type, 3406 rc = SendReceive2(xid, tcon->ses, iov, 1 /* num iovec */, &buf_type,
3090 CIFS_STD_OP); 3407 0);
3091 cifs_stats_inc(&tcon->num_acl_get); 3408 cifs_stats_inc(&tcon->num_acl_get);
3092 if (rc) { 3409 if (rc) {
3093 cFYI(1, "Send error in QuerySecDesc = %d", rc); 3410 cFYI(1, "Send error in QuerySecDesc = %d", rc);
@@ -3149,7 +3466,7 @@ qsec_out:
3149} 3466}
3150 3467
3151int 3468int
3152CIFSSMBSetCIFSACL(const int xid, struct cifsTconInfo *tcon, __u16 fid, 3469CIFSSMBSetCIFSACL(const int xid, struct cifs_tcon *tcon, __u16 fid,
3153 struct cifs_ntsd *pntsd, __u32 acllen) 3470 struct cifs_ntsd *pntsd, __u32 acllen)
3154{ 3471{
3155 __u16 byte_count, param_count, data_count, param_offset, data_offset; 3472 __u16 byte_count, param_count, data_count, param_offset, data_offset;
@@ -3193,10 +3510,9 @@ setCifsAclRetry:
3193 memcpy((char *) &pSMBr->hdr.Protocol + data_offset, 3510 memcpy((char *) &pSMBr->hdr.Protocol + data_offset,
3194 (char *) pntsd, 3511 (char *) pntsd,
3195 acllen); 3512 acllen);
3196 pSMB->hdr.smb_buf_length += (byte_count + data_count); 3513 inc_rfc1001_len(pSMB, byte_count + data_count);
3197
3198 } else 3514 } else
3199 pSMB->hdr.smb_buf_length += byte_count; 3515 inc_rfc1001_len(pSMB, byte_count);
3200 3516
3201 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, 3517 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
3202 (struct smb_hdr *) pSMBr, &bytes_returned, 0); 3518 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
@@ -3212,11 +3528,11 @@ setCifsAclRetry:
3212 return (rc); 3528 return (rc);
3213} 3529}
3214 3530
3215#endif /* CONFIG_CIFS_EXPERIMENTAL */ 3531#endif /* CONFIG_CIFS_ACL */
3216 3532
3217/* Legacy Query Path Information call for lookup to old servers such 3533/* Legacy Query Path Information call for lookup to old servers such
3218 as Win9x/WinME */ 3534 as Win9x/WinME */
3219int SMBQueryInformation(const int xid, struct cifsTconInfo *tcon, 3535int SMBQueryInformation(const int xid, struct cifs_tcon *tcon,
3220 const unsigned char *searchName, 3536 const unsigned char *searchName,
3221 FILE_ALL_INFO *pFinfo, 3537 FILE_ALL_INFO *pFinfo,
3222 const struct nls_table *nls_codepage, int remap) 3538 const struct nls_table *nls_codepage, int remap)
@@ -3247,7 +3563,7 @@ QInfRetry:
3247 } 3563 }
3248 pSMB->BufferFormat = 0x04; 3564 pSMB->BufferFormat = 0x04;
3249 name_len++; /* account for buffer type byte */ 3565 name_len++; /* account for buffer type byte */
3250 pSMB->hdr.smb_buf_length += (__u16) name_len; 3566 inc_rfc1001_len(pSMB, (__u16)name_len);
3251 pSMB->ByteCount = cpu_to_le16(name_len); 3567 pSMB->ByteCount = cpu_to_le16(name_len);
3252 3568
3253 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, 3569 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
@@ -3284,7 +3600,7 @@ QInfRetry:
3284} 3600}
3285 3601
3286int 3602int
3287CIFSSMBQFileInfo(const int xid, struct cifsTconInfo *tcon, 3603CIFSSMBQFileInfo(const int xid, struct cifs_tcon *tcon,
3288 u16 netfid, FILE_ALL_INFO *pFindData) 3604 u16 netfid, FILE_ALL_INFO *pFindData)
3289{ 3605{
3290 struct smb_t2_qfi_req *pSMB = NULL; 3606 struct smb_t2_qfi_req *pSMB = NULL;
@@ -3322,7 +3638,7 @@ QFileInfoRetry:
3322 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FILE_ALL_INFO); 3638 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FILE_ALL_INFO);
3323 pSMB->Pad = 0; 3639 pSMB->Pad = 0;
3324 pSMB->Fid = netfid; 3640 pSMB->Fid = netfid;
3325 pSMB->hdr.smb_buf_length += byte_count; 3641 inc_rfc1001_len(pSMB, byte_count);
3326 3642
3327 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, 3643 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
3328 (struct smb_hdr *) pSMBr, &bytes_returned, 0); 3644 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
@@ -3333,7 +3649,7 @@ QFileInfoRetry:
3333 3649
3334 if (rc) /* BB add auto retry on EOPNOTSUPP? */ 3650 if (rc) /* BB add auto retry on EOPNOTSUPP? */
3335 rc = -EIO; 3651 rc = -EIO;
3336 else if (pSMBr->ByteCount < 40) 3652 else if (get_bcc(&pSMBr->hdr) < 40)
3337 rc = -EIO; /* bad smb */ 3653 rc = -EIO; /* bad smb */
3338 else if (pFindData) { 3654 else if (pFindData) {
3339 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset); 3655 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
@@ -3351,7 +3667,7 @@ QFileInfoRetry:
3351} 3667}
3352 3668
3353int 3669int
3354CIFSSMBQPathInfo(const int xid, struct cifsTconInfo *tcon, 3670CIFSSMBQPathInfo(const int xid, struct cifs_tcon *tcon,
3355 const unsigned char *searchName, 3671 const unsigned char *searchName,
3356 FILE_ALL_INFO *pFindData, 3672 FILE_ALL_INFO *pFindData,
3357 int legacy /* old style infolevel */, 3673 int legacy /* old style infolevel */,
@@ -3409,7 +3725,7 @@ QPathInfoRetry:
3409 else 3725 else
3410 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FILE_ALL_INFO); 3726 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FILE_ALL_INFO);
3411 pSMB->Reserved4 = 0; 3727 pSMB->Reserved4 = 0;
3412 pSMB->hdr.smb_buf_length += byte_count; 3728 inc_rfc1001_len(pSMB, byte_count);
3413 pSMB->ByteCount = cpu_to_le16(byte_count); 3729 pSMB->ByteCount = cpu_to_le16(byte_count);
3414 3730
3415 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, 3731 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
@@ -3421,9 +3737,9 @@ QPathInfoRetry:
3421 3737
3422 if (rc) /* BB add auto retry on EOPNOTSUPP? */ 3738 if (rc) /* BB add auto retry on EOPNOTSUPP? */
3423 rc = -EIO; 3739 rc = -EIO;
3424 else if (!legacy && (pSMBr->ByteCount < 40)) 3740 else if (!legacy && get_bcc(&pSMBr->hdr) < 40)
3425 rc = -EIO; /* bad smb */ 3741 rc = -EIO; /* bad smb */
3426 else if (legacy && (pSMBr->ByteCount < 24)) 3742 else if (legacy && get_bcc(&pSMBr->hdr) < 24)
3427 rc = -EIO; /* 24 or 26 expected but we do not read 3743 rc = -EIO; /* 24 or 26 expected but we do not read
3428 last field */ 3744 last field */
3429 else if (pFindData) { 3745 else if (pFindData) {
@@ -3452,7 +3768,7 @@ QPathInfoRetry:
3452} 3768}
3453 3769
3454int 3770int
3455CIFSSMBUnixQFileInfo(const int xid, struct cifsTconInfo *tcon, 3771CIFSSMBUnixQFileInfo(const int xid, struct cifs_tcon *tcon,
3456 u16 netfid, FILE_UNIX_BASIC_INFO *pFindData) 3772 u16 netfid, FILE_UNIX_BASIC_INFO *pFindData)
3457{ 3773{
3458 struct smb_t2_qfi_req *pSMB = NULL; 3774 struct smb_t2_qfi_req *pSMB = NULL;
@@ -3490,7 +3806,7 @@ UnixQFileInfoRetry:
3490 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FILE_UNIX_BASIC); 3806 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FILE_UNIX_BASIC);
3491 pSMB->Pad = 0; 3807 pSMB->Pad = 0;
3492 pSMB->Fid = netfid; 3808 pSMB->Fid = netfid;
3493 pSMB->hdr.smb_buf_length += byte_count; 3809 inc_rfc1001_len(pSMB, byte_count);
3494 3810
3495 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, 3811 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
3496 (struct smb_hdr *) pSMBr, &bytes_returned, 0); 3812 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
@@ -3499,7 +3815,7 @@ UnixQFileInfoRetry:
3499 } else { /* decode response */ 3815 } else { /* decode response */
3500 rc = validate_t2((struct smb_t2_rsp *)pSMBr); 3816 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
3501 3817
3502 if (rc || (pSMBr->ByteCount < sizeof(FILE_UNIX_BASIC_INFO))) { 3818 if (rc || get_bcc(&pSMBr->hdr) < sizeof(FILE_UNIX_BASIC_INFO)) {
3503 cERROR(1, "Malformed FILE_UNIX_BASIC_INFO response.\n" 3819 cERROR(1, "Malformed FILE_UNIX_BASIC_INFO response.\n"
3504 "Unix Extensions can be disabled on mount " 3820 "Unix Extensions can be disabled on mount "
3505 "by specifying the nosfu mount option."); 3821 "by specifying the nosfu mount option.");
@@ -3521,7 +3837,7 @@ UnixQFileInfoRetry:
3521} 3837}
3522 3838
3523int 3839int
3524CIFSSMBUnixQPathInfo(const int xid, struct cifsTconInfo *tcon, 3840CIFSSMBUnixQPathInfo(const int xid, struct cifs_tcon *tcon,
3525 const unsigned char *searchName, 3841 const unsigned char *searchName,
3526 FILE_UNIX_BASIC_INFO *pFindData, 3842 FILE_UNIX_BASIC_INFO *pFindData,
3527 const struct nls_table *nls_codepage, int remap) 3843 const struct nls_table *nls_codepage, int remap)
@@ -3575,7 +3891,7 @@ UnixQPathInfoRetry:
3575 pSMB->ParameterCount = pSMB->TotalParameterCount; 3891 pSMB->ParameterCount = pSMB->TotalParameterCount;
3576 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FILE_UNIX_BASIC); 3892 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FILE_UNIX_BASIC);
3577 pSMB->Reserved4 = 0; 3893 pSMB->Reserved4 = 0;
3578 pSMB->hdr.smb_buf_length += byte_count; 3894 inc_rfc1001_len(pSMB, byte_count);
3579 pSMB->ByteCount = cpu_to_le16(byte_count); 3895 pSMB->ByteCount = cpu_to_le16(byte_count);
3580 3896
3581 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, 3897 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
@@ -3585,7 +3901,7 @@ UnixQPathInfoRetry:
3585 } else { /* decode response */ 3901 } else { /* decode response */
3586 rc = validate_t2((struct smb_t2_rsp *)pSMBr); 3902 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
3587 3903
3588 if (rc || (pSMBr->ByteCount < sizeof(FILE_UNIX_BASIC_INFO))) { 3904 if (rc || get_bcc(&pSMBr->hdr) < sizeof(FILE_UNIX_BASIC_INFO)) {
3589 cERROR(1, "Malformed FILE_UNIX_BASIC_INFO response.\n" 3905 cERROR(1, "Malformed FILE_UNIX_BASIC_INFO response.\n"
3590 "Unix Extensions can be disabled on mount " 3906 "Unix Extensions can be disabled on mount "
3591 "by specifying the nosfu mount option."); 3907 "by specifying the nosfu mount option.");
@@ -3607,7 +3923,7 @@ UnixQPathInfoRetry:
3607 3923
3608/* xid, tcon, searchName and codepage are input parms, rest are returned */ 3924/* xid, tcon, searchName and codepage are input parms, rest are returned */
3609int 3925int
3610CIFSFindFirst(const int xid, struct cifsTconInfo *tcon, 3926CIFSFindFirst(const int xid, struct cifs_tcon *tcon,
3611 const char *searchName, 3927 const char *searchName,
3612 const struct nls_table *nls_codepage, 3928 const struct nls_table *nls_codepage,
3613 __u16 *pnetfid, 3929 __u16 *pnetfid,
@@ -3689,7 +4005,7 @@ findFirstRetry:
3689 4005
3690 /* BB what should we set StorageType to? Does it matter? BB */ 4006 /* BB what should we set StorageType to? Does it matter? BB */
3691 pSMB->SearchStorageType = 0; 4007 pSMB->SearchStorageType = 0;
3692 pSMB->hdr.smb_buf_length += byte_count; 4008 inc_rfc1001_len(pSMB, byte_count);
3693 pSMB->ByteCount = cpu_to_le16(byte_count); 4009 pSMB->ByteCount = cpu_to_le16(byte_count);
3694 4010
3695 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, 4011 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
@@ -3755,7 +4071,7 @@ findFirstRetry:
3755 return rc; 4071 return rc;
3756} 4072}
3757 4073
3758int CIFSFindNext(const int xid, struct cifsTconInfo *tcon, 4074int CIFSFindNext(const int xid, struct cifs_tcon *tcon,
3759 __u16 searchHandle, struct cifs_search_info *psrch_inf) 4075 __u16 searchHandle, struct cifs_search_info *psrch_inf)
3760{ 4076{
3761 TRANSACTION2_FNEXT_REQ *pSMB = NULL; 4077 TRANSACTION2_FNEXT_REQ *pSMB = NULL;
@@ -3818,7 +4134,7 @@ int CIFSFindNext(const int xid, struct cifsTconInfo *tcon,
3818 byte_count = params + 1 /* pad */ ; 4134 byte_count = params + 1 /* pad */ ;
3819 pSMB->TotalParameterCount = cpu_to_le16(params); 4135 pSMB->TotalParameterCount = cpu_to_le16(params);
3820 pSMB->ParameterCount = pSMB->TotalParameterCount; 4136 pSMB->ParameterCount = pSMB->TotalParameterCount;
3821 pSMB->hdr.smb_buf_length += byte_count; 4137 inc_rfc1001_len(pSMB, byte_count);
3822 pSMB->ByteCount = cpu_to_le16(byte_count); 4138 pSMB->ByteCount = cpu_to_le16(byte_count);
3823 4139
3824 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, 4140 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
@@ -3893,7 +4209,7 @@ FNext2_err_exit:
3893} 4209}
3894 4210
3895int 4211int
3896CIFSFindClose(const int xid, struct cifsTconInfo *tcon, 4212CIFSFindClose(const int xid, struct cifs_tcon *tcon,
3897 const __u16 searchHandle) 4213 const __u16 searchHandle)
3898{ 4214{
3899 int rc = 0; 4215 int rc = 0;
@@ -3925,7 +4241,7 @@ CIFSFindClose(const int xid, struct cifsTconInfo *tcon,
3925} 4241}
3926 4242
3927int 4243int
3928CIFSGetSrvInodeNumber(const int xid, struct cifsTconInfo *tcon, 4244CIFSGetSrvInodeNumber(const int xid, struct cifs_tcon *tcon,
3929 const unsigned char *searchName, 4245 const unsigned char *searchName,
3930 __u64 *inode_number, 4246 __u64 *inode_number,
3931 const struct nls_table *nls_codepage, int remap) 4247 const struct nls_table *nls_codepage, int remap)
@@ -3980,7 +4296,7 @@ GetInodeNumberRetry:
3980 pSMB->ParameterCount = pSMB->TotalParameterCount; 4296 pSMB->ParameterCount = pSMB->TotalParameterCount;
3981 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FILE_INTERNAL_INFO); 4297 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FILE_INTERNAL_INFO);
3982 pSMB->Reserved4 = 0; 4298 pSMB->Reserved4 = 0;
3983 pSMB->hdr.smb_buf_length += byte_count; 4299 inc_rfc1001_len(pSMB, byte_count);
3984 pSMB->ByteCount = cpu_to_le16(byte_count); 4300 pSMB->ByteCount = cpu_to_le16(byte_count);
3985 4301
3986 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, 4302 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
@@ -3990,8 +4306,8 @@ GetInodeNumberRetry:
3990 } else { 4306 } else {
3991 /* decode response */ 4307 /* decode response */
3992 rc = validate_t2((struct smb_t2_rsp *)pSMBr); 4308 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
3993 if (rc || (pSMBr->ByteCount < 2))
3994 /* BB also check enough total bytes returned */ 4309 /* BB also check enough total bytes returned */
4310 if (rc || get_bcc(&pSMBr->hdr) < 2)
3995 /* If rc should we check for EOPNOSUPP and 4311 /* If rc should we check for EOPNOSUPP and
3996 disable the srvino flag? or in caller? */ 4312 disable the srvino flag? or in caller? */
3997 rc = -EIO; /* bad smb */ 4313 rc = -EIO; /* bad smb */
@@ -4127,7 +4443,7 @@ parse_DFS_referrals_exit:
4127} 4443}
4128 4444
4129int 4445int
4130CIFSGetDFSRefer(const int xid, struct cifsSesInfo *ses, 4446CIFSGetDFSRefer(const int xid, struct cifs_ses *ses,
4131 const unsigned char *searchName, 4447 const unsigned char *searchName,
4132 struct dfs_info3_param **target_nodes, 4448 struct dfs_info3_param **target_nodes,
4133 unsigned int *num_of_nodes, 4449 unsigned int *num_of_nodes,
@@ -4176,7 +4492,7 @@ getDFSRetry:
4176 } 4492 }
4177 4493
4178 if (ses->server) { 4494 if (ses->server) {
4179 if (ses->server->secMode & 4495 if (ses->server->sec_mode &
4180 (SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED)) 4496 (SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED))
4181 pSMB->hdr.Flags2 |= SMBFLG2_SECURITY_SIGNATURE; 4497 pSMB->hdr.Flags2 |= SMBFLG2_SECURITY_SIGNATURE;
4182 } 4498 }
@@ -4204,7 +4520,7 @@ getDFSRetry:
4204 pSMB->ParameterCount = cpu_to_le16(params); 4520 pSMB->ParameterCount = cpu_to_le16(params);
4205 pSMB->TotalParameterCount = pSMB->ParameterCount; 4521 pSMB->TotalParameterCount = pSMB->ParameterCount;
4206 pSMB->MaxReferralLevel = cpu_to_le16(3); 4522 pSMB->MaxReferralLevel = cpu_to_le16(3);
4207 pSMB->hdr.smb_buf_length += byte_count; 4523 inc_rfc1001_len(pSMB, byte_count);
4208 pSMB->ByteCount = cpu_to_le16(byte_count); 4524 pSMB->ByteCount = cpu_to_le16(byte_count);
4209 4525
4210 rc = SendReceive(xid, ses, (struct smb_hdr *) pSMB, 4526 rc = SendReceive(xid, ses, (struct smb_hdr *) pSMB,
@@ -4216,13 +4532,13 @@ getDFSRetry:
4216 rc = validate_t2((struct smb_t2_rsp *)pSMBr); 4532 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
4217 4533
4218 /* BB Also check if enough total bytes returned? */ 4534 /* BB Also check if enough total bytes returned? */
4219 if (rc || (pSMBr->ByteCount < 17)) { 4535 if (rc || get_bcc(&pSMBr->hdr) < 17) {
4220 rc = -EIO; /* bad smb */ 4536 rc = -EIO; /* bad smb */
4221 goto GetDFSRefExit; 4537 goto GetDFSRefExit;
4222 } 4538 }
4223 4539
4224 cFYI(1, "Decoding GetDFSRefer response BCC: %d Offset %d", 4540 cFYI(1, "Decoding GetDFSRefer response BCC: %d Offset %d",
4225 pSMBr->ByteCount, 4541 get_bcc(&pSMBr->hdr),
4226 le16_to_cpu(pSMBr->t2.DataOffset)); 4542 le16_to_cpu(pSMBr->t2.DataOffset));
4227 4543
4228 /* parse returned result into more usable form */ 4544 /* parse returned result into more usable form */
@@ -4241,7 +4557,7 @@ GetDFSRefExit:
4241 4557
4242/* Query File System Info such as free space to old servers such as Win 9x */ 4558/* Query File System Info such as free space to old servers such as Win 9x */
4243int 4559int
4244SMBOldQFSInfo(const int xid, struct cifsTconInfo *tcon, struct kstatfs *FSData) 4560SMBOldQFSInfo(const int xid, struct cifs_tcon *tcon, struct kstatfs *FSData)
4245{ 4561{
4246/* level 0x01 SMB_QUERY_FILE_SYSTEM_INFO */ 4562/* level 0x01 SMB_QUERY_FILE_SYSTEM_INFO */
4247 TRANSACTION2_QFSI_REQ *pSMB = NULL; 4563 TRANSACTION2_QFSI_REQ *pSMB = NULL;
@@ -4278,7 +4594,7 @@ oldQFSInfoRetry:
4278 pSMB->Reserved3 = 0; 4594 pSMB->Reserved3 = 0;
4279 pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_FS_INFORMATION); 4595 pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_FS_INFORMATION);
4280 pSMB->InformationLevel = cpu_to_le16(SMB_INFO_ALLOCATION); 4596 pSMB->InformationLevel = cpu_to_le16(SMB_INFO_ALLOCATION);
4281 pSMB->hdr.smb_buf_length += byte_count; 4597 inc_rfc1001_len(pSMB, byte_count);
4282 pSMB->ByteCount = cpu_to_le16(byte_count); 4598 pSMB->ByteCount = cpu_to_le16(byte_count);
4283 4599
4284 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, 4600 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
@@ -4288,12 +4604,12 @@ oldQFSInfoRetry:
4288 } else { /* decode response */ 4604 } else { /* decode response */
4289 rc = validate_t2((struct smb_t2_rsp *)pSMBr); 4605 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
4290 4606
4291 if (rc || (pSMBr->ByteCount < 18)) 4607 if (rc || get_bcc(&pSMBr->hdr) < 18)
4292 rc = -EIO; /* bad smb */ 4608 rc = -EIO; /* bad smb */
4293 else { 4609 else {
4294 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset); 4610 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
4295 cFYI(1, "qfsinf resp BCC: %d Offset %d", 4611 cFYI(1, "qfsinf resp BCC: %d Offset %d",
4296 pSMBr->ByteCount, data_offset); 4612 get_bcc(&pSMBr->hdr), data_offset);
4297 4613
4298 response_data = (FILE_SYSTEM_ALLOC_INFO *) 4614 response_data = (FILE_SYSTEM_ALLOC_INFO *)
4299 (((char *) &pSMBr->hdr.Protocol) + data_offset); 4615 (((char *) &pSMBr->hdr.Protocol) + data_offset);
@@ -4320,7 +4636,7 @@ oldQFSInfoRetry:
4320} 4636}
4321 4637
4322int 4638int
4323CIFSSMBQFSInfo(const int xid, struct cifsTconInfo *tcon, struct kstatfs *FSData) 4639CIFSSMBQFSInfo(const int xid, struct cifs_tcon *tcon, struct kstatfs *FSData)
4324{ 4640{
4325/* level 0x103 SMB_QUERY_FILE_SYSTEM_INFO */ 4641/* level 0x103 SMB_QUERY_FILE_SYSTEM_INFO */
4326 TRANSACTION2_QFSI_REQ *pSMB = NULL; 4642 TRANSACTION2_QFSI_REQ *pSMB = NULL;
@@ -4357,7 +4673,7 @@ QFSInfoRetry:
4357 pSMB->Reserved3 = 0; 4673 pSMB->Reserved3 = 0;
4358 pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_FS_INFORMATION); 4674 pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_FS_INFORMATION);
4359 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FS_SIZE_INFO); 4675 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FS_SIZE_INFO);
4360 pSMB->hdr.smb_buf_length += byte_count; 4676 inc_rfc1001_len(pSMB, byte_count);
4361 pSMB->ByteCount = cpu_to_le16(byte_count); 4677 pSMB->ByteCount = cpu_to_le16(byte_count);
4362 4678
4363 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, 4679 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
@@ -4367,7 +4683,7 @@ QFSInfoRetry:
4367 } else { /* decode response */ 4683 } else { /* decode response */
4368 rc = validate_t2((struct smb_t2_rsp *)pSMBr); 4684 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
4369 4685
4370 if (rc || (pSMBr->ByteCount < 24)) 4686 if (rc || get_bcc(&pSMBr->hdr) < 24)
4371 rc = -EIO; /* bad smb */ 4687 rc = -EIO; /* bad smb */
4372 else { 4688 else {
4373 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset); 4689 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
@@ -4399,7 +4715,7 @@ QFSInfoRetry:
4399} 4715}
4400 4716
4401int 4717int
4402CIFSSMBQFSAttributeInfo(const int xid, struct cifsTconInfo *tcon) 4718CIFSSMBQFSAttributeInfo(const int xid, struct cifs_tcon *tcon)
4403{ 4719{
4404/* level 0x105 SMB_QUERY_FILE_SYSTEM_INFO */ 4720/* level 0x105 SMB_QUERY_FILE_SYSTEM_INFO */
4405 TRANSACTION2_QFSI_REQ *pSMB = NULL; 4721 TRANSACTION2_QFSI_REQ *pSMB = NULL;
@@ -4437,7 +4753,7 @@ QFSAttributeRetry:
4437 pSMB->Reserved3 = 0; 4753 pSMB->Reserved3 = 0;
4438 pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_FS_INFORMATION); 4754 pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_FS_INFORMATION);
4439 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FS_ATTRIBUTE_INFO); 4755 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FS_ATTRIBUTE_INFO);
4440 pSMB->hdr.smb_buf_length += byte_count; 4756 inc_rfc1001_len(pSMB, byte_count);
4441 pSMB->ByteCount = cpu_to_le16(byte_count); 4757 pSMB->ByteCount = cpu_to_le16(byte_count);
4442 4758
4443 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, 4759 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
@@ -4447,7 +4763,7 @@ QFSAttributeRetry:
4447 } else { /* decode response */ 4763 } else { /* decode response */
4448 rc = validate_t2((struct smb_t2_rsp *)pSMBr); 4764 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
4449 4765
4450 if (rc || (pSMBr->ByteCount < 13)) { 4766 if (rc || get_bcc(&pSMBr->hdr) < 13) {
4451 /* BB also check if enough bytes returned */ 4767 /* BB also check if enough bytes returned */
4452 rc = -EIO; /* bad smb */ 4768 rc = -EIO; /* bad smb */
4453 } else { 4769 } else {
@@ -4469,7 +4785,7 @@ QFSAttributeRetry:
4469} 4785}
4470 4786
4471int 4787int
4472CIFSSMBQFSDeviceInfo(const int xid, struct cifsTconInfo *tcon) 4788CIFSSMBQFSDeviceInfo(const int xid, struct cifs_tcon *tcon)
4473{ 4789{
4474/* level 0x104 SMB_QUERY_FILE_SYSTEM_INFO */ 4790/* level 0x104 SMB_QUERY_FILE_SYSTEM_INFO */
4475 TRANSACTION2_QFSI_REQ *pSMB = NULL; 4791 TRANSACTION2_QFSI_REQ *pSMB = NULL;
@@ -4508,7 +4824,7 @@ QFSDeviceRetry:
4508 pSMB->Reserved3 = 0; 4824 pSMB->Reserved3 = 0;
4509 pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_FS_INFORMATION); 4825 pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_FS_INFORMATION);
4510 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FS_DEVICE_INFO); 4826 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FS_DEVICE_INFO);
4511 pSMB->hdr.smb_buf_length += byte_count; 4827 inc_rfc1001_len(pSMB, byte_count);
4512 pSMB->ByteCount = cpu_to_le16(byte_count); 4828 pSMB->ByteCount = cpu_to_le16(byte_count);
4513 4829
4514 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, 4830 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
@@ -4518,7 +4834,8 @@ QFSDeviceRetry:
4518 } else { /* decode response */ 4834 } else { /* decode response */
4519 rc = validate_t2((struct smb_t2_rsp *)pSMBr); 4835 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
4520 4836
4521 if (rc || (pSMBr->ByteCount < sizeof(FILE_SYSTEM_DEVICE_INFO))) 4837 if (rc || get_bcc(&pSMBr->hdr) <
4838 sizeof(FILE_SYSTEM_DEVICE_INFO))
4522 rc = -EIO; /* bad smb */ 4839 rc = -EIO; /* bad smb */
4523 else { 4840 else {
4524 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset); 4841 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
@@ -4539,7 +4856,7 @@ QFSDeviceRetry:
4539} 4856}
4540 4857
4541int 4858int
4542CIFSSMBQFSUnixInfo(const int xid, struct cifsTconInfo *tcon) 4859CIFSSMBQFSUnixInfo(const int xid, struct cifs_tcon *tcon)
4543{ 4860{
4544/* level 0x200 SMB_QUERY_CIFS_UNIX_INFO */ 4861/* level 0x200 SMB_QUERY_CIFS_UNIX_INFO */
4545 TRANSACTION2_QFSI_REQ *pSMB = NULL; 4862 TRANSACTION2_QFSI_REQ *pSMB = NULL;
@@ -4577,7 +4894,7 @@ QFSUnixRetry:
4577 pSMB->Reserved3 = 0; 4894 pSMB->Reserved3 = 0;
4578 pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_FS_INFORMATION); 4895 pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_FS_INFORMATION);
4579 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_CIFS_UNIX_INFO); 4896 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_CIFS_UNIX_INFO);
4580 pSMB->hdr.smb_buf_length += byte_count; 4897 inc_rfc1001_len(pSMB, byte_count);
4581 pSMB->ByteCount = cpu_to_le16(byte_count); 4898 pSMB->ByteCount = cpu_to_le16(byte_count);
4582 4899
4583 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, 4900 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
@@ -4587,7 +4904,7 @@ QFSUnixRetry:
4587 } else { /* decode response */ 4904 } else { /* decode response */
4588 rc = validate_t2((struct smb_t2_rsp *)pSMBr); 4905 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
4589 4906
4590 if (rc || (pSMBr->ByteCount < 13)) { 4907 if (rc || get_bcc(&pSMBr->hdr) < 13) {
4591 rc = -EIO; /* bad smb */ 4908 rc = -EIO; /* bad smb */
4592 } else { 4909 } else {
4593 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset); 4910 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
@@ -4609,7 +4926,7 @@ QFSUnixRetry:
4609} 4926}
4610 4927
4611int 4928int
4612CIFSSMBSetFSUnixInfo(const int xid, struct cifsTconInfo *tcon, __u64 cap) 4929CIFSSMBSetFSUnixInfo(const int xid, struct cifs_tcon *tcon, __u64 cap)
4613{ 4930{
4614/* level 0x200 SMB_SET_CIFS_UNIX_INFO */ 4931/* level 0x200 SMB_SET_CIFS_UNIX_INFO */
4615 TRANSACTION2_SETFSI_REQ *pSMB = NULL; 4932 TRANSACTION2_SETFSI_REQ *pSMB = NULL;
@@ -4660,7 +4977,7 @@ SETFSUnixRetry:
4660 pSMB->ClientUnixMinor = cpu_to_le16(CIFS_UNIX_MINOR_VERSION); 4977 pSMB->ClientUnixMinor = cpu_to_le16(CIFS_UNIX_MINOR_VERSION);
4661 pSMB->ClientUnixCap = cpu_to_le64(cap); 4978 pSMB->ClientUnixCap = cpu_to_le64(cap);
4662 4979
4663 pSMB->hdr.smb_buf_length += byte_count; 4980 inc_rfc1001_len(pSMB, byte_count);
4664 pSMB->ByteCount = cpu_to_le16(byte_count); 4981 pSMB->ByteCount = cpu_to_le16(byte_count);
4665 4982
4666 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, 4983 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
@@ -4683,7 +5000,7 @@ SETFSUnixRetry:
4683 5000
4684 5001
4685int 5002int
4686CIFSSMBQFSPosixInfo(const int xid, struct cifsTconInfo *tcon, 5003CIFSSMBQFSPosixInfo(const int xid, struct cifs_tcon *tcon,
4687 struct kstatfs *FSData) 5004 struct kstatfs *FSData)
4688{ 5005{
4689/* level 0x201 SMB_QUERY_CIFS_POSIX_INFO */ 5006/* level 0x201 SMB_QUERY_CIFS_POSIX_INFO */
@@ -4722,7 +5039,7 @@ QFSPosixRetry:
4722 pSMB->Reserved3 = 0; 5039 pSMB->Reserved3 = 0;
4723 pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_FS_INFORMATION); 5040 pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_FS_INFORMATION);
4724 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_POSIX_FS_INFO); 5041 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_POSIX_FS_INFO);
4725 pSMB->hdr.smb_buf_length += byte_count; 5042 inc_rfc1001_len(pSMB, byte_count);
4726 pSMB->ByteCount = cpu_to_le16(byte_count); 5043 pSMB->ByteCount = cpu_to_le16(byte_count);
4727 5044
4728 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, 5045 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
@@ -4732,7 +5049,7 @@ QFSPosixRetry:
4732 } else { /* decode response */ 5049 } else { /* decode response */
4733 rc = validate_t2((struct smb_t2_rsp *)pSMBr); 5050 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
4734 5051
4735 if (rc || (pSMBr->ByteCount < 13)) { 5052 if (rc || get_bcc(&pSMBr->hdr) < 13) {
4736 rc = -EIO; /* bad smb */ 5053 rc = -EIO; /* bad smb */
4737 } else { 5054 } else {
4738 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset); 5055 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
@@ -4776,7 +5093,7 @@ QFSPosixRetry:
4776 in Samba which this routine can run into */ 5093 in Samba which this routine can run into */
4777 5094
4778int 5095int
4779CIFSSMBSetEOF(const int xid, struct cifsTconInfo *tcon, const char *fileName, 5096CIFSSMBSetEOF(const int xid, struct cifs_tcon *tcon, const char *fileName,
4780 __u64 size, bool SetAllocation, 5097 __u64 size, bool SetAllocation,
4781 const struct nls_table *nls_codepage, int remap) 5098 const struct nls_table *nls_codepage, int remap)
4782{ 5099{
@@ -4848,7 +5165,7 @@ SetEOFRetry:
4848 pSMB->ParameterCount = cpu_to_le16(params); 5165 pSMB->ParameterCount = cpu_to_le16(params);
4849 pSMB->TotalParameterCount = pSMB->ParameterCount; 5166 pSMB->TotalParameterCount = pSMB->ParameterCount;
4850 pSMB->Reserved4 = 0; 5167 pSMB->Reserved4 = 0;
4851 pSMB->hdr.smb_buf_length += byte_count; 5168 inc_rfc1001_len(pSMB, byte_count);
4852 parm_data->FileSize = cpu_to_le64(size); 5169 parm_data->FileSize = cpu_to_le64(size);
4853 pSMB->ByteCount = cpu_to_le16(byte_count); 5170 pSMB->ByteCount = cpu_to_le16(byte_count);
4854 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, 5171 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
@@ -4865,11 +5182,10 @@ SetEOFRetry:
4865} 5182}
4866 5183
4867int 5184int
4868CIFSSMBSetFileSize(const int xid, struct cifsTconInfo *tcon, __u64 size, 5185CIFSSMBSetFileSize(const int xid, struct cifs_tcon *tcon, __u64 size,
4869 __u16 fid, __u32 pid_of_opener, bool SetAllocation) 5186 __u16 fid, __u32 pid_of_opener, bool SetAllocation)
4870{ 5187{
4871 struct smb_com_transaction2_sfi_req *pSMB = NULL; 5188 struct smb_com_transaction2_sfi_req *pSMB = NULL;
4872 char *data_offset;
4873 struct file_end_of_file_info *parm_data; 5189 struct file_end_of_file_info *parm_data;
4874 int rc = 0; 5190 int rc = 0;
4875 __u16 params, param_offset, offset, byte_count, count; 5191 __u16 params, param_offset, offset, byte_count, count;
@@ -4893,8 +5209,6 @@ CIFSSMBSetFileSize(const int xid, struct cifsTconInfo *tcon, __u64 size,
4893 param_offset = offsetof(struct smb_com_transaction2_sfi_req, Fid) - 4; 5209 param_offset = offsetof(struct smb_com_transaction2_sfi_req, Fid) - 4;
4894 offset = param_offset + params; 5210 offset = param_offset + params;
4895 5211
4896 data_offset = (char *) (&pSMB->hdr.Protocol) + offset;
4897
4898 count = sizeof(struct file_end_of_file_info); 5212 count = sizeof(struct file_end_of_file_info);
4899 pSMB->MaxParameterCount = cpu_to_le16(2); 5213 pSMB->MaxParameterCount = cpu_to_le16(2);
4900 /* BB find exact max SMB PDU from sess structure BB */ 5214 /* BB find exact max SMB PDU from sess structure BB */
@@ -4930,7 +5244,7 @@ CIFSSMBSetFileSize(const int xid, struct cifsTconInfo *tcon, __u64 size,
4930 cpu_to_le16(SMB_SET_FILE_END_OF_FILE_INFO); 5244 cpu_to_le16(SMB_SET_FILE_END_OF_FILE_INFO);
4931 } 5245 }
4932 pSMB->Reserved4 = 0; 5246 pSMB->Reserved4 = 0;
4933 pSMB->hdr.smb_buf_length += byte_count; 5247 inc_rfc1001_len(pSMB, byte_count);
4934 pSMB->ByteCount = cpu_to_le16(byte_count); 5248 pSMB->ByteCount = cpu_to_le16(byte_count);
4935 rc = SendReceiveNoRsp(xid, tcon->ses, (struct smb_hdr *) pSMB, 0); 5249 rc = SendReceiveNoRsp(xid, tcon->ses, (struct smb_hdr *) pSMB, 0);
4936 if (rc) { 5250 if (rc) {
@@ -4950,7 +5264,7 @@ CIFSSMBSetFileSize(const int xid, struct cifsTconInfo *tcon, __u64 size,
4950 time and resort to the original setpathinfo level which takes the ancient 5264 time and resort to the original setpathinfo level which takes the ancient
4951 DOS time format with 2 second granularity */ 5265 DOS time format with 2 second granularity */
4952int 5266int
4953CIFSSMBSetFileInfo(const int xid, struct cifsTconInfo *tcon, 5267CIFSSMBSetFileInfo(const int xid, struct cifs_tcon *tcon,
4954 const FILE_BASIC_INFO *data, __u16 fid, __u32 pid_of_opener) 5268 const FILE_BASIC_INFO *data, __u16 fid, __u32 pid_of_opener)
4955{ 5269{
4956 struct smb_com_transaction2_sfi_req *pSMB = NULL; 5270 struct smb_com_transaction2_sfi_req *pSMB = NULL;
@@ -4998,7 +5312,7 @@ CIFSSMBSetFileInfo(const int xid, struct cifsTconInfo *tcon,
4998 else 5312 else
4999 pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_BASIC_INFO); 5313 pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_BASIC_INFO);
5000 pSMB->Reserved4 = 0; 5314 pSMB->Reserved4 = 0;
5001 pSMB->hdr.smb_buf_length += byte_count; 5315 inc_rfc1001_len(pSMB, byte_count);
5002 pSMB->ByteCount = cpu_to_le16(byte_count); 5316 pSMB->ByteCount = cpu_to_le16(byte_count);
5003 memcpy(data_offset, data, sizeof(FILE_BASIC_INFO)); 5317 memcpy(data_offset, data, sizeof(FILE_BASIC_INFO));
5004 rc = SendReceiveNoRsp(xid, tcon->ses, (struct smb_hdr *) pSMB, 0); 5318 rc = SendReceiveNoRsp(xid, tcon->ses, (struct smb_hdr *) pSMB, 0);
@@ -5012,7 +5326,7 @@ CIFSSMBSetFileInfo(const int xid, struct cifsTconInfo *tcon,
5012} 5326}
5013 5327
5014int 5328int
5015CIFSSMBSetFileDisposition(const int xid, struct cifsTconInfo *tcon, 5329CIFSSMBSetFileDisposition(const int xid, struct cifs_tcon *tcon,
5016 bool delete_file, __u16 fid, __u32 pid_of_opener) 5330 bool delete_file, __u16 fid, __u32 pid_of_opener)
5017{ 5331{
5018 struct smb_com_transaction2_sfi_req *pSMB = NULL; 5332 struct smb_com_transaction2_sfi_req *pSMB = NULL;
@@ -5057,7 +5371,7 @@ CIFSSMBSetFileDisposition(const int xid, struct cifsTconInfo *tcon,
5057 pSMB->Fid = fid; 5371 pSMB->Fid = fid;
5058 pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_DISPOSITION_INFO); 5372 pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_DISPOSITION_INFO);
5059 pSMB->Reserved4 = 0; 5373 pSMB->Reserved4 = 0;
5060 pSMB->hdr.smb_buf_length += byte_count; 5374 inc_rfc1001_len(pSMB, byte_count);
5061 pSMB->ByteCount = cpu_to_le16(byte_count); 5375 pSMB->ByteCount = cpu_to_le16(byte_count);
5062 *data_offset = delete_file ? 1 : 0; 5376 *data_offset = delete_file ? 1 : 0;
5063 rc = SendReceiveNoRsp(xid, tcon->ses, (struct smb_hdr *) pSMB, 0); 5377 rc = SendReceiveNoRsp(xid, tcon->ses, (struct smb_hdr *) pSMB, 0);
@@ -5068,7 +5382,7 @@ CIFSSMBSetFileDisposition(const int xid, struct cifsTconInfo *tcon,
5068} 5382}
5069 5383
5070int 5384int
5071CIFSSMBSetPathInfo(const int xid, struct cifsTconInfo *tcon, 5385CIFSSMBSetPathInfo(const int xid, struct cifs_tcon *tcon,
5072 const char *fileName, const FILE_BASIC_INFO *data, 5386 const char *fileName, const FILE_BASIC_INFO *data,
5073 const struct nls_table *nls_codepage, int remap) 5387 const struct nls_table *nls_codepage, int remap)
5074{ 5388{
@@ -5130,7 +5444,7 @@ SetTimesRetry:
5130 else 5444 else
5131 pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_BASIC_INFO); 5445 pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_BASIC_INFO);
5132 pSMB->Reserved4 = 0; 5446 pSMB->Reserved4 = 0;
5133 pSMB->hdr.smb_buf_length += byte_count; 5447 inc_rfc1001_len(pSMB, byte_count);
5134 memcpy(data_offset, data, sizeof(FILE_BASIC_INFO)); 5448 memcpy(data_offset, data, sizeof(FILE_BASIC_INFO));
5135 pSMB->ByteCount = cpu_to_le16(byte_count); 5449 pSMB->ByteCount = cpu_to_le16(byte_count);
5136 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, 5450 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
@@ -5152,7 +5466,7 @@ SetTimesRetry:
5152 handling it anyway and NT4 was what we thought it would be needed for 5466 handling it anyway and NT4 was what we thought it would be needed for
5153 Do not delete it until we prove whether needed for Win9x though */ 5467 Do not delete it until we prove whether needed for Win9x though */
5154int 5468int
5155CIFSSMBSetAttrLegacy(int xid, struct cifsTconInfo *tcon, char *fileName, 5469CIFSSMBSetAttrLegacy(int xid, struct cifs_tcon *tcon, char *fileName,
5156 __u16 dos_attrs, const struct nls_table *nls_codepage) 5470 __u16 dos_attrs, const struct nls_table *nls_codepage)
5157{ 5471{
5158 SETATTR_REQ *pSMB = NULL; 5472 SETATTR_REQ *pSMB = NULL;
@@ -5182,7 +5496,7 @@ SetAttrLgcyRetry:
5182 } 5496 }
5183 pSMB->attr = cpu_to_le16(dos_attrs); 5497 pSMB->attr = cpu_to_le16(dos_attrs);
5184 pSMB->BufferFormat = 0x04; 5498 pSMB->BufferFormat = 0x04;
5185 pSMB->hdr.smb_buf_length += name_len + 1; 5499 inc_rfc1001_len(pSMB, name_len + 1);
5186 pSMB->ByteCount = cpu_to_le16(name_len + 1); 5500 pSMB->ByteCount = cpu_to_le16(name_len + 1);
5187 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, 5501 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
5188 (struct smb_hdr *) pSMBr, &bytes_returned, 0); 5502 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
@@ -5208,7 +5522,7 @@ cifs_fill_unix_set_info(FILE_UNIX_BASIC_INFO *data_offset,
5208 * Samba server ignores set of file size to zero due to bugs in some 5522 * Samba server ignores set of file size to zero due to bugs in some
5209 * older clients, but we should be precise - we use SetFileSize to 5523 * older clients, but we should be precise - we use SetFileSize to
5210 * set file size and do not want to truncate file size to zero 5524 * set file size and do not want to truncate file size to zero
5211 * accidently as happened on one Samba server beta by putting 5525 * accidentally as happened on one Samba server beta by putting
5212 * zero instead of -1 here 5526 * zero instead of -1 here
5213 */ 5527 */
5214 data_offset->EndOfFile = cpu_to_le64(NO_CHANGE_64); 5528 data_offset->EndOfFile = cpu_to_le64(NO_CHANGE_64);
@@ -5240,7 +5554,7 @@ cifs_fill_unix_set_info(FILE_UNIX_BASIC_INFO *data_offset,
5240} 5554}
5241 5555
5242int 5556int
5243CIFSSMBUnixSetFileInfo(const int xid, struct cifsTconInfo *tcon, 5557CIFSSMBUnixSetFileInfo(const int xid, struct cifs_tcon *tcon,
5244 const struct cifs_unix_set_info_args *args, 5558 const struct cifs_unix_set_info_args *args,
5245 u16 fid, u32 pid_of_opener) 5559 u16 fid, u32 pid_of_opener)
5246{ 5560{
@@ -5287,7 +5601,7 @@ CIFSSMBUnixSetFileInfo(const int xid, struct cifsTconInfo *tcon,
5287 pSMB->Fid = fid; 5601 pSMB->Fid = fid;
5288 pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_UNIX_BASIC); 5602 pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_UNIX_BASIC);
5289 pSMB->Reserved4 = 0; 5603 pSMB->Reserved4 = 0;
5290 pSMB->hdr.smb_buf_length += byte_count; 5604 inc_rfc1001_len(pSMB, byte_count);
5291 pSMB->ByteCount = cpu_to_le16(byte_count); 5605 pSMB->ByteCount = cpu_to_le16(byte_count);
5292 5606
5293 cifs_fill_unix_set_info(data_offset, args); 5607 cifs_fill_unix_set_info(data_offset, args);
@@ -5303,7 +5617,7 @@ CIFSSMBUnixSetFileInfo(const int xid, struct cifsTconInfo *tcon,
5303} 5617}
5304 5618
5305int 5619int
5306CIFSSMBUnixSetPathInfo(const int xid, struct cifsTconInfo *tcon, char *fileName, 5620CIFSSMBUnixSetPathInfo(const int xid, struct cifs_tcon *tcon, char *fileName,
5307 const struct cifs_unix_set_info_args *args, 5621 const struct cifs_unix_set_info_args *args,
5308 const struct nls_table *nls_codepage, int remap) 5622 const struct nls_table *nls_codepage, int remap)
5309{ 5623{
@@ -5363,7 +5677,7 @@ setPermsRetry:
5363 pSMB->TotalDataCount = pSMB->DataCount; 5677 pSMB->TotalDataCount = pSMB->DataCount;
5364 pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_UNIX_BASIC); 5678 pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_UNIX_BASIC);
5365 pSMB->Reserved4 = 0; 5679 pSMB->Reserved4 = 0;
5366 pSMB->hdr.smb_buf_length += byte_count; 5680 inc_rfc1001_len(pSMB, byte_count);
5367 5681
5368 cifs_fill_unix_set_info(data_offset, args); 5682 cifs_fill_unix_set_info(data_offset, args);
5369 5683
@@ -5379,79 +5693,6 @@ setPermsRetry:
5379 return rc; 5693 return rc;
5380} 5694}
5381 5695
5382int CIFSSMBNotify(const int xid, struct cifsTconInfo *tcon,
5383 const int notify_subdirs, const __u16 netfid,
5384 __u32 filter, struct file *pfile, int multishot,
5385 const struct nls_table *nls_codepage)
5386{
5387 int rc = 0;
5388 struct smb_com_transaction_change_notify_req *pSMB = NULL;
5389 struct smb_com_ntransaction_change_notify_rsp *pSMBr = NULL;
5390 struct dir_notify_req *dnotify_req;
5391 int bytes_returned;
5392
5393 cFYI(1, "In CIFSSMBNotify for file handle %d", (int)netfid);
5394 rc = smb_init(SMB_COM_NT_TRANSACT, 23, tcon, (void **) &pSMB,
5395 (void **) &pSMBr);
5396 if (rc)
5397 return rc;
5398
5399 pSMB->TotalParameterCount = 0 ;
5400 pSMB->TotalDataCount = 0;
5401 pSMB->MaxParameterCount = cpu_to_le32(2);
5402 /* BB find exact data count max from sess structure BB */
5403 pSMB->MaxDataCount = 0; /* same in little endian or be */
5404/* BB VERIFY verify which is correct for above BB */
5405 pSMB->MaxDataCount = cpu_to_le32((tcon->ses->server->maxBuf -
5406 MAX_CIFS_HDR_SIZE) & 0xFFFFFF00);
5407
5408 pSMB->MaxSetupCount = 4;
5409 pSMB->Reserved = 0;
5410 pSMB->ParameterOffset = 0;
5411 pSMB->DataCount = 0;
5412 pSMB->DataOffset = 0;
5413 pSMB->SetupCount = 4; /* single byte does not need le conversion */
5414 pSMB->SubCommand = cpu_to_le16(NT_TRANSACT_NOTIFY_CHANGE);
5415 pSMB->ParameterCount = pSMB->TotalParameterCount;
5416 if (notify_subdirs)
5417 pSMB->WatchTree = 1; /* one byte - no le conversion needed */
5418 pSMB->Reserved2 = 0;
5419 pSMB->CompletionFilter = cpu_to_le32(filter);
5420 pSMB->Fid = netfid; /* file handle always le */
5421 pSMB->ByteCount = 0;
5422
5423 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
5424 (struct smb_hdr *)pSMBr, &bytes_returned,
5425 CIFS_ASYNC_OP);
5426 if (rc) {
5427 cFYI(1, "Error in Notify = %d", rc);
5428 } else {
5429 /* Add file to outstanding requests */
5430 /* BB change to kmem cache alloc */
5431 dnotify_req = kmalloc(
5432 sizeof(struct dir_notify_req),
5433 GFP_KERNEL);
5434 if (dnotify_req) {
5435 dnotify_req->Pid = pSMB->hdr.Pid;
5436 dnotify_req->PidHigh = pSMB->hdr.PidHigh;
5437 dnotify_req->Mid = pSMB->hdr.Mid;
5438 dnotify_req->Tid = pSMB->hdr.Tid;
5439 dnotify_req->Uid = pSMB->hdr.Uid;
5440 dnotify_req->netfid = netfid;
5441 dnotify_req->pfile = pfile;
5442 dnotify_req->filter = filter;
5443 dnotify_req->multishot = multishot;
5444 spin_lock(&GlobalMid_Lock);
5445 list_add_tail(&dnotify_req->lhead,
5446 &GlobalDnotifyReqList);
5447 spin_unlock(&GlobalMid_Lock);
5448 } else
5449 rc = -ENOMEM;
5450 }
5451 cifs_buf_release(pSMB);
5452 return rc;
5453}
5454
5455#ifdef CONFIG_CIFS_XATTR 5696#ifdef CONFIG_CIFS_XATTR
5456/* 5697/*
5457 * Do a path-based QUERY_ALL_EAS call and parse the result. This is a common 5698 * Do a path-based QUERY_ALL_EAS call and parse the result. This is a common
@@ -5463,7 +5704,7 @@ int CIFSSMBNotify(const int xid, struct cifsTconInfo *tcon,
5463 * the data isn't copied to it, but the length is returned. 5704 * the data isn't copied to it, but the length is returned.
5464 */ 5705 */
5465ssize_t 5706ssize_t
5466CIFSSMBQAllEAs(const int xid, struct cifsTconInfo *tcon, 5707CIFSSMBQAllEAs(const int xid, struct cifs_tcon *tcon,
5467 const unsigned char *searchName, const unsigned char *ea_name, 5708 const unsigned char *searchName, const unsigned char *ea_name,
5468 char *EAData, size_t buf_size, 5709 char *EAData, size_t buf_size,
5469 const struct nls_table *nls_codepage, int remap) 5710 const struct nls_table *nls_codepage, int remap)
@@ -5521,7 +5762,7 @@ QAllEAsRetry:
5521 pSMB->ParameterCount = pSMB->TotalParameterCount; 5762 pSMB->ParameterCount = pSMB->TotalParameterCount;
5522 pSMB->InformationLevel = cpu_to_le16(SMB_INFO_QUERY_ALL_EAS); 5763 pSMB->InformationLevel = cpu_to_le16(SMB_INFO_QUERY_ALL_EAS);
5523 pSMB->Reserved4 = 0; 5764 pSMB->Reserved4 = 0;
5524 pSMB->hdr.smb_buf_length += byte_count; 5765 inc_rfc1001_len(pSMB, byte_count);
5525 pSMB->ByteCount = cpu_to_le16(byte_count); 5766 pSMB->ByteCount = cpu_to_le16(byte_count);
5526 5767
5527 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, 5768 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
@@ -5537,7 +5778,7 @@ QAllEAsRetry:
5537 of these trans2 responses */ 5778 of these trans2 responses */
5538 5779
5539 rc = validate_t2((struct smb_t2_rsp *)pSMBr); 5780 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
5540 if (rc || (pSMBr->ByteCount < 4)) { 5781 if (rc || get_bcc(&pSMBr->hdr) < 4) {
5541 rc = -EIO; /* bad smb */ 5782 rc = -EIO; /* bad smb */
5542 goto QAllEAsOut; 5783 goto QAllEAsOut;
5543 } 5784 }
@@ -5562,7 +5803,7 @@ QAllEAsRetry:
5562 } 5803 }
5563 5804
5564 /* make sure list_len doesn't go past end of SMB */ 5805 /* make sure list_len doesn't go past end of SMB */
5565 end_of_smb = (char *)pByteArea(&pSMBr->hdr) + BCC(&pSMBr->hdr); 5806 end_of_smb = (char *)pByteArea(&pSMBr->hdr) + get_bcc(&pSMBr->hdr);
5566 if ((char *)ea_response_data + list_len > end_of_smb) { 5807 if ((char *)ea_response_data + list_len > end_of_smb) {
5567 cFYI(1, "EA list appears to go beyond SMB"); 5808 cFYI(1, "EA list appears to go beyond SMB");
5568 rc = -EIO; 5809 rc = -EIO;
@@ -5644,7 +5885,7 @@ QAllEAsOut:
5644} 5885}
5645 5886
5646int 5887int
5647CIFSSMBSetEA(const int xid, struct cifsTconInfo *tcon, const char *fileName, 5888CIFSSMBSetEA(const int xid, struct cifs_tcon *tcon, const char *fileName,
5648 const char *ea_name, const void *ea_value, 5889 const char *ea_name, const void *ea_value,
5649 const __u16 ea_value_len, const struct nls_table *nls_codepage, 5890 const __u16 ea_value_len, const struct nls_table *nls_codepage,
5650 int remap) 5891 int remap)
@@ -5734,7 +5975,7 @@ SetEARetry:
5734 pSMB->ParameterCount = cpu_to_le16(params); 5975 pSMB->ParameterCount = cpu_to_le16(params);
5735 pSMB->TotalParameterCount = pSMB->ParameterCount; 5976 pSMB->TotalParameterCount = pSMB->ParameterCount;
5736 pSMB->Reserved4 = 0; 5977 pSMB->Reserved4 = 0;
5737 pSMB->hdr.smb_buf_length += byte_count; 5978 inc_rfc1001_len(pSMB, byte_count);
5738 pSMB->ByteCount = cpu_to_le16(byte_count); 5979 pSMB->ByteCount = cpu_to_le16(byte_count);
5739 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, 5980 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
5740 (struct smb_hdr *) pSMBr, &bytes_returned, 0); 5981 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
@@ -5748,5 +5989,99 @@ SetEARetry:
5748 5989
5749 return rc; 5990 return rc;
5750} 5991}
5751
5752#endif 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 */
6015int 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 */