aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--net/unix/af_unix.c13
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 */