forked from mirrors/linux
		
	vsock: add support for SIOCOUTQ ioctl
Add support for ioctl(s) in AF_VSOCK. The only ioctl available is SIOCOUTQ/TIOCOUTQ, which returns the number of unsent bytes in the socket. This information is transport-specific and is delegated to them using a callback. Suggested-by: Daan De Meyer <daan.j.demeyer@gmail.com> Signed-off-by: Luigi Leonardi <luigi.leonardi@outlook.com> Reviewed-by: Stefano Garzarella <sgarzare@redhat.com> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
		
							parent
							
								
									5fe164fb0e
								
							
						
					
					
						commit
						744500d81f
					
				
					 2 changed files with 58 additions and 3 deletions
				
			
		|  | @ -169,6 +169,9 @@ struct vsock_transport { | |||
| 	void (*notify_buffer_size)(struct vsock_sock *, u64 *); | ||||
| 	int (*notify_set_rcvlowat)(struct vsock_sock *vsk, int val); | ||||
| 
 | ||||
| 	/* SIOCOUTQ ioctl */ | ||||
| 	ssize_t (*unsent_bytes)(struct vsock_sock *vsk); | ||||
| 
 | ||||
| 	/* Shutdown. */ | ||||
| 	int (*shutdown)(struct vsock_sock *, int); | ||||
| 
 | ||||
|  |  | |||
|  | @ -112,6 +112,7 @@ | |||
| #include <net/sock.h> | ||||
| #include <net/af_vsock.h> | ||||
| #include <uapi/linux/vm_sockets.h> | ||||
| #include <uapi/asm-generic/ioctls.h> | ||||
| 
 | ||||
| static int __vsock_bind(struct sock *sk, struct sockaddr_vm *addr); | ||||
| static void vsock_sk_destruct(struct sock *sk); | ||||
|  | @ -1292,6 +1293,57 @@ int vsock_dgram_recvmsg(struct socket *sock, struct msghdr *msg, | |||
| } | ||||
| EXPORT_SYMBOL_GPL(vsock_dgram_recvmsg); | ||||
| 
 | ||||
| static int vsock_do_ioctl(struct socket *sock, unsigned int cmd, | ||||
| 			  int __user *arg) | ||||
| { | ||||
| 	struct sock *sk = sock->sk; | ||||
| 	struct vsock_sock *vsk; | ||||
| 	int ret; | ||||
| 
 | ||||
| 	vsk = vsock_sk(sk); | ||||
| 
 | ||||
| 	switch (cmd) { | ||||
| 	case SIOCOUTQ: { | ||||
| 		ssize_t n_bytes; | ||||
| 
 | ||||
| 		if (!vsk->transport || !vsk->transport->unsent_bytes) { | ||||
| 			ret = -EOPNOTSUPP; | ||||
| 			break; | ||||
| 		} | ||||
| 
 | ||||
| 		if (sock_type_connectible(sk->sk_type) && sk->sk_state == TCP_LISTEN) { | ||||
| 			ret = -EINVAL; | ||||
| 			break; | ||||
| 		} | ||||
| 
 | ||||
| 		n_bytes = vsk->transport->unsent_bytes(vsk); | ||||
| 		if (n_bytes < 0) { | ||||
| 			ret = n_bytes; | ||||
| 			break; | ||||
| 		} | ||||
| 
 | ||||
| 		ret = put_user(n_bytes, arg); | ||||
| 		break; | ||||
| 	} | ||||
| 	default: | ||||
| 		ret = -ENOIOCTLCMD; | ||||
| 	} | ||||
| 
 | ||||
| 	return ret; | ||||
| } | ||||
| 
 | ||||
| static int vsock_ioctl(struct socket *sock, unsigned int cmd, | ||||
| 		       unsigned long arg) | ||||
| { | ||||
| 	int ret; | ||||
| 
 | ||||
| 	lock_sock(sock->sk); | ||||
| 	ret = vsock_do_ioctl(sock, cmd, (int __user *)arg); | ||||
| 	release_sock(sock->sk); | ||||
| 
 | ||||
| 	return ret; | ||||
| } | ||||
| 
 | ||||
| static const struct proto_ops vsock_dgram_ops = { | ||||
| 	.family = PF_VSOCK, | ||||
| 	.owner = THIS_MODULE, | ||||
|  | @ -1302,7 +1354,7 @@ static const struct proto_ops vsock_dgram_ops = { | |||
| 	.accept = sock_no_accept, | ||||
| 	.getname = vsock_getname, | ||||
| 	.poll = vsock_poll, | ||||
| 	.ioctl = sock_no_ioctl, | ||||
| 	.ioctl = vsock_ioctl, | ||||
| 	.listen = sock_no_listen, | ||||
| 	.shutdown = vsock_shutdown, | ||||
| 	.sendmsg = vsock_dgram_sendmsg, | ||||
|  | @ -2286,7 +2338,7 @@ static const struct proto_ops vsock_stream_ops = { | |||
| 	.accept = vsock_accept, | ||||
| 	.getname = vsock_getname, | ||||
| 	.poll = vsock_poll, | ||||
| 	.ioctl = sock_no_ioctl, | ||||
| 	.ioctl = vsock_ioctl, | ||||
| 	.listen = vsock_listen, | ||||
| 	.shutdown = vsock_shutdown, | ||||
| 	.setsockopt = vsock_connectible_setsockopt, | ||||
|  | @ -2308,7 +2360,7 @@ static const struct proto_ops vsock_seqpacket_ops = { | |||
| 	.accept = vsock_accept, | ||||
| 	.getname = vsock_getname, | ||||
| 	.poll = vsock_poll, | ||||
| 	.ioctl = sock_no_ioctl, | ||||
| 	.ioctl = vsock_ioctl, | ||||
| 	.listen = vsock_listen, | ||||
| 	.shutdown = vsock_shutdown, | ||||
| 	.setsockopt = vsock_connectible_setsockopt, | ||||
|  |  | |||
		Loading…
	
		Reference in a new issue
	
	 Luigi Leonardi
						Luigi Leonardi