Skip to content

Commit a68f4a2

Browse files
committed
rxrpc: Support service upgrade from a kernel service
Provide support for a kernel service to make use of the service upgrade facility. This involves: (1) Pass an upgrade request flag to rxrpc_kernel_begin_call(). (2) Make rxrpc_kernel_recv_data() return the call's current service ID so that the caller can detect service upgrade and see what the service was upgraded to. Signed-off-by: David Howells <[email protected]>
1 parent 8a5f216 commit a68f4a2

File tree

6 files changed

+34
-10
lines changed

6 files changed

+34
-10
lines changed

Documentation/networking/rxrpc.txt

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -782,7 +782,9 @@ The kernel interface functions are as follows:
782782
struct key *key,
783783
unsigned long user_call_ID,
784784
s64 tx_total_len,
785-
gfp_t gfp);
785+
gfp_t gfp,
786+
rxrpc_notify_rx_t notify_rx,
787+
bool upgrade);
786788

787789
This allocates the infrastructure to make a new RxRPC call and assigns
788790
call and connection numbers. The call will be made on the UDP port that
@@ -803,6 +805,13 @@ The kernel interface functions are as follows:
803805
allows the kernel to encrypt directly to the packet buffers, thereby
804806
saving a copy. The value may not be less than -1.
805807

808+
notify_rx is a pointer to a function to be called when events such as
809+
incoming data packets or remote aborts happen.
810+
811+
upgrade should be set to true if a client operation should request that
812+
the server upgrade the service to a better one. The resultant service ID
813+
is returned by rxrpc_kernel_recv_data().
814+
806815
If this function is successful, an opaque reference to the RxRPC call is
807816
returned. The caller now holds a reference on this and it must be
808817
properly ended.
@@ -850,7 +859,8 @@ The kernel interface functions are as follows:
850859
size_t size,
851860
size_t *_offset,
852861
bool want_more,
853-
u32 *_abort)
862+
u32 *_abort,
863+
u16 *_service)
854864

855865
This is used to receive data from either the reply part of a client call
856866
or the request part of a service call. buf and size specify how much
@@ -873,6 +883,9 @@ The kernel interface functions are as follows:
873883
If a remote ABORT is detected, the abort code received will be stored in
874884
*_abort and ECONNABORTED will be returned.
875885

886+
The service ID that the call ended up with is returned into *_service.
887+
This can be used to see if a call got a service upgrade.
888+
876889
(*) Abort a call.
877890

878891
void rxrpc_kernel_abort_call(struct socket *sock,

fs/afs/internal.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,7 @@ struct afs_call {
100100
bool send_pages; /* T if data from mapping should be sent */
101101
bool need_attention; /* T if RxRPC poked us */
102102
bool async; /* T if asynchronous */
103+
bool upgrade; /* T to request service upgrade */
103104
u16 service_id; /* RxRPC service ID to call */
104105
__be16 port; /* target UDP port */
105106
u32 operation_ID; /* operation ID for an incoming call */

fs/afs/rxrpc.c

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -387,7 +387,8 @@ int afs_make_call(struct in_addr *addr, struct afs_call *call, gfp_t gfp,
387387
tx_total_len, gfp,
388388
(async ?
389389
afs_wake_up_async_call :
390-
afs_wake_up_call_waiter));
390+
afs_wake_up_call_waiter),
391+
call->upgrade);
391392
call->key = NULL;
392393
if (IS_ERR(rxcall)) {
393394
ret = PTR_ERR(rxcall);
@@ -443,7 +444,7 @@ int afs_make_call(struct in_addr *addr, struct afs_call *call, gfp_t gfp,
443444
abort_code = 0;
444445
offset = 0;
445446
rxrpc_kernel_recv_data(afs_socket, rxcall, NULL, 0, &offset,
446-
false, &abort_code);
447+
false, &abort_code, &call->service_id);
447448
ret = call->type->abort_to_error(abort_code);
448449
}
449450
error_kill_call:
@@ -471,7 +472,8 @@ static void afs_deliver_to_call(struct afs_call *call)
471472
size_t offset = 0;
472473
ret = rxrpc_kernel_recv_data(afs_socket, call->rxcall,
473474
NULL, 0, &offset, false,
474-
&call->abort_code);
475+
&call->abort_code,
476+
&call->service_id);
475477
trace_afs_recv_data(call, 0, offset, false, ret);
476478

477479
if (ret == -EINPROGRESS || ret == -EAGAIN)
@@ -851,7 +853,8 @@ int afs_extract_data(struct afs_call *call, void *buf, size_t count,
851853

852854
ret = rxrpc_kernel_recv_data(afs_socket, call->rxcall,
853855
buf, count, &call->offset,
854-
want_more, &call->abort_code);
856+
want_more, &call->abort_code,
857+
&call->service_id);
855858
trace_afs_recv_data(call, count, call->offset, want_more, ret);
856859
if (ret == 0 || ret == -EAGAIN)
857860
return ret;

include/net/af_rxrpc.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -49,12 +49,13 @@ struct rxrpc_call *rxrpc_kernel_begin_call(struct socket *,
4949
unsigned long,
5050
s64,
5151
gfp_t,
52-
rxrpc_notify_rx_t);
52+
rxrpc_notify_rx_t,
53+
bool);
5354
int rxrpc_kernel_send_data(struct socket *, struct rxrpc_call *,
5455
struct msghdr *, size_t,
5556
rxrpc_notify_end_tx_t);
5657
int rxrpc_kernel_recv_data(struct socket *, struct rxrpc_call *,
57-
void *, size_t, size_t *, bool, u32 *);
58+
void *, size_t, size_t *, bool, u32 *, u16 *);
5859
bool rxrpc_kernel_abort_call(struct socket *, struct rxrpc_call *,
5960
u32, int, const char *);
6061
void rxrpc_kernel_end_call(struct socket *, struct rxrpc_call *);

net/rxrpc/af_rxrpc.c

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -265,6 +265,7 @@ static int rxrpc_listen(struct socket *sock, int backlog)
265265
* @tx_total_len: Total length of data to transmit during the call (or -1)
266266
* @gfp: The allocation constraints
267267
* @notify_rx: Where to send notifications instead of socket queue
268+
* @upgrade: Request service upgrade for call
268269
*
269270
* Allow a kernel service to begin a call on the nominated socket. This just
270271
* sets up all the internal tracking structures and allocates connection and
@@ -279,7 +280,8 @@ struct rxrpc_call *rxrpc_kernel_begin_call(struct socket *sock,
279280
unsigned long user_call_ID,
280281
s64 tx_total_len,
281282
gfp_t gfp,
282-
rxrpc_notify_rx_t notify_rx)
283+
rxrpc_notify_rx_t notify_rx,
284+
bool upgrade)
283285
{
284286
struct rxrpc_conn_parameters cp;
285287
struct rxrpc_call *call;
@@ -304,6 +306,7 @@ struct rxrpc_call *rxrpc_kernel_begin_call(struct socket *sock,
304306
cp.key = key;
305307
cp.security_level = 0;
306308
cp.exclusive = false;
309+
cp.upgrade = upgrade;
307310
cp.service_id = srx->srx_service;
308311
call = rxrpc_new_client_call(rx, &cp, srx, user_call_ID, tx_total_len,
309312
gfp);

net/rxrpc/recvmsg.c

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -607,6 +607,7 @@ int rxrpc_recvmsg(struct socket *sock, struct msghdr *msg, size_t len,
607607
* @_offset: The running offset into the buffer.
608608
* @want_more: True if more data is expected to be read
609609
* @_abort: Where the abort code is stored if -ECONNABORTED is returned
610+
* @_service: Where to store the actual service ID (may be upgraded)
610611
*
611612
* Allow a kernel service to receive data and pick up information about the
612613
* state of a call. Returns 0 if got what was asked for and there's more
@@ -624,7 +625,7 @@ int rxrpc_recvmsg(struct socket *sock, struct msghdr *msg, size_t len,
624625
*/
625626
int rxrpc_kernel_recv_data(struct socket *sock, struct rxrpc_call *call,
626627
void *buf, size_t size, size_t *_offset,
627-
bool want_more, u32 *_abort)
628+
bool want_more, u32 *_abort, u16 *_service)
628629
{
629630
struct iov_iter iter;
630631
struct kvec iov;
@@ -680,6 +681,8 @@ int rxrpc_kernel_recv_data(struct socket *sock, struct rxrpc_call *call,
680681
read_phase_complete:
681682
ret = 1;
682683
out:
684+
if (_service)
685+
*_service = call->service_id;
683686
mutex_unlock(&call->user_mutex);
684687
_leave(" = %d [%zu,%d]", ret, *_offset, *_abort);
685688
return ret;

0 commit comments

Comments
 (0)