aboutsummaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
authorJeff Layton <jlayton@redhat.com>2012-01-17 13:49:17 -0500
committerSteve French <smfrench@gmail.com>2012-01-17 23:39:34 -0500
commitf5fffcee27c09143ba80e5257dbd1f381d86342f (patch)
tree14471cf7b68f1845949c6f0bc3bd6852e38ca233 /fs
parent7250170c9ed00f3b74b11b98afefab45020672dd (diff)
cifs: better instrumentation for coalesce_t2
When coalesce_t2 returns an error, have it throw a cFYI message that explains the reason. Also rename some variables to clarify what they represent. Reported-and-Tested-by: Konstantinos Skarlatos <k.skarlatos@gmail.com> Signed-off-by: Jeff Layton <jlayton@redhat.com> Signed-off-by: Steve French <smfrench@gmail.com>
Diffstat (limited to 'fs')
-rw-r--r--fs/cifs/connect.c84
1 files changed, 50 insertions, 34 deletions
diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c
index 4666780f315d..5cc15856e4ad 100644
--- a/fs/cifs/connect.c
+++ b/fs/cifs/connect.c
@@ -225,74 +225,90 @@ static int check2ndT2(struct smb_hdr *pSMB)
225 225
226static int coalesce_t2(struct smb_hdr *psecond, struct smb_hdr *pTargetSMB) 226static int coalesce_t2(struct smb_hdr *psecond, struct smb_hdr *pTargetSMB)
227{ 227{
228 struct smb_t2_rsp *pSMB2 = (struct smb_t2_rsp *)psecond; 228 struct smb_t2_rsp *pSMBs = (struct smb_t2_rsp *)psecond;
229 struct smb_t2_rsp *pSMBt = (struct smb_t2_rsp *)pTargetSMB; 229 struct smb_t2_rsp *pSMBt = (struct smb_t2_rsp *)pTargetSMB;
230 char *data_area_of_target; 230 char *data_area_of_tgt;
231 char *data_area_of_buf2; 231 char *data_area_of_src;
232 int remaining; 232 int remaining;
233 unsigned int byte_count, total_in_buf; 233 unsigned int byte_count, total_in_tgt;
234 __u16 total_data_size, total_in_buf2; 234 __u16 tgt_total_cnt, src_total_cnt, total_in_src;
235 235
236 total_data_size = get_unaligned_le16(&pSMBt->t2_rsp.TotalDataCount); 236 src_total_cnt = get_unaligned_le16(&pSMBs->t2_rsp.TotalDataCount);
237 tgt_total_cnt = get_unaligned_le16(&pSMBt->t2_rsp.TotalDataCount);
237 238
238 if (total_data_size != 239 if (tgt_total_cnt != src_total_cnt)
239 get_unaligned_le16(&pSMB2->t2_rsp.TotalDataCount)) 240 cFYI(1, "total data count of primary and secondary t2 differ "
240 cFYI(1, "total data size of primary and secondary t2 differ"); 241 "source=%hu target=%hu", src_total_cnt, tgt_total_cnt);
241 242
242 total_in_buf = get_unaligned_le16(&pSMBt->t2_rsp.DataCount); 243 total_in_tgt = get_unaligned_le16(&pSMBt->t2_rsp.DataCount);
243 244
244 remaining = total_data_size - total_in_buf; 245 remaining = tgt_total_cnt - total_in_tgt;
245 246
246 if (remaining < 0) 247 if (remaining < 0) {
248 cFYI(1, "Server sent too much data. tgt_total_cnt=%hu "
249 "total_in_tgt=%hu", tgt_total_cnt, total_in_tgt);
247 return -EPROTO; 250 return -EPROTO;
251 }
248 252
249 if (remaining == 0) /* nothing to do, ignore */ 253 if (remaining == 0) {
254 /* nothing to do, ignore */
255 cFYI(1, "no more data remains");
250 return 0; 256 return 0;
257 }
251 258
252 total_in_buf2 = get_unaligned_le16(&pSMB2->t2_rsp.DataCount); 259 total_in_src = get_unaligned_le16(&pSMBs->t2_rsp.DataCount);
253 if (remaining < total_in_buf2) { 260 if (remaining < total_in_src)
254 cFYI(1, "transact2 2nd response contains too much data"); 261 cFYI(1, "transact2 2nd response contains too much data");
255 }
256 262
257 /* find end of first SMB data area */ 263 /* find end of first SMB data area */
258 data_area_of_target = (char *)&pSMBt->hdr.Protocol + 264 data_area_of_tgt = (char *)&pSMBt->hdr.Protocol +
259 get_unaligned_le16(&pSMBt->t2_rsp.DataOffset); 265 get_unaligned_le16(&pSMBt->t2_rsp.DataOffset);
260 /* validate target area */
261 266
262 data_area_of_buf2 = (char *)&pSMB2->hdr.Protocol + 267 /* validate target area */
263 get_unaligned_le16(&pSMB2->t2_rsp.DataOffset); 268 data_area_of_src = (char *)&pSMBs->hdr.Protocol +
269 get_unaligned_le16(&pSMBs->t2_rsp.DataOffset);
264 270
265 data_area_of_target += total_in_buf; 271 data_area_of_tgt += total_in_tgt;
266 272
267 /* copy second buffer into end of first buffer */ 273 total_in_tgt += total_in_src;
268 total_in_buf += total_in_buf2;
269 /* is the result too big for the field? */ 274 /* is the result too big for the field? */
270 if (total_in_buf > USHRT_MAX) 275 if (total_in_tgt > USHRT_MAX) {
276 cFYI(1, "coalesced DataCount too large (%u)", total_in_tgt);
271 return -EPROTO; 277 return -EPROTO;
272 put_unaligned_le16(total_in_buf, &pSMBt->t2_rsp.DataCount); 278 }
279 put_unaligned_le16(total_in_tgt, &pSMBt->t2_rsp.DataCount);
273 280
274 /* fix up the BCC */ 281 /* fix up the BCC */
275 byte_count = get_bcc(pTargetSMB); 282 byte_count = get_bcc(pTargetSMB);
276 byte_count += total_in_buf2; 283 byte_count += total_in_src;
277 /* is the result too big for the field? */ 284 /* is the result too big for the field? */
278 if (byte_count > USHRT_MAX) 285 if (byte_count > USHRT_MAX) {
286 cFYI(1, "coalesced BCC too large (%u)", byte_count);
279 return -EPROTO; 287 return -EPROTO;
288 }
280 put_bcc(byte_count, pTargetSMB); 289 put_bcc(byte_count, pTargetSMB);
281 290
282 byte_count = be32_to_cpu(pTargetSMB->smb_buf_length); 291 byte_count = be32_to_cpu(pTargetSMB->smb_buf_length);
283 byte_count += total_in_buf2; 292 byte_count += total_in_src;
284 /* don't allow buffer to overflow */ 293 /* don't allow buffer to overflow */
285 if (byte_count > CIFSMaxBufSize + MAX_CIFS_HDR_SIZE - 4) 294 if (byte_count > CIFSMaxBufSize + MAX_CIFS_HDR_SIZE - 4) {
295 cFYI(1, "coalesced BCC exceeds buffer size (%u)", byte_count);
286 return -ENOBUFS; 296 return -ENOBUFS;
297 }
287 pTargetSMB->smb_buf_length = cpu_to_be32(byte_count); 298 pTargetSMB->smb_buf_length = cpu_to_be32(byte_count);
288 299
289 memcpy(data_area_of_target, data_area_of_buf2, total_in_buf2); 300 /* copy second buffer into end of first buffer */
301 memcpy(data_area_of_tgt, data_area_of_src, total_in_src);
290 302
291 if (remaining == total_in_buf2) { 303 if (remaining != total_in_src) {
292 cFYI(1, "found the last secondary response"); 304 /* more responses to go */
293 return 0; /* we are done */ 305 cFYI(1, "waiting for more secondary responses");
294 } else /* more responses to go */
295 return 1; 306 return 1;
307 }
308
309 /* we are done */
310 cFYI(1, "found the last secondary response");
311 return 0;
296} 312}
297 313
298static void 314static void