summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJianyu Li <jianyu.li@mediatek.com>2026-06-01 19:36:39 +0800
committerJakub Kicinski <kuba@kernel.org>2026-06-03 18:52:25 -0700
commitc1f07a7f2d47aeb9878301e7bb36bc1c2bc2be8e (patch)
tree6e62c19b5a0bf1e877e46467bfeddefec0d173a4
parent9a85ec3dc28b6df246801c19e4d9bae6297a25b0 (diff)
af_unix: Fix inq_len update problem in partial read
Currently inq_len is updated only when the whole skb is consumed. If only part of the data is read, following SIOCINQ query would get value greater than what actually left. This change update inq_len timely in unix_stream_read_generic(), and adjust unix_stream_read_skb() accordingly to prevent repetitive update. Fixes: f4e1fb04c123 ("af_unix: Use cached value for SOCK_STREAM in unix_inq_len().") Signed-off-by: Jianyu Li <jianyu.li@mediatek.com> Reviewed-by: Kuniyuki Iwashima <kuniyu@google.com> Link: https://patch.msgid.link/20260601113640.231897-2-jianyu.li@mediatek.com Signed-off-by: Jakub Kicinski <kuba@kernel.org>
-rw-r--r--net/unix/af_unix.c11
1 files changed, 6 insertions, 5 deletions
diff --git a/net/unix/af_unix.c b/net/unix/af_unix.c
index dc71ed79be4a..0d9cd977c7b7 100644
--- a/net/unix/af_unix.c
+++ b/net/unix/af_unix.c
@@ -2886,7 +2886,7 @@ static int unix_stream_read_skb(struct sock *sk, skb_read_actor_t recv_actor)
return -EAGAIN;
}
- WRITE_ONCE(u->inq_len, u->inq_len - skb->len);
+ WRITE_ONCE(u->inq_len, u->inq_len - unix_skb_len(skb));
#if IS_ENABLED(CONFIG_AF_UNIX_OOB)
if (skb == u->oob_skb) {
@@ -3063,11 +3063,12 @@ unlock:
unix_detach_fds(&scm, skb);
}
- if (unix_skb_len(skb))
- break;
-
spin_lock(&sk->sk_receive_queue.lock);
- WRITE_ONCE(u->inq_len, u->inq_len - skb->len);
+ WRITE_ONCE(u->inq_len, u->inq_len - chunk);
+ if (unix_skb_len(skb)) {
+ spin_unlock(&sk->sk_receive_queue.lock);
+ break;
+ }
__skb_unlink(skb, &sk->sk_receive_queue);
spin_unlock(&sk->sk_receive_queue.lock);