.. | .. |
---|
| 1 | +// SPDX-License-Identifier: GPL-2.0-or-later |
---|
1 | 2 | /* AF_RXRPC sendmsg() implementation. |
---|
2 | 3 | * |
---|
3 | 4 | * Copyright (C) 2007, 2016 Red Hat, Inc. All Rights Reserved. |
---|
4 | 5 | * Written by David Howells (dhowells@redhat.com) |
---|
5 | | - * |
---|
6 | | - * This program is free software; you can redistribute it and/or |
---|
7 | | - * modify it under the terms of the GNU General Public Licence |
---|
8 | | - * as published by the Free Software Foundation; either version |
---|
9 | | - * 2 of the Licence, or (at your option) any later version. |
---|
10 | 6 | */ |
---|
11 | 7 | |
---|
12 | 8 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt |
---|
.. | .. |
---|
22 | 18 | #include "ar-internal.h" |
---|
23 | 19 | |
---|
24 | 20 | /* |
---|
| 21 | + * Return true if there's sufficient Tx queue space. |
---|
| 22 | + */ |
---|
| 23 | +static bool rxrpc_check_tx_space(struct rxrpc_call *call, rxrpc_seq_t *_tx_win) |
---|
| 24 | +{ |
---|
| 25 | + unsigned int win_size = |
---|
| 26 | + min_t(unsigned int, call->tx_winsize, |
---|
| 27 | + call->cong_cwnd + call->cong_extra); |
---|
| 28 | + rxrpc_seq_t tx_win = READ_ONCE(call->tx_hard_ack); |
---|
| 29 | + |
---|
| 30 | + if (_tx_win) |
---|
| 31 | + *_tx_win = tx_win; |
---|
| 32 | + return call->tx_top - tx_win < win_size; |
---|
| 33 | +} |
---|
| 34 | + |
---|
| 35 | +/* |
---|
25 | 36 | * Wait for space to appear in the Tx queue or a signal to occur. |
---|
26 | 37 | */ |
---|
27 | 38 | static int rxrpc_wait_for_tx_window_intr(struct rxrpc_sock *rx, |
---|
.. | .. |
---|
30 | 41 | { |
---|
31 | 42 | for (;;) { |
---|
32 | 43 | set_current_state(TASK_INTERRUPTIBLE); |
---|
33 | | - if (call->tx_top - call->tx_hard_ack < |
---|
34 | | - min_t(unsigned int, call->tx_winsize, |
---|
35 | | - call->cong_cwnd + call->cong_extra)) |
---|
| 44 | + if (rxrpc_check_tx_space(call, NULL)) |
---|
36 | 45 | return 0; |
---|
37 | 46 | |
---|
38 | 47 | if (call->state >= RXRPC_CALL_COMPLETE) |
---|
.. | .. |
---|
42 | 51 | return sock_intr_errno(*timeo); |
---|
43 | 52 | |
---|
44 | 53 | trace_rxrpc_transmit(call, rxrpc_transmit_wait); |
---|
45 | | - mutex_unlock(&call->user_mutex); |
---|
46 | 54 | *timeo = schedule_timeout(*timeo); |
---|
47 | | - if (mutex_lock_interruptible(&call->user_mutex) < 0) |
---|
48 | | - return sock_intr_errno(*timeo); |
---|
49 | 55 | } |
---|
50 | 56 | } |
---|
51 | 57 | |
---|
.. | .. |
---|
53 | 59 | * Wait for space to appear in the Tx queue uninterruptibly, but with |
---|
54 | 60 | * a timeout of 2*RTT if no progress was made and a signal occurred. |
---|
55 | 61 | */ |
---|
56 | | -static int rxrpc_wait_for_tx_window_nonintr(struct rxrpc_sock *rx, |
---|
| 62 | +static int rxrpc_wait_for_tx_window_waitall(struct rxrpc_sock *rx, |
---|
57 | 63 | struct rxrpc_call *call) |
---|
58 | 64 | { |
---|
59 | 65 | rxrpc_seq_t tx_start, tx_win; |
---|
60 | | - signed long rtt2, timeout; |
---|
61 | | - u64 rtt; |
---|
| 66 | + signed long rtt, timeout; |
---|
62 | 67 | |
---|
63 | | - rtt = READ_ONCE(call->peer->rtt); |
---|
64 | | - rtt2 = nsecs_to_jiffies64(rtt) * 2; |
---|
65 | | - if (rtt2 < 2) |
---|
66 | | - rtt2 = 2; |
---|
| 68 | + rtt = READ_ONCE(call->peer->srtt_us) >> 3; |
---|
| 69 | + rtt = usecs_to_jiffies(rtt) * 2; |
---|
| 70 | + if (rtt < 2) |
---|
| 71 | + rtt = 2; |
---|
67 | 72 | |
---|
68 | | - timeout = rtt2; |
---|
| 73 | + timeout = rtt; |
---|
69 | 74 | tx_start = READ_ONCE(call->tx_hard_ack); |
---|
70 | 75 | |
---|
71 | 76 | for (;;) { |
---|
72 | 77 | set_current_state(TASK_UNINTERRUPTIBLE); |
---|
73 | 78 | |
---|
74 | 79 | tx_win = READ_ONCE(call->tx_hard_ack); |
---|
75 | | - if (call->tx_top - tx_win < |
---|
76 | | - min_t(unsigned int, call->tx_winsize, |
---|
77 | | - call->cong_cwnd + call->cong_extra)) |
---|
| 80 | + if (rxrpc_check_tx_space(call, &tx_win)) |
---|
78 | 81 | return 0; |
---|
79 | 82 | |
---|
80 | 83 | if (call->state >= RXRPC_CALL_COMPLETE) |
---|
.. | .. |
---|
85 | 88 | return -EINTR; |
---|
86 | 89 | |
---|
87 | 90 | if (tx_win != tx_start) { |
---|
88 | | - timeout = rtt2; |
---|
| 91 | + timeout = rtt; |
---|
89 | 92 | tx_start = tx_win; |
---|
90 | 93 | } |
---|
91 | 94 | |
---|
92 | 95 | trace_rxrpc_transmit(call, rxrpc_transmit_wait); |
---|
93 | 96 | timeout = schedule_timeout(timeout); |
---|
| 97 | + } |
---|
| 98 | +} |
---|
| 99 | + |
---|
| 100 | +/* |
---|
| 101 | + * Wait for space to appear in the Tx queue uninterruptibly. |
---|
| 102 | + */ |
---|
| 103 | +static int rxrpc_wait_for_tx_window_nonintr(struct rxrpc_sock *rx, |
---|
| 104 | + struct rxrpc_call *call, |
---|
| 105 | + long *timeo) |
---|
| 106 | +{ |
---|
| 107 | + for (;;) { |
---|
| 108 | + set_current_state(TASK_UNINTERRUPTIBLE); |
---|
| 109 | + if (rxrpc_check_tx_space(call, NULL)) |
---|
| 110 | + return 0; |
---|
| 111 | + |
---|
| 112 | + if (call->state >= RXRPC_CALL_COMPLETE) |
---|
| 113 | + return call->error; |
---|
| 114 | + |
---|
| 115 | + trace_rxrpc_transmit(call, rxrpc_transmit_wait); |
---|
| 116 | + *timeo = schedule_timeout(*timeo); |
---|
94 | 117 | } |
---|
95 | 118 | } |
---|
96 | 119 | |
---|
.. | .. |
---|
111 | 134 | |
---|
112 | 135 | add_wait_queue(&call->waitq, &myself); |
---|
113 | 136 | |
---|
114 | | - if (waitall) |
---|
115 | | - ret = rxrpc_wait_for_tx_window_nonintr(rx, call); |
---|
116 | | - else |
---|
117 | | - ret = rxrpc_wait_for_tx_window_intr(rx, call, timeo); |
---|
| 137 | + switch (call->interruptibility) { |
---|
| 138 | + case RXRPC_INTERRUPTIBLE: |
---|
| 139 | + if (waitall) |
---|
| 140 | + ret = rxrpc_wait_for_tx_window_waitall(rx, call); |
---|
| 141 | + else |
---|
| 142 | + ret = rxrpc_wait_for_tx_window_intr(rx, call, timeo); |
---|
| 143 | + break; |
---|
| 144 | + case RXRPC_PREINTERRUPTIBLE: |
---|
| 145 | + case RXRPC_UNINTERRUPTIBLE: |
---|
| 146 | + default: |
---|
| 147 | + ret = rxrpc_wait_for_tx_window_nonintr(rx, call, timeo); |
---|
| 148 | + break; |
---|
| 149 | + } |
---|
118 | 150 | |
---|
119 | 151 | remove_wait_queue(&call->waitq, &myself); |
---|
120 | 152 | set_current_state(TASK_RUNNING); |
---|
.. | .. |
---|
152 | 184 | } |
---|
153 | 185 | |
---|
154 | 186 | /* |
---|
155 | | - * Queue a DATA packet for transmission, set the resend timeout and send the |
---|
156 | | - * packet immediately |
---|
| 187 | + * Queue a DATA packet for transmission, set the resend timeout and send |
---|
| 188 | + * the packet immediately. Returns the error from rxrpc_send_data_packet() |
---|
| 189 | + * in case the caller wants to do something with it. |
---|
157 | 190 | */ |
---|
158 | | -static void rxrpc_queue_packet(struct rxrpc_sock *rx, struct rxrpc_call *call, |
---|
159 | | - struct sk_buff *skb, bool last, |
---|
160 | | - rxrpc_notify_end_tx_t notify_end_tx) |
---|
| 191 | +static int rxrpc_queue_packet(struct rxrpc_sock *rx, struct rxrpc_call *call, |
---|
| 192 | + struct sk_buff *skb, bool last, |
---|
| 193 | + rxrpc_notify_end_tx_t notify_end_tx) |
---|
161 | 194 | { |
---|
162 | 195 | struct rxrpc_skb_priv *sp = rxrpc_skb(skb); |
---|
163 | 196 | unsigned long now; |
---|
.. | .. |
---|
169 | 202 | |
---|
170 | 203 | ASSERTCMP(seq, ==, call->tx_top + 1); |
---|
171 | 204 | |
---|
172 | | - if (last) { |
---|
| 205 | + if (last) |
---|
173 | 206 | annotation |= RXRPC_TX_ANNO_LAST; |
---|
174 | | - set_bit(RXRPC_CALL_TX_LASTQ, &call->flags); |
---|
175 | | - } |
---|
176 | 207 | |
---|
177 | 208 | /* We have to set the timestamp before queueing as the retransmit |
---|
178 | 209 | * algorithm can see the packet as soon as we queue it. |
---|
.. | .. |
---|
180 | 211 | skb->tstamp = ktime_get_real(); |
---|
181 | 212 | |
---|
182 | 213 | ix = seq & RXRPC_RXTX_BUFF_MASK; |
---|
183 | | - rxrpc_get_skb(skb, rxrpc_skb_tx_got); |
---|
| 214 | + rxrpc_get_skb(skb, rxrpc_skb_got); |
---|
184 | 215 | call->rxtx_annotations[ix] = annotation; |
---|
185 | 216 | smp_wmb(); |
---|
186 | 217 | call->rxtx_buffer[ix] = skb; |
---|
.. | .. |
---|
207 | 238 | trace_rxrpc_timer(call, rxrpc_timer_init_for_send_reply, now); |
---|
208 | 239 | if (!last) |
---|
209 | 240 | break; |
---|
210 | | - /* Fall through */ |
---|
| 241 | + fallthrough; |
---|
211 | 242 | case RXRPC_CALL_SERVER_SEND_REPLY: |
---|
212 | 243 | call->state = RXRPC_CALL_SERVER_AWAIT_ACK; |
---|
213 | 244 | rxrpc_notify_end_tx(rx, call, notify_end_tx); |
---|
.. | .. |
---|
227 | 258 | case -ENETUNREACH: |
---|
228 | 259 | case -EHOSTUNREACH: |
---|
229 | 260 | case -ECONNREFUSED: |
---|
230 | | - rxrpc_set_call_completion(call, |
---|
231 | | - RXRPC_CALL_LOCAL_ERROR, |
---|
| 261 | + rxrpc_set_call_completion(call, RXRPC_CALL_LOCAL_ERROR, |
---|
232 | 262 | 0, ret); |
---|
233 | | - rxrpc_notify_socket(call); |
---|
234 | 263 | goto out; |
---|
235 | 264 | } |
---|
236 | 265 | _debug("need instant resend %d", ret); |
---|
237 | 266 | rxrpc_instant_resend(call, ix); |
---|
238 | 267 | } else { |
---|
239 | | - unsigned long now = jiffies, resend_at; |
---|
| 268 | + unsigned long now = jiffies; |
---|
| 269 | + unsigned long resend_at = now + call->peer->rto_j; |
---|
240 | 270 | |
---|
241 | | - if (call->peer->rtt_usage > 1) |
---|
242 | | - resend_at = nsecs_to_jiffies(call->peer->rtt * 3 / 2); |
---|
243 | | - else |
---|
244 | | - resend_at = rxrpc_resend_timeout; |
---|
245 | | - if (resend_at < 1) |
---|
246 | | - resend_at = 1; |
---|
247 | | - |
---|
248 | | - resend_at += now; |
---|
249 | 271 | WRITE_ONCE(call->resend_at, resend_at); |
---|
250 | 272 | rxrpc_reduce_call_timer(call, resend_at, now, |
---|
251 | 273 | rxrpc_timer_set_for_send); |
---|
252 | 274 | } |
---|
253 | 275 | |
---|
254 | 276 | out: |
---|
255 | | - rxrpc_free_skb(skb, rxrpc_skb_tx_freed); |
---|
256 | | - _leave(""); |
---|
| 277 | + rxrpc_free_skb(skb, rxrpc_skb_freed); |
---|
| 278 | + _leave(" = %d", ret); |
---|
| 279 | + return ret; |
---|
257 | 280 | } |
---|
258 | 281 | |
---|
259 | 282 | /* |
---|
.. | .. |
---|
264 | 287 | static int rxrpc_send_data(struct rxrpc_sock *rx, |
---|
265 | 288 | struct rxrpc_call *call, |
---|
266 | 289 | struct msghdr *msg, size_t len, |
---|
267 | | - rxrpc_notify_end_tx_t notify_end_tx) |
---|
| 290 | + rxrpc_notify_end_tx_t notify_end_tx, |
---|
| 291 | + bool *_dropped_lock) |
---|
268 | 292 | { |
---|
269 | 293 | struct rxrpc_skb_priv *sp; |
---|
270 | 294 | struct sk_buff *skb; |
---|
271 | 295 | struct sock *sk = &rx->sk; |
---|
| 296 | + enum rxrpc_call_state state; |
---|
272 | 297 | long timeo; |
---|
273 | | - bool more; |
---|
274 | | - int ret, copied; |
---|
| 298 | + bool more = msg->msg_flags & MSG_MORE; |
---|
| 299 | + int ret, copied = 0; |
---|
275 | 300 | |
---|
276 | 301 | timeo = sock_sndtimeo(sk, msg->msg_flags & MSG_DONTWAIT); |
---|
277 | 302 | |
---|
278 | 303 | /* this should be in poll */ |
---|
279 | 304 | sk_clear_bit(SOCKWQ_ASYNC_NOSPACE, sk); |
---|
280 | 305 | |
---|
| 306 | +reload: |
---|
| 307 | + ret = -EPIPE; |
---|
281 | 308 | if (sk->sk_shutdown & SEND_SHUTDOWN) |
---|
282 | | - return -EPIPE; |
---|
| 309 | + goto maybe_error; |
---|
| 310 | + state = READ_ONCE(call->state); |
---|
| 311 | + ret = -ESHUTDOWN; |
---|
| 312 | + if (state >= RXRPC_CALL_COMPLETE) |
---|
| 313 | + goto maybe_error; |
---|
| 314 | + ret = -EPROTO; |
---|
| 315 | + if (state != RXRPC_CALL_CLIENT_SEND_REQUEST && |
---|
| 316 | + state != RXRPC_CALL_SERVER_ACK_REQUEST && |
---|
| 317 | + state != RXRPC_CALL_SERVER_SEND_REPLY) |
---|
| 318 | + goto maybe_error; |
---|
283 | 319 | |
---|
284 | | - more = msg->msg_flags & MSG_MORE; |
---|
285 | | - |
---|
| 320 | + ret = -EMSGSIZE; |
---|
286 | 321 | if (call->tx_total_len != -1) { |
---|
287 | | - if (len > call->tx_total_len) |
---|
288 | | - return -EMSGSIZE; |
---|
289 | | - if (!more && len != call->tx_total_len) |
---|
290 | | - return -EMSGSIZE; |
---|
| 322 | + if (len - copied > call->tx_total_len) |
---|
| 323 | + goto maybe_error; |
---|
| 324 | + if (!more && len - copied != call->tx_total_len) |
---|
| 325 | + goto maybe_error; |
---|
291 | 326 | } |
---|
292 | 327 | |
---|
293 | 328 | skb = call->tx_pending; |
---|
294 | 329 | call->tx_pending = NULL; |
---|
295 | | - rxrpc_see_skb(skb, rxrpc_skb_tx_seen); |
---|
| 330 | + rxrpc_see_skb(skb, rxrpc_skb_seen); |
---|
296 | 331 | |
---|
297 | | - copied = 0; |
---|
298 | 332 | do { |
---|
299 | 333 | /* Check to see if there's a ping ACK to reply to. */ |
---|
300 | 334 | if (call->ackr_reason == RXRPC_ACK_PING_RESPONSE) |
---|
.. | .. |
---|
305 | 339 | |
---|
306 | 340 | _debug("alloc"); |
---|
307 | 341 | |
---|
308 | | - if (call->tx_top - call->tx_hard_ack >= |
---|
309 | | - min_t(unsigned int, call->tx_winsize, |
---|
310 | | - call->cong_cwnd + call->cong_extra)) { |
---|
311 | | - ret = -EAGAIN; |
---|
312 | | - if (msg->msg_flags & MSG_DONTWAIT) |
---|
313 | | - goto maybe_error; |
---|
314 | | - ret = rxrpc_wait_for_tx_window(rx, call, |
---|
315 | | - &timeo, |
---|
316 | | - msg->msg_flags & MSG_WAITALL); |
---|
317 | | - if (ret < 0) |
---|
318 | | - goto maybe_error; |
---|
319 | | - } |
---|
| 342 | + if (!rxrpc_check_tx_space(call, NULL)) |
---|
| 343 | + goto wait_for_space; |
---|
320 | 344 | |
---|
321 | 345 | max = RXRPC_JUMBO_DATALEN; |
---|
322 | 346 | max -= call->conn->security_size; |
---|
.. | .. |
---|
339 | 363 | if (!skb) |
---|
340 | 364 | goto maybe_error; |
---|
341 | 365 | |
---|
342 | | - rxrpc_new_skb(skb, rxrpc_skb_tx_new); |
---|
| 366 | + sp = rxrpc_skb(skb); |
---|
| 367 | + sp->rx_flags |= RXRPC_SKB_TX_BUFFER; |
---|
| 368 | + rxrpc_new_skb(skb, rxrpc_skb_new); |
---|
343 | 369 | |
---|
344 | 370 | _debug("ALLOC SEND %p", skb); |
---|
345 | 371 | |
---|
.. | .. |
---|
349 | 375 | skb_reserve(skb, call->conn->security_size); |
---|
350 | 376 | skb->len += call->conn->security_size; |
---|
351 | 377 | |
---|
352 | | - sp = rxrpc_skb(skb); |
---|
353 | 378 | sp->remain = chunk; |
---|
354 | 379 | if (sp->remain > skb_tailroom(skb)) |
---|
355 | 380 | sp->remain = skb_tailroom(skb); |
---|
.. | .. |
---|
387 | 412 | call->tx_total_len -= copy; |
---|
388 | 413 | } |
---|
389 | 414 | |
---|
| 415 | + /* check for the far side aborting the call or a network error |
---|
| 416 | + * occurring */ |
---|
| 417 | + if (call->state == RXRPC_CALL_COMPLETE) |
---|
| 418 | + goto call_terminated; |
---|
| 419 | + |
---|
390 | 420 | /* add the packet to the send queue if it's now full */ |
---|
391 | 421 | if (sp->remain <= 0 || |
---|
392 | 422 | (msg_data_left(msg) == 0 && !more)) { |
---|
.. | .. |
---|
416 | 446 | call->tx_winsize) |
---|
417 | 447 | sp->hdr.flags |= RXRPC_MORE_PACKETS; |
---|
418 | 448 | |
---|
419 | | - ret = conn->security->secure_packet( |
---|
| 449 | + ret = call->security->secure_packet( |
---|
420 | 450 | call, skb, skb->mark, skb->head); |
---|
421 | 451 | if (ret < 0) |
---|
422 | 452 | goto out; |
---|
423 | 453 | |
---|
424 | | - rxrpc_queue_packet(rx, call, skb, |
---|
425 | | - !msg_data_left(msg) && !more, |
---|
426 | | - notify_end_tx); |
---|
| 454 | + ret = rxrpc_queue_packet(rx, call, skb, |
---|
| 455 | + !msg_data_left(msg) && !more, |
---|
| 456 | + notify_end_tx); |
---|
| 457 | + /* Should check for failure here */ |
---|
427 | 458 | skb = NULL; |
---|
428 | | - } |
---|
429 | | - |
---|
430 | | - /* Check for the far side aborting the call or a network error |
---|
431 | | - * occurring. If this happens, save any packet that was under |
---|
432 | | - * construction so that in the case of a network error, the |
---|
433 | | - * call can be retried or redirected. |
---|
434 | | - */ |
---|
435 | | - if (call->state == RXRPC_CALL_COMPLETE) { |
---|
436 | | - ret = call->error; |
---|
437 | | - goto out; |
---|
438 | 459 | } |
---|
439 | 460 | } while (msg_data_left(msg) > 0); |
---|
440 | 461 | |
---|
441 | 462 | success: |
---|
442 | 463 | ret = copied; |
---|
| 464 | + if (READ_ONCE(call->state) == RXRPC_CALL_COMPLETE) { |
---|
| 465 | + read_lock_bh(&call->state_lock); |
---|
| 466 | + if (call->error < 0) |
---|
| 467 | + ret = call->error; |
---|
| 468 | + read_unlock_bh(&call->state_lock); |
---|
| 469 | + } |
---|
443 | 470 | out: |
---|
444 | 471 | call->tx_pending = skb; |
---|
445 | 472 | _leave(" = %d", ret); |
---|
446 | 473 | return ret; |
---|
| 474 | + |
---|
| 475 | +call_terminated: |
---|
| 476 | + rxrpc_free_skb(skb, rxrpc_skb_freed); |
---|
| 477 | + _leave(" = %d", call->error); |
---|
| 478 | + return call->error; |
---|
447 | 479 | |
---|
448 | 480 | maybe_error: |
---|
449 | 481 | if (copied) |
---|
.. | .. |
---|
453 | 485 | efault: |
---|
454 | 486 | ret = -EFAULT; |
---|
455 | 487 | goto out; |
---|
| 488 | + |
---|
| 489 | +wait_for_space: |
---|
| 490 | + ret = -EAGAIN; |
---|
| 491 | + if (msg->msg_flags & MSG_DONTWAIT) |
---|
| 492 | + goto maybe_error; |
---|
| 493 | + mutex_unlock(&call->user_mutex); |
---|
| 494 | + *_dropped_lock = true; |
---|
| 495 | + ret = rxrpc_wait_for_tx_window(rx, call, &timeo, |
---|
| 496 | + msg->msg_flags & MSG_WAITALL); |
---|
| 497 | + if (ret < 0) |
---|
| 498 | + goto maybe_error; |
---|
| 499 | + if (call->interruptibility == RXRPC_INTERRUPTIBLE) { |
---|
| 500 | + if (mutex_lock_interruptible(&call->user_mutex) < 0) { |
---|
| 501 | + ret = sock_intr_errno(timeo); |
---|
| 502 | + goto maybe_error; |
---|
| 503 | + } |
---|
| 504 | + } else { |
---|
| 505 | + mutex_lock(&call->user_mutex); |
---|
| 506 | + } |
---|
| 507 | + *_dropped_lock = false; |
---|
| 508 | + goto reload; |
---|
456 | 509 | } |
---|
457 | 510 | |
---|
458 | 511 | /* |
---|
.. | .. |
---|
504 | 557 | return -EINVAL; |
---|
505 | 558 | break; |
---|
506 | 559 | |
---|
507 | | - case RXRPC_ACCEPT: |
---|
| 560 | + case RXRPC_CHARGE_ACCEPT: |
---|
508 | 561 | if (p->command != RXRPC_CMD_SEND_DATA) |
---|
509 | 562 | return -EINVAL; |
---|
510 | | - p->command = RXRPC_CMD_ACCEPT; |
---|
| 563 | + p->command = RXRPC_CMD_CHARGE_ACCEPT; |
---|
511 | 564 | if (len != 0) |
---|
512 | 565 | return -EINVAL; |
---|
513 | 566 | break; |
---|
.. | .. |
---|
614 | 667 | enum rxrpc_call_state state; |
---|
615 | 668 | struct rxrpc_call *call; |
---|
616 | 669 | unsigned long now, j; |
---|
| 670 | + bool dropped_lock = false; |
---|
617 | 671 | int ret; |
---|
618 | 672 | |
---|
619 | 673 | struct rxrpc_send_params p = { |
---|
620 | 674 | .call.tx_total_len = -1, |
---|
621 | 675 | .call.user_call_ID = 0, |
---|
622 | 676 | .call.nr_timeouts = 0, |
---|
| 677 | + .call.interruptibility = RXRPC_INTERRUPTIBLE, |
---|
623 | 678 | .abort_code = 0, |
---|
624 | 679 | .command = RXRPC_CMD_SEND_DATA, |
---|
625 | 680 | .exclusive = false, |
---|
.. | .. |
---|
632 | 687 | if (ret < 0) |
---|
633 | 688 | goto error_release_sock; |
---|
634 | 689 | |
---|
635 | | - if (p.command == RXRPC_CMD_ACCEPT) { |
---|
| 690 | + if (p.command == RXRPC_CMD_CHARGE_ACCEPT) { |
---|
636 | 691 | ret = -EINVAL; |
---|
637 | 692 | if (rx->sk.sk_state != RXRPC_SERVER_LISTENING) |
---|
638 | 693 | goto error_release_sock; |
---|
639 | | - call = rxrpc_accept_call(rx, p.call.user_call_ID, NULL); |
---|
640 | | - /* The socket is now unlocked. */ |
---|
641 | | - if (IS_ERR(call)) |
---|
642 | | - return PTR_ERR(call); |
---|
643 | | - ret = 0; |
---|
644 | | - goto out_put_unlock; |
---|
| 694 | + ret = rxrpc_user_charge_accept(rx, p.call.user_call_ID); |
---|
| 695 | + goto error_release_sock; |
---|
645 | 696 | } |
---|
646 | 697 | |
---|
647 | 698 | call = rxrpc_find_call_by_user_ID(rx, p.call.user_call_ID); |
---|
.. | .. |
---|
663 | 714 | case RXRPC_CALL_CLIENT_AWAIT_CONN: |
---|
664 | 715 | case RXRPC_CALL_SERVER_PREALLOC: |
---|
665 | 716 | case RXRPC_CALL_SERVER_SECURING: |
---|
666 | | - case RXRPC_CALL_SERVER_ACCEPTING: |
---|
667 | 717 | rxrpc_put_call(call, rxrpc_call_put); |
---|
668 | 718 | ret = -EBUSY; |
---|
669 | 719 | goto error_release_sock; |
---|
.. | .. |
---|
683 | 733 | if (call->tx_total_len != -1 || |
---|
684 | 734 | call->tx_pending || |
---|
685 | 735 | call->tx_top != 0) |
---|
686 | | - goto error_put; |
---|
| 736 | + goto out_put_unlock; |
---|
687 | 737 | call->tx_total_len = p.call.tx_total_len; |
---|
688 | 738 | } |
---|
689 | 739 | } |
---|
.. | .. |
---|
694 | 744 | if (p.call.timeouts.normal > 0 && j == 0) |
---|
695 | 745 | j = 1; |
---|
696 | 746 | WRITE_ONCE(call->next_rx_timo, j); |
---|
697 | | - /* Fall through */ |
---|
| 747 | + fallthrough; |
---|
698 | 748 | case 2: |
---|
699 | 749 | j = msecs_to_jiffies(p.call.timeouts.idle); |
---|
700 | 750 | if (p.call.timeouts.idle > 0 && j == 0) |
---|
701 | 751 | j = 1; |
---|
702 | 752 | WRITE_ONCE(call->next_req_timo, j); |
---|
703 | | - /* Fall through */ |
---|
| 753 | + fallthrough; |
---|
704 | 754 | case 1: |
---|
705 | 755 | if (p.call.timeouts.hard > 0) { |
---|
706 | | - j = msecs_to_jiffies(p.call.timeouts.hard); |
---|
| 756 | + j = p.call.timeouts.hard * HZ; |
---|
707 | 757 | now = jiffies; |
---|
708 | 758 | j += now; |
---|
709 | 759 | WRITE_ONCE(call->expect_term_by, j); |
---|
.. | .. |
---|
726 | 776 | ret = rxrpc_send_abort_packet(call); |
---|
727 | 777 | } else if (p.command != RXRPC_CMD_SEND_DATA) { |
---|
728 | 778 | ret = -EINVAL; |
---|
729 | | - } else if (rxrpc_is_client_call(call) && |
---|
730 | | - state != RXRPC_CALL_CLIENT_SEND_REQUEST) { |
---|
731 | | - /* request phase complete for this client call */ |
---|
732 | | - ret = -EPROTO; |
---|
733 | | - } else if (rxrpc_is_service_call(call) && |
---|
734 | | - state != RXRPC_CALL_SERVER_ACK_REQUEST && |
---|
735 | | - state != RXRPC_CALL_SERVER_SEND_REPLY) { |
---|
736 | | - /* Reply phase not begun or not complete for service call. */ |
---|
737 | | - ret = -EPROTO; |
---|
738 | 779 | } else { |
---|
739 | | - ret = rxrpc_send_data(rx, call, msg, len, NULL); |
---|
| 780 | + ret = rxrpc_send_data(rx, call, msg, len, NULL, &dropped_lock); |
---|
740 | 781 | } |
---|
741 | 782 | |
---|
742 | 783 | out_put_unlock: |
---|
743 | | - mutex_unlock(&call->user_mutex); |
---|
| 784 | + if (!dropped_lock) |
---|
| 785 | + mutex_unlock(&call->user_mutex); |
---|
744 | 786 | error_put: |
---|
745 | 787 | rxrpc_put_call(call, rxrpc_call_put); |
---|
746 | 788 | _leave(" = %d", ret); |
---|
.. | .. |
---|
768 | 810 | struct msghdr *msg, size_t len, |
---|
769 | 811 | rxrpc_notify_end_tx_t notify_end_tx) |
---|
770 | 812 | { |
---|
| 813 | + bool dropped_lock = false; |
---|
771 | 814 | int ret; |
---|
772 | 815 | |
---|
773 | 816 | _enter("{%d,%s},", call->debug_id, rxrpc_call_states[call->state]); |
---|
.. | .. |
---|
785 | 828 | case RXRPC_CALL_SERVER_ACK_REQUEST: |
---|
786 | 829 | case RXRPC_CALL_SERVER_SEND_REPLY: |
---|
787 | 830 | ret = rxrpc_send_data(rxrpc_sk(sock->sk), call, msg, len, |
---|
788 | | - notify_end_tx); |
---|
| 831 | + notify_end_tx, &dropped_lock); |
---|
789 | 832 | break; |
---|
790 | 833 | case RXRPC_CALL_COMPLETE: |
---|
791 | 834 | read_lock_bh(&call->state_lock); |
---|
.. | .. |
---|
799 | 842 | break; |
---|
800 | 843 | } |
---|
801 | 844 | |
---|
802 | | - mutex_unlock(&call->user_mutex); |
---|
| 845 | + if (!dropped_lock) |
---|
| 846 | + mutex_unlock(&call->user_mutex); |
---|
803 | 847 | _leave(" = %d", ret); |
---|
804 | 848 | return ret; |
---|
805 | 849 | } |
---|