diff mbox series

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

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

Commit Message

Arseny Krasnov March 7, 2021, 6 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>
---
 include/net/af_vsock.h   |  2 ++
 net/vmw_vsock/af_vsock.c | 22 ++++++++++++++++------
 2 files changed, 18 insertions(+), 6 deletions(-)

Comments

Stefano Garzarella March 12, 2021, 3:10 p.m. UTC | #1
On Sun, Mar 07, 2021 at 09:00:26PM +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>

>---

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

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

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

>

>diff --git a/include/net/af_vsock.h b/include/net/af_vsock.h

>index a8c4039e40cf..aed306292ab3 100644

>--- a/include/net/af_vsock.h

>+++ b/include/net/af_vsock.h

>@@ -139,6 +139,8 @@ struct vsock_transport {

> 	size_t (*seqpacket_seq_get_len)(struct vsock_sock *vsk);

> 	int (*seqpacket_dequeue)(struct vsock_sock *vsk, struct msghdr *msg,

> 				 int flags, bool *msg_ready);

>+	int (*seqpacket_enqueue)(struct vsock_sock *vsk, struct msghdr *msg,

>+				 int flags, 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 5bf64a3e678a..a031f165494d 100644

>--- a/net/vmw_vsock/af_vsock.c

>+++ b/net/vmw_vsock/af_vsock.c

>@@ -1830,9 +1830,14 @@ 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, msg->msg_flags,


I think we can avoid to pass 'msg->msg_flags', since the transport can 
access it through the 'msg' pointer, right?

>+						len - total_written);

>+		} else {

>+			written = transport->stream_enqueue(vsk,

>+					msg, len - total_written);

>+		}

> 		if (written < 0) {

> 			err = -ENOMEM;

> 			goto out_err;

>@@ -1844,12 +1849,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;

>-- 

>2.25.1

>
Arseny Krasnov March 15, 2021, 7:49 a.m. UTC | #2
On 12.03.2021 18:10, Stefano Garzarella wrote:
> On Sun, Mar 07, 2021 at 09:00:26PM +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>

>> ---

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

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

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

>>

>> diff --git a/include/net/af_vsock.h b/include/net/af_vsock.h

>> index a8c4039e40cf..aed306292ab3 100644

>> --- a/include/net/af_vsock.h

>> +++ b/include/net/af_vsock.h

>> @@ -139,6 +139,8 @@ struct vsock_transport {

>> 	size_t (*seqpacket_seq_get_len)(struct vsock_sock *vsk);

>> 	int (*seqpacket_dequeue)(struct vsock_sock *vsk, struct msghdr *msg,

>> 				 int flags, bool *msg_ready);

>> +	int (*seqpacket_enqueue)(struct vsock_sock *vsk, struct msghdr *msg,

>> +				 int flags, 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 5bf64a3e678a..a031f165494d 100644

>> --- a/net/vmw_vsock/af_vsock.c

>> +++ b/net/vmw_vsock/af_vsock.c

>> @@ -1830,9 +1830,14 @@ 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, msg->msg_flags,

> I think we can avoid to pass 'msg->msg_flags', since the transport can 

> access it through the 'msg' pointer, right?

Ack
>

>> +						len - total_written);

>> +		} else {

>> +			written = transport->stream_enqueue(vsk,

>> +					msg, len - total_written);

>> +		}

>> 		if (written < 0) {

>> 			err = -ENOMEM;

>> 			goto out_err;

>> @@ -1844,12 +1849,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;

>> -- 

>> 2.25.1

>>

>
diff mbox series

Patch

diff --git a/include/net/af_vsock.h b/include/net/af_vsock.h
index a8c4039e40cf..aed306292ab3 100644
--- a/include/net/af_vsock.h
+++ b/include/net/af_vsock.h
@@ -139,6 +139,8 @@  struct vsock_transport {
 	size_t (*seqpacket_seq_get_len)(struct vsock_sock *vsk);
 	int (*seqpacket_dequeue)(struct vsock_sock *vsk, struct msghdr *msg,
 				 int flags, bool *msg_ready);
+	int (*seqpacket_enqueue)(struct vsock_sock *vsk, struct msghdr *msg,
+				 int flags, 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 5bf64a3e678a..a031f165494d 100644
--- a/net/vmw_vsock/af_vsock.c
+++ b/net/vmw_vsock/af_vsock.c
@@ -1830,9 +1830,14 @@  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, msg->msg_flags,
+						len - total_written);
+		} else {
+			written = transport->stream_enqueue(vsk,
+					msg, len - total_written);
+		}
 		if (written < 0) {
 			err = -ENOMEM;
 			goto out_err;
@@ -1844,12 +1849,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;