diff options
Diffstat (limited to 'net/unix')
-rw-r--r-- | net/unix/af_unix.c | 13 |
1 files changed, 10 insertions, 3 deletions
diff --git a/net/unix/af_unix.c b/net/unix/af_unix.c index 87c794d8fa2d..d70fa30d4294 100644 --- a/net/unix/af_unix.c +++ b/net/unix/af_unix.c | |||
@@ -1744,20 +1744,23 @@ static int unix_stream_recvmsg(struct kiocb *iocb, struct socket *sock, | |||
1744 | int chunk; | 1744 | int chunk; |
1745 | struct sk_buff *skb; | 1745 | struct sk_buff *skb; |
1746 | 1746 | ||
1747 | unix_state_lock(sk); | ||
1747 | skb = skb_dequeue(&sk->sk_receive_queue); | 1748 | skb = skb_dequeue(&sk->sk_receive_queue); |
1748 | if (skb==NULL) | 1749 | if (skb==NULL) |
1749 | { | 1750 | { |
1750 | if (copied >= target) | 1751 | if (copied >= target) |
1751 | break; | 1752 | goto unlock; |
1752 | 1753 | ||
1753 | /* | 1754 | /* |
1754 | * POSIX 1003.1g mandates this order. | 1755 | * POSIX 1003.1g mandates this order. |
1755 | */ | 1756 | */ |
1756 | 1757 | ||
1757 | if ((err = sock_error(sk)) != 0) | 1758 | if ((err = sock_error(sk)) != 0) |
1758 | break; | 1759 | goto unlock; |
1759 | if (sk->sk_shutdown & RCV_SHUTDOWN) | 1760 | if (sk->sk_shutdown & RCV_SHUTDOWN) |
1760 | break; | 1761 | goto unlock; |
1762 | |||
1763 | unix_state_unlock(sk); | ||
1761 | err = -EAGAIN; | 1764 | err = -EAGAIN; |
1762 | if (!timeo) | 1765 | if (!timeo) |
1763 | break; | 1766 | break; |
@@ -1771,7 +1774,11 @@ static int unix_stream_recvmsg(struct kiocb *iocb, struct socket *sock, | |||
1771 | } | 1774 | } |
1772 | mutex_lock(&u->readlock); | 1775 | mutex_lock(&u->readlock); |
1773 | continue; | 1776 | continue; |
1777 | unlock: | ||
1778 | unix_state_unlock(sk); | ||
1779 | break; | ||
1774 | } | 1780 | } |
1781 | unix_state_unlock(sk); | ||
1775 | 1782 | ||
1776 | if (check_creds) { | 1783 | if (check_creds) { |
1777 | /* Never glue messages from different writers */ | 1784 | /* Never glue messages from different writers */ |