diff options
| -rw-r--r-- | fs/afs/rxrpc.c | 35 |
1 files changed, 27 insertions, 8 deletions
diff --git a/fs/afs/rxrpc.c b/fs/afs/rxrpc.c index bf7761fe6ef5..22d26b369070 100644 --- a/fs/afs/rxrpc.c +++ b/fs/afs/rxrpc.c | |||
| @@ -340,6 +340,8 @@ int afs_make_call(struct in_addr *addr, struct afs_call *call, gfp_t gfp, | |||
| 340 | struct rxrpc_call *rxcall; | 340 | struct rxrpc_call *rxcall; |
| 341 | struct msghdr msg; | 341 | struct msghdr msg; |
| 342 | struct kvec iov[1]; | 342 | struct kvec iov[1]; |
| 343 | size_t offset; | ||
| 344 | u32 abort_code; | ||
| 343 | int ret; | 345 | int ret; |
| 344 | 346 | ||
| 345 | _enter("%x,{%d},", addr->s_addr, ntohs(call->port)); | 347 | _enter("%x,{%d},", addr->s_addr, ntohs(call->port)); |
| @@ -388,9 +390,11 @@ int afs_make_call(struct in_addr *addr, struct afs_call *call, gfp_t gfp, | |||
| 388 | msg.msg_controllen = 0; | 390 | msg.msg_controllen = 0; |
| 389 | msg.msg_flags = (call->send_pages ? MSG_MORE : 0); | 391 | msg.msg_flags = (call->send_pages ? MSG_MORE : 0); |
| 390 | 392 | ||
| 391 | /* have to change the state *before* sending the last packet as RxRPC | 393 | /* We have to change the state *before* sending the last packet as |
| 392 | * might give us the reply before it returns from sending the | 394 | * rxrpc might give us the reply before it returns from sending the |
| 393 | * request */ | 395 | * request. Further, if the send fails, we may already have been given |
| 396 | * a notification and may have collected it. | ||
| 397 | */ | ||
| 394 | if (!call->send_pages) | 398 | if (!call->send_pages) |
| 395 | call->state = AFS_CALL_AWAIT_REPLY; | 399 | call->state = AFS_CALL_AWAIT_REPLY; |
| 396 | ret = rxrpc_kernel_send_data(afs_socket, rxcall, | 400 | ret = rxrpc_kernel_send_data(afs_socket, rxcall, |
| @@ -412,7 +416,17 @@ int afs_make_call(struct in_addr *addr, struct afs_call *call, gfp_t gfp, | |||
| 412 | return afs_wait_for_call_to_complete(call); | 416 | return afs_wait_for_call_to_complete(call); |
| 413 | 417 | ||
| 414 | error_do_abort: | 418 | error_do_abort: |
| 415 | rxrpc_kernel_abort_call(afs_socket, rxcall, RX_USER_ABORT, -ret, "KSD"); | 419 | call->state = AFS_CALL_COMPLETE; |
| 420 | if (ret != -ECONNABORTED) { | ||
| 421 | rxrpc_kernel_abort_call(afs_socket, rxcall, RX_USER_ABORT, | ||
| 422 | -ret, "KSD"); | ||
| 423 | } else { | ||
| 424 | abort_code = 0; | ||
| 425 | offset = 0; | ||
| 426 | rxrpc_kernel_recv_data(afs_socket, rxcall, NULL, 0, &offset, | ||
| 427 | false, &abort_code); | ||
| 428 | ret = call->type->abort_to_error(abort_code); | ||
| 429 | } | ||
| 416 | error_kill_call: | 430 | error_kill_call: |
| 417 | afs_put_call(call); | 431 | afs_put_call(call); |
| 418 | _leave(" = %d", ret); | 432 | _leave(" = %d", ret); |
| @@ -459,16 +473,18 @@ static void afs_deliver_to_call(struct afs_call *call) | |||
| 459 | case -EINPROGRESS: | 473 | case -EINPROGRESS: |
| 460 | case -EAGAIN: | 474 | case -EAGAIN: |
| 461 | goto out; | 475 | goto out; |
| 476 | case -ECONNABORTED: | ||
| 477 | goto call_complete; | ||
| 462 | case -ENOTCONN: | 478 | case -ENOTCONN: |
| 463 | abort_code = RX_CALL_DEAD; | 479 | abort_code = RX_CALL_DEAD; |
| 464 | rxrpc_kernel_abort_call(afs_socket, call->rxcall, | 480 | rxrpc_kernel_abort_call(afs_socket, call->rxcall, |
| 465 | abort_code, -ret, "KNC"); | 481 | abort_code, -ret, "KNC"); |
| 466 | goto do_abort; | 482 | goto save_error; |
| 467 | case -ENOTSUPP: | 483 | case -ENOTSUPP: |
| 468 | abort_code = RXGEN_OPCODE; | 484 | abort_code = RXGEN_OPCODE; |
| 469 | rxrpc_kernel_abort_call(afs_socket, call->rxcall, | 485 | rxrpc_kernel_abort_call(afs_socket, call->rxcall, |
| 470 | abort_code, -ret, "KIV"); | 486 | abort_code, -ret, "KIV"); |
| 471 | goto do_abort; | 487 | goto save_error; |
| 472 | case -ENODATA: | 488 | case -ENODATA: |
| 473 | case -EBADMSG: | 489 | case -EBADMSG: |
| 474 | case -EMSGSIZE: | 490 | case -EMSGSIZE: |
| @@ -478,7 +494,7 @@ static void afs_deliver_to_call(struct afs_call *call) | |||
| 478 | abort_code = RXGEN_SS_UNMARSHAL; | 494 | abort_code = RXGEN_SS_UNMARSHAL; |
| 479 | rxrpc_kernel_abort_call(afs_socket, call->rxcall, | 495 | rxrpc_kernel_abort_call(afs_socket, call->rxcall, |
| 480 | abort_code, EBADMSG, "KUM"); | 496 | abort_code, EBADMSG, "KUM"); |
| 481 | goto do_abort; | 497 | goto save_error; |
| 482 | } | 498 | } |
| 483 | } | 499 | } |
| 484 | 500 | ||
| @@ -489,8 +505,9 @@ out: | |||
| 489 | _leave(""); | 505 | _leave(""); |
| 490 | return; | 506 | return; |
| 491 | 507 | ||
| 492 | do_abort: | 508 | save_error: |
| 493 | call->error = ret; | 509 | call->error = ret; |
| 510 | call_complete: | ||
| 494 | call->state = AFS_CALL_COMPLETE; | 511 | call->state = AFS_CALL_COMPLETE; |
| 495 | goto done; | 512 | goto done; |
| 496 | } | 513 | } |
| @@ -538,6 +555,8 @@ static int afs_wait_for_call_to_complete(struct afs_call *call) | |||
| 538 | _debug("call incomplete"); | 555 | _debug("call incomplete"); |
| 539 | rxrpc_kernel_abort_call(afs_socket, call->rxcall, | 556 | rxrpc_kernel_abort_call(afs_socket, call->rxcall, |
| 540 | RX_CALL_DEAD, -ret, abort_why); | 557 | RX_CALL_DEAD, -ret, abort_why); |
| 558 | } else if (call->error < 0) { | ||
| 559 | ret = call->error; | ||
| 541 | } | 560 | } |
| 542 | 561 | ||
| 543 | _debug("call complete"); | 562 | _debug("call complete"); |
