diff mbox series

[RFC,v7,06/22] af_vsock: implement send logic for SEQPACKET

Message ID 20210323131045.2460319-1-arseny.krasnov@kaspersky.com
State Superseded
Headers show
Series virtio/vsock: introduce SOCK_SEQPACKET support | expand

Commit Message

Arseny Krasnov March 23, 2021, 1:10 p.m. UTC
This adds some logic to current stream enqueue function for SEQPACKET
support:
1) Use transport's seqpacket enqueue callback.
2) Return value from enqueue function is whole record length or error
   for SOCK_SEQPACKET.

Signed-off-by: Arseny Krasnov <arseny.krasnov@kaspersky.com>
---
 v6 -> v7:
 'seqpacket_enqueue' callback interface changed, 'flags' argument was
 removed, because it was 'msg_flags' field of 'msg' argument which is
 already exists.

 include/net/af_vsock.h   |  2 ++
 net/vmw_vsock/af_vsock.c | 21 +++++++++++++++------
 2 files changed, 17 insertions(+), 6 deletions(-)

Comments

Stefano Garzarella March 25, 2021, 9:42 a.m. UTC | #1
On Tue, Mar 23, 2021 at 04:10:42PM +0300, Arseny Krasnov wrote:
>This adds some logic to current stream enqueue function for SEQPACKET

>support:

>1) Use transport's seqpacket enqueue callback.

>2) Return value from enqueue function is whole record length or error

>   for SOCK_SEQPACKET.

>

>Signed-off-by: Arseny Krasnov <arseny.krasnov@kaspersky.com>

>---

> v6 -> v7:

> 'seqpacket_enqueue' callback interface changed, 'flags' argument was

> removed, because it was 'msg_flags' field of 'msg' argument which is

> already exists.

>

> include/net/af_vsock.h   |  2 ++

> net/vmw_vsock/af_vsock.c | 21 +++++++++++++++------

> 2 files changed, 17 insertions(+), 6 deletions(-)



Reviewed-by: Stefano Garzarella <sgarzare@redhat.com>
diff mbox series

Patch

diff --git a/include/net/af_vsock.h b/include/net/af_vsock.h
index 7232f6c42a36..b7063820d0bc 100644
--- a/include/net/af_vsock.h
+++ b/include/net/af_vsock.h
@@ -138,6 +138,8 @@  struct vsock_transport {
 	/* SEQ_PACKET. */
 	int (*seqpacket_dequeue)(struct vsock_sock *vsk, struct msghdr *msg,
 				 int flags, bool *msg_ready, size_t *record_len);
+	int (*seqpacket_enqueue)(struct vsock_sock *vsk, struct msghdr *msg,
+				 size_t len);
 
 	/* Notification. */
 	int (*notify_poll_in)(struct vsock_sock *, size_t, bool *);
diff --git a/net/vmw_vsock/af_vsock.c b/net/vmw_vsock/af_vsock.c
index 617ffe42693d..a98e5daa06b7 100644
--- a/net/vmw_vsock/af_vsock.c
+++ b/net/vmw_vsock/af_vsock.c
@@ -1830,9 +1830,13 @@  static int vsock_connectible_sendmsg(struct socket *sock, struct msghdr *msg,
 		 * responsibility to check how many bytes we were able to send.
 		 */
 
-		written = transport->stream_enqueue(
-				vsk, msg,
-				len - total_written);
+		if (sk->sk_type == SOCK_SEQPACKET) {
+			written = transport->seqpacket_enqueue(vsk,
+						msg, len - total_written);
+		} else {
+			written = transport->stream_enqueue(vsk,
+					msg, len - total_written);
+		}
 		if (written < 0) {
 			err = -ENOMEM;
 			goto out_err;
@@ -1844,12 +1848,17 @@  static int vsock_connectible_sendmsg(struct socket *sock, struct msghdr *msg,
 				vsk, written, &send_data);
 		if (err < 0)
 			goto out_err;
-
 	}
 
 out_err:
-	if (total_written > 0)
-		err = total_written;
+	if (total_written > 0) {
+		/* Return number of written bytes only if:
+		 * 1) SOCK_STREAM socket.
+		 * 2) SOCK_SEQPACKET socket when whole buffer is sent.
+		 */
+		if (sk->sk_type == SOCK_STREAM || total_written == len)
+			err = total_written;
+	}
 out:
 	release_sock(sk);
 	return err;