@@ -958,21 +958,19 @@ CIFSSMBOpen(const int xid, struct cifsTconInfo *tcon,
958
958
return rc ;
959
959
}
960
960
961
- /* If no buffer passed in, then caller wants to do the copy
962
- as in the case of readpages so the SMB buffer must be
963
- freed by the caller */
964
-
965
961
int
966
962
CIFSSMBRead (const int xid , struct cifsTconInfo * tcon ,
967
- const int netfid , const unsigned int count ,
968
- const __u64 lseek , unsigned int * nbytes , char * * buf )
963
+ const int netfid , const unsigned int count ,
964
+ const __u64 lseek , unsigned int * nbytes , char * * buf ,
965
+ int * pbuf_type )
969
966
{
970
967
int rc = - EACCES ;
971
968
READ_REQ * pSMB = NULL ;
972
969
READ_RSP * pSMBr = NULL ;
973
970
char * pReadData = NULL ;
974
- int bytes_returned ;
975
971
int wct ;
972
+ int resp_buf_type = 0 ;
973
+ struct kvec iov [1 ];
976
974
977
975
cFYI (1 ,("Reading %d bytes on fid %d" ,count ,netfid ));
978
976
if (tcon -> ses -> capabilities & CAP_LARGE_FILES )
@@ -981,22 +979,21 @@ CIFSSMBRead(const int xid, struct cifsTconInfo *tcon,
981
979
wct = 10 ; /* old style read */
982
980
983
981
* nbytes = 0 ;
984
- rc = smb_init (SMB_COM_READ_ANDX , wct , tcon , (void * * ) & pSMB ,
985
- (void * * ) & pSMBr );
982
+ rc = small_smb_init (SMB_COM_READ_ANDX , wct , tcon , (void * * ) & pSMB );
986
983
if (rc )
987
984
return rc ;
988
985
989
986
/* tcon and ses pointer are checked in smb_init */
990
987
if (tcon -> ses -> server == NULL )
991
988
return - ECONNABORTED ;
992
989
993
- pSMB -> AndXCommand = 0xFF ; /* none */
990
+ pSMB -> AndXCommand = 0xFF ; /* none */
994
991
pSMB -> Fid = netfid ;
995
992
pSMB -> OffsetLow = cpu_to_le32 (lseek & 0xFFFFFFFF );
996
993
if (wct == 12 )
997
994
pSMB -> OffsetHigh = cpu_to_le32 (lseek >> 32 );
998
- else if ((lseek >> 32 ) > 0 ) /* can not handle this big offset for old */
999
- return - EIO ;
995
+ else if ((lseek >> 32 ) > 0 ) /* can not handle this big offset for old */
996
+ return - EIO ;
1000
997
1001
998
pSMB -> Remaining = 0 ;
1002
999
pSMB -> MaxCount = cpu_to_le16 (count & 0xFFFF );
@@ -1005,14 +1002,18 @@ CIFSSMBRead(const int xid, struct cifsTconInfo *tcon,
1005
1002
pSMB -> ByteCount = 0 ; /* no need to do le conversion since 0 */
1006
1003
else {
1007
1004
/* old style read */
1008
- struct smb_com_readx_req * pSMBW =
1005
+ struct smb_com_readx_req * pSMBW =
1009
1006
(struct smb_com_readx_req * )pSMB ;
1010
- pSMBW -> ByteCount = 0 ;
1007
+ pSMBW -> ByteCount = 0 ;
1011
1008
}
1012
-
1013
- rc = SendReceive (xid , tcon -> ses , (struct smb_hdr * ) pSMB ,
1014
- (struct smb_hdr * ) pSMBr , & bytes_returned , 0 );
1009
+
1010
+ iov [0 ].iov_base = (char * )pSMB ;
1011
+ iov [0 ].iov_len = pSMB -> hdr .smb_buf_length + 4 ;
1012
+ rc = SendReceive2 (xid , tcon -> ses , iov ,
1013
+ 1 /* num iovecs */ ,
1014
+ & resp_buf_type , 0 );
1015
1015
cifs_stats_inc (& tcon -> num_reads );
1016
+ pSMBr = (READ_RSP * )iov [0 ].iov_base ;
1016
1017
if (rc ) {
1017
1018
cERROR (1 , ("Send error in read = %d" , rc ));
1018
1019
} else {
@@ -1022,33 +1023,43 @@ CIFSSMBRead(const int xid, struct cifsTconInfo *tcon,
1022
1023
* nbytes = data_length ;
1023
1024
1024
1025
/*check that DataLength would not go beyond end of SMB */
1025
- if ((data_length > CIFSMaxBufSize )
1026
+ if ((data_length > CIFSMaxBufSize )
1026
1027
|| (data_length > count )) {
1027
1028
cFYI (1 ,("bad length %d for count %d" ,data_length ,count ));
1028
1029
rc = - EIO ;
1029
1030
* nbytes = 0 ;
1030
1031
} else {
1031
- pReadData =
1032
- (char * ) (& pSMBr -> hdr .Protocol ) +
1032
+ pReadData = (char * ) (& pSMBr -> hdr .Protocol ) +
1033
1033
le16_to_cpu (pSMBr -> DataOffset );
1034
- /* if(rc = copy_to_user(buf, pReadData, data_length)) {
1035
- cERROR(1,("Faulting on read rc = %d",rc));
1036
- rc = -EFAULT;
1037
- }*/ /* can not use copy_to_user when using page cache*/
1034
+ /* if(rc = copy_to_user(buf, pReadData, data_length)) {
1035
+ cERROR(1,("Faulting on read rc = %d",rc));
1036
+ rc = -EFAULT;
1037
+ }*/ /* can not use copy_to_user when using page cache*/
1038
1038
if (* buf )
1039
- memcpy (* buf ,pReadData ,data_length );
1039
+ memcpy (* buf ,pReadData ,data_length );
1040
1040
}
1041
1041
}
1042
- if (* buf )
1043
- cifs_buf_release (pSMB );
1044
- else
1045
- * buf = (char * )pSMB ;
1046
1042
1047
- /* Note: On -EAGAIN error only caller can retry on handle based calls
1043
+ cifs_small_buf_release (pSMB );
1044
+ if (* buf ) {
1045
+ if (resp_buf_type == CIFS_SMALL_BUFFER )
1046
+ cifs_small_buf_release (iov [0 ].iov_base );
1047
+ else if (resp_buf_type == CIFS_LARGE_BUFFER )
1048
+ cifs_buf_release (iov [0 ].iov_base );
1049
+ } else /* return buffer to caller to free */ /* BB FIXME how do we tell caller if it is not a large buffer */ {
1050
+ * buf = iov [0 ].iov_base ;
1051
+ if (resp_buf_type == CIFS_SMALL_BUFFER )
1052
+ * pbuf_type = CIFS_SMALL_BUFFER ;
1053
+ else if (resp_buf_type == CIFS_LARGE_BUFFER )
1054
+ * pbuf_type = CIFS_LARGE_BUFFER ;
1055
+ }
1056
+
1057
+ /* Note: On -EAGAIN error only caller can retry on handle based calls
1048
1058
since file handle passed in no longer valid */
1049
1059
return rc ;
1050
1060
}
1051
1061
1062
+
1052
1063
int
1053
1064
CIFSSMBWrite (const int xid , struct cifsTconInfo * tcon ,
1054
1065
const int netfid , const unsigned int count ,
@@ -1163,10 +1174,10 @@ CIFSSMBWrite2(const int xid, struct cifsTconInfo *tcon,
1163
1174
{
1164
1175
int rc = - EACCES ;
1165
1176
WRITE_REQ * pSMB = NULL ;
1166
- int bytes_returned , wct ;
1177
+ int wct ;
1167
1178
int smb_hdr_len ;
1179
+ int resp_buf_type = 0 ;
1168
1180
1169
- /* BB removeme BB */
1170
1181
cFYI (1 ,("write2 at %lld %d bytes" , (long long )offset , count ));
1171
1182
1172
1183
if (tcon -> ses -> capabilities & CAP_LARGE_FILES )
@@ -1209,22 +1220,34 @@ CIFSSMBWrite2(const int xid, struct cifsTconInfo *tcon,
1209
1220
pSMBW -> ByteCount = cpu_to_le16 (count + 5 );
1210
1221
}
1211
1222
iov [0 ].iov_base = pSMB ;
1212
- iov [0 ].iov_len = smb_hdr_len + 4 ;
1223
+ if (wct == 14 )
1224
+ iov [0 ].iov_len = smb_hdr_len + 4 ;
1225
+ else /* wct == 12 pad bigger by four bytes */
1226
+ iov [0 ].iov_len = smb_hdr_len + 8 ;
1227
+
1213
1228
1214
- rc = SendReceive2 (xid , tcon -> ses , iov , n_vec + 1 , & bytes_returned ,
1229
+ rc = SendReceive2 (xid , tcon -> ses , iov , n_vec + 1 , & resp_buf_type ,
1215
1230
long_op );
1216
1231
cifs_stats_inc (& tcon -> num_writes );
1217
1232
if (rc ) {
1218
1233
cFYI (1 , ("Send error Write2 = %d" , rc ));
1219
1234
* nbytes = 0 ;
1235
+ } else if (resp_buf_type == 0 ) {
1236
+ /* presumably this can not happen, but best to be safe */
1237
+ rc = - EIO ;
1238
+ * nbytes = 0 ;
1220
1239
} else {
1221
- WRITE_RSP * pSMBr = (WRITE_RSP * )pSMB ;
1240
+ WRITE_RSP * pSMBr = (WRITE_RSP * )iov [ 0 ]. iov_base ;
1222
1241
* nbytes = le16_to_cpu (pSMBr -> CountHigh );
1223
1242
* nbytes = (* nbytes ) << 16 ;
1224
1243
* nbytes += le16_to_cpu (pSMBr -> Count );
1225
1244
}
1226
1245
1227
1246
cifs_small_buf_release (pSMB );
1247
+ if (resp_buf_type == CIFS_SMALL_BUFFER )
1248
+ cifs_small_buf_release (iov [0 ].iov_base );
1249
+ else if (resp_buf_type == CIFS_LARGE_BUFFER )
1250
+ cifs_buf_release (iov [0 ].iov_base );
1228
1251
1229
1252
/* Note: On -EAGAIN error only caller can retry on handle based calls
1230
1253
since file handle passed in no longer valid */
0 commit comments