diff options
-rw-r--r-- | net/rxrpc/call_accept.c | 2 | ||||
-rw-r--r-- | net/rxrpc/call_event.c | 14 | ||||
-rw-r--r-- | net/rxrpc/call_object.c | 46 | ||||
-rw-r--r-- | net/rxrpc/conn_client.c | 29 | ||||
-rw-r--r-- | net/rxrpc/input.c | 6 | ||||
-rw-r--r-- | net/rxrpc/output.c | 7 | ||||
-rw-r--r-- | net/rxrpc/recvmsg.c | 53 | ||||
-rw-r--r-- | net/rxrpc/sendmsg.c | 2 |
8 files changed, 89 insertions, 70 deletions
diff --git a/net/rxrpc/call_accept.c b/net/rxrpc/call_accept.c index 26c293ef98eb..323b8da50163 100644 --- a/net/rxrpc/call_accept.c +++ b/net/rxrpc/call_accept.c | |||
@@ -369,6 +369,8 @@ found_service: | |||
369 | 369 | ||
370 | if (rx->notify_new_call) | 370 | if (rx->notify_new_call) |
371 | rx->notify_new_call(&rx->sk, call, call->user_call_ID); | 371 | rx->notify_new_call(&rx->sk, call, call->user_call_ID); |
372 | else | ||
373 | sk_acceptq_added(&rx->sk); | ||
372 | 374 | ||
373 | spin_lock(&conn->state_lock); | 375 | spin_lock(&conn->state_lock); |
374 | switch (conn->state) { | 376 | switch (conn->state) { |
diff --git a/net/rxrpc/call_event.c b/net/rxrpc/call_event.c index 61432049869b..f0cabc48a1b7 100644 --- a/net/rxrpc/call_event.c +++ b/net/rxrpc/call_event.c | |||
@@ -31,7 +31,7 @@ static void rxrpc_set_timer(struct rxrpc_call *call) | |||
31 | _enter("{%ld,%ld,%ld:%ld}", | 31 | _enter("{%ld,%ld,%ld:%ld}", |
32 | call->ack_at - now, call->resend_at - now, call->expire_at - now, | 32 | call->ack_at - now, call->resend_at - now, call->expire_at - now, |
33 | call->timer.expires - now); | 33 | call->timer.expires - now); |
34 | 34 | ||
35 | read_lock_bh(&call->state_lock); | 35 | read_lock_bh(&call->state_lock); |
36 | 36 | ||
37 | if (call->state < RXRPC_CALL_COMPLETE) { | 37 | if (call->state < RXRPC_CALL_COMPLETE) { |
@@ -163,8 +163,7 @@ static void rxrpc_resend(struct rxrpc_call *call) | |||
163 | */ | 163 | */ |
164 | now = jiffies; | 164 | now = jiffies; |
165 | resend_at = now + rxrpc_resend_timeout; | 165 | resend_at = now + rxrpc_resend_timeout; |
166 | seq = cursor + 1; | 166 | for (seq = cursor + 1; before_eq(seq, top); seq++) { |
167 | do { | ||
168 | ix = seq & RXRPC_RXTX_BUFF_MASK; | 167 | ix = seq & RXRPC_RXTX_BUFF_MASK; |
169 | annotation = call->rxtx_annotations[ix]; | 168 | annotation = call->rxtx_annotations[ix]; |
170 | if (annotation == RXRPC_TX_ANNO_ACK) | 169 | if (annotation == RXRPC_TX_ANNO_ACK) |
@@ -184,8 +183,7 @@ static void rxrpc_resend(struct rxrpc_call *call) | |||
184 | 183 | ||
185 | /* Okay, we need to retransmit a packet. */ | 184 | /* Okay, we need to retransmit a packet. */ |
186 | call->rxtx_annotations[ix] = RXRPC_TX_ANNO_RETRANS; | 185 | call->rxtx_annotations[ix] = RXRPC_TX_ANNO_RETRANS; |
187 | seq++; | 186 | } |
188 | } while (before_eq(seq, top)); | ||
189 | 187 | ||
190 | call->resend_at = resend_at; | 188 | call->resend_at = resend_at; |
191 | 189 | ||
@@ -194,8 +192,7 @@ static void rxrpc_resend(struct rxrpc_call *call) | |||
194 | * lock is dropped, it may clear some of the retransmission markers for | 192 | * lock is dropped, it may clear some of the retransmission markers for |
195 | * packets that it soft-ACKs. | 193 | * packets that it soft-ACKs. |
196 | */ | 194 | */ |
197 | seq = cursor + 1; | 195 | for (seq = cursor + 1; before_eq(seq, top); seq++) { |
198 | do { | ||
199 | ix = seq & RXRPC_RXTX_BUFF_MASK; | 196 | ix = seq & RXRPC_RXTX_BUFF_MASK; |
200 | annotation = call->rxtx_annotations[ix]; | 197 | annotation = call->rxtx_annotations[ix]; |
201 | if (annotation != RXRPC_TX_ANNO_RETRANS) | 198 | if (annotation != RXRPC_TX_ANNO_RETRANS) |
@@ -237,8 +234,7 @@ static void rxrpc_resend(struct rxrpc_call *call) | |||
237 | 234 | ||
238 | if (after(call->tx_hard_ack, seq)) | 235 | if (after(call->tx_hard_ack, seq)) |
239 | seq = call->tx_hard_ack; | 236 | seq = call->tx_hard_ack; |
240 | seq++; | 237 | } |
241 | } while (before_eq(seq, top)); | ||
242 | 238 | ||
243 | out_unlock: | 239 | out_unlock: |
244 | spin_unlock_bh(&call->lock); | 240 | spin_unlock_bh(&call->lock); |
diff --git a/net/rxrpc/call_object.c b/net/rxrpc/call_object.c index 22f9b0d1a138..23f5a5f58282 100644 --- a/net/rxrpc/call_object.c +++ b/net/rxrpc/call_object.c | |||
@@ -226,9 +226,6 @@ struct rxrpc_call *rxrpc_new_client_call(struct rxrpc_sock *rx, | |||
226 | (const void *)user_call_ID); | 226 | (const void *)user_call_ID); |
227 | 227 | ||
228 | /* Publish the call, even though it is incompletely set up as yet */ | 228 | /* Publish the call, even though it is incompletely set up as yet */ |
229 | call->user_call_ID = user_call_ID; | ||
230 | __set_bit(RXRPC_CALL_HAS_USERID, &call->flags); | ||
231 | |||
232 | write_lock(&rx->call_lock); | 229 | write_lock(&rx->call_lock); |
233 | 230 | ||
234 | pp = &rx->calls.rb_node; | 231 | pp = &rx->calls.rb_node; |
@@ -242,10 +239,12 @@ struct rxrpc_call *rxrpc_new_client_call(struct rxrpc_sock *rx, | |||
242 | else if (user_call_ID > xcall->user_call_ID) | 239 | else if (user_call_ID > xcall->user_call_ID) |
243 | pp = &(*pp)->rb_right; | 240 | pp = &(*pp)->rb_right; |
244 | else | 241 | else |
245 | goto found_user_ID_now_present; | 242 | goto error_dup_user_ID; |
246 | } | 243 | } |
247 | 244 | ||
248 | rcu_assign_pointer(call->socket, rx); | 245 | rcu_assign_pointer(call->socket, rx); |
246 | call->user_call_ID = user_call_ID; | ||
247 | __set_bit(RXRPC_CALL_HAS_USERID, &call->flags); | ||
249 | rxrpc_get_call(call, rxrpc_call_got_userid); | 248 | rxrpc_get_call(call, rxrpc_call_got_userid); |
250 | rb_link_node(&call->sock_node, parent, pp); | 249 | rb_link_node(&call->sock_node, parent, pp); |
251 | rb_insert_color(&call->sock_node, &rx->calls); | 250 | rb_insert_color(&call->sock_node, &rx->calls); |
@@ -276,33 +275,22 @@ struct rxrpc_call *rxrpc_new_client_call(struct rxrpc_sock *rx, | |||
276 | _leave(" = %p [new]", call); | 275 | _leave(" = %p [new]", call); |
277 | return call; | 276 | return call; |
278 | 277 | ||
279 | error: | ||
280 | write_lock(&rx->call_lock); | ||
281 | rb_erase(&call->sock_node, &rx->calls); | ||
282 | write_unlock(&rx->call_lock); | ||
283 | rxrpc_put_call(call, rxrpc_call_put_userid); | ||
284 | |||
285 | write_lock(&rxrpc_call_lock); | ||
286 | list_del_init(&call->link); | ||
287 | write_unlock(&rxrpc_call_lock); | ||
288 | |||
289 | error_out: | ||
290 | __rxrpc_set_call_completion(call, RXRPC_CALL_LOCAL_ERROR, | ||
291 | RX_CALL_DEAD, ret); | ||
292 | set_bit(RXRPC_CALL_RELEASED, &call->flags); | ||
293 | rxrpc_put_call(call, rxrpc_call_put); | ||
294 | _leave(" = %d", ret); | ||
295 | return ERR_PTR(ret); | ||
296 | |||
297 | /* We unexpectedly found the user ID in the list after taking | 278 | /* We unexpectedly found the user ID in the list after taking |
298 | * the call_lock. This shouldn't happen unless the user races | 279 | * the call_lock. This shouldn't happen unless the user races |
299 | * with itself and tries to add the same user ID twice at the | 280 | * with itself and tries to add the same user ID twice at the |
300 | * same time in different threads. | 281 | * same time in different threads. |
301 | */ | 282 | */ |
302 | found_user_ID_now_present: | 283 | error_dup_user_ID: |
303 | write_unlock(&rx->call_lock); | 284 | write_unlock(&rx->call_lock); |
304 | ret = -EEXIST; | 285 | ret = -EEXIST; |
305 | goto error_out; | 286 | |
287 | error: | ||
288 | __rxrpc_set_call_completion(call, RXRPC_CALL_LOCAL_ERROR, | ||
289 | RX_CALL_DEAD, ret); | ||
290 | rxrpc_release_call(rx, call); | ||
291 | rxrpc_put_call(call, rxrpc_call_put); | ||
292 | _leave(" = %d", ret); | ||
293 | return ERR_PTR(ret); | ||
306 | } | 294 | } |
307 | 295 | ||
308 | /* | 296 | /* |
@@ -476,6 +464,16 @@ void rxrpc_release_calls_on_socket(struct rxrpc_sock *rx) | |||
476 | 464 | ||
477 | _enter("%p", rx); | 465 | _enter("%p", rx); |
478 | 466 | ||
467 | while (!list_empty(&rx->to_be_accepted)) { | ||
468 | call = list_entry(rx->to_be_accepted.next, | ||
469 | struct rxrpc_call, accept_link); | ||
470 | list_del(&call->accept_link); | ||
471 | rxrpc_abort_call("SKR", call, 0, RX_CALL_DEAD, ECONNRESET); | ||
472 | rxrpc_send_call_packet(call, RXRPC_PACKET_TYPE_ABORT); | ||
473 | rxrpc_release_call(rx, call); | ||
474 | rxrpc_put_call(call, rxrpc_call_put); | ||
475 | } | ||
476 | |||
479 | while (!list_empty(&rx->sock_calls)) { | 477 | while (!list_empty(&rx->sock_calls)) { |
480 | call = list_entry(rx->sock_calls.next, | 478 | call = list_entry(rx->sock_calls.next, |
481 | struct rxrpc_call, sock_link); | 479 | struct rxrpc_call, sock_link); |
diff --git a/net/rxrpc/conn_client.c b/net/rxrpc/conn_client.c index 9344a8416ceb..226bc910e556 100644 --- a/net/rxrpc/conn_client.c +++ b/net/rxrpc/conn_client.c | |||
@@ -721,7 +721,6 @@ void rxrpc_disconnect_client_call(struct rxrpc_call *call) | |||
721 | } | 721 | } |
722 | 722 | ||
723 | ASSERTCMP(rcu_access_pointer(chan->call), ==, call); | 723 | ASSERTCMP(rcu_access_pointer(chan->call), ==, call); |
724 | ASSERTCMP(atomic_read(&conn->usage), >=, 2); | ||
725 | 724 | ||
726 | /* If a client call was exposed to the world, we save the result for | 725 | /* If a client call was exposed to the world, we save the result for |
727 | * retransmission. | 726 | * retransmission. |
@@ -818,7 +817,7 @@ idle_connection: | |||
818 | static struct rxrpc_connection * | 817 | static struct rxrpc_connection * |
819 | rxrpc_put_one_client_conn(struct rxrpc_connection *conn) | 818 | rxrpc_put_one_client_conn(struct rxrpc_connection *conn) |
820 | { | 819 | { |
821 | struct rxrpc_connection *next; | 820 | struct rxrpc_connection *next = NULL; |
822 | struct rxrpc_local *local = conn->params.local; | 821 | struct rxrpc_local *local = conn->params.local; |
823 | unsigned int nr_conns; | 822 | unsigned int nr_conns; |
824 | 823 | ||
@@ -834,24 +833,22 @@ rxrpc_put_one_client_conn(struct rxrpc_connection *conn) | |||
834 | 833 | ||
835 | ASSERTCMP(conn->cache_state, ==, RXRPC_CONN_CLIENT_INACTIVE); | 834 | ASSERTCMP(conn->cache_state, ==, RXRPC_CONN_CLIENT_INACTIVE); |
836 | 835 | ||
837 | if (!test_bit(RXRPC_CONN_COUNTED, &conn->flags)) | 836 | if (test_bit(RXRPC_CONN_COUNTED, &conn->flags)) { |
838 | return NULL; | 837 | spin_lock(&rxrpc_client_conn_cache_lock); |
839 | 838 | nr_conns = --rxrpc_nr_client_conns; | |
840 | spin_lock(&rxrpc_client_conn_cache_lock); | 839 | |
841 | nr_conns = --rxrpc_nr_client_conns; | 840 | if (nr_conns < rxrpc_max_client_connections && |
841 | !list_empty(&rxrpc_waiting_client_conns)) { | ||
842 | next = list_entry(rxrpc_waiting_client_conns.next, | ||
843 | struct rxrpc_connection, cache_link); | ||
844 | rxrpc_get_connection(next); | ||
845 | rxrpc_activate_conn(next); | ||
846 | } | ||
842 | 847 | ||
843 | next = NULL; | 848 | spin_unlock(&rxrpc_client_conn_cache_lock); |
844 | if (nr_conns < rxrpc_max_client_connections && | ||
845 | !list_empty(&rxrpc_waiting_client_conns)) { | ||
846 | next = list_entry(rxrpc_waiting_client_conns.next, | ||
847 | struct rxrpc_connection, cache_link); | ||
848 | rxrpc_get_connection(next); | ||
849 | rxrpc_activate_conn(next); | ||
850 | } | 849 | } |
851 | 850 | ||
852 | spin_unlock(&rxrpc_client_conn_cache_lock); | ||
853 | rxrpc_kill_connection(conn); | 851 | rxrpc_kill_connection(conn); |
854 | |||
855 | if (next) | 852 | if (next) |
856 | rxrpc_activate_channels(next); | 853 | rxrpc_activate_channels(next); |
857 | 854 | ||
diff --git a/net/rxrpc/input.c b/net/rxrpc/input.c index 75af0bd316c7..c1f83d22f9b7 100644 --- a/net/rxrpc/input.c +++ b/net/rxrpc/input.c | |||
@@ -238,7 +238,7 @@ next_subpacket: | |||
238 | len = RXRPC_JUMBO_DATALEN; | 238 | len = RXRPC_JUMBO_DATALEN; |
239 | 239 | ||
240 | if (flags & RXRPC_LAST_PACKET) { | 240 | if (flags & RXRPC_LAST_PACKET) { |
241 | if (test_and_set_bit(RXRPC_CALL_RX_LAST, &call->flags) && | 241 | if (test_bit(RXRPC_CALL_RX_LAST, &call->flags) && |
242 | seq != call->rx_top) | 242 | seq != call->rx_top) |
243 | return rxrpc_proto_abort("LSN", call, seq); | 243 | return rxrpc_proto_abort("LSN", call, seq); |
244 | } else { | 244 | } else { |
@@ -282,6 +282,8 @@ next_subpacket: | |||
282 | call->rxtx_buffer[ix] = skb; | 282 | call->rxtx_buffer[ix] = skb; |
283 | if (after(seq, call->rx_top)) | 283 | if (after(seq, call->rx_top)) |
284 | smp_store_release(&call->rx_top, seq); | 284 | smp_store_release(&call->rx_top, seq); |
285 | if (flags & RXRPC_LAST_PACKET) | ||
286 | set_bit(RXRPC_CALL_RX_LAST, &call->flags); | ||
285 | queued = true; | 287 | queued = true; |
286 | 288 | ||
287 | if (after_eq(seq, call->rx_expect_next)) { | 289 | if (after_eq(seq, call->rx_expect_next)) { |
@@ -382,7 +384,7 @@ static void rxrpc_input_soft_acks(struct rxrpc_call *call, u8 *acks, | |||
382 | 384 | ||
383 | for (; nr_acks > 0; nr_acks--, seq++) { | 385 | for (; nr_acks > 0; nr_acks--, seq++) { |
384 | ix = seq & RXRPC_RXTX_BUFF_MASK; | 386 | ix = seq & RXRPC_RXTX_BUFF_MASK; |
385 | switch (*acks) { | 387 | switch (*acks++) { |
386 | case RXRPC_ACK_TYPE_ACK: | 388 | case RXRPC_ACK_TYPE_ACK: |
387 | call->rxtx_annotations[ix] = RXRPC_TX_ANNO_ACK; | 389 | call->rxtx_annotations[ix] = RXRPC_TX_ANNO_ACK; |
388 | break; | 390 | break; |
diff --git a/net/rxrpc/output.c b/net/rxrpc/output.c index 06a9aca739d1..0b21ed859de7 100644 --- a/net/rxrpc/output.c +++ b/net/rxrpc/output.c | |||
@@ -137,6 +137,11 @@ int rxrpc_send_call_packet(struct rxrpc_call *call, u8 type) | |||
137 | switch (type) { | 137 | switch (type) { |
138 | case RXRPC_PACKET_TYPE_ACK: | 138 | case RXRPC_PACKET_TYPE_ACK: |
139 | spin_lock_bh(&call->lock); | 139 | spin_lock_bh(&call->lock); |
140 | if (!call->ackr_reason) { | ||
141 | spin_unlock_bh(&call->lock); | ||
142 | ret = 0; | ||
143 | goto out; | ||
144 | } | ||
140 | n = rxrpc_fill_out_ack(call, pkt); | 145 | n = rxrpc_fill_out_ack(call, pkt); |
141 | call->ackr_reason = 0; | 146 | call->ackr_reason = 0; |
142 | 147 | ||
@@ -177,7 +182,7 @@ int rxrpc_send_call_packet(struct rxrpc_call *call, u8 type) | |||
177 | &msg, iov, ioc, len); | 182 | &msg, iov, ioc, len); |
178 | 183 | ||
179 | if (ret < 0 && call->state < RXRPC_CALL_COMPLETE) { | 184 | if (ret < 0 && call->state < RXRPC_CALL_COMPLETE) { |
180 | switch (pkt->whdr.type) { | 185 | switch (type) { |
181 | case RXRPC_PACKET_TYPE_ACK: | 186 | case RXRPC_PACKET_TYPE_ACK: |
182 | rxrpc_propose_ACK(call, pkt->ack.reason, | 187 | rxrpc_propose_ACK(call, pkt->ack.reason, |
183 | ntohs(pkt->ack.maxSkew), | 188 | ntohs(pkt->ack.maxSkew), |
diff --git a/net/rxrpc/recvmsg.c b/net/rxrpc/recvmsg.c index a284205b8ecf..8b8d7e14f800 100644 --- a/net/rxrpc/recvmsg.c +++ b/net/rxrpc/recvmsg.c | |||
@@ -134,6 +134,8 @@ static void rxrpc_end_rx_phase(struct rxrpc_call *call) | |||
134 | { | 134 | { |
135 | _enter("%d,%s", call->debug_id, rxrpc_call_states[call->state]); | 135 | _enter("%d,%s", call->debug_id, rxrpc_call_states[call->state]); |
136 | 136 | ||
137 | ASSERTCMP(call->rx_hard_ack, ==, call->rx_top); | ||
138 | |||
137 | if (call->state == RXRPC_CALL_CLIENT_RECV_REPLY) { | 139 | if (call->state == RXRPC_CALL_CLIENT_RECV_REPLY) { |
138 | rxrpc_propose_ACK(call, RXRPC_ACK_IDLE, 0, 0, true, false); | 140 | rxrpc_propose_ACK(call, RXRPC_ACK_IDLE, 0, 0, true, false); |
139 | rxrpc_send_call_packet(call, RXRPC_PACKET_TYPE_ACK); | 141 | rxrpc_send_call_packet(call, RXRPC_PACKET_TYPE_ACK); |
@@ -163,8 +165,10 @@ static void rxrpc_end_rx_phase(struct rxrpc_call *call) | |||
163 | */ | 165 | */ |
164 | static void rxrpc_rotate_rx_window(struct rxrpc_call *call) | 166 | static void rxrpc_rotate_rx_window(struct rxrpc_call *call) |
165 | { | 167 | { |
168 | struct rxrpc_skb_priv *sp; | ||
166 | struct sk_buff *skb; | 169 | struct sk_buff *skb; |
167 | rxrpc_seq_t hard_ack, top; | 170 | rxrpc_seq_t hard_ack, top; |
171 | u8 flags; | ||
168 | int ix; | 172 | int ix; |
169 | 173 | ||
170 | _enter("%d", call->debug_id); | 174 | _enter("%d", call->debug_id); |
@@ -177,6 +181,8 @@ static void rxrpc_rotate_rx_window(struct rxrpc_call *call) | |||
177 | ix = hard_ack & RXRPC_RXTX_BUFF_MASK; | 181 | ix = hard_ack & RXRPC_RXTX_BUFF_MASK; |
178 | skb = call->rxtx_buffer[ix]; | 182 | skb = call->rxtx_buffer[ix]; |
179 | rxrpc_see_skb(skb); | 183 | rxrpc_see_skb(skb); |
184 | sp = rxrpc_skb(skb); | ||
185 | flags = sp->hdr.flags; | ||
180 | call->rxtx_buffer[ix] = NULL; | 186 | call->rxtx_buffer[ix] = NULL; |
181 | call->rxtx_annotations[ix] = 0; | 187 | call->rxtx_annotations[ix] = 0; |
182 | /* Barrier against rxrpc_input_data(). */ | 188 | /* Barrier against rxrpc_input_data(). */ |
@@ -184,8 +190,8 @@ static void rxrpc_rotate_rx_window(struct rxrpc_call *call) | |||
184 | 190 | ||
185 | rxrpc_free_skb(skb); | 191 | rxrpc_free_skb(skb); |
186 | 192 | ||
187 | _debug("%u,%u,%lx", hard_ack, top, call->flags); | 193 | _debug("%u,%u,%02x", hard_ack, top, flags); |
188 | if (hard_ack == top && test_bit(RXRPC_CALL_RX_LAST, &call->flags)) | 194 | if (flags & RXRPC_LAST_PACKET) |
189 | rxrpc_end_rx_phase(call); | 195 | rxrpc_end_rx_phase(call); |
190 | } | 196 | } |
191 | 197 | ||
@@ -240,9 +246,6 @@ static int rxrpc_locate_data(struct rxrpc_call *call, struct sk_buff *skb, | |||
240 | int ret; | 246 | int ret; |
241 | u8 annotation = *_annotation; | 247 | u8 annotation = *_annotation; |
242 | 248 | ||
243 | if (offset > 0) | ||
244 | return 0; | ||
245 | |||
246 | /* Locate the subpacket */ | 249 | /* Locate the subpacket */ |
247 | offset = sp->offset; | 250 | offset = sp->offset; |
248 | len = skb->len - sp->offset; | 251 | len = skb->len - sp->offset; |
@@ -281,13 +284,19 @@ static int rxrpc_recvmsg_data(struct socket *sock, struct rxrpc_call *call, | |||
281 | size_t remain; | 284 | size_t remain; |
282 | bool last; | 285 | bool last; |
283 | unsigned int rx_pkt_offset, rx_pkt_len; | 286 | unsigned int rx_pkt_offset, rx_pkt_len; |
284 | int ix, copy, ret = 0; | 287 | int ix, copy, ret = -EAGAIN, ret2; |
285 | 288 | ||
286 | _enter(""); | 289 | _enter(""); |
287 | 290 | ||
288 | rx_pkt_offset = call->rx_pkt_offset; | 291 | rx_pkt_offset = call->rx_pkt_offset; |
289 | rx_pkt_len = call->rx_pkt_len; | 292 | rx_pkt_len = call->rx_pkt_len; |
290 | 293 | ||
294 | if (call->state >= RXRPC_CALL_SERVER_ACK_REQUEST) { | ||
295 | seq = call->rx_hard_ack; | ||
296 | ret = 1; | ||
297 | goto done; | ||
298 | } | ||
299 | |||
291 | /* Barriers against rxrpc_input_data(). */ | 300 | /* Barriers against rxrpc_input_data(). */ |
292 | hard_ack = call->rx_hard_ack; | 301 | hard_ack = call->rx_hard_ack; |
293 | top = smp_load_acquire(&call->rx_top); | 302 | top = smp_load_acquire(&call->rx_top); |
@@ -303,8 +312,15 @@ static int rxrpc_recvmsg_data(struct socket *sock, struct rxrpc_call *call, | |||
303 | if (msg) | 312 | if (msg) |
304 | sock_recv_timestamp(msg, sock->sk, skb); | 313 | sock_recv_timestamp(msg, sock->sk, skb); |
305 | 314 | ||
306 | ret = rxrpc_locate_data(call, skb, &call->rxtx_annotations[ix], | 315 | if (rx_pkt_offset == 0) { |
307 | &rx_pkt_offset, &rx_pkt_len); | 316 | ret2 = rxrpc_locate_data(call, skb, |
317 | &call->rxtx_annotations[ix], | ||
318 | &rx_pkt_offset, &rx_pkt_len); | ||
319 | if (ret2 < 0) { | ||
320 | ret = ret2; | ||
321 | goto out; | ||
322 | } | ||
323 | } | ||
308 | _debug("recvmsg %x DATA #%u { %d, %d }", | 324 | _debug("recvmsg %x DATA #%u { %d, %d }", |
309 | sp->hdr.callNumber, seq, rx_pkt_offset, rx_pkt_len); | 325 | sp->hdr.callNumber, seq, rx_pkt_offset, rx_pkt_len); |
310 | 326 | ||
@@ -314,10 +330,12 @@ static int rxrpc_recvmsg_data(struct socket *sock, struct rxrpc_call *call, | |||
314 | if (copy > remain) | 330 | if (copy > remain) |
315 | copy = remain; | 331 | copy = remain; |
316 | if (copy > 0) { | 332 | if (copy > 0) { |
317 | ret = skb_copy_datagram_iter(skb, rx_pkt_offset, iter, | 333 | ret2 = skb_copy_datagram_iter(skb, rx_pkt_offset, iter, |
318 | copy); | 334 | copy); |
319 | if (ret < 0) | 335 | if (ret2 < 0) { |
336 | ret = ret2; | ||
320 | goto out; | 337 | goto out; |
338 | } | ||
321 | 339 | ||
322 | /* handle piecemeal consumption of data packets */ | 340 | /* handle piecemeal consumption of data packets */ |
323 | _debug("copied %d @%zu", copy, *_offset); | 341 | _debug("copied %d @%zu", copy, *_offset); |
@@ -330,6 +348,7 @@ static int rxrpc_recvmsg_data(struct socket *sock, struct rxrpc_call *call, | |||
330 | if (rx_pkt_len > 0) { | 348 | if (rx_pkt_len > 0) { |
331 | _debug("buffer full"); | 349 | _debug("buffer full"); |
332 | ASSERTCMP(*_offset, ==, len); | 350 | ASSERTCMP(*_offset, ==, len); |
351 | ret = 0; | ||
333 | break; | 352 | break; |
334 | } | 353 | } |
335 | 354 | ||
@@ -340,19 +359,19 @@ static int rxrpc_recvmsg_data(struct socket *sock, struct rxrpc_call *call, | |||
340 | rx_pkt_offset = 0; | 359 | rx_pkt_offset = 0; |
341 | rx_pkt_len = 0; | 360 | rx_pkt_len = 0; |
342 | 361 | ||
343 | ASSERTIFCMP(last, seq, ==, top); | 362 | if (last) { |
344 | } | 363 | ASSERTCMP(seq, ==, READ_ONCE(call->rx_top)); |
345 | |||
346 | if (after(seq, top)) { | ||
347 | ret = -EAGAIN; | ||
348 | if (test_bit(RXRPC_CALL_RX_LAST, &call->flags)) | ||
349 | ret = 1; | 364 | ret = 1; |
365 | goto out; | ||
366 | } | ||
350 | } | 367 | } |
368 | |||
351 | out: | 369 | out: |
352 | if (!(flags & MSG_PEEK)) { | 370 | if (!(flags & MSG_PEEK)) { |
353 | call->rx_pkt_offset = rx_pkt_offset; | 371 | call->rx_pkt_offset = rx_pkt_offset; |
354 | call->rx_pkt_len = rx_pkt_len; | 372 | call->rx_pkt_len = rx_pkt_len; |
355 | } | 373 | } |
374 | done: | ||
356 | _leave(" = %d [%u/%u]", ret, seq, top); | 375 | _leave(" = %d [%u/%u]", ret, seq, top); |
357 | return ret; | 376 | return ret; |
358 | } | 377 | } |
diff --git a/net/rxrpc/sendmsg.c b/net/rxrpc/sendmsg.c index cba236575073..8bfddf4e338c 100644 --- a/net/rxrpc/sendmsg.c +++ b/net/rxrpc/sendmsg.c | |||
@@ -214,7 +214,7 @@ static int rxrpc_send_data(struct rxrpc_sock *rx, | |||
214 | goto maybe_error; | 214 | goto maybe_error; |
215 | } | 215 | } |
216 | 216 | ||
217 | max = call->conn->params.peer->maxdata; | 217 | max = RXRPC_JUMBO_DATALEN; |
218 | max -= call->conn->security_size; | 218 | max -= call->conn->security_size; |
219 | max &= ~(call->conn->size_align - 1UL); | 219 | max &= ~(call->conn->size_align - 1UL); |
220 | 220 | ||