In preparation for sharing the implementation of sock_get_timeout.
Unified · Split
| @@ -1648,68 +1648,59 @@ static int vsock_connectible_getsockopt(struct socket *sock, · 1647 unmodified lines | |||
| 1648 | char __user *optval, | 1648 | char __user *optval, |
| 1649 | int __user *optlen) | 1649 | int __user *optlen) |
| 1650 | { | 1650 | { |
| 1651 | int err; | 1651 | struct sock *sk = sock->sk; |
| 1652 | struct vsock_sock *vsk = vsock_sk(sk); | ||
| 1653 | |||
| 1654 | union { | ||
| 1655 | u64 val64; | ||
| 1656 | struct __kernel_old_timeval tm; | ||
| 1657 | } v; | ||
| 1658 | |||
| 1659 | int lv = sizeof(v.val64); | ||
| 1652 | int len; | 1660 | int len; |
| 1653 | struct sock *sk; | ||
| 1654 | struct vsock_sock *vsk; | ||
| 1655 | u64 val; | ||
| 1656 | 1661 | ||
| 1657 | if (level != AF_VSOCK) | 1662 | if (level != AF_VSOCK) |
| 1658 | return -ENOPROTOOPT; | 1663 | return -ENOPROTOOPT; |
| 1659 | 1664 | ||
| 1660 | err = get_user(len, optlen); | 1665 | if (get_user(len, optlen)) |
| 1661 | if (err != 0) | 1666 | return -EFAULT; |
| 1662 | return err; | ||
| 1663 | |||
| 1664 | #define COPY_OUT(_v) \ | ||
| 1665 | do { \ | ||
| 1666 | if (len < sizeof(_v)) \ | ||
| 1667 | return -EINVAL; \ | ||
| 1668 | \ | ||
| 1669 | len = sizeof(_v); \ | ||
| 1670 | if (copy_to_user(optval, &_v, len) != 0) \ | ||
| 1671 | return -EFAULT; \ | ||
| 1672 | \ | ||
| 1673 | } while (0) | ||
| 1674 | 1667 | ||
| 1675 | err = 0; | 1668 | memset(&v, 0, sizeof(v)); |
| 1676 | sk = sock->sk; | ||
| 1677 | vsk = vsock_sk(sk); | ||
| 1678 | 1669 | ||
| 1679 | switch (optname) { | 1670 | switch (optname) { |
| 1680 | case SO_VM_SOCKETS_BUFFER_SIZE: | 1671 | case SO_VM_SOCKETS_BUFFER_SIZE: |
| 1681 | val = vsk->buffer_size; | 1672 | v.val64 = vsk->buffer_size; |
| 1682 | COPY_OUT(val); | ||
| 1683 | break; | 1673 | break; |
| 1684 | 1674 | ||
| 1685 | case SO_VM_SOCKETS_BUFFER_MAX_SIZE: | 1675 | case SO_VM_SOCKETS_BUFFER_MAX_SIZE: |
| 1686 | val = vsk->buffer_max_size; | 1676 | v.val64 = vsk->buffer_max_size; |
| 1687 | COPY_OUT(val); | ||
| 1688 | break; | 1677 | break; |
| 1689 | 1678 | ||
| 1690 | case SO_VM_SOCKETS_BUFFER_MIN_SIZE: | 1679 | case SO_VM_SOCKETS_BUFFER_MIN_SIZE: |
| 1691 | val = vsk->buffer_min_size; | 1680 | v.val64 = vsk->buffer_min_size; |
| 1692 | COPY_OUT(val); | ||
| 1693 | break; | 1681 | break; |
| 1694 | 1682 | ||
| 1695 | case SO_VM_SOCKETS_CONNECT_TIMEOUT: { | 1683 | case SO_VM_SOCKETS_CONNECT_TIMEOUT: |
| 1696 | struct __kernel_old_timeval tv; | 1684 | lv = sizeof(v.tm); |
| 1697 | tv.tv_sec = vsk->connect_timeout / HZ; | 1685 | v.tm.tv_sec = vsk->connect_timeout / HZ; |
| 1698 | tv.tv_usec = | 1686 | v.tm.tv_usec = |
| 1699 | (vsk->connect_timeout - | 1687 | (vsk->connect_timeout - |
| 1700 | tv.tv_sec * HZ) * (1000000 / HZ); | 1688 | v.tm.tv_sec * HZ) * (1000000 / HZ); |
| 1701 | COPY_OUT(tv); | ||
| 1702 | break; | 1689 | break; |
| 1703 | } | 1690 | |
| 1704 | default: | 1691 | default: |
| 1705 | return -ENOPROTOOPT; | 1692 | return -ENOPROTOOPT; |
| 1706 | } | 1693 | } |
| 1707 | 1694 | ||
| 1708 | err = put_user(len, optlen); | 1695 | if (len < lv) |
| 1709 | if (err != 0) | 1696 | return -EINVAL; |
| 1697 | if (len > lv) | ||
| 1698 | len = lv; | ||
| 1699 | if (copy_to_user(optval, &v, len)) | ||
| 1710 | return -EFAULT; | 1700 | return -EFAULT; |
| 1711 | 1701 | ||
| 1712 | #undef COPY_OUT | 1702 | if (put_user(len, optlen)) |
| 1703 | return -EFAULT; | ||
| 1713 | 1704 | ||
| 1714 | return 0; | 1705 | return 0; |
| 1715 | } | 1706 | } |