vsock: Refactor vsock_*_getsockopt to resemble sock_getsockopt
authorRichard Palethorpe <rpalethorpe@suse.com>
Fri, 8 Oct 2021 10:00:52 +0000 (11:00 +0100)
committerDavid S. Miller <davem@davemloft.net>
Fri, 8 Oct 2021 15:21:53 +0000 (16:21 +0100)
In preparation for sharing the implementation of sock_get_timeout.

Signed-off-by: Richard Palethorpe <rpalethorpe@suse.com>
Cc: Richard Palethorpe <rpalethorpe@richiejp.com>
Reviewed-by: Arnd Bergmann <arnd@arndb.de>
Signed-off-by: David S. Miller <davem@davemloft.net>
net/vmw_vsock/af_vsock.c

index e2c0cfb..9d0de37 100644 (file)
@@ -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;
-
-#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)
+       if (get_user(len, optlen))
+               return -EFAULT;
 
-       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;
 }