aboutsummaryrefslogtreecommitdiffstats
path: root/fs/cifs/cifssmb.c
diff options
context:
space:
mode:
authorLen Brown <len.brown@intel.com>2005-12-06 17:31:30 -0500
committerLen Brown <len.brown@intel.com>2005-12-06 17:31:30 -0500
commit3d5271f9883cba7b54762bc4fe027d4172f06db7 (patch)
treeab8a881a14478598a0c8bda0d26c62cdccfffd6d /fs/cifs/cifssmb.c
parent378b2556f4e09fa6f87ff0cb5c4395ff28257d02 (diff)
parent9115a6c787596e687df03010d97fccc5e0762506 (diff)
Pull release into acpica branch
Diffstat (limited to 'fs/cifs/cifssmb.c')
-rw-r--r--fs/cifs/cifssmb.c727
1 files changed, 595 insertions, 132 deletions
diff --git a/fs/cifs/cifssmb.c b/fs/cifs/cifssmb.c
index 0db0b313d715..6867e556d37e 100644
--- a/fs/cifs/cifssmb.c
+++ b/fs/cifs/cifssmb.c
@@ -90,6 +90,18 @@ small_smb_init(int smb_command, int wct, struct cifsTconInfo *tcon,
90 check for tcp and smb session status done differently 90 check for tcp and smb session status done differently
91 for those three - in the calling routine */ 91 for those three - in the calling routine */
92 if(tcon) { 92 if(tcon) {
93 if(tcon->tidStatus == CifsExiting) {
94 /* only tree disconnect, open, and write,
95 (and ulogoff which does not have tcon)
96 are allowed as we start force umount */
97 if((smb_command != SMB_COM_WRITE_ANDX) &&
98 (smb_command != SMB_COM_OPEN_ANDX) &&
99 (smb_command != SMB_COM_TREE_DISCONNECT)) {
100 cFYI(1,("can not send cmd %d while umounting",
101 smb_command));
102 return -ENODEV;
103 }
104 }
93 if((tcon->ses) && (tcon->ses->status != CifsExiting) && 105 if((tcon->ses) && (tcon->ses->status != CifsExiting) &&
94 (tcon->ses->server)){ 106 (tcon->ses->server)){
95 struct nls_table *nls_codepage; 107 struct nls_table *nls_codepage;
@@ -125,6 +137,9 @@ small_smb_init(int smb_command, int wct, struct cifsTconInfo *tcon,
125 rc = CIFSTCon(0, tcon->ses, tcon->treeName, tcon 137 rc = CIFSTCon(0, tcon->ses, tcon->treeName, tcon
126 , nls_codepage); 138 , nls_codepage);
127 up(&tcon->ses->sesSem); 139 up(&tcon->ses->sesSem);
140 /* BB FIXME add code to check if wsize needs
141 update due to negotiated smb buffer size
142 shrinking */
128 if(rc == 0) 143 if(rc == 0)
129 atomic_inc(&tconInfoReconnectCount); 144 atomic_inc(&tconInfoReconnectCount);
130 145
@@ -166,11 +181,9 @@ small_smb_init(int smb_command, int wct, struct cifsTconInfo *tcon,
166 181
167 header_assemble((struct smb_hdr *) *request_buf, smb_command, tcon,wct); 182 header_assemble((struct smb_hdr *) *request_buf, smb_command, tcon,wct);
168 183
169#ifdef CONFIG_CIFS_STATS 184 if(tcon != NULL)
170 if(tcon != NULL) { 185 cifs_stats_inc(&tcon->num_smbs_sent);
171 atomic_inc(&tcon->num_smbs_sent); 186
172 }
173#endif /* CONFIG_CIFS_STATS */
174 return rc; 187 return rc;
175} 188}
176 189
@@ -186,6 +199,19 @@ smb_init(int smb_command, int wct, struct cifsTconInfo *tcon,
186 check for tcp and smb session status done differently 199 check for tcp and smb session status done differently
187 for those three - in the calling routine */ 200 for those three - in the calling routine */
188 if(tcon) { 201 if(tcon) {
202 if(tcon->tidStatus == CifsExiting) {
203 /* only tree disconnect, open, and write,
204 (and ulogoff which does not have tcon)
205 are allowed as we start force umount */
206 if((smb_command != SMB_COM_WRITE_ANDX) &&
207 (smb_command != SMB_COM_OPEN_ANDX) &&
208 (smb_command != SMB_COM_TREE_DISCONNECT)) {
209 cFYI(1,("can not send cmd %d while umounting",
210 smb_command));
211 return -ENODEV;
212 }
213 }
214
189 if((tcon->ses) && (tcon->ses->status != CifsExiting) && 215 if((tcon->ses) && (tcon->ses->status != CifsExiting) &&
190 (tcon->ses->server)){ 216 (tcon->ses->server)){
191 struct nls_table *nls_codepage; 217 struct nls_table *nls_codepage;
@@ -222,6 +248,9 @@ smb_init(int smb_command, int wct, struct cifsTconInfo *tcon,
222 rc = CIFSTCon(0, tcon->ses, tcon->treeName, 248 rc = CIFSTCon(0, tcon->ses, tcon->treeName,
223 tcon, nls_codepage); 249 tcon, nls_codepage);
224 up(&tcon->ses->sesSem); 250 up(&tcon->ses->sesSem);
251 /* BB FIXME add code to check if wsize needs
252 update due to negotiated smb buffer size
253 shrinking */
225 if(rc == 0) 254 if(rc == 0)
226 atomic_inc(&tconInfoReconnectCount); 255 atomic_inc(&tconInfoReconnectCount);
227 256
@@ -269,11 +298,9 @@ smb_init(int smb_command, int wct, struct cifsTconInfo *tcon,
269 header_assemble((struct smb_hdr *) *request_buf, smb_command, tcon, 298 header_assemble((struct smb_hdr *) *request_buf, smb_command, tcon,
270 wct /*wct */ ); 299 wct /*wct */ );
271 300
272#ifdef CONFIG_CIFS_STATS 301 if(tcon != NULL)
273 if(tcon != NULL) { 302 cifs_stats_inc(&tcon->num_smbs_sent);
274 atomic_inc(&tcon->num_smbs_sent); 303
275 }
276#endif /* CONFIG_CIFS_STATS */
277 return rc; 304 return rc;
278} 305}
279 306
@@ -330,7 +357,7 @@ CIFSSMBNegotiate(unsigned int xid, struct cifsSesInfo *ses)
330 (void **) &pSMB, (void **) &pSMBr); 357 (void **) &pSMB, (void **) &pSMBr);
331 if (rc) 358 if (rc)
332 return rc; 359 return rc;
333 360 pSMB->hdr.Mid = GetNextMid(server);
334 pSMB->hdr.Flags2 |= SMBFLG2_UNICODE; 361 pSMB->hdr.Flags2 |= SMBFLG2_UNICODE;
335 if (extended_security) 362 if (extended_security)
336 pSMB->hdr.Flags2 |= SMBFLG2_EXT_SEC; 363 pSMB->hdr.Flags2 |= SMBFLG2_EXT_SEC;
@@ -422,8 +449,8 @@ CIFSSMBNegotiate(unsigned int xid, struct cifsSesInfo *ses)
422 } 449 }
423 450
424 } 451 }
425 if (pSMB) 452
426 cifs_buf_release(pSMB); 453 cifs_buf_release(pSMB);
427 return rc; 454 return rc;
428} 455}
429 456
@@ -518,6 +545,8 @@ CIFSSMBLogoff(const int xid, struct cifsSesInfo *ses)
518 smb_buffer_response = (struct smb_hdr *)pSMB; /* BB removeme BB */ 545 smb_buffer_response = (struct smb_hdr *)pSMB; /* BB removeme BB */
519 546
520 if(ses->server) { 547 if(ses->server) {
548 pSMB->hdr.Mid = GetNextMid(ses->server);
549
521 if(ses->server->secMode & 550 if(ses->server->secMode &
522 (SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED)) 551 (SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED))
523 pSMB->hdr.Flags2 |= SMBFLG2_SECURITY_SIGNATURE; 552 pSMB->hdr.Flags2 |= SMBFLG2_SECURITY_SIGNATURE;
@@ -537,9 +566,8 @@ CIFSSMBLogoff(const int xid, struct cifsSesInfo *ses)
537 rc = -ESHUTDOWN; 566 rc = -ESHUTDOWN;
538 } 567 }
539 } 568 }
540 if (pSMB)
541 cifs_small_buf_release(pSMB);
542 up(&ses->sesSem); 569 up(&ses->sesSem);
570 cifs_small_buf_release(pSMB);
543 571
544 /* if session dead then we do not need to do ulogoff, 572 /* if session dead then we do not need to do ulogoff,
545 since server closed smb session, no sense reporting 573 since server closed smb session, no sense reporting
@@ -583,14 +611,10 @@ DelFileRetry:
583 pSMB->ByteCount = cpu_to_le16(name_len + 1); 611 pSMB->ByteCount = cpu_to_le16(name_len + 1);
584 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, 612 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
585 (struct smb_hdr *) pSMBr, &bytes_returned, 0); 613 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
614 cifs_stats_inc(&tcon->num_deletes);
586 if (rc) { 615 if (rc) {
587 cFYI(1, ("Error in RMFile = %d", rc)); 616 cFYI(1, ("Error in RMFile = %d", rc));
588 } 617 }
589#ifdef CONFIG_CIFS_STATS
590 else {
591 atomic_inc(&tcon->num_deletes);
592 }
593#endif
594 618
595 cifs_buf_release(pSMB); 619 cifs_buf_release(pSMB);
596 if (rc == -EAGAIN) 620 if (rc == -EAGAIN)
@@ -632,14 +656,10 @@ RmDirRetry:
632 pSMB->ByteCount = cpu_to_le16(name_len + 1); 656 pSMB->ByteCount = cpu_to_le16(name_len + 1);
633 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, 657 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
634 (struct smb_hdr *) pSMBr, &bytes_returned, 0); 658 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
659 cifs_stats_inc(&tcon->num_rmdirs);
635 if (rc) { 660 if (rc) {
636 cFYI(1, ("Error in RMDir = %d", rc)); 661 cFYI(1, ("Error in RMDir = %d", rc));
637 } 662 }
638#ifdef CONFIG_CIFS_STATS
639 else {
640 atomic_inc(&tcon->num_rmdirs);
641 }
642#endif
643 663
644 cifs_buf_release(pSMB); 664 cifs_buf_release(pSMB);
645 if (rc == -EAGAIN) 665 if (rc == -EAGAIN)
@@ -680,20 +700,161 @@ MkDirRetry:
680 pSMB->ByteCount = cpu_to_le16(name_len + 1); 700 pSMB->ByteCount = cpu_to_le16(name_len + 1);
681 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, 701 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
682 (struct smb_hdr *) pSMBr, &bytes_returned, 0); 702 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
703 cifs_stats_inc(&tcon->num_mkdirs);
683 if (rc) { 704 if (rc) {
684 cFYI(1, ("Error in Mkdir = %d", rc)); 705 cFYI(1, ("Error in Mkdir = %d", rc));
685 } 706 }
686#ifdef CONFIG_CIFS_STATS 707
687 else {
688 atomic_inc(&tcon->num_mkdirs);
689 }
690#endif
691 cifs_buf_release(pSMB); 708 cifs_buf_release(pSMB);
692 if (rc == -EAGAIN) 709 if (rc == -EAGAIN)
693 goto MkDirRetry; 710 goto MkDirRetry;
694 return rc; 711 return rc;
695} 712}
696 713
714static __u16 convert_disposition(int disposition)
715{
716 __u16 ofun = 0;
717
718 switch (disposition) {
719 case FILE_SUPERSEDE:
720 ofun = SMBOPEN_OCREATE | SMBOPEN_OTRUNC;
721 break;
722 case FILE_OPEN:
723 ofun = SMBOPEN_OAPPEND;
724 break;
725 case FILE_CREATE:
726 ofun = SMBOPEN_OCREATE;
727 break;
728 case FILE_OPEN_IF:
729 ofun = SMBOPEN_OCREATE | SMBOPEN_OAPPEND;
730 break;
731 case FILE_OVERWRITE:
732 ofun = SMBOPEN_OTRUNC;
733 break;
734 case FILE_OVERWRITE_IF:
735 ofun = SMBOPEN_OCREATE | SMBOPEN_OTRUNC;
736 break;
737 default:
738 cFYI(1,("unknown disposition %d",disposition));
739 ofun = SMBOPEN_OAPPEND; /* regular open */
740 }
741 return ofun;
742}
743
744int
745SMBLegacyOpen(const int xid, struct cifsTconInfo *tcon,
746 const char *fileName, const int openDisposition,
747 const int access_flags, const int create_options, __u16 * netfid,
748 int *pOplock, FILE_ALL_INFO * pfile_info,
749 const struct nls_table *nls_codepage, int remap)
750{
751 int rc = -EACCES;
752 OPENX_REQ *pSMB = NULL;
753 OPENX_RSP *pSMBr = NULL;
754 int bytes_returned;
755 int name_len;
756 __u16 count;
757
758OldOpenRetry:
759 rc = smb_init(SMB_COM_OPEN_ANDX, 15, tcon, (void **) &pSMB,
760 (void **) &pSMBr);
761 if (rc)
762 return rc;
763
764 pSMB->AndXCommand = 0xFF; /* none */
765
766 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
767 count = 1; /* account for one byte pad to word boundary */
768 name_len =
769 cifsConvertToUCS((__le16 *) (pSMB->fileName + 1),
770 fileName, PATH_MAX, nls_codepage, remap);
771 name_len++; /* trailing null */
772 name_len *= 2;
773 } else { /* BB improve check for buffer overruns BB */
774 count = 0; /* no pad */
775 name_len = strnlen(fileName, PATH_MAX);
776 name_len++; /* trailing null */
777 strncpy(pSMB->fileName, fileName, name_len);
778 }
779 if (*pOplock & REQ_OPLOCK)
780 pSMB->OpenFlags = cpu_to_le16(REQ_OPLOCK);
781 else if (*pOplock & REQ_BATCHOPLOCK) {
782 pSMB->OpenFlags = cpu_to_le16(REQ_BATCHOPLOCK);
783 }
784 pSMB->OpenFlags |= cpu_to_le16(REQ_MORE_INFO);
785 /* BB fixme add conversion for access_flags to bits 0 - 2 of mode */
786 /* 0 = read
787 1 = write
788 2 = rw
789 3 = execute
790 */
791 pSMB->Mode = cpu_to_le16(2);
792 pSMB->Mode |= cpu_to_le16(0x40); /* deny none */
793 /* set file as system file if special file such
794 as fifo and server expecting SFU style and
795 no Unix extensions */
796
797 if(create_options & CREATE_OPTION_SPECIAL)
798 pSMB->FileAttributes = cpu_to_le16(ATTR_SYSTEM);
799 else
800 pSMB->FileAttributes = cpu_to_le16(0/*ATTR_NORMAL*/); /* BB FIXME */
801
802 /* if ((omode & S_IWUGO) == 0)
803 pSMB->FileAttributes |= cpu_to_le32(ATTR_READONLY);*/
804 /* Above line causes problems due to vfs splitting create into two
805 pieces - need to set mode after file created not while it is
806 being created */
807
808 /* BB FIXME BB */
809/* pSMB->CreateOptions = cpu_to_le32(create_options & CREATE_OPTIONS_MASK); */
810 /* BB FIXME END BB */
811
812 pSMB->Sattr = cpu_to_le16(ATTR_HIDDEN | ATTR_SYSTEM | ATTR_DIRECTORY);
813 pSMB->OpenFunction = cpu_to_le16(convert_disposition(openDisposition));
814 count += name_len;
815 pSMB->hdr.smb_buf_length += count;
816
817 pSMB->ByteCount = cpu_to_le16(count);
818 /* long_op set to 1 to allow for oplock break timeouts */
819 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
820 (struct smb_hdr *) pSMBr, &bytes_returned, 1);
821 cifs_stats_inc(&tcon->num_opens);
822 if (rc) {
823 cFYI(1, ("Error in Open = %d", rc));
824 } else {
825 /* BB verify if wct == 15 */
826
827/* *pOplock = pSMBr->OplockLevel; */ /* BB take from action field BB */
828
829 *netfid = pSMBr->Fid; /* cifs fid stays in le */
830 /* Let caller know file was created so we can set the mode. */
831 /* Do we care about the CreateAction in any other cases? */
832 /* BB FIXME BB */
833/* if(cpu_to_le32(FILE_CREATE) == pSMBr->CreateAction)
834 *pOplock |= CIFS_CREATE_ACTION; */
835 /* BB FIXME END */
836
837 if(pfile_info) {
838 pfile_info->CreationTime = 0; /* BB convert CreateTime*/
839 pfile_info->LastAccessTime = 0; /* BB fixme */
840 pfile_info->LastWriteTime = 0; /* BB fixme */
841 pfile_info->ChangeTime = 0; /* BB fixme */
842 pfile_info->Attributes =
843 cpu_to_le32(le16_to_cpu(pSMBr->FileAttributes));
844 /* the file_info buf is endian converted by caller */
845 pfile_info->AllocationSize =
846 cpu_to_le64(le32_to_cpu(pSMBr->EndOfFile));
847 pfile_info->EndOfFile = pfile_info->AllocationSize;
848 pfile_info->NumberOfLinks = cpu_to_le32(1);
849 }
850 }
851
852 cifs_buf_release(pSMB);
853 if (rc == -EAGAIN)
854 goto OldOpenRetry;
855 return rc;
856}
857
697int 858int
698CIFSSMBOpen(const int xid, struct cifsTconInfo *tcon, 859CIFSSMBOpen(const int xid, struct cifsTconInfo *tcon,
699 const char *fileName, const int openDisposition, 860 const char *fileName, const int openDisposition,
@@ -738,7 +899,13 @@ openRetry:
738 } 899 }
739 pSMB->DesiredAccess = cpu_to_le32(access_flags); 900 pSMB->DesiredAccess = cpu_to_le32(access_flags);
740 pSMB->AllocationSize = 0; 901 pSMB->AllocationSize = 0;
741 pSMB->FileAttributes = cpu_to_le32(ATTR_NORMAL); 902 /* set file as system file if special file such
903 as fifo and server expecting SFU style and
904 no Unix extensions */
905 if(create_options & CREATE_OPTION_SPECIAL)
906 pSMB->FileAttributes = cpu_to_le32(ATTR_SYSTEM);
907 else
908 pSMB->FileAttributes = cpu_to_le32(ATTR_NORMAL);
742 /* XP does not handle ATTR_POSIX_SEMANTICS */ 909 /* XP does not handle ATTR_POSIX_SEMANTICS */
743 /* but it helps speed up case sensitive checks for other 910 /* but it helps speed up case sensitive checks for other
744 servers such as Samba */ 911 servers such as Samba */
@@ -752,7 +919,7 @@ openRetry:
752 being created */ 919 being created */
753 pSMB->ShareAccess = cpu_to_le32(FILE_SHARE_ALL); 920 pSMB->ShareAccess = cpu_to_le32(FILE_SHARE_ALL);
754 pSMB->CreateDisposition = cpu_to_le32(openDisposition); 921 pSMB->CreateDisposition = cpu_to_le32(openDisposition);
755 pSMB->CreateOptions = cpu_to_le32(create_options); 922 pSMB->CreateOptions = cpu_to_le32(create_options & CREATE_OPTIONS_MASK);
756 /* BB Expirement with various impersonation levels and verify */ 923 /* BB Expirement with various impersonation levels and verify */
757 pSMB->ImpersonationLevel = cpu_to_le32(SECURITY_IMPERSONATION); 924 pSMB->ImpersonationLevel = cpu_to_le32(SECURITY_IMPERSONATION);
758 pSMB->SecurityFlags = 925 pSMB->SecurityFlags =
@@ -765,6 +932,7 @@ openRetry:
765 /* long_op set to 1 to allow for oplock break timeouts */ 932 /* long_op set to 1 to allow for oplock break timeouts */
766 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, 933 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
767 (struct smb_hdr *) pSMBr, &bytes_returned, 1); 934 (struct smb_hdr *) pSMBr, &bytes_returned, 1);
935 cifs_stats_inc(&tcon->num_opens);
768 if (rc) { 936 if (rc) {
769 cFYI(1, ("Error in Open = %d", rc)); 937 cFYI(1, ("Error in Open = %d", rc));
770 } else { 938 } else {
@@ -782,11 +950,8 @@ openRetry:
782 pfile_info->EndOfFile = pSMBr->EndOfFile; 950 pfile_info->EndOfFile = pSMBr->EndOfFile;
783 pfile_info->NumberOfLinks = cpu_to_le32(1); 951 pfile_info->NumberOfLinks = cpu_to_le32(1);
784 } 952 }
785
786#ifdef CONFIG_CIFS_STATS
787 atomic_inc(&tcon->num_opens);
788#endif
789 } 953 }
954
790 cifs_buf_release(pSMB); 955 cifs_buf_release(pSMB);
791 if (rc == -EAGAIN) 956 if (rc == -EAGAIN)
792 goto openRetry; 957 goto openRetry;
@@ -807,11 +972,16 @@ CIFSSMBRead(const int xid, struct cifsTconInfo *tcon,
807 READ_RSP *pSMBr = NULL; 972 READ_RSP *pSMBr = NULL;
808 char *pReadData = NULL; 973 char *pReadData = NULL;
809 int bytes_returned; 974 int bytes_returned;
975 int wct;
810 976
811 cFYI(1,("Reading %d bytes on fid %d",count,netfid)); 977 cFYI(1,("Reading %d bytes on fid %d",count,netfid));
978 if(tcon->ses->capabilities & CAP_LARGE_FILES)
979 wct = 12;
980 else
981 wct = 10; /* old style read */
812 982
813 *nbytes = 0; 983 *nbytes = 0;
814 rc = smb_init(SMB_COM_READ_ANDX, 12, tcon, (void **) &pSMB, 984 rc = smb_init(SMB_COM_READ_ANDX, wct, tcon, (void **) &pSMB,
815 (void **) &pSMBr); 985 (void **) &pSMBr);
816 if (rc) 986 if (rc)
817 return rc; 987 return rc;
@@ -823,14 +993,26 @@ CIFSSMBRead(const int xid, struct cifsTconInfo *tcon,
823 pSMB->AndXCommand = 0xFF; /* none */ 993 pSMB->AndXCommand = 0xFF; /* none */
824 pSMB->Fid = netfid; 994 pSMB->Fid = netfid;
825 pSMB->OffsetLow = cpu_to_le32(lseek & 0xFFFFFFFF); 995 pSMB->OffsetLow = cpu_to_le32(lseek & 0xFFFFFFFF);
826 pSMB->OffsetHigh = cpu_to_le32(lseek >> 32); 996 if(wct == 12)
997 pSMB->OffsetHigh = cpu_to_le32(lseek >> 32);
998 else if((lseek >> 32) > 0) /* can not handle this big offset for old */
999 return -EIO;
1000
827 pSMB->Remaining = 0; 1001 pSMB->Remaining = 0;
828 pSMB->MaxCount = cpu_to_le16(count & 0xFFFF); 1002 pSMB->MaxCount = cpu_to_le16(count & 0xFFFF);
829 pSMB->MaxCountHigh = cpu_to_le32(count >> 16); 1003 pSMB->MaxCountHigh = cpu_to_le32(count >> 16);
830 pSMB->ByteCount = 0; /* no need to do le conversion since it is 0 */ 1004 if(wct == 12)
831 1005 pSMB->ByteCount = 0; /* no need to do le conversion since 0 */
1006 else {
1007 /* old style read */
1008 struct smb_com_readx_req * pSMBW =
1009 (struct smb_com_readx_req *)pSMB;
1010 pSMBW->ByteCount = 0;
1011 }
1012
832 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, 1013 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
833 (struct smb_hdr *) pSMBr, &bytes_returned, 0); 1014 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
1015 cifs_stats_inc(&tcon->num_reads);
834 if (rc) { 1016 if (rc) {
835 cERROR(1, ("Send error in read = %d", rc)); 1017 cERROR(1, ("Send error in read = %d", rc));
836 } else { 1018 } else {
@@ -876,12 +1058,20 @@ CIFSSMBWrite(const int xid, struct cifsTconInfo *tcon,
876 int rc = -EACCES; 1058 int rc = -EACCES;
877 WRITE_REQ *pSMB = NULL; 1059 WRITE_REQ *pSMB = NULL;
878 WRITE_RSP *pSMBr = NULL; 1060 WRITE_RSP *pSMBr = NULL;
879 int bytes_returned; 1061 int bytes_returned, wct;
880 __u32 bytes_sent; 1062 __u32 bytes_sent;
881 __u16 byte_count; 1063 __u16 byte_count;
882 1064
883 /* cFYI(1,("write at %lld %d bytes",offset,count));*/ 1065 /* cFYI(1,("write at %lld %d bytes",offset,count));*/
884 rc = smb_init(SMB_COM_WRITE_ANDX, 14, tcon, (void **) &pSMB, 1066 if(tcon->ses == NULL)
1067 return -ECONNABORTED;
1068
1069 if(tcon->ses->capabilities & CAP_LARGE_FILES)
1070 wct = 14;
1071 else
1072 wct = 12;
1073
1074 rc = smb_init(SMB_COM_WRITE_ANDX, wct, tcon, (void **) &pSMB,
885 (void **) &pSMBr); 1075 (void **) &pSMBr);
886 if (rc) 1076 if (rc)
887 return rc; 1077 return rc;
@@ -892,7 +1082,11 @@ CIFSSMBWrite(const int xid, struct cifsTconInfo *tcon,
892 pSMB->AndXCommand = 0xFF; /* none */ 1082 pSMB->AndXCommand = 0xFF; /* none */
893 pSMB->Fid = netfid; 1083 pSMB->Fid = netfid;
894 pSMB->OffsetLow = cpu_to_le32(offset & 0xFFFFFFFF); 1084 pSMB->OffsetLow = cpu_to_le32(offset & 0xFFFFFFFF);
895 pSMB->OffsetHigh = cpu_to_le32(offset >> 32); 1085 if(wct == 14)
1086 pSMB->OffsetHigh = cpu_to_le32(offset >> 32);
1087 else if((offset >> 32) > 0) /* can not handle this big offset for old */
1088 return -EIO;
1089
896 pSMB->Reserved = 0xFFFFFFFF; 1090 pSMB->Reserved = 0xFFFFFFFF;
897 pSMB->WriteMode = 0; 1091 pSMB->WriteMode = 0;
898 pSMB->Remaining = 0; 1092 pSMB->Remaining = 0;
@@ -911,7 +1105,7 @@ CIFSSMBWrite(const int xid, struct cifsTconInfo *tcon,
911 if (bytes_sent > count) 1105 if (bytes_sent > count)
912 bytes_sent = count; 1106 bytes_sent = count;
913 pSMB->DataOffset = 1107 pSMB->DataOffset =
914 cpu_to_le16(offsetof(struct smb_com_write_req,Data) - 4); 1108 cpu_to_le16(offsetof(struct smb_com_write_req,Data) - 4);
915 if(buf) 1109 if(buf)
916 memcpy(pSMB->Data,buf,bytes_sent); 1110 memcpy(pSMB->Data,buf,bytes_sent);
917 else if(ubuf) { 1111 else if(ubuf) {
@@ -919,20 +1113,31 @@ CIFSSMBWrite(const int xid, struct cifsTconInfo *tcon,
919 cifs_buf_release(pSMB); 1113 cifs_buf_release(pSMB);
920 return -EFAULT; 1114 return -EFAULT;
921 } 1115 }
922 } else { 1116 } else if (count != 0) {
923 /* No buffer */ 1117 /* No buffer */
924 cifs_buf_release(pSMB); 1118 cifs_buf_release(pSMB);
925 return -EINVAL; 1119 return -EINVAL;
1120 } /* else setting file size with write of zero bytes */
1121 if(wct == 14)
1122 byte_count = bytes_sent + 1; /* pad */
1123 else /* wct == 12 */ {
1124 byte_count = bytes_sent + 5; /* bigger pad, smaller smb hdr */
926 } 1125 }
927
928 byte_count = bytes_sent + 1 /* pad */ ; /* BB fix this for sends > 64K */
929 pSMB->DataLengthLow = cpu_to_le16(bytes_sent & 0xFFFF); 1126 pSMB->DataLengthLow = cpu_to_le16(bytes_sent & 0xFFFF);
930 pSMB->DataLengthHigh = cpu_to_le16(bytes_sent >> 16); 1127 pSMB->DataLengthHigh = cpu_to_le16(bytes_sent >> 16);
931 pSMB->hdr.smb_buf_length += bytes_sent+1; 1128 pSMB->hdr.smb_buf_length += byte_count;
932 pSMB->ByteCount = cpu_to_le16(byte_count); 1129
1130 if(wct == 14)
1131 pSMB->ByteCount = cpu_to_le16(byte_count);
1132 else { /* old style write has byte count 4 bytes earlier so 4 bytes pad */
1133 struct smb_com_writex_req * pSMBW =
1134 (struct smb_com_writex_req *)pSMB;
1135 pSMBW->ByteCount = cpu_to_le16(byte_count);
1136 }
933 1137
934 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, 1138 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
935 (struct smb_hdr *) pSMBr, &bytes_returned, long_op); 1139 (struct smb_hdr *) pSMBr, &bytes_returned, long_op);
1140 cifs_stats_inc(&tcon->num_writes);
936 if (rc) { 1141 if (rc) {
937 cFYI(1, ("Send error in write = %d", rc)); 1142 cFYI(1, ("Send error in write = %d", rc));
938 *nbytes = 0; 1143 *nbytes = 0;
@@ -951,56 +1156,74 @@ CIFSSMBWrite(const int xid, struct cifsTconInfo *tcon,
951} 1156}
952 1157
953#ifdef CONFIG_CIFS_EXPERIMENTAL 1158#ifdef CONFIG_CIFS_EXPERIMENTAL
954int CIFSSMBWrite2(const int xid, struct cifsTconInfo *tcon, 1159int
1160CIFSSMBWrite2(const int xid, struct cifsTconInfo *tcon,
955 const int netfid, const unsigned int count, 1161 const int netfid, const unsigned int count,
956 const __u64 offset, unsigned int *nbytes, const char __user *buf, 1162 const __u64 offset, unsigned int *nbytes, struct kvec *iov,
957 const int long_op) 1163 int n_vec, const int long_op)
958{ 1164{
959 int rc = -EACCES; 1165 int rc = -EACCES;
960 WRITE_REQ *pSMB = NULL; 1166 WRITE_REQ *pSMB = NULL;
961 WRITE_RSP *pSMBr = NULL; 1167 int bytes_returned, wct;
962 /*int bytes_returned;*/ 1168 int smb_hdr_len;
963 unsigned bytes_sent;
964 __u16 byte_count;
965 1169
966 rc = small_smb_init(SMB_COM_WRITE_ANDX, 14, tcon, (void **) &pSMB); 1170 /* BB removeme BB */
967 1171 cFYI(1,("write2 at %lld %d bytes", (long long)offset, count));
1172
1173 if(tcon->ses->capabilities & CAP_LARGE_FILES)
1174 wct = 14;
1175 else
1176 wct = 12;
1177 rc = small_smb_init(SMB_COM_WRITE_ANDX, wct, tcon, (void **) &pSMB);
968 if (rc) 1178 if (rc)
969 return rc; 1179 return rc;
970
971 pSMBr = (WRITE_RSP *)pSMB; /* BB removeme BB */
972
973 /* tcon and ses pointer are checked in smb_init */ 1180 /* tcon and ses pointer are checked in smb_init */
974 if (tcon->ses->server == NULL) 1181 if (tcon->ses->server == NULL)
975 return -ECONNABORTED; 1182 return -ECONNABORTED;
976 1183
977 pSMB->AndXCommand = 0xFF; /* none */ 1184 pSMB->AndXCommand = 0xFF; /* none */
978 pSMB->Fid = netfid; 1185 pSMB->Fid = netfid;
979 pSMB->OffsetLow = cpu_to_le32(offset & 0xFFFFFFFF); 1186 pSMB->OffsetLow = cpu_to_le32(offset & 0xFFFFFFFF);
980 pSMB->OffsetHigh = cpu_to_le32(offset >> 32); 1187 if(wct == 14)
1188 pSMB->OffsetHigh = cpu_to_le32(offset >> 32);
1189 else if((offset >> 32) > 0) /* can not handle this big offset for old */
1190 return -EIO;
981 pSMB->Reserved = 0xFFFFFFFF; 1191 pSMB->Reserved = 0xFFFFFFFF;
982 pSMB->WriteMode = 0; 1192 pSMB->WriteMode = 0;
983 pSMB->Remaining = 0; 1193 pSMB->Remaining = 0;
984 bytes_sent = (tcon->ses->server->maxBuf - MAX_CIFS_HDR_SIZE) & ~0xFF; 1194
985 if (bytes_sent > count)
986 bytes_sent = count;
987 pSMB->DataLengthHigh = 0;
988 pSMB->DataOffset = 1195 pSMB->DataOffset =
989 cpu_to_le16(offsetof(struct smb_com_write_req,Data) - 4); 1196 cpu_to_le16(offsetof(struct smb_com_write_req,Data) - 4);
990 1197
991 byte_count = bytes_sent + 1 /* pad */ ; 1198 pSMB->DataLengthLow = cpu_to_le16(count & 0xFFFF);
992 pSMB->DataLengthLow = cpu_to_le16(bytes_sent); 1199 pSMB->DataLengthHigh = cpu_to_le16(count >> 16);
993 pSMB->DataLengthHigh = 0; 1200 smb_hdr_len = pSMB->hdr.smb_buf_length + 1; /* hdr + 1 byte pad */
994 pSMB->hdr.smb_buf_length += byte_count; 1201 if(wct == 14)
995 pSMB->ByteCount = cpu_to_le16(byte_count); 1202 pSMB->hdr.smb_buf_length += count+1;
1203 else /* wct == 12 */
1204 pSMB->hdr.smb_buf_length += count+5; /* smb data starts later */
1205 if(wct == 14)
1206 pSMB->ByteCount = cpu_to_le16(count + 1);
1207 else /* wct == 12 */ /* bigger pad, smaller smb hdr, keep offset ok */ {
1208 struct smb_com_writex_req * pSMBW =
1209 (struct smb_com_writex_req *)pSMB;
1210 pSMBW->ByteCount = cpu_to_le16(count + 5);
1211 }
1212 iov[0].iov_base = pSMB;
1213 iov[0].iov_len = smb_hdr_len + 4;
996 1214
997/* rc = SendReceive2(xid, tcon->ses, (struct smb_hdr *) pSMB, 1215 rc = SendReceive2(xid, tcon->ses, iov, n_vec + 1, &bytes_returned,
998 (struct smb_hdr *) pSMBr, buf, buflen, &bytes_returned, long_op); */ /* BB fixme BB */ 1216 long_op);
1217 cifs_stats_inc(&tcon->num_writes);
999 if (rc) { 1218 if (rc) {
1000 cFYI(1, ("Send error in write2 (large write) = %d", rc)); 1219 cFYI(1, ("Send error Write2 = %d", rc));
1001 *nbytes = 0; 1220 *nbytes = 0;
1002 } else 1221 } else {
1003 *nbytes = le16_to_cpu(pSMBr->Count); 1222 WRITE_RSP * pSMBr = (WRITE_RSP *)pSMB;
1223 *nbytes = le16_to_cpu(pSMBr->CountHigh);
1224 *nbytes = (*nbytes) << 16;
1225 *nbytes += le16_to_cpu(pSMBr->Count);
1226 }
1004 1227
1005 cifs_small_buf_release(pSMB); 1228 cifs_small_buf_release(pSMB);
1006 1229
@@ -1009,6 +1232,8 @@ int CIFSSMBWrite2(const int xid, struct cifsTconInfo *tcon,
1009 1232
1010 return rc; 1233 return rc;
1011} 1234}
1235
1236
1012#endif /* CIFS_EXPERIMENTAL */ 1237#endif /* CIFS_EXPERIMENTAL */
1013 1238
1014int 1239int
@@ -1065,7 +1290,7 @@ CIFSSMBLock(const int xid, struct cifsTconInfo *tcon,
1065 1290
1066 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, 1291 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
1067 (struct smb_hdr *) pSMBr, &bytes_returned, timeout); 1292 (struct smb_hdr *) pSMBr, &bytes_returned, timeout);
1068 1293 cifs_stats_inc(&tcon->num_locks);
1069 if (rc) { 1294 if (rc) {
1070 cFYI(1, ("Send error in Lock = %d", rc)); 1295 cFYI(1, ("Send error in Lock = %d", rc));
1071 } 1296 }
@@ -1099,6 +1324,7 @@ CIFSSMBClose(const int xid, struct cifsTconInfo *tcon, int smb_file_id)
1099 pSMB->ByteCount = 0; 1324 pSMB->ByteCount = 0;
1100 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, 1325 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
1101 (struct smb_hdr *) pSMBr, &bytes_returned, 0); 1326 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
1327 cifs_stats_inc(&tcon->num_closes);
1102 if (rc) { 1328 if (rc) {
1103 if(rc!=-EINTR) { 1329 if(rc!=-EINTR) {
1104 /* EINTR is expected when user ctl-c to kill app */ 1330 /* EINTR is expected when user ctl-c to kill app */
@@ -1171,16 +1397,11 @@ renameRetry:
1171 1397
1172 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, 1398 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
1173 (struct smb_hdr *) pSMBr, &bytes_returned, 0); 1399 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
1400 cifs_stats_inc(&tcon->num_renames);
1174 if (rc) { 1401 if (rc) {
1175 cFYI(1, ("Send error in rename = %d", rc)); 1402 cFYI(1, ("Send error in rename = %d", rc));
1176 } 1403 }
1177 1404
1178#ifdef CONFIG_CIFS_STATS
1179 else {
1180 atomic_inc(&tcon->num_renames);
1181 }
1182#endif
1183
1184 cifs_buf_release(pSMB); 1405 cifs_buf_release(pSMB);
1185 1406
1186 if (rc == -EAGAIN) 1407 if (rc == -EAGAIN)
@@ -1255,14 +1476,11 @@ int CIFSSMBRenameOpenFile(const int xid,struct cifsTconInfo *pTcon,
1255 pSMB->ByteCount = cpu_to_le16(byte_count); 1476 pSMB->ByteCount = cpu_to_le16(byte_count);
1256 rc = SendReceive(xid, pTcon->ses, (struct smb_hdr *) pSMB, 1477 rc = SendReceive(xid, pTcon->ses, (struct smb_hdr *) pSMB,
1257 (struct smb_hdr *) pSMBr, &bytes_returned, 0); 1478 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
1479 cifs_stats_inc(&pTcon->num_t2renames);
1258 if (rc) { 1480 if (rc) {
1259 cFYI(1,("Send error in Rename (by file handle) = %d", rc)); 1481 cFYI(1,("Send error in Rename (by file handle) = %d", rc));
1260 } 1482 }
1261#ifdef CONFIG_CIFS_STATS 1483
1262 else {
1263 atomic_inc(&pTcon->num_t2renames);
1264 }
1265#endif
1266 cifs_buf_release(pSMB); 1484 cifs_buf_release(pSMB);
1267 1485
1268 /* Note: On -EAGAIN error only caller can retry on handle based calls 1486 /* Note: On -EAGAIN error only caller can retry on handle based calls
@@ -1362,7 +1580,7 @@ createSymLinkRetry:
1362 1580
1363 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) { 1581 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
1364 name_len = 1582 name_len =
1365 cifs_strtoUCS((wchar_t *) pSMB->FileName, fromName, PATH_MAX 1583 cifs_strtoUCS((__le16 *) pSMB->FileName, fromName, PATH_MAX
1366 /* find define for this maxpathcomponent */ 1584 /* find define for this maxpathcomponent */
1367 , nls_codepage); 1585 , nls_codepage);
1368 name_len++; /* trailing null */ 1586 name_len++; /* trailing null */
@@ -1386,7 +1604,7 @@ createSymLinkRetry:
1386 data_offset = (char *) (&pSMB->hdr.Protocol) + offset; 1604 data_offset = (char *) (&pSMB->hdr.Protocol) + offset;
1387 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) { 1605 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
1388 name_len_target = 1606 name_len_target =
1389 cifs_strtoUCS((wchar_t *) data_offset, toName, PATH_MAX 1607 cifs_strtoUCS((__le16 *) data_offset, toName, PATH_MAX
1390 /* find define for this maxpathcomponent */ 1608 /* find define for this maxpathcomponent */
1391 , nls_codepage); 1609 , nls_codepage);
1392 name_len_target++; /* trailing null */ 1610 name_len_target++; /* trailing null */
@@ -1416,6 +1634,7 @@ createSymLinkRetry:
1416 pSMB->ByteCount = cpu_to_le16(byte_count); 1634 pSMB->ByteCount = cpu_to_le16(byte_count);
1417 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, 1635 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
1418 (struct smb_hdr *) pSMBr, &bytes_returned, 0); 1636 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
1637 cifs_stats_inc(&tcon->num_symlinks);
1419 if (rc) { 1638 if (rc) {
1420 cFYI(1, 1639 cFYI(1,
1421 ("Send error in SetPathInfo (create symlink) = %d", 1640 ("Send error in SetPathInfo (create symlink) = %d",
@@ -1505,6 +1724,7 @@ createHardLinkRetry:
1505 pSMB->ByteCount = cpu_to_le16(byte_count); 1724 pSMB->ByteCount = cpu_to_le16(byte_count);
1506 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, 1725 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
1507 (struct smb_hdr *) pSMBr, &bytes_returned, 0); 1726 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
1727 cifs_stats_inc(&tcon->num_hardlinks);
1508 if (rc) { 1728 if (rc) {
1509 cFYI(1, ("Send error in SetPathInfo (hard link) = %d", rc)); 1729 cFYI(1, ("Send error in SetPathInfo (hard link) = %d", rc));
1510 } 1730 }
@@ -1575,6 +1795,7 @@ winCreateHardLinkRetry:
1575 1795
1576 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, 1796 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
1577 (struct smb_hdr *) pSMBr, &bytes_returned, 0); 1797 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
1798 cifs_stats_inc(&tcon->num_hardlinks);
1578 if (rc) { 1799 if (rc) {
1579 cFYI(1, ("Send error in hard link (NT rename) = %d", rc)); 1800 cFYI(1, ("Send error in hard link (NT rename) = %d", rc));
1580 } 1801 }
@@ -1609,7 +1830,7 @@ querySymLinkRetry:
1609 1830
1610 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) { 1831 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
1611 name_len = 1832 name_len =
1612 cifs_strtoUCS((wchar_t *) pSMB->FileName, searchName, PATH_MAX 1833 cifs_strtoUCS((__le16 *) pSMB->FileName, searchName, PATH_MAX
1613 /* find define for this maxpathcomponent */ 1834 /* find define for this maxpathcomponent */
1614 , nls_codepage); 1835 , nls_codepage);
1615 name_len++; /* trailing null */ 1836 name_len++; /* trailing null */
@@ -1666,7 +1887,7 @@ querySymLinkRetry:
1666 min_t(const int, buflen,count) / 2); 1887 min_t(const int, buflen,count) / 2);
1667 /* BB FIXME investigate remapping reserved chars here */ 1888 /* BB FIXME investigate remapping reserved chars here */
1668 cifs_strfromUCS_le(symlinkinfo, 1889 cifs_strfromUCS_le(symlinkinfo,
1669 (wchar_t *) ((char *)&pSMBr->hdr.Protocol + 1890 (__le16 *) ((char *)&pSMBr->hdr.Protocol +
1670 data_offset), 1891 data_offset),
1671 name_len, nls_codepage); 1892 name_len, nls_codepage);
1672 } else { 1893 } else {
@@ -1757,7 +1978,7 @@ CIFSSMBQueryReparseLinkInfo(const int xid, struct cifsTconInfo *tcon,
1757 reparse_buf->TargetNameOffset), 1978 reparse_buf->TargetNameOffset),
1758 min(buflen/2, reparse_buf->TargetNameLen / 2)); 1979 min(buflen/2, reparse_buf->TargetNameLen / 2));
1759 cifs_strfromUCS_le(symlinkinfo, 1980 cifs_strfromUCS_le(symlinkinfo,
1760 (wchar_t *) (reparse_buf->LinkNamesBuf + 1981 (__le16 *) (reparse_buf->LinkNamesBuf +
1761 reparse_buf->TargetNameOffset), 1982 reparse_buf->TargetNameOffset),
1762 name_len, nls_codepage); 1983 name_len, nls_codepage);
1763 } else { /* ASCII names */ 1984 } else { /* ASCII names */
@@ -1775,8 +1996,7 @@ CIFSSMBQueryReparseLinkInfo(const int xid, struct cifsTconInfo *tcon,
1775 } 1996 }
1776 } 1997 }
1777qreparse_out: 1998qreparse_out:
1778 if (pSMB) 1999 cifs_buf_release(pSMB);
1779 cifs_buf_release(pSMB);
1780 2000
1781 /* Note: On -EAGAIN error only caller can retry on handle based calls 2001 /* Note: On -EAGAIN error only caller can retry on handle based calls
1782 since file handle passed in no longer valid */ 2002 since file handle passed in no longer valid */
@@ -1790,9 +2010,9 @@ qreparse_out:
1790static void cifs_convert_ace(posix_acl_xattr_entry * ace, struct cifs_posix_ace * cifs_ace) 2010static void cifs_convert_ace(posix_acl_xattr_entry * ace, struct cifs_posix_ace * cifs_ace)
1791{ 2011{
1792 /* u8 cifs fields do not need le conversion */ 2012 /* u8 cifs fields do not need le conversion */
1793 ace->e_perm = (__u16)cifs_ace->cifs_e_perm; 2013 ace->e_perm = cpu_to_le16(cifs_ace->cifs_e_perm);
1794 ace->e_tag = (__u16)cifs_ace->cifs_e_tag; 2014 ace->e_tag = cpu_to_le16(cifs_ace->cifs_e_tag);
1795 ace->e_id = (__u32)le64_to_cpu(cifs_ace->cifs_uid); 2015 ace->e_id = cpu_to_le32(le64_to_cpu(cifs_ace->cifs_uid));
1796 /* cFYI(1,("perm %d tag %d id %d",ace->e_perm,ace->e_tag,ace->e_id)); */ 2016 /* cFYI(1,("perm %d tag %d id %d",ace->e_perm,ace->e_tag,ace->e_id)); */
1797 2017
1798 return; 2018 return;
@@ -1844,7 +2064,7 @@ static int cifs_copy_posix_acl(char * trgt,char * src, const int buflen,
1844 } else if(size > buflen) { 2064 } else if(size > buflen) {
1845 return -ERANGE; 2065 return -ERANGE;
1846 } else /* buffer big enough */ { 2066 } else /* buffer big enough */ {
1847 local_acl->a_version = POSIX_ACL_XATTR_VERSION; 2067 local_acl->a_version = cpu_to_le32(POSIX_ACL_XATTR_VERSION);
1848 for(i = 0;i < count ;i++) { 2068 for(i = 0;i < count ;i++) {
1849 cifs_convert_ace(&local_acl->a_entries[i],pACE); 2069 cifs_convert_ace(&local_acl->a_entries[i],pACE);
1850 pACE ++; 2070 pACE ++;
@@ -1858,14 +2078,14 @@ static __u16 convert_ace_to_cifs_ace(struct cifs_posix_ace * cifs_ace,
1858{ 2078{
1859 __u16 rc = 0; /* 0 = ACL converted ok */ 2079 __u16 rc = 0; /* 0 = ACL converted ok */
1860 2080
1861 cifs_ace->cifs_e_perm = (__u8)cpu_to_le16(local_ace->e_perm); 2081 cifs_ace->cifs_e_perm = le16_to_cpu(local_ace->e_perm);
1862 cifs_ace->cifs_e_tag = (__u8)cpu_to_le16(local_ace->e_tag); 2082 cifs_ace->cifs_e_tag = le16_to_cpu(local_ace->e_tag);
1863 /* BB is there a better way to handle the large uid? */ 2083 /* BB is there a better way to handle the large uid? */
1864 if(local_ace->e_id == -1) { 2084 if(local_ace->e_id == cpu_to_le32(-1)) {
1865 /* Probably no need to le convert -1 on any arch but can not hurt */ 2085 /* Probably no need to le convert -1 on any arch but can not hurt */
1866 cifs_ace->cifs_uid = cpu_to_le64(-1); 2086 cifs_ace->cifs_uid = cpu_to_le64(-1);
1867 } else 2087 } else
1868 cifs_ace->cifs_uid = (__u64)cpu_to_le32(local_ace->e_id); 2088 cifs_ace->cifs_uid = cpu_to_le64(le32_to_cpu(local_ace->e_id));
1869 /*cFYI(1,("perm %d tag %d id %d",ace->e_perm,ace->e_tag,ace->e_id));*/ 2089 /*cFYI(1,("perm %d tag %d id %d",ace->e_perm,ace->e_tag,ace->e_id));*/
1870 return rc; 2090 return rc;
1871} 2091}
@@ -1885,16 +2105,17 @@ static __u16 ACL_to_cifs_posix(char * parm_data,const char * pACL,const int bufl
1885 2105
1886 count = posix_acl_xattr_count((size_t)buflen); 2106 count = posix_acl_xattr_count((size_t)buflen);
1887 cFYI(1,("setting acl with %d entries from buf of length %d and version of %d", 2107 cFYI(1,("setting acl with %d entries from buf of length %d and version of %d",
1888 count,buflen,local_acl->a_version)); 2108 count, buflen, le32_to_cpu(local_acl->a_version)));
1889 if(local_acl->a_version != 2) { 2109 if(le32_to_cpu(local_acl->a_version) != 2) {
1890 cFYI(1,("unknown POSIX ACL version %d",local_acl->a_version)); 2110 cFYI(1,("unknown POSIX ACL version %d",
2111 le32_to_cpu(local_acl->a_version)));
1891 return 0; 2112 return 0;
1892 } 2113 }
1893 cifs_acl->version = cpu_to_le16(1); 2114 cifs_acl->version = cpu_to_le16(1);
1894 if(acl_type == ACL_TYPE_ACCESS) 2115 if(acl_type == ACL_TYPE_ACCESS)
1895 cifs_acl->access_entry_count = count; 2116 cifs_acl->access_entry_count = cpu_to_le16(count);
1896 else if(acl_type == ACL_TYPE_DEFAULT) 2117 else if(acl_type == ACL_TYPE_DEFAULT)
1897 cifs_acl->default_entry_count = count; 2118 cifs_acl->default_entry_count = cpu_to_le16(count);
1898 else { 2119 else {
1899 cFYI(1,("unknown ACL type %d",acl_type)); 2120 cFYI(1,("unknown ACL type %d",acl_type));
1900 return 0; 2121 return 0;
@@ -2165,6 +2386,67 @@ GetExtAttrOut:
2165 2386
2166#endif /* CONFIG_POSIX */ 2387#endif /* CONFIG_POSIX */
2167 2388
2389/* Legacy Query Path Information call for lookup to old servers such
2390 as Win9x/WinME */
2391int SMBQueryInformation(const int xid, struct cifsTconInfo *tcon,
2392 const unsigned char *searchName,
2393 FILE_ALL_INFO * pFinfo,
2394 const struct nls_table *nls_codepage, int remap)
2395{
2396 QUERY_INFORMATION_REQ * pSMB;
2397 QUERY_INFORMATION_RSP * pSMBr;
2398 int rc = 0;
2399 int bytes_returned;
2400 int name_len;
2401
2402 cFYI(1, ("In SMBQPath path %s", searchName));
2403QInfRetry:
2404 rc = smb_init(SMB_COM_QUERY_INFORMATION, 0, tcon, (void **) &pSMB,
2405 (void **) &pSMBr);
2406 if (rc)
2407 return rc;
2408
2409 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
2410 name_len =
2411 cifsConvertToUCS((__le16 *) pSMB->FileName, searchName,
2412 PATH_MAX, nls_codepage, remap);
2413 name_len++; /* trailing null */
2414 name_len *= 2;
2415 } else {
2416 name_len = strnlen(searchName, PATH_MAX);
2417 name_len++; /* trailing null */
2418 strncpy(pSMB->FileName, searchName, name_len);
2419 }
2420 pSMB->BufferFormat = 0x04;
2421 name_len++; /* account for buffer type byte */
2422 pSMB->hdr.smb_buf_length += (__u16) name_len;
2423 pSMB->ByteCount = cpu_to_le16(name_len);
2424
2425 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
2426 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
2427 if (rc) {
2428 cFYI(1, ("Send error in QueryInfo = %d", rc));
2429 } else if (pFinfo) { /* decode response */
2430 memset(pFinfo, 0, sizeof(FILE_ALL_INFO));
2431 pFinfo->AllocationSize =
2432 cpu_to_le64(le32_to_cpu(pSMBr->size));
2433 pFinfo->EndOfFile = pFinfo->AllocationSize;
2434 pFinfo->Attributes =
2435 cpu_to_le32(le16_to_cpu(pSMBr->attr));
2436 } else
2437 rc = -EIO; /* bad buffer passed in */
2438
2439 cifs_buf_release(pSMB);
2440
2441 if (rc == -EAGAIN)
2442 goto QInfRetry;
2443
2444 return rc;
2445}
2446
2447
2448
2449
2168int 2450int
2169CIFSSMBQPathInfo(const int xid, struct cifsTconInfo *tcon, 2451CIFSSMBQPathInfo(const int xid, struct cifsTconInfo *tcon,
2170 const unsigned char *searchName, 2452 const unsigned char *searchName,
@@ -2396,7 +2678,7 @@ findUniqueRetry:
2396 if (rc) { 2678 if (rc) {
2397 cFYI(1, ("Send error in FindFileDirInfo = %d", rc)); 2679 cFYI(1, ("Send error in FindFileDirInfo = %d", rc));
2398 } else { /* decode response */ 2680 } else { /* decode response */
2399 2681 cifs_stats_inc(&tcon->num_ffirst);
2400 /* BB fill in */ 2682 /* BB fill in */
2401 } 2683 }
2402 2684
@@ -2414,7 +2696,7 @@ CIFSFindFirst(const int xid, struct cifsTconInfo *tcon,
2414 const char *searchName, 2696 const char *searchName,
2415 const struct nls_table *nls_codepage, 2697 const struct nls_table *nls_codepage,
2416 __u16 * pnetfid, 2698 __u16 * pnetfid,
2417 struct cifs_search_info * psrch_inf, int remap) 2699 struct cifs_search_info * psrch_inf, int remap, const char dirsep)
2418{ 2700{
2419/* level 257 SMB_ */ 2701/* level 257 SMB_ */
2420 TRANSACTION2_FFIRST_REQ *pSMB = NULL; 2702 TRANSACTION2_FFIRST_REQ *pSMB = NULL;
@@ -2441,7 +2723,7 @@ findFirstRetry:
2441 it got remapped to 0xF03A as if it were part of the 2723 it got remapped to 0xF03A as if it were part of the
2442 directory name instead of a wildcard */ 2724 directory name instead of a wildcard */
2443 name_len *= 2; 2725 name_len *= 2;
2444 pSMB->FileName[name_len] = '\\'; 2726 pSMB->FileName[name_len] = dirsep;
2445 pSMB->FileName[name_len+1] = 0; 2727 pSMB->FileName[name_len+1] = 0;
2446 pSMB->FileName[name_len+2] = '*'; 2728 pSMB->FileName[name_len+2] = '*';
2447 pSMB->FileName[name_len+3] = 0; 2729 pSMB->FileName[name_len+3] = 0;
@@ -2455,7 +2737,7 @@ findFirstRetry:
2455 if(name_len > buffersize-header) 2737 if(name_len > buffersize-header)
2456 free buffer exit; BB */ 2738 free buffer exit; BB */
2457 strncpy(pSMB->FileName, searchName, name_len); 2739 strncpy(pSMB->FileName, searchName, name_len);
2458 pSMB->FileName[name_len] = '\\'; 2740 pSMB->FileName[name_len] = dirsep;
2459 pSMB->FileName[name_len+1] = '*'; 2741 pSMB->FileName[name_len+1] = '*';
2460 pSMB->FileName[name_len+2] = 0; 2742 pSMB->FileName[name_len+2] = 0;
2461 name_len += 3; 2743 name_len += 3;
@@ -2496,6 +2778,7 @@ findFirstRetry:
2496 2778
2497 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, 2779 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
2498 (struct smb_hdr *) pSMBr, &bytes_returned, 0); 2780 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
2781 cifs_stats_inc(&tcon->num_ffirst);
2499 2782
2500 if (rc) {/* BB add logic to retry regular search if Unix search rejected unexpectedly by server */ 2783 if (rc) {/* BB add logic to retry regular search if Unix search rejected unexpectedly by server */
2501 /* BB Add code to handle unsupported level rc */ 2784 /* BB Add code to handle unsupported level rc */
@@ -2617,7 +2900,7 @@ int CIFSFindNext(const int xid, struct cifsTconInfo *tcon,
2617 2900
2618 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, 2901 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
2619 (struct smb_hdr *) pSMBr, &bytes_returned, 0); 2902 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
2620 2903 cifs_stats_inc(&tcon->num_fnext);
2621 if (rc) { 2904 if (rc) {
2622 if (rc == -EBADF) { 2905 if (rc == -EBADF) {
2623 psrch_inf->endOfSearch = TRUE; 2906 psrch_inf->endOfSearch = TRUE;
@@ -2694,6 +2977,7 @@ CIFSFindClose(const int xid, struct cifsTconInfo *tcon, const __u16 searchHandle
2694 if (rc) { 2977 if (rc) {
2695 cERROR(1, ("Send error in FindClose = %d", rc)); 2978 cERROR(1, ("Send error in FindClose = %d", rc));
2696 } 2979 }
2980 cifs_stats_inc(&tcon->num_fclose);
2697 cifs_small_buf_release(pSMB); 2981 cifs_small_buf_release(pSMB);
2698 2982
2699 /* Since session is dead, search handle closed on server already */ 2983 /* Since session is dead, search handle closed on server already */
@@ -2703,7 +2987,6 @@ CIFSFindClose(const int xid, struct cifsTconInfo *tcon, const __u16 searchHandle
2703 return rc; 2987 return rc;
2704} 2988}
2705 2989
2706#ifdef CONFIG_CIFS_EXPERIMENTAL
2707int 2990int
2708CIFSGetSrvInodeNumber(const int xid, struct cifsTconInfo *tcon, 2991CIFSGetSrvInodeNumber(const int xid, struct cifsTconInfo *tcon,
2709 const unsigned char *searchName, 2992 const unsigned char *searchName,
@@ -2797,7 +3080,6 @@ GetInodeNumOut:
2797 goto GetInodeNumberRetry; 3080 goto GetInodeNumberRetry;
2798 return rc; 3081 return rc;
2799} 3082}
2800#endif /* CIFS_EXPERIMENTAL */
2801 3083
2802int 3084int
2803CIFSGetDFSRefer(const int xid, struct cifsSesInfo *ses, 3085CIFSGetDFSRefer(const int xid, struct cifsSesInfo *ses,
@@ -2827,7 +3109,10 @@ getDFSRetry:
2827 (void **) &pSMBr); 3109 (void **) &pSMBr);
2828 if (rc) 3110 if (rc)
2829 return rc; 3111 return rc;
2830 3112
3113 /* server pointer checked in called function,
3114 but should never be null here anyway */
3115 pSMB->hdr.Mid = GetNextMid(ses->server);
2831 pSMB->hdr.Tid = ses->ipc_tid; 3116 pSMB->hdr.Tid = ses->ipc_tid;
2832 pSMB->hdr.Uid = ses->Suid; 3117 pSMB->hdr.Uid = ses->Suid;
2833 if (ses->capabilities & CAP_STATUS32) { 3118 if (ses->capabilities & CAP_STATUS32) {
@@ -2946,7 +3231,7 @@ getDFSRetry:
2946 temp = ((char *)referrals) + le16_to_cpu(referrals->DfsPathOffset); 3231 temp = ((char *)referrals) + le16_to_cpu(referrals->DfsPathOffset);
2947 if (pSMBr->hdr.Flags2 & SMBFLG2_UNICODE) { 3232 if (pSMBr->hdr.Flags2 & SMBFLG2_UNICODE) {
2948 cifs_strfromUCS_le(*targetUNCs, 3233 cifs_strfromUCS_le(*targetUNCs,
2949 (wchar_t *) temp, name_len, nls_codepage); 3234 (__le16 *) temp, name_len, nls_codepage);
2950 } else { 3235 } else {
2951 strncpy(*targetUNCs,temp,name_len); 3236 strncpy(*targetUNCs,temp,name_len);
2952 } 3237 }
@@ -2968,6 +3253,92 @@ GetDFSRefExit:
2968 return rc; 3253 return rc;
2969} 3254}
2970 3255
3256/* Query File System Info such as free space to old servers such as Win 9x */
3257int
3258SMBOldQFSInfo(const int xid, struct cifsTconInfo *tcon, struct kstatfs *FSData)
3259{
3260/* level 0x01 SMB_QUERY_FILE_SYSTEM_INFO */
3261 TRANSACTION2_QFSI_REQ *pSMB = NULL;
3262 TRANSACTION2_QFSI_RSP *pSMBr = NULL;
3263 FILE_SYSTEM_ALLOC_INFO *response_data;
3264 int rc = 0;
3265 int bytes_returned = 0;
3266 __u16 params, byte_count;
3267
3268 cFYI(1, ("OldQFSInfo"));
3269oldQFSInfoRetry:
3270 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
3271 (void **) &pSMBr);
3272 if (rc)
3273 return rc;
3274 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
3275 (void **) &pSMBr);
3276 if (rc)
3277 return rc;
3278
3279 params = 2; /* level */
3280 pSMB->TotalDataCount = 0;
3281 pSMB->MaxParameterCount = cpu_to_le16(2);
3282 pSMB->MaxDataCount = cpu_to_le16(1000);
3283 pSMB->MaxSetupCount = 0;
3284 pSMB->Reserved = 0;
3285 pSMB->Flags = 0;
3286 pSMB->Timeout = 0;
3287 pSMB->Reserved2 = 0;
3288 byte_count = params + 1 /* pad */ ;
3289 pSMB->TotalParameterCount = cpu_to_le16(params);
3290 pSMB->ParameterCount = pSMB->TotalParameterCount;
3291 pSMB->ParameterOffset = cpu_to_le16(offsetof(
3292 struct smb_com_transaction2_qfsi_req, InformationLevel) - 4);
3293 pSMB->DataCount = 0;
3294 pSMB->DataOffset = 0;
3295 pSMB->SetupCount = 1;
3296 pSMB->Reserved3 = 0;
3297 pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_FS_INFORMATION);
3298 pSMB->InformationLevel = cpu_to_le16(SMB_INFO_ALLOCATION);
3299 pSMB->hdr.smb_buf_length += byte_count;
3300 pSMB->ByteCount = cpu_to_le16(byte_count);
3301
3302 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
3303 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
3304 if (rc) {
3305 cFYI(1, ("Send error in QFSInfo = %d", rc));
3306 } else { /* decode response */
3307 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
3308
3309 if (rc || (pSMBr->ByteCount < 18))
3310 rc = -EIO; /* bad smb */
3311 else {
3312 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
3313 cFYI(1,("qfsinf resp BCC: %d Offset %d",
3314 pSMBr->ByteCount, data_offset));
3315
3316 response_data =
3317 (FILE_SYSTEM_ALLOC_INFO *)
3318 (((char *) &pSMBr->hdr.Protocol) + data_offset);
3319 FSData->f_bsize =
3320 le16_to_cpu(response_data->BytesPerSector) *
3321 le32_to_cpu(response_data->
3322 SectorsPerAllocationUnit);
3323 FSData->f_blocks =
3324 le32_to_cpu(response_data->TotalAllocationUnits);
3325 FSData->f_bfree = FSData->f_bavail =
3326 le32_to_cpu(response_data->FreeAllocationUnits);
3327 cFYI(1,
3328 ("Blocks: %lld Free: %lld Block size %ld",
3329 (unsigned long long)FSData->f_blocks,
3330 (unsigned long long)FSData->f_bfree,
3331 FSData->f_bsize));
3332 }
3333 }
3334 cifs_buf_release(pSMB);
3335
3336 if (rc == -EAGAIN)
3337 goto oldQFSInfoRetry;
3338
3339 return rc;
3340}
3341
2971int 3342int
2972CIFSSMBQFSInfo(const int xid, struct cifsTconInfo *tcon, struct kstatfs *FSData) 3343CIFSSMBQFSInfo(const int xid, struct cifsTconInfo *tcon, struct kstatfs *FSData)
2973{ 3344{
@@ -2989,7 +3360,7 @@ QFSInfoRetry:
2989 params = 2; /* level */ 3360 params = 2; /* level */
2990 pSMB->TotalDataCount = 0; 3361 pSMB->TotalDataCount = 0;
2991 pSMB->MaxParameterCount = cpu_to_le16(2); 3362 pSMB->MaxParameterCount = cpu_to_le16(2);
2992 pSMB->MaxDataCount = cpu_to_le16(1000); /* BB find exact max SMB PDU from sess structure BB */ 3363 pSMB->MaxDataCount = cpu_to_le16(1000);
2993 pSMB->MaxSetupCount = 0; 3364 pSMB->MaxSetupCount = 0;
2994 pSMB->Reserved = 0; 3365 pSMB->Reserved = 0;
2995 pSMB->Flags = 0; 3366 pSMB->Flags = 0;
@@ -3012,17 +3383,14 @@ QFSInfoRetry:
3012 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, 3383 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
3013 (struct smb_hdr *) pSMBr, &bytes_returned, 0); 3384 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
3014 if (rc) { 3385 if (rc) {
3015 cERROR(1, ("Send error in QFSInfo = %d", rc)); 3386 cFYI(1, ("Send error in QFSInfo = %d", rc));
3016 } else { /* decode response */ 3387 } else { /* decode response */
3017 rc = validate_t2((struct smb_t2_rsp *)pSMBr); 3388 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
3018 3389
3019 if (rc || (pSMBr->ByteCount < 24)) /* BB alsO CHEck enough total bytes returned */ 3390 if (rc || (pSMBr->ByteCount < 24))
3020 rc = -EIO; /* bad smb */ 3391 rc = -EIO; /* bad smb */
3021 else { 3392 else {
3022 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset); 3393 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
3023 cFYI(1,
3024 ("Decoding qfsinfo response. BCC: %d Offset %d",
3025 pSMBr->ByteCount, data_offset));
3026 3394
3027 response_data = 3395 response_data =
3028 (FILE_SYSTEM_INFO 3396 (FILE_SYSTEM_INFO
@@ -3257,6 +3625,77 @@ QFSUnixRetry:
3257 return rc; 3625 return rc;
3258} 3626}
3259 3627
3628int
3629CIFSSMBSetFSUnixInfo(const int xid, struct cifsTconInfo *tcon, __u64 cap)
3630{
3631/* level 0x200 SMB_SET_CIFS_UNIX_INFO */
3632 TRANSACTION2_SETFSI_REQ *pSMB = NULL;
3633 TRANSACTION2_SETFSI_RSP *pSMBr = NULL;
3634 int rc = 0;
3635 int bytes_returned = 0;
3636 __u16 params, param_offset, offset, byte_count;
3637
3638 cFYI(1, ("In SETFSUnixInfo"));
3639SETFSUnixRetry:
3640 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
3641 (void **) &pSMBr);
3642 if (rc)
3643 return rc;
3644
3645 params = 4; /* 2 bytes zero followed by info level. */
3646 pSMB->MaxSetupCount = 0;
3647 pSMB->Reserved = 0;
3648 pSMB->Flags = 0;
3649 pSMB->Timeout = 0;
3650 pSMB->Reserved2 = 0;
3651 param_offset = offsetof(struct smb_com_transaction2_setfsi_req, FileNum) - 4;
3652 offset = param_offset + params;
3653
3654 pSMB->MaxParameterCount = cpu_to_le16(4);
3655 pSMB->MaxDataCount = cpu_to_le16(100); /* BB find exact max SMB PDU from sess structure BB */
3656 pSMB->SetupCount = 1;
3657 pSMB->Reserved3 = 0;
3658 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_FS_INFORMATION);
3659 byte_count = 1 /* pad */ + params + 12;
3660
3661 pSMB->DataCount = cpu_to_le16(12);
3662 pSMB->ParameterCount = cpu_to_le16(params);
3663 pSMB->TotalDataCount = pSMB->DataCount;
3664 pSMB->TotalParameterCount = pSMB->ParameterCount;
3665 pSMB->ParameterOffset = cpu_to_le16(param_offset);
3666 pSMB->DataOffset = cpu_to_le16(offset);
3667
3668 /* Params. */
3669 pSMB->FileNum = 0;
3670 pSMB->InformationLevel = cpu_to_le16(SMB_SET_CIFS_UNIX_INFO);
3671
3672 /* Data. */
3673 pSMB->ClientUnixMajor = cpu_to_le16(CIFS_UNIX_MAJOR_VERSION);
3674 pSMB->ClientUnixMinor = cpu_to_le16(CIFS_UNIX_MINOR_VERSION);
3675 pSMB->ClientUnixCap = cpu_to_le64(cap);
3676
3677 pSMB->hdr.smb_buf_length += byte_count;
3678 pSMB->ByteCount = cpu_to_le16(byte_count);
3679
3680 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
3681 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
3682 if (rc) {
3683 cERROR(1, ("Send error in SETFSUnixInfo = %d", rc));
3684 } else { /* decode response */
3685 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
3686 if (rc) {
3687 rc = -EIO; /* bad smb */
3688 }
3689 }
3690 cifs_buf_release(pSMB);
3691
3692 if (rc == -EAGAIN)
3693 goto SETFSUnixRetry;
3694
3695 return rc;
3696}
3697
3698
3260 3699
3261int 3700int
3262CIFSSMBQFSPosixInfo(const int xid, struct cifsTconInfo *tcon, 3701CIFSSMBQFSPosixInfo(const int xid, struct cifsTconInfo *tcon,
@@ -3321,16 +3760,16 @@ QFSPosixRetry:
3321 le64_to_cpu(response_data->TotalBlocks); 3760 le64_to_cpu(response_data->TotalBlocks);
3322 FSData->f_bfree = 3761 FSData->f_bfree =
3323 le64_to_cpu(response_data->BlocksAvail); 3762 le64_to_cpu(response_data->BlocksAvail);
3324 if(response_data->UserBlocksAvail == -1) { 3763 if(response_data->UserBlocksAvail == cpu_to_le64(-1)) {
3325 FSData->f_bavail = FSData->f_bfree; 3764 FSData->f_bavail = FSData->f_bfree;
3326 } else { 3765 } else {
3327 FSData->f_bavail = 3766 FSData->f_bavail =
3328 le64_to_cpu(response_data->UserBlocksAvail); 3767 le64_to_cpu(response_data->UserBlocksAvail);
3329 } 3768 }
3330 if(response_data->TotalFileNodes != -1) 3769 if(response_data->TotalFileNodes != cpu_to_le64(-1))
3331 FSData->f_files = 3770 FSData->f_files =
3332 le64_to_cpu(response_data->TotalFileNodes); 3771 le64_to_cpu(response_data->TotalFileNodes);
3333 if(response_data->FreeFileNodes != -1) 3772 if(response_data->FreeFileNodes != cpu_to_le64(-1))
3334 FSData->f_ffree = 3773 FSData->f_ffree =
3335 le64_to_cpu(response_data->FreeFileNodes); 3774 le64_to_cpu(response_data->FreeFileNodes);
3336 } 3775 }
@@ -3376,7 +3815,7 @@ SetEOFRetry:
3376 PATH_MAX, nls_codepage, remap); 3815 PATH_MAX, nls_codepage, remap);
3377 name_len++; /* trailing null */ 3816 name_len++; /* trailing null */
3378 name_len *= 2; 3817 name_len *= 2;
3379 } else { /* BB improve the check for buffer overruns BB */ 3818 } else { /* BB improve the check for buffer overruns BB */
3380 name_len = strnlen(fileName, PATH_MAX); 3819 name_len = strnlen(fileName, PATH_MAX);
3381 name_len++; /* trailing null */ 3820 name_len++; /* trailing null */
3382 strncpy(pSMB->FileName, fileName, name_len); 3821 strncpy(pSMB->FileName, fileName, name_len);
@@ -3384,7 +3823,7 @@ SetEOFRetry:
3384 params = 6 + name_len; 3823 params = 6 + name_len;
3385 data_count = sizeof (struct file_end_of_file_info); 3824 data_count = sizeof (struct file_end_of_file_info);
3386 pSMB->MaxParameterCount = cpu_to_le16(2); 3825 pSMB->MaxParameterCount = cpu_to_le16(2);
3387 pSMB->MaxDataCount = cpu_to_le16(1000); /* BB find max SMB size from sess */ 3826 pSMB->MaxDataCount = cpu_to_le16(4100);
3388 pSMB->MaxSetupCount = 0; 3827 pSMB->MaxSetupCount = 0;
3389 pSMB->Reserved = 0; 3828 pSMB->Reserved = 0;
3390 pSMB->Flags = 0; 3829 pSMB->Flags = 0;
@@ -3766,7 +4205,7 @@ setPermsRetry:
3766 PATH_MAX, nls_codepage, remap); 4205 PATH_MAX, nls_codepage, remap);
3767 name_len++; /* trailing null */ 4206 name_len++; /* trailing null */
3768 name_len *= 2; 4207 name_len *= 2;
3769 } else { /* BB improve the check for buffer overruns BB */ 4208 } else { /* BB improve the check for buffer overruns BB */
3770 name_len = strnlen(fileName, PATH_MAX); 4209 name_len = strnlen(fileName, PATH_MAX);
3771 name_len++; /* trailing null */ 4210 name_len++; /* trailing null */
3772 strncpy(pSMB->FileName, fileName, name_len); 4211 strncpy(pSMB->FileName, fileName, name_len);
@@ -3839,12 +4278,14 @@ setPermsRetry:
3839} 4278}
3840 4279
3841int CIFSSMBNotify(const int xid, struct cifsTconInfo *tcon, 4280int CIFSSMBNotify(const int xid, struct cifsTconInfo *tcon,
3842 const int notify_subdirs, const __u16 netfid, 4281 const int notify_subdirs, const __u16 netfid,
3843 __u32 filter, const struct nls_table *nls_codepage) 4282 __u32 filter, struct file * pfile, int multishot,
4283 const struct nls_table *nls_codepage)
3844{ 4284{
3845 int rc = 0; 4285 int rc = 0;
3846 struct smb_com_transaction_change_notify_req * pSMB = NULL; 4286 struct smb_com_transaction_change_notify_req * pSMB = NULL;
3847 struct smb_com_transaction_change_notify_rsp * pSMBr = NULL; 4287 struct smb_com_transaction_change_notify_rsp * pSMBr = NULL;
4288 struct dir_notify_req *dnotify_req;
3848 int bytes_returned; 4289 int bytes_returned;
3849 4290
3850 cFYI(1, ("In CIFSSMBNotify for file handle %d",(int)netfid)); 4291 cFYI(1, ("In CIFSSMBNotify for file handle %d",(int)netfid));
@@ -3877,6 +4318,28 @@ int CIFSSMBNotify(const int xid, struct cifsTconInfo *tcon,
3877 (struct smb_hdr *) pSMBr, &bytes_returned, -1); 4318 (struct smb_hdr *) pSMBr, &bytes_returned, -1);
3878 if (rc) { 4319 if (rc) {
3879 cFYI(1, ("Error in Notify = %d", rc)); 4320 cFYI(1, ("Error in Notify = %d", rc));
4321 } else {
4322 /* Add file to outstanding requests */
4323 /* BB change to kmem cache alloc */
4324 dnotify_req = (struct dir_notify_req *) kmalloc(
4325 sizeof(struct dir_notify_req),
4326 GFP_KERNEL);
4327 if(dnotify_req) {
4328 dnotify_req->Pid = pSMB->hdr.Pid;
4329 dnotify_req->PidHigh = pSMB->hdr.PidHigh;
4330 dnotify_req->Mid = pSMB->hdr.Mid;
4331 dnotify_req->Tid = pSMB->hdr.Tid;
4332 dnotify_req->Uid = pSMB->hdr.Uid;
4333 dnotify_req->netfid = netfid;
4334 dnotify_req->pfile = pfile;
4335 dnotify_req->filter = filter;
4336 dnotify_req->multishot = multishot;
4337 spin_lock(&GlobalMid_Lock);
4338 list_add_tail(&dnotify_req->lhead,
4339 &GlobalDnotifyReqList);
4340 spin_unlock(&GlobalMid_Lock);
4341 } else
4342 rc = -ENOMEM;
3880 } 4343 }
3881 cifs_buf_release(pSMB); 4344 cifs_buf_release(pSMB);
3882 return rc; 4345 return rc;