Skip to content

Commit 357f5ef

Browse files
committed
rxrpc: Call rxrpc_release_call() on error in rxrpc_new_client_call()
Call rxrpc_release_call() on getting an error in rxrpc_new_client_call() rather than trying to do the cleanup ourselves. This isn't a problem, provided we set RXRPC_CALL_HAS_USERID only if we actually add the call to the calls tree as cleanup code fragments that would otherwise cause problems are conditional. Without this, we miss some of the cleanup. Signed-off-by: David Howells <[email protected]>
1 parent 66d58af commit 357f5ef

File tree

1 file changed

+12
-24
lines changed

1 file changed

+12
-24
lines changed

net/rxrpc/call_object.c

Lines changed: 12 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -226,9 +226,6 @@ struct rxrpc_call *rxrpc_new_client_call(struct rxrpc_sock *rx,
226226
(const void *)user_call_ID);
227227

228228
/* 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-
232229
write_lock(&rx->call_lock);
233230

234231
pp = &rx->calls.rb_node;
@@ -242,10 +239,12 @@ struct rxrpc_call *rxrpc_new_client_call(struct rxrpc_sock *rx,
242239
else if (user_call_ID > xcall->user_call_ID)
243240
pp = &(*pp)->rb_right;
244241
else
245-
goto found_user_ID_now_present;
242+
goto error_dup_user_ID;
246243
}
247244

248245
rcu_assign_pointer(call->socket, rx);
246+
call->user_call_ID = user_call_ID;
247+
__set_bit(RXRPC_CALL_HAS_USERID, &call->flags);
249248
rxrpc_get_call(call, rxrpc_call_got_userid);
250249
rb_link_node(&call->sock_node, parent, pp);
251250
rb_insert_color(&call->sock_node, &rx->calls);
@@ -276,33 +275,22 @@ struct rxrpc_call *rxrpc_new_client_call(struct rxrpc_sock *rx,
276275
_leave(" = %p [new]", call);
277276
return call;
278277

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-
297278
/* We unexpectedly found the user ID in the list after taking
298279
* the call_lock. This shouldn't happen unless the user races
299280
* with itself and tries to add the same user ID twice at the
300281
* same time in different threads.
301282
*/
302-
found_user_ID_now_present:
283+
error_dup_user_ID:
303284
write_unlock(&rx->call_lock);
304285
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);
306294
}
307295

308296
/*

0 commit comments

Comments
 (0)