A reply can arrive after io_wait_event_killable() reports an interruption
but before the client starts cancellation. In that case the request is
already complete and must not be flushed or returned as an error.
Recheck REQ_STATUS_RCVD before entering the flush path in both regular and
zero-copy RPCs.
Signed-off-by: Ze Tan <redacted>
---
net/9p/client.c | 10 ++++++++++
1 file changed, 10 insertions(+)
diff --git a/net/9p/client.c b/net/9p/client.c
index ef64546c6d52..b9860ccb224b 100644
--- a/net/9p/client.c
+++ b/net/9p/client.c
@@ -612,6 +612,11 @@ p9_client_rpc(struct p9_client *c, int8_t type, const char *fmt, ...)
err = req->t_err;
}
if (err == -ERESTARTSYS && c->status == Connected) {
+ if (READ_ONCE(req->status) == REQ_STATUS_RCVD) {
+ err = 0;
+ goto recalc_sigpending;
+ }
+
p9_debug(P9_DEBUG_MUX, "flushing\n");
sigpending = 1;
clear_thread_flag(TIF_SIGPENDING);@@ -697,6 +702,11 @@ static struct p9_req_t *p9_client_zc_rpc(struct p9_client *c, int8_t type,
err = req->t_err;
}
if (err == -ERESTARTSYS && c->status == Connected) {
+ if (READ_ONCE(req->status) == REQ_STATUS_RCVD) {
+ err = 0;
+ goto recalc_sigpending;
+ }
+
p9_debug(P9_DEBUG_MUX, "flushing\n");
sigpending = 1;
clear_thread_flag(TIF_SIGPENDING);--
2.43.0