Commit 685c3f2f authored by Richard Palethorpe's avatar Richard Palethorpe Committed by David S. Miller
Browse files

vsock: Refactor vsock_*_getsockopt to resemble sock_getsockopt



In preparation for sharing the implementation of sock_get_timeout.

Signed-off-by: default avatarRichard Palethorpe <rpalethorpe@suse.com>
Cc: Richard Palethorpe <rpalethorpe@richiejp.com>
Reviewed-by: default avatarArnd Bergmann <arnd@arndb.de>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 16bdce2a
Loading
Loading
Loading
Loading
+28 −37
Original line number Diff line number Diff line
@@ -1648,68 +1648,59 @@ static int vsock_connectible_getsockopt(struct socket *sock,
					char __user *optval,
					int __user *optlen)
{
	int err;
	struct sock *sk = sock->sk;
	struct vsock_sock *vsk = vsock_sk(sk);

	union {
		u64 val64;
		struct __kernel_old_timeval tm;
	} v;

	int lv = sizeof(v.val64);
	int len;
	struct sock *sk;
	struct vsock_sock *vsk;
	u64 val;

	if (level != AF_VSOCK)
		return -ENOPROTOOPT;

	err = get_user(len, optlen);
	if (err != 0)
		return err;
	if (get_user(len, optlen))
		return -EFAULT;

#define COPY_OUT(_v)                            \
	do {					\
		if (len < sizeof(_v))		\
			return -EINVAL;		\
						\
		len = sizeof(_v);		\
		if (copy_to_user(optval, &_v, len) != 0)	\
			return -EFAULT;				\
								\
	} while (0)

	err = 0;
	sk = sock->sk;
	vsk = vsock_sk(sk);
	memset(&v, 0, sizeof(v));

	switch (optname) {
	case SO_VM_SOCKETS_BUFFER_SIZE:
		val = vsk->buffer_size;
		COPY_OUT(val);
		v.val64 = vsk->buffer_size;
		break;

	case SO_VM_SOCKETS_BUFFER_MAX_SIZE:
		val = vsk->buffer_max_size;
		COPY_OUT(val);
		v.val64 = vsk->buffer_max_size;
		break;

	case SO_VM_SOCKETS_BUFFER_MIN_SIZE:
		val = vsk->buffer_min_size;
		COPY_OUT(val);
		v.val64 = vsk->buffer_min_size;
		break;

	case SO_VM_SOCKETS_CONNECT_TIMEOUT: {
		struct __kernel_old_timeval tv;
		tv.tv_sec = vsk->connect_timeout / HZ;
		tv.tv_usec =
	case SO_VM_SOCKETS_CONNECT_TIMEOUT:
		lv = sizeof(v.tm);
		v.tm.tv_sec = vsk->connect_timeout / HZ;
		v.tm.tv_usec =
		    (vsk->connect_timeout -
		     tv.tv_sec * HZ) * (1000000 / HZ);
		COPY_OUT(tv);
		     v.tm.tv_sec * HZ) * (1000000 / HZ);
		break;
	}

	default:
		return -ENOPROTOOPT;
	}

	err = put_user(len, optlen);
	if (err != 0)
	if (len < lv)
		return -EINVAL;
	if (len > lv)
		len = lv;
	if (copy_to_user(optval, &v, len))
		return -EFAULT;

#undef COPY_OUT
	if (put_user(len, optlen))
		return -EFAULT;

	return 0;
}