|
|
@@ -226,9 +226,6 @@ struct rxrpc_call *rxrpc_new_client_call(struct rxrpc_sock *rx,
|
|
|
(const void *)user_call_ID);
|
|
|
|
|
|
/* Publish the call, even though it is incompletely set up as yet */
|
|
|
- call->user_call_ID = user_call_ID;
|
|
|
- __set_bit(RXRPC_CALL_HAS_USERID, &call->flags);
|
|
|
-
|
|
|
write_lock(&rx->call_lock);
|
|
|
|
|
|
pp = &rx->calls.rb_node;
|
|
|
@@ -242,10 +239,12 @@ struct rxrpc_call *rxrpc_new_client_call(struct rxrpc_sock *rx,
|
|
|
else if (user_call_ID > xcall->user_call_ID)
|
|
|
pp = &(*pp)->rb_right;
|
|
|
else
|
|
|
- goto found_user_ID_now_present;
|
|
|
+ goto error_dup_user_ID;
|
|
|
}
|
|
|
|
|
|
rcu_assign_pointer(call->socket, rx);
|
|
|
+ call->user_call_ID = user_call_ID;
|
|
|
+ __set_bit(RXRPC_CALL_HAS_USERID, &call->flags);
|
|
|
rxrpc_get_call(call, rxrpc_call_got_userid);
|
|
|
rb_link_node(&call->sock_node, parent, pp);
|
|
|
rb_insert_color(&call->sock_node, &rx->calls);
|
|
|
@@ -276,33 +275,22 @@ struct rxrpc_call *rxrpc_new_client_call(struct rxrpc_sock *rx,
|
|
|
_leave(" = %p [new]", call);
|
|
|
return call;
|
|
|
|
|
|
-error:
|
|
|
- write_lock(&rx->call_lock);
|
|
|
- rb_erase(&call->sock_node, &rx->calls);
|
|
|
- write_unlock(&rx->call_lock);
|
|
|
- rxrpc_put_call(call, rxrpc_call_put_userid);
|
|
|
-
|
|
|
- write_lock(&rxrpc_call_lock);
|
|
|
- list_del_init(&call->link);
|
|
|
- write_unlock(&rxrpc_call_lock);
|
|
|
-
|
|
|
-error_out:
|
|
|
- __rxrpc_set_call_completion(call, RXRPC_CALL_LOCAL_ERROR,
|
|
|
- RX_CALL_DEAD, ret);
|
|
|
- set_bit(RXRPC_CALL_RELEASED, &call->flags);
|
|
|
- rxrpc_put_call(call, rxrpc_call_put);
|
|
|
- _leave(" = %d", ret);
|
|
|
- return ERR_PTR(ret);
|
|
|
-
|
|
|
/* We unexpectedly found the user ID in the list after taking
|
|
|
* the call_lock. This shouldn't happen unless the user races
|
|
|
* with itself and tries to add the same user ID twice at the
|
|
|
* same time in different threads.
|
|
|
*/
|
|
|
-found_user_ID_now_present:
|
|
|
+error_dup_user_ID:
|
|
|
write_unlock(&rx->call_lock);
|
|
|
ret = -EEXIST;
|
|
|
- goto error_out;
|
|
|
+
|
|
|
+error:
|
|
|
+ __rxrpc_set_call_completion(call, RXRPC_CALL_LOCAL_ERROR,
|
|
|
+ RX_CALL_DEAD, ret);
|
|
|
+ rxrpc_release_call(rx, call);
|
|
|
+ rxrpc_put_call(call, rxrpc_call_put);
|
|
|
+ _leave(" = %d", ret);
|
|
|
+ return ERR_PTR(ret);
|
|
|
}
|
|
|
|
|
|
/*
|