aboutsummaryrefslogtreecommitdiffstats
path: root/fs/cifs
diff options
context:
space:
mode:
authorPavel Shilovsky <piastryyy@gmail.com>2011-08-01 05:19:40 -0400
committerSteve French <sfrench@us.ibm.com>2011-08-01 08:33:44 -0400
commit3d9c2472a53ee1d26de9803899037aeeb44ccef1 (patch)
tree71d65fc36988d56aff29e59ec61651faa5d65252 /fs/cifs
parentc4a5534a1b61cdffaa83187efe63712f75544726 (diff)
CIFS: Move buffer allocation to a separate function
Reviewed-and-Tested-by: Jeff Layton <jlayton@redhat.com> Signed-off-by: Pavel Shilovsky <piastryyy@gmail.com> Signed-off-by: Steve French <sfrench@us.ibm.com>
Diffstat (limited to 'fs/cifs')
-rw-r--r--fs/cifs/connect.c92
1 files changed, 55 insertions, 37 deletions
diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c
index 50b3523912ff..217d36587185 100644
--- a/fs/cifs/connect.c
+++ b/fs/cifs/connect.c
@@ -319,15 +319,53 @@ requeue_echo:
319 queue_delayed_work(system_nrt_wq, &server->echo, SMB_ECHO_INTERVAL); 319 queue_delayed_work(system_nrt_wq, &server->echo, SMB_ECHO_INTERVAL);
320} 320}
321 321
322static bool
323allocate_buffers(char **bigbuf, char **smallbuf, unsigned int size,
324 bool is_large_buf)
325{
326 char *bbuf = *bigbuf, *sbuf = *smallbuf;
327
328 if (bbuf == NULL) {
329 bbuf = (char *)cifs_buf_get();
330 if (!bbuf) {
331 cERROR(1, "No memory for large SMB response");
332 msleep(3000);
333 /* retry will check if exiting */
334 return false;
335 }
336 } else if (is_large_buf) {
337 /* we are reusing a dirty large buf, clear its start */
338 memset(bbuf, 0, size);
339 }
340
341 if (sbuf == NULL) {
342 sbuf = (char *)cifs_small_buf_get();
343 if (!sbuf) {
344 cERROR(1, "No memory for SMB response");
345 msleep(1000);
346 /* retry will check if exiting */
347 return false;
348 }
349 /* beginning of smb buffer is cleared in our buf_get */
350 } else {
351 /* if existing small buf clear beginning */
352 memset(sbuf, 0, size);
353 }
354
355 *bigbuf = bbuf;
356 *smallbuf = sbuf;
357
358 return true;
359}
360
322static int 361static int
323cifs_demultiplex_thread(void *p) 362cifs_demultiplex_thread(void *p)
324{ 363{
325 int length; 364 int length;
326 struct TCP_Server_Info *server = p; 365 struct TCP_Server_Info *server = p;
327 unsigned int pdu_length, total_read; 366 unsigned int pdu_length, total_read;
367 char *buf = NULL, *bigbuf = NULL, *smallbuf = NULL;
328 struct smb_hdr *smb_buffer = NULL; 368 struct smb_hdr *smb_buffer = NULL;
329 struct smb_hdr *bigbuf = NULL;
330 struct smb_hdr *smallbuf = NULL;
331 struct msghdr smb_msg; 369 struct msghdr smb_msg;
332 struct kvec iov; 370 struct kvec iov;
333 struct socket *csocket = server->ssocket; 371 struct socket *csocket = server->ssocket;
@@ -351,35 +389,16 @@ cifs_demultiplex_thread(void *p)
351 while (server->tcpStatus != CifsExiting) { 389 while (server->tcpStatus != CifsExiting) {
352 if (try_to_freeze()) 390 if (try_to_freeze())
353 continue; 391 continue;
354 if (bigbuf == NULL) {
355 bigbuf = cifs_buf_get();
356 if (!bigbuf) {
357 cERROR(1, "No memory for large SMB response");
358 msleep(3000);
359 /* retry will check if exiting */
360 continue;
361 }
362 } else if (isLargeBuf) {
363 /* we are reusing a dirty large buf, clear its start */
364 memset(bigbuf, 0, sizeof(struct smb_hdr));
365 }
366 392
367 if (smallbuf == NULL) { 393 if (!allocate_buffers(&bigbuf, &smallbuf,
368 smallbuf = cifs_small_buf_get(); 394 sizeof(struct smb_hdr), isLargeBuf))
369 if (!smallbuf) { 395 continue;
370 cERROR(1, "No memory for SMB response");
371 msleep(1000);
372 /* retry will check if exiting */
373 continue;
374 }
375 /* beginning of smb buffer is cleared in our buf_get */
376 } else /* if existing small buf clear beginning */
377 memset(smallbuf, 0, sizeof(struct smb_hdr));
378 396
379 isLargeBuf = false; 397 isLargeBuf = false;
380 isMultiRsp = false; 398 isMultiRsp = false;
381 smb_buffer = smallbuf; 399 smb_buffer = (struct smb_hdr *)smallbuf;
382 iov.iov_base = smb_buffer; 400 buf = smallbuf;
401 iov.iov_base = buf;
383 iov.iov_len = 4; 402 iov.iov_len = 4;
384 smb_msg.msg_control = NULL; 403 smb_msg.msg_control = NULL;
385 smb_msg.msg_controllen = 0; 404 smb_msg.msg_controllen = 0;
@@ -417,8 +436,7 @@ incomplete_rcv:
417 allowing socket to clear and app threads to set 436 allowing socket to clear and app threads to set
418 tcpStatus CifsNeedReconnect if server hung */ 437 tcpStatus CifsNeedReconnect if server hung */
419 if (pdu_length < 4) { 438 if (pdu_length < 4) {
420 iov.iov_base = (4 - pdu_length) + 439 iov.iov_base = (4 - pdu_length) + buf;
421 (char *)smb_buffer;
422 iov.iov_len = pdu_length; 440 iov.iov_len = pdu_length;
423 smb_msg.msg_control = NULL; 441 smb_msg.msg_control = NULL;
424 smb_msg.msg_controllen = 0; 442 smb_msg.msg_controllen = 0;
@@ -446,7 +464,7 @@ incomplete_rcv:
446 /* the first byte big endian of the length field, 464 /* the first byte big endian of the length field,
447 is actually not part of the length but the type 465 is actually not part of the length but the type
448 with the most common, zero, as regular data */ 466 with the most common, zero, as regular data */
449 temp = *((char *) smb_buffer); 467 temp = *buf;
450 468
451 /* Note that FC 1001 length is big endian on the wire, 469 /* Note that FC 1001 length is big endian on the wire,
452 but we convert it here so it is always manipulated 470 but we convert it here so it is always manipulated
@@ -480,8 +498,7 @@ incomplete_rcv:
480 continue; 498 continue;
481 } else if (temp != (char) 0) { 499 } else if (temp != (char) 0) {
482 cERROR(1, "Unknown RFC 1002 frame"); 500 cERROR(1, "Unknown RFC 1002 frame");
483 cifs_dump_mem(" Received Data: ", (char *)smb_buffer, 501 cifs_dump_mem(" Received Data: ", buf, length);
484 length);
485 cifs_reconnect(server); 502 cifs_reconnect(server);
486 csocket = server->ssocket; 503 csocket = server->ssocket;
487 continue; 504 continue;
@@ -504,10 +521,11 @@ incomplete_rcv:
504 if (pdu_length > MAX_CIFS_SMALL_BUFFER_SIZE - 4) { 521 if (pdu_length > MAX_CIFS_SMALL_BUFFER_SIZE - 4) {
505 isLargeBuf = true; 522 isLargeBuf = true;
506 memcpy(bigbuf, smallbuf, 4); 523 memcpy(bigbuf, smallbuf, 4);
507 smb_buffer = bigbuf; 524 smb_buffer = (struct smb_hdr *)bigbuf;
525 buf = bigbuf;
508 } 526 }
509 length = 0; 527 length = 0;
510 iov.iov_base = 4 + (char *)smb_buffer; 528 iov.iov_base = 4 + buf;
511 iov.iov_len = pdu_length; 529 iov.iov_len = pdu_length;
512 for (total_read = 0; total_read < pdu_length; 530 for (total_read = 0; total_read < pdu_length;
513 total_read += length) { 531 total_read += length) {
@@ -562,8 +580,8 @@ incomplete_rcv:
562 */ 580 */
563 length = checkSMB(smb_buffer, smb_buffer->Mid, total_read); 581 length = checkSMB(smb_buffer, smb_buffer->Mid, total_read);
564 if (length != 0) 582 if (length != 0)
565 cifs_dump_mem("Bad SMB: ", smb_buffer, 583 cifs_dump_mem("Bad SMB: ", buf,
566 min_t(unsigned int, total_read, 48)); 584 min_t(unsigned int, total_read, 48));
567 585
568 mid_entry = NULL; 586 mid_entry = NULL;
569 server->lstrp = jiffies; 587 server->lstrp = jiffies;
@@ -648,7 +666,7 @@ multi_t2_fnd:
648 !isMultiRsp) { 666 !isMultiRsp) {
649 cERROR(1, "No task to wake, unknown frame received! " 667 cERROR(1, "No task to wake, unknown frame received! "
650 "NumMids %d", atomic_read(&midCount)); 668 "NumMids %d", atomic_read(&midCount));
651 cifs_dump_mem("Received Data is: ", (char *)smb_buffer, 669 cifs_dump_mem("Received Data is: ", buf,
652 sizeof(struct smb_hdr)); 670 sizeof(struct smb_hdr));
653#ifdef CONFIG_CIFS_DEBUG2 671#ifdef CONFIG_CIFS_DEBUG2
654 cifs_dump_detail(smb_buffer); 672 cifs_dump_detail(smb_buffer);