]> Git Repo - linux.git/commitdiff
rxrpc: Fix call expiry handling
authorDavid Howells <[email protected]>
Thu, 2 Nov 2017 15:06:26 +0000 (15:06 +0000)
committerDavid Howells <[email protected]>
Thu, 2 Nov 2017 15:20:43 +0000 (15:20 +0000)
Fix call expiry handling in the following ways

 (1) If all the request data from a client call is acked, don't send a
     follow up IDLE ACK with firstPacket == 1 and previousPacket == 0 as
     this appears to fool some servers into thinking everything has been
     accepted.

 (2) Never send an abort back to the server once it has ACK'd all the
     request packets; rather just try to reuse the channel for the next
     call.  The first request DATA packet of the next call on the same
     channel will implicitly ACK the entire reply of the dead call - even
     if we haven't transmitted it yet.

 (3) Don't send RX_CALL_TIMEOUT in an ABORT packet, librx uses abort codes
     to pass local errors to the caller in addition to remote errors, and
     this is meant to be local only.

The following also need to be addressed in future patches:

 (4) Service calls should send PING ACKs as 'keep alives' if the server is
     still processing the call.

 (5) VERSION REPLY packets should be sent to the peers of service
     connections to act as keep-alives.  This is used to keep firewall
     routes in place.  The AFS CM should enable this.

Signed-off-by: David Howells <[email protected]>
net/rxrpc/call_event.c
net/rxrpc/input.c
net/rxrpc/output.c

index 7a77844aab16be5f32a16b7edd3a7f440006c221..3574508baf9aa6d65dcf368e1b6de041a60ee933 100644 (file)
@@ -386,7 +386,7 @@ recheck_state:
 
        now = ktime_get_real();
        if (ktime_before(call->expire_at, now)) {
-               rxrpc_abort_call("EXP", call, 0, RX_CALL_TIMEOUT, -ETIME);
+               rxrpc_abort_call("EXP", call, 0, RX_USER_ABORT, -ETIME);
                set_bit(RXRPC_CALL_EV_ABORT, &call->events);
                goto recheck_state;
        }
index 1e37eb1c0c6600be7db2eed96176fc7393fd6e04..1b592073ec960bb5eaac103f8717711045e49b35 100644 (file)
@@ -298,8 +298,6 @@ static bool rxrpc_end_tx_phase(struct rxrpc_call *call, bool reply_begun,
 
        write_unlock(&call->state_lock);
        if (call->state == RXRPC_CALL_CLIENT_AWAIT_REPLY) {
-               rxrpc_propose_ACK(call, RXRPC_ACK_IDLE, 0, 0, false, true,
-                                 rxrpc_propose_ack_client_tx_end);
                trace_rxrpc_transmit(call, rxrpc_transmit_await_reply);
        } else {
                trace_rxrpc_transmit(call, rxrpc_transmit_end);
index 8ee8b2d4a3ebd36aab92e25703d4edc0576840c1..f47659c7b224ef910fcaa7f8c9271d449ae3eada 100644 (file)
@@ -222,6 +222,16 @@ int rxrpc_send_abort_packet(struct rxrpc_call *call)
        rxrpc_serial_t serial;
        int ret;
 
+       /* Don't bother sending aborts for a client call once the server has
+        * hard-ACK'd all of its request data.  After that point, we're not
+        * going to stop the operation proceeding, and whilst we might limit
+        * the reply, it's not worth it if we can send a new call on the same
+        * channel instead, thereby closing off this call.
+        */
+       if (rxrpc_is_client_call(call) &&
+           test_bit(RXRPC_CALL_TX_LAST, &call->flags))
+               return 0;
+
        spin_lock_bh(&call->lock);
        if (call->conn)
                conn = rxrpc_get_connection_maybe(call->conn);
This page took 0.061999 seconds and 4 git commands to generate.