diff options
Diffstat (limited to 'net/unix/af_unix.c')
-rw-r--r-- | net/unix/af_unix.c | 25 |
1 files changed, 19 insertions, 6 deletions
diff --git a/net/unix/af_unix.c b/net/unix/af_unix.c index 4414a18c63b4..0ebc777a6660 100644 --- a/net/unix/af_unix.c +++ b/net/unix/af_unix.c | |||
@@ -692,6 +692,7 @@ static int unix_autobind(struct socket *sock) | |||
692 | static u32 ordernum = 1; | 692 | static u32 ordernum = 1; |
693 | struct unix_address *addr; | 693 | struct unix_address *addr; |
694 | int err; | 694 | int err; |
695 | unsigned int retries = 0; | ||
695 | 696 | ||
696 | mutex_lock(&u->readlock); | 697 | mutex_lock(&u->readlock); |
697 | 698 | ||
@@ -717,9 +718,17 @@ retry: | |||
717 | if (__unix_find_socket_byname(net, addr->name, addr->len, sock->type, | 718 | if (__unix_find_socket_byname(net, addr->name, addr->len, sock->type, |
718 | addr->hash)) { | 719 | addr->hash)) { |
719 | spin_unlock(&unix_table_lock); | 720 | spin_unlock(&unix_table_lock); |
720 | /* Sanity yield. It is unusual case, but yet... */ | 721 | /* |
721 | if (!(ordernum&0xFF)) | 722 | * __unix_find_socket_byname() may take long time if many names |
722 | yield(); | 723 | * are already in use. |
724 | */ | ||
725 | cond_resched(); | ||
726 | /* Give up if all names seems to be in use. */ | ||
727 | if (retries++ == 0xFFFFF) { | ||
728 | err = -ENOSPC; | ||
729 | kfree(addr); | ||
730 | goto out; | ||
731 | } | ||
723 | goto retry; | 732 | goto retry; |
724 | } | 733 | } |
725 | addr->hash ^= sk->sk_type; | 734 | addr->hash ^= sk->sk_type; |
@@ -1502,6 +1511,8 @@ restart: | |||
1502 | goto restart; | 1511 | goto restart; |
1503 | } | 1512 | } |
1504 | 1513 | ||
1514 | if (sock_flag(other, SOCK_RCVTSTAMP)) | ||
1515 | __net_timestamp(skb); | ||
1505 | skb_queue_tail(&other->sk_receive_queue, skb); | 1516 | skb_queue_tail(&other->sk_receive_queue, skb); |
1506 | unix_state_unlock(other); | 1517 | unix_state_unlock(other); |
1507 | other->sk_data_ready(other, len); | 1518 | other->sk_data_ready(other, len); |
@@ -1713,6 +1724,9 @@ static int unix_dgram_recvmsg(struct kiocb *iocb, struct socket *sock, | |||
1713 | if (err) | 1724 | if (err) |
1714 | goto out_free; | 1725 | goto out_free; |
1715 | 1726 | ||
1727 | if (sock_flag(sk, SOCK_RCVTSTAMP)) | ||
1728 | __sock_recv_timestamp(msg, sk, skb); | ||
1729 | |||
1716 | if (!siocb->scm) { | 1730 | if (!siocb->scm) { |
1717 | siocb->scm = &tmp_scm; | 1731 | siocb->scm = &tmp_scm; |
1718 | memset(&tmp_scm, 0, sizeof(tmp_scm)); | 1732 | memset(&tmp_scm, 0, sizeof(tmp_scm)); |
@@ -2024,11 +2038,10 @@ static unsigned int unix_poll(struct file *file, struct socket *sock, poll_table | |||
2024 | if (sk->sk_shutdown == SHUTDOWN_MASK) | 2038 | if (sk->sk_shutdown == SHUTDOWN_MASK) |
2025 | mask |= POLLHUP; | 2039 | mask |= POLLHUP; |
2026 | if (sk->sk_shutdown & RCV_SHUTDOWN) | 2040 | if (sk->sk_shutdown & RCV_SHUTDOWN) |
2027 | mask |= POLLRDHUP; | 2041 | mask |= POLLRDHUP | POLLIN | POLLRDNORM; |
2028 | 2042 | ||
2029 | /* readable? */ | 2043 | /* readable? */ |
2030 | if (!skb_queue_empty(&sk->sk_receive_queue) || | 2044 | if (!skb_queue_empty(&sk->sk_receive_queue)) |
2031 | (sk->sk_shutdown & RCV_SHUTDOWN)) | ||
2032 | mask |= POLLIN | POLLRDNORM; | 2045 | mask |= POLLIN | POLLRDNORM; |
2033 | 2046 | ||
2034 | /* Connection-based need to check for termination and startup */ | 2047 | /* Connection-based need to check for termination and startup */ |