diff options
Diffstat (limited to 'net/vmw_vsock/af_vsock.c')
-rw-r--r-- | net/vmw_vsock/af_vsock.c | 167 |
1 files changed, 87 insertions, 80 deletions
diff --git a/net/vmw_vsock/af_vsock.c b/net/vmw_vsock/af_vsock.c index 9b5bd6d142dc..60324f7c72bd 100644 --- a/net/vmw_vsock/af_vsock.c +++ b/net/vmw_vsock/af_vsock.c | |||
@@ -1209,10 +1209,14 @@ static int vsock_stream_connect(struct socket *sock, struct sockaddr *addr, | |||
1209 | 1209 | ||
1210 | if (signal_pending(current)) { | 1210 | if (signal_pending(current)) { |
1211 | err = sock_intr_errno(timeout); | 1211 | err = sock_intr_errno(timeout); |
1212 | goto out_wait_error; | 1212 | sk->sk_state = SS_UNCONNECTED; |
1213 | sock->state = SS_UNCONNECTED; | ||
1214 | goto out_wait; | ||
1213 | } else if (timeout == 0) { | 1215 | } else if (timeout == 0) { |
1214 | err = -ETIMEDOUT; | 1216 | err = -ETIMEDOUT; |
1215 | goto out_wait_error; | 1217 | sk->sk_state = SS_UNCONNECTED; |
1218 | sock->state = SS_UNCONNECTED; | ||
1219 | goto out_wait; | ||
1216 | } | 1220 | } |
1217 | 1221 | ||
1218 | prepare_to_wait(sk_sleep(sk), &wait, TASK_INTERRUPTIBLE); | 1222 | prepare_to_wait(sk_sleep(sk), &wait, TASK_INTERRUPTIBLE); |
@@ -1220,20 +1224,17 @@ static int vsock_stream_connect(struct socket *sock, struct sockaddr *addr, | |||
1220 | 1224 | ||
1221 | if (sk->sk_err) { | 1225 | if (sk->sk_err) { |
1222 | err = -sk->sk_err; | 1226 | err = -sk->sk_err; |
1223 | goto out_wait_error; | 1227 | sk->sk_state = SS_UNCONNECTED; |
1224 | } else | 1228 | sock->state = SS_UNCONNECTED; |
1229 | } else { | ||
1225 | err = 0; | 1230 | err = 0; |
1231 | } | ||
1226 | 1232 | ||
1227 | out_wait: | 1233 | out_wait: |
1228 | finish_wait(sk_sleep(sk), &wait); | 1234 | finish_wait(sk_sleep(sk), &wait); |
1229 | out: | 1235 | out: |
1230 | release_sock(sk); | 1236 | release_sock(sk); |
1231 | return err; | 1237 | return err; |
1232 | |||
1233 | out_wait_error: | ||
1234 | sk->sk_state = SS_UNCONNECTED; | ||
1235 | sock->state = SS_UNCONNECTED; | ||
1236 | goto out_wait; | ||
1237 | } | 1238 | } |
1238 | 1239 | ||
1239 | static int vsock_accept(struct socket *sock, struct socket *newsock, int flags) | 1240 | static int vsock_accept(struct socket *sock, struct socket *newsock, int flags) |
@@ -1270,18 +1271,20 @@ static int vsock_accept(struct socket *sock, struct socket *newsock, int flags) | |||
1270 | listener->sk_err == 0) { | 1271 | listener->sk_err == 0) { |
1271 | release_sock(listener); | 1272 | release_sock(listener); |
1272 | timeout = schedule_timeout(timeout); | 1273 | timeout = schedule_timeout(timeout); |
1274 | finish_wait(sk_sleep(listener), &wait); | ||
1273 | lock_sock(listener); | 1275 | lock_sock(listener); |
1274 | 1276 | ||
1275 | if (signal_pending(current)) { | 1277 | if (signal_pending(current)) { |
1276 | err = sock_intr_errno(timeout); | 1278 | err = sock_intr_errno(timeout); |
1277 | goto out_wait; | 1279 | goto out; |
1278 | } else if (timeout == 0) { | 1280 | } else if (timeout == 0) { |
1279 | err = -EAGAIN; | 1281 | err = -EAGAIN; |
1280 | goto out_wait; | 1282 | goto out; |
1281 | } | 1283 | } |
1282 | 1284 | ||
1283 | prepare_to_wait(sk_sleep(listener), &wait, TASK_INTERRUPTIBLE); | 1285 | prepare_to_wait(sk_sleep(listener), &wait, TASK_INTERRUPTIBLE); |
1284 | } | 1286 | } |
1287 | finish_wait(sk_sleep(listener), &wait); | ||
1285 | 1288 | ||
1286 | if (listener->sk_err) | 1289 | if (listener->sk_err) |
1287 | err = -listener->sk_err; | 1290 | err = -listener->sk_err; |
@@ -1301,19 +1304,15 @@ static int vsock_accept(struct socket *sock, struct socket *newsock, int flags) | |||
1301 | */ | 1304 | */ |
1302 | if (err) { | 1305 | if (err) { |
1303 | vconnected->rejected = true; | 1306 | vconnected->rejected = true; |
1304 | release_sock(connected); | 1307 | } else { |
1305 | sock_put(connected); | 1308 | newsock->state = SS_CONNECTED; |
1306 | goto out_wait; | 1309 | sock_graft(connected, newsock); |
1307 | } | 1310 | } |
1308 | 1311 | ||
1309 | newsock->state = SS_CONNECTED; | ||
1310 | sock_graft(connected, newsock); | ||
1311 | release_sock(connected); | 1312 | release_sock(connected); |
1312 | sock_put(connected); | 1313 | sock_put(connected); |
1313 | } | 1314 | } |
1314 | 1315 | ||
1315 | out_wait: | ||
1316 | finish_wait(sk_sleep(listener), &wait); | ||
1317 | out: | 1316 | out: |
1318 | release_sock(listener); | 1317 | release_sock(listener); |
1319 | return err; | 1318 | return err; |
@@ -1513,8 +1512,7 @@ static int vsock_stream_sendmsg(struct socket *sock, struct msghdr *msg, | |||
1513 | long timeout; | 1512 | long timeout; |
1514 | int err; | 1513 | int err; |
1515 | struct vsock_transport_send_notify_data send_data; | 1514 | struct vsock_transport_send_notify_data send_data; |
1516 | 1515 | DEFINE_WAIT_FUNC(wait, woken_wake_function); | |
1517 | DEFINE_WAIT(wait); | ||
1518 | 1516 | ||
1519 | sk = sock->sk; | 1517 | sk = sock->sk; |
1520 | vsk = vsock_sk(sk); | 1518 | vsk = vsock_sk(sk); |
@@ -1557,11 +1555,10 @@ static int vsock_stream_sendmsg(struct socket *sock, struct msghdr *msg, | |||
1557 | if (err < 0) | 1555 | if (err < 0) |
1558 | goto out; | 1556 | goto out; |
1559 | 1557 | ||
1560 | prepare_to_wait(sk_sleep(sk), &wait, TASK_INTERRUPTIBLE); | ||
1561 | |||
1562 | while (total_written < len) { | 1558 | while (total_written < len) { |
1563 | ssize_t written; | 1559 | ssize_t written; |
1564 | 1560 | ||
1561 | add_wait_queue(sk_sleep(sk), &wait); | ||
1565 | while (vsock_stream_has_space(vsk) == 0 && | 1562 | while (vsock_stream_has_space(vsk) == 0 && |
1566 | sk->sk_err == 0 && | 1563 | sk->sk_err == 0 && |
1567 | !(sk->sk_shutdown & SEND_SHUTDOWN) && | 1564 | !(sk->sk_shutdown & SEND_SHUTDOWN) && |
@@ -1570,27 +1567,30 @@ static int vsock_stream_sendmsg(struct socket *sock, struct msghdr *msg, | |||
1570 | /* Don't wait for non-blocking sockets. */ | 1567 | /* Don't wait for non-blocking sockets. */ |
1571 | if (timeout == 0) { | 1568 | if (timeout == 0) { |
1572 | err = -EAGAIN; | 1569 | err = -EAGAIN; |
1573 | goto out_wait; | 1570 | remove_wait_queue(sk_sleep(sk), &wait); |
1571 | goto out_err; | ||
1574 | } | 1572 | } |
1575 | 1573 | ||
1576 | err = transport->notify_send_pre_block(vsk, &send_data); | 1574 | err = transport->notify_send_pre_block(vsk, &send_data); |
1577 | if (err < 0) | 1575 | if (err < 0) { |
1578 | goto out_wait; | 1576 | remove_wait_queue(sk_sleep(sk), &wait); |
1577 | goto out_err; | ||
1578 | } | ||
1579 | 1579 | ||
1580 | release_sock(sk); | 1580 | release_sock(sk); |
1581 | timeout = schedule_timeout(timeout); | 1581 | timeout = wait_woken(&wait, TASK_INTERRUPTIBLE, timeout); |
1582 | lock_sock(sk); | 1582 | lock_sock(sk); |
1583 | if (signal_pending(current)) { | 1583 | if (signal_pending(current)) { |
1584 | err = sock_intr_errno(timeout); | 1584 | err = sock_intr_errno(timeout); |
1585 | goto out_wait; | 1585 | remove_wait_queue(sk_sleep(sk), &wait); |
1586 | goto out_err; | ||
1586 | } else if (timeout == 0) { | 1587 | } else if (timeout == 0) { |
1587 | err = -EAGAIN; | 1588 | err = -EAGAIN; |
1588 | goto out_wait; | 1589 | remove_wait_queue(sk_sleep(sk), &wait); |
1590 | goto out_err; | ||
1589 | } | 1591 | } |
1590 | |||
1591 | prepare_to_wait(sk_sleep(sk), &wait, | ||
1592 | TASK_INTERRUPTIBLE); | ||
1593 | } | 1592 | } |
1593 | remove_wait_queue(sk_sleep(sk), &wait); | ||
1594 | 1594 | ||
1595 | /* These checks occur both as part of and after the loop | 1595 | /* These checks occur both as part of and after the loop |
1596 | * conditional since we need to check before and after | 1596 | * conditional since we need to check before and after |
@@ -1598,16 +1598,16 @@ static int vsock_stream_sendmsg(struct socket *sock, struct msghdr *msg, | |||
1598 | */ | 1598 | */ |
1599 | if (sk->sk_err) { | 1599 | if (sk->sk_err) { |
1600 | err = -sk->sk_err; | 1600 | err = -sk->sk_err; |
1601 | goto out_wait; | 1601 | goto out_err; |
1602 | } else if ((sk->sk_shutdown & SEND_SHUTDOWN) || | 1602 | } else if ((sk->sk_shutdown & SEND_SHUTDOWN) || |
1603 | (vsk->peer_shutdown & RCV_SHUTDOWN)) { | 1603 | (vsk->peer_shutdown & RCV_SHUTDOWN)) { |
1604 | err = -EPIPE; | 1604 | err = -EPIPE; |
1605 | goto out_wait; | 1605 | goto out_err; |
1606 | } | 1606 | } |
1607 | 1607 | ||
1608 | err = transport->notify_send_pre_enqueue(vsk, &send_data); | 1608 | err = transport->notify_send_pre_enqueue(vsk, &send_data); |
1609 | if (err < 0) | 1609 | if (err < 0) |
1610 | goto out_wait; | 1610 | goto out_err; |
1611 | 1611 | ||
1612 | /* Note that enqueue will only write as many bytes as are free | 1612 | /* Note that enqueue will only write as many bytes as are free |
1613 | * in the produce queue, so we don't need to ensure len is | 1613 | * in the produce queue, so we don't need to ensure len is |
@@ -1620,7 +1620,7 @@ static int vsock_stream_sendmsg(struct socket *sock, struct msghdr *msg, | |||
1620 | len - total_written); | 1620 | len - total_written); |
1621 | if (written < 0) { | 1621 | if (written < 0) { |
1622 | err = -ENOMEM; | 1622 | err = -ENOMEM; |
1623 | goto out_wait; | 1623 | goto out_err; |
1624 | } | 1624 | } |
1625 | 1625 | ||
1626 | total_written += written; | 1626 | total_written += written; |
@@ -1628,14 +1628,13 @@ static int vsock_stream_sendmsg(struct socket *sock, struct msghdr *msg, | |||
1628 | err = transport->notify_send_post_enqueue( | 1628 | err = transport->notify_send_post_enqueue( |
1629 | vsk, written, &send_data); | 1629 | vsk, written, &send_data); |
1630 | if (err < 0) | 1630 | if (err < 0) |
1631 | goto out_wait; | 1631 | goto out_err; |
1632 | 1632 | ||
1633 | } | 1633 | } |
1634 | 1634 | ||
1635 | out_wait: | 1635 | out_err: |
1636 | if (total_written > 0) | 1636 | if (total_written > 0) |
1637 | err = total_written; | 1637 | err = total_written; |
1638 | finish_wait(sk_sleep(sk), &wait); | ||
1639 | out: | 1638 | out: |
1640 | release_sock(sk); | 1639 | release_sock(sk); |
1641 | return err; | 1640 | return err; |
@@ -1716,21 +1715,61 @@ vsock_stream_recvmsg(struct socket *sock, struct msghdr *msg, size_t len, | |||
1716 | if (err < 0) | 1715 | if (err < 0) |
1717 | goto out; | 1716 | goto out; |
1718 | 1717 | ||
1719 | prepare_to_wait(sk_sleep(sk), &wait, TASK_INTERRUPTIBLE); | ||
1720 | 1718 | ||
1721 | while (1) { | 1719 | while (1) { |
1722 | s64 ready = vsock_stream_has_data(vsk); | 1720 | s64 ready; |
1723 | 1721 | ||
1724 | if (ready < 0) { | 1722 | prepare_to_wait(sk_sleep(sk), &wait, TASK_INTERRUPTIBLE); |
1725 | /* Invalid queue pair content. XXX This should be | 1723 | ready = vsock_stream_has_data(vsk); |
1726 | * changed to a connection reset in a later change. | ||
1727 | */ | ||
1728 | 1724 | ||
1729 | err = -ENOMEM; | 1725 | if (ready == 0) { |
1730 | goto out_wait; | 1726 | if (sk->sk_err != 0 || |
1731 | } else if (ready > 0) { | 1727 | (sk->sk_shutdown & RCV_SHUTDOWN) || |
1728 | (vsk->peer_shutdown & SEND_SHUTDOWN)) { | ||
1729 | finish_wait(sk_sleep(sk), &wait); | ||
1730 | break; | ||
1731 | } | ||
1732 | /* Don't wait for non-blocking sockets. */ | ||
1733 | if (timeout == 0) { | ||
1734 | err = -EAGAIN; | ||
1735 | finish_wait(sk_sleep(sk), &wait); | ||
1736 | break; | ||
1737 | } | ||
1738 | |||
1739 | err = transport->notify_recv_pre_block( | ||
1740 | vsk, target, &recv_data); | ||
1741 | if (err < 0) { | ||
1742 | finish_wait(sk_sleep(sk), &wait); | ||
1743 | break; | ||
1744 | } | ||
1745 | release_sock(sk); | ||
1746 | timeout = schedule_timeout(timeout); | ||
1747 | lock_sock(sk); | ||
1748 | |||
1749 | if (signal_pending(current)) { | ||
1750 | err = sock_intr_errno(timeout); | ||
1751 | finish_wait(sk_sleep(sk), &wait); | ||
1752 | break; | ||
1753 | } else if (timeout == 0) { | ||
1754 | err = -EAGAIN; | ||
1755 | finish_wait(sk_sleep(sk), &wait); | ||
1756 | break; | ||
1757 | } | ||
1758 | } else { | ||
1732 | ssize_t read; | 1759 | ssize_t read; |
1733 | 1760 | ||
1761 | finish_wait(sk_sleep(sk), &wait); | ||
1762 | |||
1763 | if (ready < 0) { | ||
1764 | /* Invalid queue pair content. XXX This should | ||
1765 | * be changed to a connection reset in a later | ||
1766 | * change. | ||
1767 | */ | ||
1768 | |||
1769 | err = -ENOMEM; | ||
1770 | goto out; | ||
1771 | } | ||
1772 | |||
1734 | err = transport->notify_recv_pre_dequeue( | 1773 | err = transport->notify_recv_pre_dequeue( |
1735 | vsk, target, &recv_data); | 1774 | vsk, target, &recv_data); |
1736 | if (err < 0) | 1775 | if (err < 0) |
@@ -1750,42 +1789,12 @@ vsock_stream_recvmsg(struct socket *sock, struct msghdr *msg, size_t len, | |||
1750 | vsk, target, read, | 1789 | vsk, target, read, |
1751 | !(flags & MSG_PEEK), &recv_data); | 1790 | !(flags & MSG_PEEK), &recv_data); |
1752 | if (err < 0) | 1791 | if (err < 0) |
1753 | goto out_wait; | 1792 | goto out; |
1754 | 1793 | ||
1755 | if (read >= target || flags & MSG_PEEK) | 1794 | if (read >= target || flags & MSG_PEEK) |
1756 | break; | 1795 | break; |
1757 | 1796 | ||
1758 | target -= read; | 1797 | target -= read; |
1759 | } else { | ||
1760 | if (sk->sk_err != 0 || (sk->sk_shutdown & RCV_SHUTDOWN) | ||
1761 | || (vsk->peer_shutdown & SEND_SHUTDOWN)) { | ||
1762 | break; | ||
1763 | } | ||
1764 | /* Don't wait for non-blocking sockets. */ | ||
1765 | if (timeout == 0) { | ||
1766 | err = -EAGAIN; | ||
1767 | break; | ||
1768 | } | ||
1769 | |||
1770 | err = transport->notify_recv_pre_block( | ||
1771 | vsk, target, &recv_data); | ||
1772 | if (err < 0) | ||
1773 | break; | ||
1774 | |||
1775 | release_sock(sk); | ||
1776 | timeout = schedule_timeout(timeout); | ||
1777 | lock_sock(sk); | ||
1778 | |||
1779 | if (signal_pending(current)) { | ||
1780 | err = sock_intr_errno(timeout); | ||
1781 | break; | ||
1782 | } else if (timeout == 0) { | ||
1783 | err = -EAGAIN; | ||
1784 | break; | ||
1785 | } | ||
1786 | |||
1787 | prepare_to_wait(sk_sleep(sk), &wait, | ||
1788 | TASK_INTERRUPTIBLE); | ||
1789 | } | 1798 | } |
1790 | } | 1799 | } |
1791 | 1800 | ||
@@ -1797,8 +1806,6 @@ vsock_stream_recvmsg(struct socket *sock, struct msghdr *msg, size_t len, | |||
1797 | if (copied > 0) | 1806 | if (copied > 0) |
1798 | err = copied; | 1807 | err = copied; |
1799 | 1808 | ||
1800 | out_wait: | ||
1801 | finish_wait(sk_sleep(sk), &wait); | ||
1802 | out: | 1809 | out: |
1803 | release_sock(sk); | 1810 | release_sock(sk); |
1804 | return err; | 1811 | return err; |