diff options
Diffstat (limited to 'net/rxrpc/call_object.c')
-rw-r--r-- | net/rxrpc/call_object.c | 46 |
1 files changed, 22 insertions, 24 deletions
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); |