FAILED: patch "[PATCH] rxrpc: Fix lack of short-send handling in" failed to apply to 5.10-stable tree
Subsystems (5)
[email protected]
maintainerThe patch below does not apply to the 5.10-stable tree.
If someone wants it applied there, or to any other stable or longterm tree, then please email the backport, including the original git commit id to <[email protected]>.
To reproduce the conflict and resubmit, you may use the following commands:
git fetch https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/ linux-5.10.y
git checkout FETCH_HEAD
git cherry-pick -x af208f36ae22440cf6011a43cb3064fd525d85b4
# <resolve conflicts, build, test, etc.>
git commit -s
git send-email --to '<[email protected]>' --in-reply-to '2026110458-debug-deranged-4db4@gregkh' --subject-prefix 'PATCH 5.10.y' 'HEAD^..'
Possible dependencies:
thanks,
greg k-h
------------------ original commit in Linus's tree ------------------
From af208f36ae22440cf6011a43cb3064fd525d85b4 Mon Sep 17 00:00:00 2001
From: David Howells <[email protected]>
Date: Tue, 6 Oct 2026 14:29:56 +0100
Subject: [PATCH] rxrpc: Fix lack of short-send handling in
rxrpc_kernel_send_data()
Fix rxrpc_kernel_send_data() to loop around if it detects a short send. David Laight suggested doing it here rather than wrapping all the calls in loops. Further, remove the len argument and use the iterator count instead and return 0 on success, not the amount copied.
Note this is also a prerequisite for changing the way rxrpc_send_data() works to return a short send rather than an error if some data was buffered.
Documentation/networking/rxrpc.rst +5 -3
@@ -870,7 +870,6 @@ The kernel interface functions are as follows: int rxrpc_kernel_send_data(struct socket *sock, struct rxrpc_call *call, struct msghdr *msg, - size_t len, rxrpc_notify_end_tx_t notify_end_rx); This is used to supply either the request part of a client call or the
@@ -879,14 +878,17 @@ The kernel interface functions are as follows: exclusively to in-kernel virtual addresses. msg.msg_flags may be given MSG_MORE if there will be subsequent data sends for this call. - The msg must not specify a destination address, control data or any flags - other than MSG_MORE. len is the total amount of data to transmit. + msg must not specify a destination address, control data or any flags + other than MSG_MORE or MSG_WAITALL. notify_end_rx can be NULL or it can be used to specify a function to be called when the call changes state to end the Tx phase. This function is called with a spinlock held to prevent the last DATA packet from being transmitted until the function returns. + It returns 0 if all the provided data has been buffered and a negative + error code on failure. + (#) Receive data from a call:: int rxrpc_kernel_recv_data(struct socket *sock,
fs/afs/rxrpc.c +13 -19
@@ -412,8 +412,7 @@ void afs_make_call(struct afs_call *call, gfp_t gfp) msg.msg_controllen =0 ; msg.msg_flags =MSG_WAITALL | (call->write_iter ?MSG_MORE :0 ); - ret =rxrpc_kernel_send_data (call->net->socket, rxcall, - &msg, call->request_size, + ret =rxrpc_kernel_send_data (call->net->socket, rxcall, &msg, afs_notify_end_request_tx);if (ret <0 ) goto error_do_abort;
@@ -425,7 +424,6 @@ void afs_make_call(struct afs_call *call, gfp_t gfp) ret =rxrpc_kernel_send_data (call->net->socket, call->rxcall, &msg, -iov_iter_count (&msg.msg_iter), afs_notify_end_request_tx); *call->write_iter = msg.msg_iter;
@@ -871,7 +869,7 @@ void afs_send_empty_reply(struct afs_call *call) msg.msg_controllen =0 ; msg.msg_flags =0 ; -switch (rxrpc_kernel_send_data (net->socket, call->rxcall, &msg,0 , +switch (rxrpc_kernel_send_data (net->socket, call->rxcall, &msg, afs_notify_end_reply_tx)) {case 0 :_leave (" [replied]" );
@@ -897,7 +895,7 @@ void afs_send_simple_reply(struct afs_call *call, const void *buf, size_t len)struct afs_net *net = call->net;struct msghdr msg;struct kvec iov[1 ]; -int n; +int ret;_enter ("" );
@@ -912,21 +910,17 @@ void afs_send_simple_reply(struct afs_call *call, const void *buf, size_t len) msg.msg_controllen =0 ; msg.msg_flags =0 ; - n =rxrpc_kernel_send_data (net->socket, call->rxcall, &msg, len, - afs_notify_end_reply_tx); -if (n >=0 ) { -/* Success */ -_leave (" [replied]" ); -return ; + ret =rxrpc_kernel_send_data (net->socket, call->rxcall, &msg, + afs_notify_end_reply_tx); +if (ret <0 ) { +if (ret == -ENOMEM ) { +_debug ("oom" ); +rxrpc_kernel_abort_call (net->socket, call->rxcall, +RXGEN_SS_MARSHAL , -ENOMEM , + afs_abort_oom); + } +_leave (" [error]" ); } - -if (n == -ENOMEM ) { -_debug ("oom" ); -rxrpc_kernel_abort_call (net->socket, call->rxcall, -RXGEN_SS_MARSHAL , -ENOMEM , - afs_abort_oom); - } -_leave (" [error]" ); }/*
include/net/af_rxrpc.h +2 -3
@@ -64,9 +64,8 @@ struct rxrpc_call *rxrpc_kernel_begin_call(struct socket *sock,bool upgrade, enum rxrpc_interruptibility interruptibility, unsigned int debug_id); -int rxrpc_kernel_send_data (struct socket *,struct rxrpc_call *, -struct msghdr *,size_t , -rxrpc_notify_end_tx_t ); +int rxrpc_kernel_send_data (struct socket *sock,struct rxrpc_call *call, +struct msghdr *msg,rxrpc_notify_end_tx_t notify_end_tx);int rxrpc_kernel_recv_data (struct socket *,struct rxrpc_call *,struct iov_iter *,size_t *,bool ,u32 *,u16 *); bool rxrpc_kernel_abort_call(struct socket *, struct rxrpc_call *,
net/rxrpc/rxperf.c +10 -15
@@ -501,8 +501,8 @@ static int rxperf_process_call(struct rxperf_call *call)struct msghdr msg = {};struct bio_vec bv;struct kvec iov[1 ]; -ssize_t n;size_t reply_len = call->reply_len, len; +int ret;rxrpc_kernel_set_tx_length (rxperf_socket, call->rxcall, reply_len +sizeof (rxperf_magic_cookie));
@@ -512,13 +512,11 @@ static int rxperf_process_call(struct rxperf_call *call)bvec_set_page (&bv,ZERO_PAGE (0 ), len,0 );iov_iter_bvec (&msg.msg_iter,WRITE , &bv,1 , len); msg.msg_flags =MSG_MORE ; - n =rxrpc_kernel_send_data (rxperf_socket, call->rxcall, &msg, - len, rxperf_notify_end_reply_tx); -if (n <0 ) -return n; -if (n ==0 ) -return -EIO ; - reply_len -= n; + ret =rxrpc_kernel_send_data (rxperf_socket, call->rxcall, &msg, + rxperf_notify_end_reply_tx); +if (ret <0 ) +return ret; + reply_len -= len; } len =sizeof (rxperf_magic_cookie);
@@ -526,16 +524,13 @@ static int rxperf_process_call(struct rxperf_call *call) iov[0 ].iov_len = len;iov_iter_kvec (&msg.msg_iter,WRITE , iov,1 , len); msg.msg_flags =0 ; - n =rxrpc_kernel_send_data (rxperf_socket, call->rxcall, &msg, len, - rxperf_notify_end_reply_tx); -if (n >=0 ) -return 0 ;/* Success */ - -if (n == -ENOMEM ) + ret =rxrpc_kernel_send_data (rxperf_socket, call->rxcall, &msg, + rxperf_notify_end_reply_tx); +if (ret == -ENOMEM )rxrpc_kernel_abort_call (rxperf_socket, call->rxcall,RXGEN_SS_MARSHAL , -ENOMEM , rxperf_abort_oom); -return n; +return ret; }/*
net/rxrpc/sendmsg.c +19 -8
@@ -793,7 +793,6 @@ int rxrpc_do_sendmsg(struct rxrpc_sock *rx, struct msghdr *msg, size_t len)* @sock: The socket the call is on * @call: The call to send data through * @msg: The data to send -* @len: The amount of data to send * @notify_end_tx: Notification that the last packet is queued. * * Allow a kernel service to send data on a call. The call must be in an state
@@ -804,8 +803,7 @@ int rxrpc_do_sendmsg(struct rxrpc_sock *rx, struct msghdr *msg, size_t len)* Return: %0 if successful and a negative error code otherwise. */ int rxrpc_kernel_send_data (struct socket *sock,struct rxrpc_call *call, -struct msghdr *msg,size_t len, -rxrpc_notify_end_tx_t notify_end_tx) +struct msghdr *msg,rxrpc_notify_end_tx_t notify_end_tx) {int ret;
@@ -814,12 +812,25 @@ int rxrpc_kernel_send_data(struct socket *sock, struct rxrpc_call *call, ASSERTCMP(msg->msg_name, ==, NULL); ASSERTCMP(msg->msg_control, ==, NULL); -mutex_lock (&call->user_mutex); +for (;;) { +mutex_lock (&call->user_mutex); + + ret =rxrpc_send_data (rxrpc_sk (sock->sk), call, msg, +msg_data_left (msg), notify_end_tx); +if (ret == -ESHUTDOWN ) + ret = call->error; +if (ret <0 ) +break ; +if (msg_data_left (msg) ==0 ) { + ret =0 ; +break ; + } +if (ret ==0 ) { + ret = -EIO ; +break ; + } + } - ret =rxrpc_send_data (rxrpc_sk (sock->sk), call, msg, len, - notify_end_tx); -if (ret == -ESHUTDOWN ) - ret = call->error;_leave (" = %d" , ret);return ret; }