summaryrefslogtreecommitdiffstats
path: root/net/rxrpc
diff options
context:
space:
mode:
authorDavid Howells <dhowells@redhat.com>2017-11-24 05:18:41 -0500
committerDavid Howells <dhowells@redhat.com>2017-11-24 05:18:41 -0500
commit4812417894770f8c13e5dd8a66479ae44f4b01ff (patch)
tree13ec7da77904bfd0549ee211ec38b48a3490b54e /net/rxrpc
parent3136ef49a14ccc148becf813074e08fc92fc9b23 (diff)
rxrpc: Split the call params from the operation params
When rxrpc_sendmsg() parses the control message buffer, it places the parameters extracted into a structure, but lumps together call parameters (such as user call ID) with operation parameters (such as whether to send data, send an abort or accept a call). Split the call parameters out into their own structure, a copy of which is then embedded in the operation parameters struct. The call parameters struct is then passed down into the places that need it instead of passing the individual parameters. This allows for extra call parameters to be added. Signed-off-by: David Howells <dhowells@redhat.com>
Diffstat (limited to 'net/rxrpc')
-rw-r--r--net/rxrpc/af_rxrpc.c8
-rw-r--r--net/rxrpc/ar-internal.h31
-rw-r--r--net/rxrpc/call_object.c15
-rw-r--r--net/rxrpc/sendmsg.c51
4 files changed, 60 insertions, 45 deletions
diff --git a/net/rxrpc/af_rxrpc.c b/net/rxrpc/af_rxrpc.c
index 9b5c46b052fd..c0cdcf980ffc 100644
--- a/net/rxrpc/af_rxrpc.c
+++ b/net/rxrpc/af_rxrpc.c
@@ -285,6 +285,7 @@ struct rxrpc_call *rxrpc_kernel_begin_call(struct socket *sock,
285 bool upgrade) 285 bool upgrade)
286{ 286{
287 struct rxrpc_conn_parameters cp; 287 struct rxrpc_conn_parameters cp;
288 struct rxrpc_call_params p;
288 struct rxrpc_call *call; 289 struct rxrpc_call *call;
289 struct rxrpc_sock *rx = rxrpc_sk(sock->sk); 290 struct rxrpc_sock *rx = rxrpc_sk(sock->sk);
290 int ret; 291 int ret;
@@ -302,6 +303,10 @@ struct rxrpc_call *rxrpc_kernel_begin_call(struct socket *sock,
302 if (key && !key->payload.data[0]) 303 if (key && !key->payload.data[0])
303 key = NULL; /* a no-security key */ 304 key = NULL; /* a no-security key */
304 305
306 memset(&p, 0, sizeof(p));
307 p.user_call_ID = user_call_ID;
308 p.tx_total_len = tx_total_len;
309
305 memset(&cp, 0, sizeof(cp)); 310 memset(&cp, 0, sizeof(cp));
306 cp.local = rx->local; 311 cp.local = rx->local;
307 cp.key = key; 312 cp.key = key;
@@ -309,8 +314,7 @@ struct rxrpc_call *rxrpc_kernel_begin_call(struct socket *sock,
309 cp.exclusive = false; 314 cp.exclusive = false;
310 cp.upgrade = upgrade; 315 cp.upgrade = upgrade;
311 cp.service_id = srx->srx_service; 316 cp.service_id = srx->srx_service;
312 call = rxrpc_new_client_call(rx, &cp, srx, user_call_ID, tx_total_len, 317 call = rxrpc_new_client_call(rx, &cp, srx, &p, gfp);
313 gfp);
314 /* The socket has been unlocked. */ 318 /* The socket has been unlocked. */
315 if (!IS_ERR(call)) { 319 if (!IS_ERR(call)) {
316 call->notify_rx = notify_rx; 320 call->notify_rx = notify_rx;
diff --git a/net/rxrpc/ar-internal.h b/net/rxrpc/ar-internal.h
index d1213d503f30..ba63f2231107 100644
--- a/net/rxrpc/ar-internal.h
+++ b/net/rxrpc/ar-internal.h
@@ -643,6 +643,35 @@ struct rxrpc_ack_summary {
643 u8 cumulative_acks; 643 u8 cumulative_acks;
644}; 644};
645 645
646/*
647 * sendmsg() cmsg-specified parameters.
648 */
649enum rxrpc_command {
650 RXRPC_CMD_SEND_DATA, /* send data message */
651 RXRPC_CMD_SEND_ABORT, /* request abort generation */
652 RXRPC_CMD_ACCEPT, /* [server] accept incoming call */
653 RXRPC_CMD_REJECT_BUSY, /* [server] reject a call as busy */
654};
655
656struct rxrpc_call_params {
657 s64 tx_total_len; /* Total Tx data length (if send data) */
658 unsigned long user_call_ID; /* User's call ID */
659 struct {
660 u32 hard; /* Maximum lifetime (sec) */
661 u32 idle; /* Max time since last data packet (msec) */
662 u32 normal; /* Max time since last call packet (msec) */
663 } timeouts;
664 u8 nr_timeouts; /* Number of timeouts specified */
665};
666
667struct rxrpc_send_params {
668 struct rxrpc_call_params call;
669 u32 abort_code; /* Abort code to Tx (if abort) */
670 enum rxrpc_command command : 8; /* The command to implement */
671 bool exclusive; /* Shared or exclusive call */
672 bool upgrade; /* If the connection is upgradeable */
673};
674
646#include <trace/events/rxrpc.h> 675#include <trace/events/rxrpc.h>
647 676
648/* 677/*
@@ -687,7 +716,7 @@ struct rxrpc_call *rxrpc_alloc_call(struct rxrpc_sock *, gfp_t);
687struct rxrpc_call *rxrpc_new_client_call(struct rxrpc_sock *, 716struct rxrpc_call *rxrpc_new_client_call(struct rxrpc_sock *,
688 struct rxrpc_conn_parameters *, 717 struct rxrpc_conn_parameters *,
689 struct sockaddr_rxrpc *, 718 struct sockaddr_rxrpc *,
690 unsigned long, s64, gfp_t); 719 struct rxrpc_call_params *, gfp_t);
691int rxrpc_retry_client_call(struct rxrpc_sock *, 720int rxrpc_retry_client_call(struct rxrpc_sock *,
692 struct rxrpc_call *, 721 struct rxrpc_call *,
693 struct rxrpc_conn_parameters *, 722 struct rxrpc_conn_parameters *,
diff --git a/net/rxrpc/call_object.c b/net/rxrpc/call_object.c
index 1f141dc08ad2..c3e1fa854471 100644
--- a/net/rxrpc/call_object.c
+++ b/net/rxrpc/call_object.c
@@ -208,8 +208,7 @@ static void rxrpc_start_call_timer(struct rxrpc_call *call)
208struct rxrpc_call *rxrpc_new_client_call(struct rxrpc_sock *rx, 208struct rxrpc_call *rxrpc_new_client_call(struct rxrpc_sock *rx,
209 struct rxrpc_conn_parameters *cp, 209 struct rxrpc_conn_parameters *cp,
210 struct sockaddr_rxrpc *srx, 210 struct sockaddr_rxrpc *srx,
211 unsigned long user_call_ID, 211 struct rxrpc_call_params *p,
212 s64 tx_total_len,
213 gfp_t gfp) 212 gfp_t gfp)
214 __releases(&rx->sk.sk_lock.slock) 213 __releases(&rx->sk.sk_lock.slock)
215{ 214{
@@ -219,7 +218,7 @@ struct rxrpc_call *rxrpc_new_client_call(struct rxrpc_sock *rx,
219 const void *here = __builtin_return_address(0); 218 const void *here = __builtin_return_address(0);
220 int ret; 219 int ret;
221 220
222 _enter("%p,%lx", rx, user_call_ID); 221 _enter("%p,%lx", rx, p->user_call_ID);
223 222
224 call = rxrpc_alloc_client_call(rx, srx, gfp); 223 call = rxrpc_alloc_client_call(rx, srx, gfp);
225 if (IS_ERR(call)) { 224 if (IS_ERR(call)) {
@@ -228,9 +227,9 @@ struct rxrpc_call *rxrpc_new_client_call(struct rxrpc_sock *rx,
228 return call; 227 return call;
229 } 228 }
230 229
231 call->tx_total_len = tx_total_len; 230 call->tx_total_len = p->tx_total_len;
232 trace_rxrpc_call(call, rxrpc_call_new_client, atomic_read(&call->usage), 231 trace_rxrpc_call(call, rxrpc_call_new_client, atomic_read(&call->usage),
233 here, (const void *)user_call_ID); 232 here, (const void *)p->user_call_ID);
234 233
235 /* We need to protect a partially set up call against the user as we 234 /* We need to protect a partially set up call against the user as we
236 * will be acting outside the socket lock. 235 * will be acting outside the socket lock.
@@ -246,16 +245,16 @@ struct rxrpc_call *rxrpc_new_client_call(struct rxrpc_sock *rx,
246 parent = *pp; 245 parent = *pp;
247 xcall = rb_entry(parent, struct rxrpc_call, sock_node); 246 xcall = rb_entry(parent, struct rxrpc_call, sock_node);
248 247
249 if (user_call_ID < xcall->user_call_ID) 248 if (p->user_call_ID < xcall->user_call_ID)
250 pp = &(*pp)->rb_left; 249 pp = &(*pp)->rb_left;
251 else if (user_call_ID > xcall->user_call_ID) 250 else if (p->user_call_ID > xcall->user_call_ID)
252 pp = &(*pp)->rb_right; 251 pp = &(*pp)->rb_right;
253 else 252 else
254 goto error_dup_user_ID; 253 goto error_dup_user_ID;
255 } 254 }
256 255
257 rcu_assign_pointer(call->socket, rx); 256 rcu_assign_pointer(call->socket, rx);
258 call->user_call_ID = user_call_ID; 257 call->user_call_ID = p->user_call_ID;
259 __set_bit(RXRPC_CALL_HAS_USERID, &call->flags); 258 __set_bit(RXRPC_CALL_HAS_USERID, &call->flags);
260 rxrpc_get_call(call, rxrpc_call_got_userid); 259 rxrpc_get_call(call, rxrpc_call_got_userid);
261 rb_link_node(&call->sock_node, parent, pp); 260 rb_link_node(&call->sock_node, parent, pp);
diff --git a/net/rxrpc/sendmsg.c b/net/rxrpc/sendmsg.c
index 94555c94b2d8..de5ab327c18a 100644
--- a/net/rxrpc/sendmsg.c
+++ b/net/rxrpc/sendmsg.c
@@ -21,22 +21,6 @@
21#include <net/af_rxrpc.h> 21#include <net/af_rxrpc.h>
22#include "ar-internal.h" 22#include "ar-internal.h"
23 23
24enum rxrpc_command {
25 RXRPC_CMD_SEND_DATA, /* send data message */
26 RXRPC_CMD_SEND_ABORT, /* request abort generation */
27 RXRPC_CMD_ACCEPT, /* [server] accept incoming call */
28 RXRPC_CMD_REJECT_BUSY, /* [server] reject a call as busy */
29};
30
31struct rxrpc_send_params {
32 s64 tx_total_len; /* Total Tx data length (if send data) */
33 unsigned long user_call_ID; /* User's call ID */
34 u32 abort_code; /* Abort code to Tx (if abort) */
35 enum rxrpc_command command : 8; /* The command to implement */
36 bool exclusive; /* Shared or exclusive call */
37 bool upgrade; /* If the connection is upgradeable */
38};
39
40/* 24/*
41 * Wait for space to appear in the Tx queue or a signal to occur. 25 * Wait for space to appear in the Tx queue or a signal to occur.
42 */ 26 */
@@ -480,11 +464,11 @@ static int rxrpc_sendmsg_cmsg(struct msghdr *msg, struct rxrpc_send_params *p)
480 if (msg->msg_flags & MSG_CMSG_COMPAT) { 464 if (msg->msg_flags & MSG_CMSG_COMPAT) {
481 if (len != sizeof(u32)) 465 if (len != sizeof(u32))
482 return -EINVAL; 466 return -EINVAL;
483 p->user_call_ID = *(u32 *)CMSG_DATA(cmsg); 467 p->call.user_call_ID = *(u32 *)CMSG_DATA(cmsg);
484 } else { 468 } else {
485 if (len != sizeof(unsigned long)) 469 if (len != sizeof(unsigned long))
486 return -EINVAL; 470 return -EINVAL;
487 p->user_call_ID = *(unsigned long *) 471 p->call.user_call_ID = *(unsigned long *)
488 CMSG_DATA(cmsg); 472 CMSG_DATA(cmsg);
489 } 473 }
490 got_user_ID = true; 474 got_user_ID = true;
@@ -522,10 +506,10 @@ static int rxrpc_sendmsg_cmsg(struct msghdr *msg, struct rxrpc_send_params *p)
522 break; 506 break;
523 507
524 case RXRPC_TX_LENGTH: 508 case RXRPC_TX_LENGTH:
525 if (p->tx_total_len != -1 || len != sizeof(__s64)) 509 if (p->call.tx_total_len != -1 || len != sizeof(__s64))
526 return -EINVAL; 510 return -EINVAL;
527 p->tx_total_len = *(__s64 *)CMSG_DATA(cmsg); 511 p->call.tx_total_len = *(__s64 *)CMSG_DATA(cmsg);
528 if (p->tx_total_len < 0) 512 if (p->call.tx_total_len < 0)
529 return -EINVAL; 513 return -EINVAL;
530 break; 514 break;
531 515
@@ -536,7 +520,7 @@ static int rxrpc_sendmsg_cmsg(struct msghdr *msg, struct rxrpc_send_params *p)
536 520
537 if (!got_user_ID) 521 if (!got_user_ID)
538 return -EINVAL; 522 return -EINVAL;
539 if (p->tx_total_len != -1 && p->command != RXRPC_CMD_SEND_DATA) 523 if (p->call.tx_total_len != -1 && p->command != RXRPC_CMD_SEND_DATA)
540 return -EINVAL; 524 return -EINVAL;
541 _leave(" = 0"); 525 _leave(" = 0");
542 return 0; 526 return 0;
@@ -576,8 +560,7 @@ rxrpc_new_client_call_for_sendmsg(struct rxrpc_sock *rx, struct msghdr *msg,
576 cp.exclusive = rx->exclusive | p->exclusive; 560 cp.exclusive = rx->exclusive | p->exclusive;
577 cp.upgrade = p->upgrade; 561 cp.upgrade = p->upgrade;
578 cp.service_id = srx->srx_service; 562 cp.service_id = srx->srx_service;
579 call = rxrpc_new_client_call(rx, &cp, srx, p->user_call_ID, 563 call = rxrpc_new_client_call(rx, &cp, srx, &p->call, GFP_KERNEL);
580 p->tx_total_len, GFP_KERNEL);
581 /* The socket is now unlocked */ 564 /* The socket is now unlocked */
582 565
583 _leave(" = %p\n", call); 566 _leave(" = %p\n", call);
@@ -597,12 +580,12 @@ int rxrpc_do_sendmsg(struct rxrpc_sock *rx, struct msghdr *msg, size_t len)
597 int ret; 580 int ret;
598 581
599 struct rxrpc_send_params p = { 582 struct rxrpc_send_params p = {
600 .tx_total_len = -1, 583 .call.tx_total_len = -1,
601 .user_call_ID = 0, 584 .call.user_call_ID = 0,
602 .abort_code = 0, 585 .abort_code = 0,
603 .command = RXRPC_CMD_SEND_DATA, 586 .command = RXRPC_CMD_SEND_DATA,
604 .exclusive = false, 587 .exclusive = false,
605 .upgrade = false, 588 .upgrade = false,
606 }; 589 };
607 590
608 _enter(""); 591 _enter("");
@@ -615,7 +598,7 @@ int rxrpc_do_sendmsg(struct rxrpc_sock *rx, struct msghdr *msg, size_t len)
615 ret = -EINVAL; 598 ret = -EINVAL;
616 if (rx->sk.sk_state != RXRPC_SERVER_LISTENING) 599 if (rx->sk.sk_state != RXRPC_SERVER_LISTENING)
617 goto error_release_sock; 600 goto error_release_sock;
618 call = rxrpc_accept_call(rx, p.user_call_ID, NULL); 601 call = rxrpc_accept_call(rx, p.call.user_call_ID, NULL);
619 /* The socket is now unlocked. */ 602 /* The socket is now unlocked. */
620 if (IS_ERR(call)) 603 if (IS_ERR(call))
621 return PTR_ERR(call); 604 return PTR_ERR(call);
@@ -623,7 +606,7 @@ int rxrpc_do_sendmsg(struct rxrpc_sock *rx, struct msghdr *msg, size_t len)
623 goto out_put_unlock; 606 goto out_put_unlock;
624 } 607 }
625 608
626 call = rxrpc_find_call_by_user_ID(rx, p.user_call_ID); 609 call = rxrpc_find_call_by_user_ID(rx, p.call.user_call_ID);
627 if (!call) { 610 if (!call) {
628 ret = -EBADSLT; 611 ret = -EBADSLT;
629 if (p.command != RXRPC_CMD_SEND_DATA) 612 if (p.command != RXRPC_CMD_SEND_DATA)
@@ -653,13 +636,13 @@ int rxrpc_do_sendmsg(struct rxrpc_sock *rx, struct msghdr *msg, size_t len)
653 goto error_put; 636 goto error_put;
654 } 637 }
655 638
656 if (p.tx_total_len != -1) { 639 if (p.call.tx_total_len != -1) {
657 ret = -EINVAL; 640 ret = -EINVAL;
658 if (call->tx_total_len != -1 || 641 if (call->tx_total_len != -1 ||
659 call->tx_pending || 642 call->tx_pending ||
660 call->tx_top != 0) 643 call->tx_top != 0)
661 goto error_put; 644 goto error_put;
662 call->tx_total_len = p.tx_total_len; 645 call->tx_total_len = p.call.tx_total_len;
663 } 646 }
664 } 647 }
665 648