diff options
-rw-r--r-- | fs/cifs/cifsglob.h | 3 | ||||
-rw-r--r-- | fs/cifs/connect.c | 31 |
2 files changed, 27 insertions, 7 deletions
diff --git a/fs/cifs/cifsglob.h b/fs/cifs/cifsglob.h index 322a12450ad3..8fc0801f8457 100644 --- a/fs/cifs/cifsglob.h +++ b/fs/cifs/cifsglob.h | |||
@@ -1,7 +1,7 @@ | |||
1 | /* | 1 | /* |
2 | * fs/cifs/cifsglob.h | 2 | * fs/cifs/cifsglob.h |
3 | * | 3 | * |
4 | * Copyright (C) International Business Machines Corp., 2002,2003 | 4 | * Copyright (C) International Business Machines Corp., 2002,2005 |
5 | * Author(s): Steve French (sfrench@us.ibm.com) | 5 | * Author(s): Steve French (sfrench@us.ibm.com) |
6 | * | 6 | * |
7 | * This library is free software; you can redistribute it and/or modify | 7 | * This library is free software; you can redistribute it and/or modify |
@@ -321,6 +321,7 @@ struct mid_q_entry { | |||
321 | __u8 command; /* smb command code */ | 321 | __u8 command; /* smb command code */ |
322 | unsigned multiPart:1; /* multiple responses to one SMB request */ | 322 | unsigned multiPart:1; /* multiple responses to one SMB request */ |
323 | unsigned largeBuf:1; /* if valid response, is pointer to large buf */ | 323 | unsigned largeBuf:1; /* if valid response, is pointer to large buf */ |
324 | unsigned multiResp:1 /* multiple trans2 responses for one request */ | ||
324 | }; | 325 | }; |
325 | 326 | ||
326 | struct oplock_q_entry { | 327 | struct oplock_q_entry { |
diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c index d5d49b584db4..8c5d310514ea 100644 --- a/fs/cifs/connect.c +++ b/fs/cifs/connect.c | |||
@@ -359,20 +359,36 @@ cifs_demultiplex_thread(struct TCP_Server_Info *server) | |||
359 | length = 0; | 359 | length = 0; |
360 | iov.iov_base = 4 + (char *)smb_buffer; | 360 | iov.iov_base = 4 + (char *)smb_buffer; |
361 | iov.iov_len = pdu_length; | 361 | iov.iov_len = pdu_length; |
362 | for (total_read = 0; | 362 | for (total_read = 0; |
363 | total_read < pdu_length; | 363 | total_read < pdu_length; |
364 | total_read += length) { | 364 | total_read += length) { |
365 | length = kernel_recvmsg(csocket, &smb_msg, | 365 | length = kernel_recvmsg(csocket, &smb_msg, |
366 | &iov, 1, | 366 | &iov, 1, |
367 | pdu_length - total_read, 0); | 367 | pdu_length - total_read, 0); |
368 | if (length == 0) { | 368 | if((server->tcpStatus == CifsExiting) || |
369 | (length == -EINTR)) { | ||
370 | /* then will exit */ | ||
371 | goto dmx_loop_end; | ||
372 | } else if (server->tcpStatus == | ||
373 | CifsNeedReconnect) { | ||
374 | cifs_reconnect(server); | ||
375 | csocket = server->ssocket; | ||
376 | /* Reconnect wakes up rspns q */ | ||
377 | /* Now we will reread sock */ | ||
378 | goto dmx_loop_end; | ||
379 | } else if ((length == -ERESTARTSYS) || | ||
380 | (length == -EAGAIN)) { | ||
381 | msleep(1); /* minimum sleep to prevent looping | ||
382 | allowing socket to clear and app threads to set | ||
383 | tcpStatus CifsNeedReconnect if server hung */ | ||
384 | continue; | ||
385 | } else if (length <= 0) { | ||
369 | cERROR(1, | 386 | cERROR(1, |
370 | ("Zero length receive when expecting %d ", | 387 | ("Received no data, expecting %d", |
371 | pdu_length - total_read)); | 388 | pdu_length - total_read)); |
372 | cifs_reconnect(server); | 389 | cifs_reconnect(server); |
373 | csocket = server->ssocket; | 390 | csocket = server->ssocket; |
374 | wake_up(&server->response_q); | 391 | goto dmx_loop_end; |
375 | continue; | ||
376 | } | 392 | } |
377 | } | 393 | } |
378 | length += 4; /* account for rfc1002 hdr */ | 394 | length += 4; /* account for rfc1002 hdr */ |
@@ -434,6 +450,9 @@ cifs_demultiplex_thread(struct TCP_Server_Info *server) | |||
434 | wake_up(&server->response_q); | 450 | wake_up(&server->response_q); |
435 | continue; | 451 | continue; |
436 | } | 452 | } |
453 | dmx_loop_end: | ||
454 | cFYI(1,("Exiting cifsd loop")); | ||
455 | |||
437 | } | 456 | } |
438 | spin_lock(&GlobalMid_Lock); | 457 | spin_lock(&GlobalMid_Lock); |
439 | server->tcpStatus = CifsExiting; | 458 | server->tcpStatus = CifsExiting; |