aboutsummaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
authorJeff Layton <jlayton@redhat.com>2010-09-03 12:00:49 -0400
committerSteve French <sfrench@us.ibm.com>2010-09-08 17:22:33 -0400
commit7332f2a6217ee6925f83ef0e725013067ed316ba (patch)
tree481c0774aa1620f9e3f20e2809307d9047dd7324 /fs
parent522bbe65a2415fabce618186fc7777eb4c502989 (diff)
cifs: eliminate some more premature cifsd exits
If the tcpStatus is still CifsNew, the main cifs_demultiplex_loop can break out prematurely in some cases. This is wrong as we will almost always have other structures with pointers to the TCP_Server_Info. If the main loop breaks under any other condition other than tcpStatus == CifsExiting, then it'll face a use-after-free situation. I don't see any reason to treat a CifsNew tcpStatus differently than CifsGood. I believe we'll still want to attempt to reconnect in either case. What should happen in those situations is that the MIDs get marked as MID_RETRY_NEEDED. This will make CIFSSMBNegotiate return -EAGAIN, and then the caller can retry the whole thing on a newly reconnected socket. If that fails again in the same way, the caller of cifs_get_smb_ses should tear down the TCP_Server_Info struct. Signed-off-by: Jeff Layton <jlayton@redhat.com> Signed-off-by: Steve French <sfrench@us.ibm.com>
Diffstat (limited to 'fs')
-rw-r--r--fs/cifs/connect.c41
1 files changed, 12 insertions, 29 deletions
diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c
index 5f68b968faa7..5fde83f0c75e 100644
--- a/fs/cifs/connect.c
+++ b/fs/cifs/connect.c
@@ -416,14 +416,6 @@ incomplete_rcv:
416 } else 416 } else
417 continue; 417 continue;
418 } else if (length <= 0) { 418 } else if (length <= 0) {
419 if (server->tcpStatus == CifsNew) {
420 cFYI(1, "tcp session abend after SMBnegprot");
421 /* some servers kill the TCP session rather than
422 returning an SMB negprot error, in which
423 case reconnecting here is not going to help,
424 and so simply return error to mount */
425 break;
426 }
427 cFYI(1, "Reconnect after unexpected peek error %d", 419 cFYI(1, "Reconnect after unexpected peek error %d",
428 length); 420 length);
429 cifs_reconnect(server); 421 cifs_reconnect(server);
@@ -464,27 +456,18 @@ incomplete_rcv:
464 an error on SMB negprot response */ 456 an error on SMB negprot response */
465 cFYI(1, "Negative RFC1002 Session Response Error 0x%x)", 457 cFYI(1, "Negative RFC1002 Session Response Error 0x%x)",
466 pdu_length); 458 pdu_length);
467 if (server->tcpStatus == CifsNew) { 459 /* give server a second to clean up */
468 /* if nack on negprot (rather than 460 msleep(1000);
469 ret of smb negprot error) reconnecting 461 /* always try 445 first on reconnect since we get NACK
470 not going to help, ret error to mount */ 462 * on some if we ever connected to port 139 (the NACK
471 break; 463 * is since we do not begin with RFC1001 session
472 } else { 464 * initialize frame)
473 /* give server a second to 465 */
474 clean up before reconnect attempt */ 466 server->addr.sockAddr.sin_port = htons(CIFS_PORT);
475 msleep(1000); 467 cifs_reconnect(server);
476 /* always try 445 first on reconnect 468 csocket = server->ssocket;
477 since we get NACK on some if we ever 469 wake_up(&server->response_q);
478 connected to port 139 (the NACK is 470 continue;
479 since we do not begin with RFC1001
480 session initialize frame) */
481 server->addr.sockAddr.sin_port =
482 htons(CIFS_PORT);
483 cifs_reconnect(server);
484 csocket = server->ssocket;
485 wake_up(&server->response_q);
486 continue;
487 }
488 } else if (temp != (char) 0) { 471 } else if (temp != (char) 0) {
489 cERROR(1, "Unknown RFC 1002 frame"); 472 cERROR(1, "Unknown RFC 1002 frame");
490 cifs_dump_mem(" Received Data: ", (char *)smb_buffer, 473 cifs_dump_mem(" Received Data: ", (char *)smb_buffer,