diff options
Diffstat (limited to 'fs/afs/rxrpc.c')
-rw-r--r-- | fs/afs/rxrpc.c | 24 |
1 files changed, 17 insertions, 7 deletions
diff --git a/fs/afs/rxrpc.c b/fs/afs/rxrpc.c index 2c588f9bbbda..c14001b42d20 100644 --- a/fs/afs/rxrpc.c +++ b/fs/afs/rxrpc.c | |||
@@ -610,6 +610,7 @@ static long afs_wait_for_call_to_complete(struct afs_call *call, | |||
610 | bool stalled = false; | 610 | bool stalled = false; |
611 | u64 rtt; | 611 | u64 rtt; |
612 | u32 life, last_life; | 612 | u32 life, last_life; |
613 | bool rxrpc_complete = false; | ||
613 | 614 | ||
614 | DECLARE_WAITQUEUE(myself, current); | 615 | DECLARE_WAITQUEUE(myself, current); |
615 | 616 | ||
@@ -621,7 +622,7 @@ static long afs_wait_for_call_to_complete(struct afs_call *call, | |||
621 | rtt2 = 2; | 622 | rtt2 = 2; |
622 | 623 | ||
623 | timeout = rtt2; | 624 | timeout = rtt2; |
624 | last_life = rxrpc_kernel_check_life(call->net->socket, call->rxcall); | 625 | rxrpc_kernel_check_life(call->net->socket, call->rxcall, &last_life); |
625 | 626 | ||
626 | add_wait_queue(&call->waitq, &myself); | 627 | add_wait_queue(&call->waitq, &myself); |
627 | for (;;) { | 628 | for (;;) { |
@@ -639,7 +640,12 @@ static long afs_wait_for_call_to_complete(struct afs_call *call, | |||
639 | if (afs_check_call_state(call, AFS_CALL_COMPLETE)) | 640 | if (afs_check_call_state(call, AFS_CALL_COMPLETE)) |
640 | break; | 641 | break; |
641 | 642 | ||
642 | life = rxrpc_kernel_check_life(call->net->socket, call->rxcall); | 643 | if (!rxrpc_kernel_check_life(call->net->socket, call->rxcall, &life)) { |
644 | /* rxrpc terminated the call. */ | ||
645 | rxrpc_complete = true; | ||
646 | break; | ||
647 | } | ||
648 | |||
643 | if (timeout == 0 && | 649 | if (timeout == 0 && |
644 | life == last_life && signal_pending(current)) { | 650 | life == last_life && signal_pending(current)) { |
645 | if (stalled) | 651 | if (stalled) |
@@ -663,12 +669,16 @@ static long afs_wait_for_call_to_complete(struct afs_call *call, | |||
663 | remove_wait_queue(&call->waitq, &myself); | 669 | remove_wait_queue(&call->waitq, &myself); |
664 | __set_current_state(TASK_RUNNING); | 670 | __set_current_state(TASK_RUNNING); |
665 | 671 | ||
666 | /* Kill off the call if it's still live. */ | ||
667 | if (!afs_check_call_state(call, AFS_CALL_COMPLETE)) { | 672 | if (!afs_check_call_state(call, AFS_CALL_COMPLETE)) { |
668 | _debug("call interrupted"); | 673 | if (rxrpc_complete) { |
669 | if (rxrpc_kernel_abort_call(call->net->socket, call->rxcall, | 674 | afs_set_call_complete(call, call->error, call->abort_code); |
670 | RX_USER_ABORT, -EINTR, "KWI")) | 675 | } else { |
671 | afs_set_call_complete(call, -EINTR, 0); | 676 | /* Kill off the call if it's still live. */ |
677 | _debug("call interrupted"); | ||
678 | if (rxrpc_kernel_abort_call(call->net->socket, call->rxcall, | ||
679 | RX_USER_ABORT, -EINTR, "KWI")) | ||
680 | afs_set_call_complete(call, -EINTR, 0); | ||
681 | } | ||
672 | } | 682 | } |
673 | 683 | ||
674 | spin_lock_bh(&call->state_lock); | 684 | spin_lock_bh(&call->state_lock); |