aboutsummaryrefslogtreecommitdiffstats
path: root/net/rxrpc/ar-accept.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/rxrpc/ar-accept.c')
-rw-r--r--net/rxrpc/ar-accept.c119
1 files changed, 112 insertions, 7 deletions
diff --git a/net/rxrpc/ar-accept.c b/net/rxrpc/ar-accept.c
index e7af780cd6f9..92a87fde8bfe 100644
--- a/net/rxrpc/ar-accept.c
+++ b/net/rxrpc/ar-accept.c
@@ -139,7 +139,7 @@ static int rxrpc_accept_incoming_call(struct rxrpc_local *local,
139 call->conn->state = RXRPC_CONN_SERVER_CHALLENGING; 139 call->conn->state = RXRPC_CONN_SERVER_CHALLENGING;
140 atomic_inc(&call->conn->usage); 140 atomic_inc(&call->conn->usage);
141 set_bit(RXRPC_CONN_CHALLENGE, &call->conn->events); 141 set_bit(RXRPC_CONN_CHALLENGE, &call->conn->events);
142 schedule_work(&call->conn->processor); 142 rxrpc_queue_conn(call->conn);
143 } else { 143 } else {
144 _debug("conn ready"); 144 _debug("conn ready");
145 call->state = RXRPC_CALL_SERVER_ACCEPTING; 145 call->state = RXRPC_CALL_SERVER_ACCEPTING;
@@ -183,7 +183,7 @@ invalid_service:
183 if (!test_bit(RXRPC_CALL_RELEASE, &call->flags) && 183 if (!test_bit(RXRPC_CALL_RELEASE, &call->flags) &&
184 !test_and_set_bit(RXRPC_CALL_RELEASE, &call->events)) { 184 !test_and_set_bit(RXRPC_CALL_RELEASE, &call->events)) {
185 rxrpc_get_call(call); 185 rxrpc_get_call(call);
186 schedule_work(&call->processor); 186 rxrpc_queue_call(call);
187 } 187 }
188 read_unlock_bh(&call->state_lock); 188 read_unlock_bh(&call->state_lock);
189 rxrpc_put_call(call); 189 rxrpc_put_call(call);
@@ -310,7 +310,8 @@ security_mismatch:
310 * handle acceptance of a call by userspace 310 * handle acceptance of a call by userspace
311 * - assign the user call ID to the call at the front of the queue 311 * - assign the user call ID to the call at the front of the queue
312 */ 312 */
313int rxrpc_accept_call(struct rxrpc_sock *rx, unsigned long user_call_ID) 313struct rxrpc_call *rxrpc_accept_call(struct rxrpc_sock *rx,
314 unsigned long user_call_ID)
314{ 315{
315 struct rxrpc_call *call; 316 struct rxrpc_call *call;
316 struct rb_node *parent, **pp; 317 struct rb_node *parent, **pp;
@@ -374,12 +375,76 @@ int rxrpc_accept_call(struct rxrpc_sock *rx, unsigned long user_call_ID)
374 BUG(); 375 BUG();
375 if (test_and_set_bit(RXRPC_CALL_ACCEPTED, &call->events)) 376 if (test_and_set_bit(RXRPC_CALL_ACCEPTED, &call->events))
376 BUG(); 377 BUG();
377 schedule_work(&call->processor); 378 rxrpc_queue_call(call);
378 379
380 rxrpc_get_call(call);
379 write_unlock_bh(&call->state_lock); 381 write_unlock_bh(&call->state_lock);
380 write_unlock(&rx->call_lock); 382 write_unlock(&rx->call_lock);
381 _leave(" = 0"); 383 _leave(" = %p{%d}", call, call->debug_id);
382 return 0; 384 return call;
385
386 /* if the call is already dying or dead, then we leave the socket's ref
387 * on it to be released by rxrpc_dead_call_expired() as induced by
388 * rxrpc_release_call() */
389out_release:
390 _debug("release %p", call);
391 if (!test_bit(RXRPC_CALL_RELEASED, &call->flags) &&
392 !test_and_set_bit(RXRPC_CALL_RELEASE, &call->events))
393 rxrpc_queue_call(call);
394out_discard:
395 write_unlock_bh(&call->state_lock);
396 _debug("discard %p", call);
397out:
398 write_unlock(&rx->call_lock);
399 _leave(" = %d", ret);
400 return ERR_PTR(ret);
401}
402
403/*
404 * handle rejectance of a call by userspace
405 * - reject the call at the front of the queue
406 */
407int rxrpc_reject_call(struct rxrpc_sock *rx)
408{
409 struct rxrpc_call *call;
410 int ret;
411
412 _enter("");
413
414 ASSERT(!irqs_disabled());
415
416 write_lock(&rx->call_lock);
417
418 ret = -ENODATA;
419 if (list_empty(&rx->acceptq))
420 goto out;
421
422 /* dequeue the first call and check it's still valid */
423 call = list_entry(rx->acceptq.next, struct rxrpc_call, accept_link);
424 list_del_init(&call->accept_link);
425 sk_acceptq_removed(&rx->sk);
426
427 write_lock_bh(&call->state_lock);
428 switch (call->state) {
429 case RXRPC_CALL_SERVER_ACCEPTING:
430 call->state = RXRPC_CALL_SERVER_BUSY;
431 if (test_and_set_bit(RXRPC_CALL_REJECT_BUSY, &call->events))
432 rxrpc_queue_call(call);
433 ret = 0;
434 goto out_release;
435 case RXRPC_CALL_REMOTELY_ABORTED:
436 case RXRPC_CALL_LOCALLY_ABORTED:
437 ret = -ECONNABORTED;
438 goto out_release;
439 case RXRPC_CALL_NETWORK_ERROR:
440 ret = call->conn->error;
441 goto out_release;
442 case RXRPC_CALL_DEAD:
443 ret = -ETIME;
444 goto out_discard;
445 default:
446 BUG();
447 }
383 448
384 /* if the call is already dying or dead, then we leave the socket's ref 449 /* if the call is already dying or dead, then we leave the socket's ref
385 * on it to be released by rxrpc_dead_call_expired() as induced by 450 * on it to be released by rxrpc_dead_call_expired() as induced by
@@ -388,7 +453,7 @@ out_release:
388 _debug("release %p", call); 453 _debug("release %p", call);
389 if (!test_bit(RXRPC_CALL_RELEASED, &call->flags) && 454 if (!test_bit(RXRPC_CALL_RELEASED, &call->flags) &&
390 !test_and_set_bit(RXRPC_CALL_RELEASE, &call->events)) 455 !test_and_set_bit(RXRPC_CALL_RELEASE, &call->events))
391 schedule_work(&call->processor); 456 rxrpc_queue_call(call);
392out_discard: 457out_discard:
393 write_unlock_bh(&call->state_lock); 458 write_unlock_bh(&call->state_lock);
394 _debug("discard %p", call); 459 _debug("discard %p", call);
@@ -397,3 +462,43 @@ out:
397 _leave(" = %d", ret); 462 _leave(" = %d", ret);
398 return ret; 463 return ret;
399} 464}
465
466/**
467 * rxrpc_kernel_accept_call - Allow a kernel service to accept an incoming call
468 * @sock: The socket on which the impending call is waiting
469 * @user_call_ID: The tag to attach to the call
470 *
471 * Allow a kernel service to accept an incoming call, assuming the incoming
472 * call is still valid.
473 */
474struct rxrpc_call *rxrpc_kernel_accept_call(struct socket *sock,
475 unsigned long user_call_ID)
476{
477 struct rxrpc_call *call;
478
479 _enter(",%lx", user_call_ID);
480 call = rxrpc_accept_call(rxrpc_sk(sock->sk), user_call_ID);
481 _leave(" = %p", call);
482 return call;
483}
484
485EXPORT_SYMBOL(rxrpc_kernel_accept_call);
486
487/**
488 * rxrpc_kernel_reject_call - Allow a kernel service to reject an incoming call
489 * @sock: The socket on which the impending call is waiting
490 *
491 * Allow a kernel service to reject an incoming call with a BUSY message,
492 * assuming the incoming call is still valid.
493 */
494int rxrpc_kernel_reject_call(struct socket *sock)
495{
496 int ret;
497
498 _enter("");
499 ret = rxrpc_reject_call(rxrpc_sk(sock->sk));
500 _leave(" = %d", ret);
501 return ret;
502}
503
504EXPORT_SYMBOL(rxrpc_kernel_reject_call);