From: David Howells <dhowells@redhat.com>
To: netdev@vger.kernel.org
Cc: David Howells <dhowells@redhat.com>,
Marc Dionne <marc.dionne@auristor.com>,
Jakub Kicinski <kuba@kernel.org>,
"David S. Miller" <davem@davemloft.net>,
Eric Dumazet <edumazet@google.com>,
Paolo Abeni <pabeni@redhat.com>, Simon Horman <horms@kernel.org>,
linux-afs@lists.infradead.org, linux-kernel@vger.kernel.org,
David Laight <david.laight.linux@gmail.com>,
stable@vger.kernel.org
Subject: [PATCH net v11 04/17] rxrpc: Fix lack of short-send handling in rxrpc_kernel_send_data()
Date: Wed, 23 Sep 2026 14:36:51 +0100 [thread overview]
Message-ID: <20260923133706.1496540-5-dhowells@redhat.com> (raw)
In-Reply-To: <20260923133706.1496540-1-dhowells@redhat.com>
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.
Fixes: 651350d10f93 ("[AF_RXRPC]: Add an interface to the AF_RXRPC module for the AFS filesystem to use")
Link: https://netdev-ai.bots.linux.dev/sashiko/#/patchset/20260824091645.415423-1-dhowells%40redhat.com
Suggested-by: David Laight <david.laight.linux@gmail.com>
Signed-off-by: David Howells <dhowells@redhat.com>
cc: Marc Dionne <marc.dionne@auristor.com>
cc: Eric Dumazet <edumazet@google.com>
cc: "David S. Miller" <davem@davemloft.net>
cc: Jakub Kicinski <kuba@kernel.org>
cc: Paolo Abeni <pabeni@redhat.com>
cc: Simon Horman <horms@kernel.org>
cc: linux-afs@lists.infradead.org
cc: stable@vger.kernel.org
---
Documentation/networking/rxrpc.rst | 6 ++++--
fs/afs/rxrpc.c | 32 ++++++++++++------------------
include/net/af_rxrpc.h | 5 ++---
net/rxrpc/rxperf.c | 25 ++++++++++-------------
net/rxrpc/sendmsg.c | 27 +++++++++++++++++--------
5 files changed, 48 insertions(+), 47 deletions(-)
diff --git a/Documentation/networking/rxrpc.rst b/Documentation/networking/rxrpc.rst
index 8926dab8e2e6..01ad12fdf305 100644
--- a/Documentation/networking/rxrpc.rst
+++ b/Documentation/networking/rxrpc.rst
@@ -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
@@ -880,13 +879,16 @@ The kernel interface functions are as follows:
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.
+ other than MSG_MORE.
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 data is queued and a negative error code on
+ failure.
+
(#) Receive data from a call::
int rxrpc_kernel_recv_data(struct socket *sock,
diff --git a/fs/afs/rxrpc.c b/fs/afs/rxrpc.c
index d82916657a3d..bcb8bb15d471 100644
--- a/fs/afs/rxrpc.c
+++ b/fs/afs/rxrpc.c
@@ -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;
- }
-
- if (n == -ENOMEM) {
- _debug("oom");
- rxrpc_kernel_abort_call(net->socket, call->rxcall,
- RXGEN_SS_MARSHAL, -ENOMEM,
- afs_abort_oom);
+ 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]");
}
- _leave(" [error]");
}
/*
diff --git a/include/net/af_rxrpc.h b/include/net/af_rxrpc.h
index 0fb4c41c9bbf..f3980348ed34 100644
--- a/include/net/af_rxrpc.h
+++ b/include/net/af_rxrpc.h
@@ -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 *,
diff --git a/net/rxrpc/rxperf.c b/net/rxrpc/rxperf.c
index 26f97e1dd388..981c0596c774 100644
--- a/net/rxrpc/rxperf.c
+++ b/net/rxrpc/rxperf.c
@@ -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;
}
/*
diff --git a/net/rxrpc/sendmsg.c b/net/rxrpc/sendmsg.c
index fb8d48418882..393a2dcfda07 100644
--- a/net/rxrpc/sendmsg.c
+++ b/net/rxrpc/sendmsg.c
@@ -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;
}
next prev parent reply other threads:[~2026-09-23 13:37 UTC|newest]
Thread overview: 19+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-09-23 13:36 [PATCH net v11 00/17] rxrpc: Miscellaneous fixes David Howells
2026-09-23 13:36 ` [PATCH net v11 01/17] rxrpc: Revert "rxrpc: rxperf: Fix missing decoding of terminal magic cookie" David Howells
2026-09-23 13:36 ` [PATCH net v11 02/17] rxrpc: Fix rxperf test rxgk key kvno to be 0 David Howells
2026-09-23 13:36 ` [PATCH net v11 03/17] rxrpc: Fix update of call->tx_pending without holding lock David Howells
2026-09-23 13:36 ` David Howells [this message]
2026-09-23 13:36 ` [PATCH net v11 05/17] afs: Fix afs to abort the rxrpc call on send error David Howells
2026-09-23 13:36 ` [PATCH net v11 06/17] rxrpc: Fix aborting in rxperf test server David Howells
2026-09-23 13:36 ` [PATCH net v11 07/17] rxrpc: Fix sendmsg length David Howells
2026-09-23 13:36 ` [PATCH net v11 08/17] rxrpc: Fix error handling in rxrpc_send_data() David Howells
2026-09-23 13:36 ` [PATCH net v11 09/17] rxrpc: Fix packet encryption error handling David Howells
2026-09-23 13:36 ` [PATCH net v11 10/17] rxrpc: Fix return in rxrpc_recvmsg_data() for service calls David Howells
2026-09-23 13:36 ` [PATCH net v11 11/17] rxrpc: Fix double IRQ enablement David Howells
2026-09-23 13:36 ` [PATCH net v11 12/17] rxrpc: Fix generation of notifications after call completion David Howells
2026-09-23 13:37 ` [PATCH net v11 13/17] rxrpc: Fix RxGK key parser to check enctype is supported David Howells
2026-09-23 13:37 ` [PATCH net v11 14/17] afs: Fix creation of RxGK CM channel token to have right size David Howells
2026-09-23 13:37 ` [PATCH net v11 15/17] afs: Fix lack of setting call->server when doing FS.InlineBulkStatus David Howells
2026-09-23 13:37 ` [PATCH net v11 16/17] afs: Fix uncleared op->call pointer David Howells
2026-09-23 13:37 ` [PATCH net v11 17/17] rxrpc: fix use-after-free in rxrpc_poke_conn() David Howells
2026-09-24 8:45 ` [PATCH net v11 10/17] rxrpc: Fix return in rxrpc_recvmsg_data() for service calls David Howells
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20260923133706.1496540-5-dhowells@redhat.com \
--to=dhowells@redhat.com \
--cc=davem@davemloft.net \
--cc=david.laight.linux@gmail.com \
--cc=edumazet@google.com \
--cc=horms@kernel.org \
--cc=kuba@kernel.org \
--cc=linux-afs@lists.infradead.org \
--cc=linux-kernel@vger.kernel.org \
--cc=marc.dionne@auristor.com \
--cc=netdev@vger.kernel.org \
--cc=pabeni@redhat.com \
--cc=stable@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®