diff --git a/net/core/datagram.c b/net/core/datagram.c index c285c6465923..3a612ebbbe80 100644 --- a/net/core/datagram.c +++ b/net/core/datagram.c @@ -748,9 +748,13 @@ int __zerocopy_sg_from_iter(struct msghdr *msg, struct sock *sk, size_t length, struct net_devmem_dmabuf_binding *binding) { + struct iov_iter_state state; unsigned long orig_size = skb->truesize; unsigned long truesize; - int ret; + int ret, orig_len; + + iov_iter_save_state(from, &state); + orig_len = skb->len; if (msg && msg->msg_ubuf && msg->sg_from_iter) ret = msg->sg_from_iter(skb, from, length); @@ -759,6 +763,9 @@ int __zerocopy_sg_from_iter(struct msghdr *msg, struct sock *sk, else ret = zerocopy_fill_skb_from_iter(skb, from, length); + if (ret == -EFAULT || (ret == -EMSGSIZE && skb->len == orig_len)) + iov_iter_restore(from, &state); + truesize = skb->truesize - orig_size; if (sk && sk->sk_type == SOCK_STREAM) { sk_wmem_queued_add(sk, truesize); diff --git a/net/core/skbuff.c b/net/core/skbuff.c index a00808f7be6a..7b8836f668b7 100644 --- a/net/core/skbuff.c +++ b/net/core/skbuff.c @@ -1908,7 +1908,6 @@ int skb_zerocopy_iter_stream(struct sock *sk, struct sk_buff *skb, struct sock *save_sk = skb->sk; /* Streams do not free skb on error. Reset to prev state. */ - iov_iter_revert(&msg->msg_iter, skb->len - orig_len); skb->sk = sk; ___pskb_trim(skb, orig_len); skb->sk = save_sk;