aboutsummaryrefslogtreecommitdiffstats
path: root/net/unix
diff options
context:
space:
mode:
authorGrant Likely <grant.likely@secretlab.ca>2010-12-30 00:20:30 -0500
committerGrant Likely <grant.likely@secretlab.ca>2010-12-30 00:21:47 -0500
commitd392da5207352f09030e95d9ea335a4225667ec0 (patch)
tree7d6cd1932afcad0a5619a5c504a6d93ca318187c /net/unix
parente39d5ef678045d61812c1401f04fe8edb14d6359 (diff)
parent387c31c7e5c9805b0aef8833d1731a5fe7bdea14 (diff)
Merge v2.6.37-rc8 into powerpc/next
Diffstat (limited to 'net/unix')
-rw-r--r--net/unix/af_unix.c76
-rw-r--r--net/unix/garbage.c9
2 files changed, 66 insertions, 19 deletions
diff --git a/net/unix/af_unix.c b/net/unix/af_unix.c
index 4414a18c63b4..2268e6798124 100644
--- a/net/unix/af_unix.c
+++ b/net/unix/af_unix.c
@@ -117,7 +117,7 @@
117 117
118static struct hlist_head unix_socket_table[UNIX_HASH_SIZE + 1]; 118static struct hlist_head unix_socket_table[UNIX_HASH_SIZE + 1];
119static DEFINE_SPINLOCK(unix_table_lock); 119static DEFINE_SPINLOCK(unix_table_lock);
120static atomic_t unix_nr_socks = ATOMIC_INIT(0); 120static atomic_long_t unix_nr_socks;
121 121
122#define unix_sockets_unbound (&unix_socket_table[UNIX_HASH_SIZE]) 122#define unix_sockets_unbound (&unix_socket_table[UNIX_HASH_SIZE])
123 123
@@ -360,13 +360,13 @@ static void unix_sock_destructor(struct sock *sk)
360 if (u->addr) 360 if (u->addr)
361 unix_release_addr(u->addr); 361 unix_release_addr(u->addr);
362 362
363 atomic_dec(&unix_nr_socks); 363 atomic_long_dec(&unix_nr_socks);
364 local_bh_disable(); 364 local_bh_disable();
365 sock_prot_inuse_add(sock_net(sk), sk->sk_prot, -1); 365 sock_prot_inuse_add(sock_net(sk), sk->sk_prot, -1);
366 local_bh_enable(); 366 local_bh_enable();
367#ifdef UNIX_REFCNT_DEBUG 367#ifdef UNIX_REFCNT_DEBUG
368 printk(KERN_DEBUG "UNIX %p is destroyed, %d are still alive.\n", sk, 368 printk(KERN_DEBUG "UNIX %p is destroyed, %ld are still alive.\n", sk,
369 atomic_read(&unix_nr_socks)); 369 atomic_long_read(&unix_nr_socks));
370#endif 370#endif
371} 371}
372 372
@@ -606,8 +606,8 @@ static struct sock *unix_create1(struct net *net, struct socket *sock)
606 struct sock *sk = NULL; 606 struct sock *sk = NULL;
607 struct unix_sock *u; 607 struct unix_sock *u;
608 608
609 atomic_inc(&unix_nr_socks); 609 atomic_long_inc(&unix_nr_socks);
610 if (atomic_read(&unix_nr_socks) > 2 * get_max_files()) 610 if (atomic_long_read(&unix_nr_socks) > 2 * get_max_files())
611 goto out; 611 goto out;
612 612
613 sk = sk_alloc(net, PF_UNIX, GFP_KERNEL, &unix_proto); 613 sk = sk_alloc(net, PF_UNIX, GFP_KERNEL, &unix_proto);
@@ -632,7 +632,7 @@ static struct sock *unix_create1(struct net *net, struct socket *sock)
632 unix_insert_socket(unix_sockets_unbound, sk); 632 unix_insert_socket(unix_sockets_unbound, sk);
633out: 633out:
634 if (sk == NULL) 634 if (sk == NULL)
635 atomic_dec(&unix_nr_socks); 635 atomic_long_dec(&unix_nr_socks);
636 else { 636 else {
637 local_bh_disable(); 637 local_bh_disable();
638 sock_prot_inuse_add(sock_net(sk), sk->sk_prot, 1); 638 sock_prot_inuse_add(sock_net(sk), sk->sk_prot, 1);
@@ -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;
@@ -1334,9 +1343,25 @@ static void unix_destruct_scm(struct sk_buff *skb)
1334 sock_wfree(skb); 1343 sock_wfree(skb);
1335} 1344}
1336 1345
1346#define MAX_RECURSION_LEVEL 4
1347
1337static int unix_attach_fds(struct scm_cookie *scm, struct sk_buff *skb) 1348static int unix_attach_fds(struct scm_cookie *scm, struct sk_buff *skb)
1338{ 1349{
1339 int i; 1350 int i;
1351 unsigned char max_level = 0;
1352 int unix_sock_count = 0;
1353
1354 for (i = scm->fp->count - 1; i >= 0; i--) {
1355 struct sock *sk = unix_get_socket(scm->fp->fp[i]);
1356
1357 if (sk) {
1358 unix_sock_count++;
1359 max_level = max(max_level,
1360 unix_sk(sk)->recursion_level);
1361 }
1362 }
1363 if (unlikely(max_level > MAX_RECURSION_LEVEL))
1364 return -ETOOMANYREFS;
1340 1365
1341 /* 1366 /*
1342 * Need to duplicate file references for the sake of garbage 1367 * Need to duplicate file references for the sake of garbage
@@ -1347,9 +1372,11 @@ static int unix_attach_fds(struct scm_cookie *scm, struct sk_buff *skb)
1347 if (!UNIXCB(skb).fp) 1372 if (!UNIXCB(skb).fp)
1348 return -ENOMEM; 1373 return -ENOMEM;
1349 1374
1350 for (i = scm->fp->count-1; i >= 0; i--) 1375 if (unix_sock_count) {
1351 unix_inflight(scm->fp->fp[i]); 1376 for (i = scm->fp->count - 1; i >= 0; i--)
1352 return 0; 1377 unix_inflight(scm->fp->fp[i]);
1378 }
1379 return max_level;
1353} 1380}
1354 1381
1355static int unix_scm_to_skb(struct scm_cookie *scm, struct sk_buff *skb, bool send_fds) 1382static int unix_scm_to_skb(struct scm_cookie *scm, struct sk_buff *skb, bool send_fds)
@@ -1384,6 +1411,7 @@ static int unix_dgram_sendmsg(struct kiocb *kiocb, struct socket *sock,
1384 struct sk_buff *skb; 1411 struct sk_buff *skb;
1385 long timeo; 1412 long timeo;
1386 struct scm_cookie tmp_scm; 1413 struct scm_cookie tmp_scm;
1414 int max_level;
1387 1415
1388 if (NULL == siocb->scm) 1416 if (NULL == siocb->scm)
1389 siocb->scm = &tmp_scm; 1417 siocb->scm = &tmp_scm;
@@ -1422,8 +1450,9 @@ static int unix_dgram_sendmsg(struct kiocb *kiocb, struct socket *sock,
1422 goto out; 1450 goto out;
1423 1451
1424 err = unix_scm_to_skb(siocb->scm, skb, true); 1452 err = unix_scm_to_skb(siocb->scm, skb, true);
1425 if (err) 1453 if (err < 0)
1426 goto out_free; 1454 goto out_free;
1455 max_level = err + 1;
1427 unix_get_secdata(siocb->scm, skb); 1456 unix_get_secdata(siocb->scm, skb);
1428 1457
1429 skb_reset_transport_header(skb); 1458 skb_reset_transport_header(skb);
@@ -1502,7 +1531,11 @@ restart:
1502 goto restart; 1531 goto restart;
1503 } 1532 }
1504 1533
1534 if (sock_flag(other, SOCK_RCVTSTAMP))
1535 __net_timestamp(skb);
1505 skb_queue_tail(&other->sk_receive_queue, skb); 1536 skb_queue_tail(&other->sk_receive_queue, skb);
1537 if (max_level > unix_sk(other)->recursion_level)
1538 unix_sk(other)->recursion_level = max_level;
1506 unix_state_unlock(other); 1539 unix_state_unlock(other);
1507 other->sk_data_ready(other, len); 1540 other->sk_data_ready(other, len);
1508 sock_put(other); 1541 sock_put(other);
@@ -1533,6 +1566,7 @@ static int unix_stream_sendmsg(struct kiocb *kiocb, struct socket *sock,
1533 int sent = 0; 1566 int sent = 0;
1534 struct scm_cookie tmp_scm; 1567 struct scm_cookie tmp_scm;
1535 bool fds_sent = false; 1568 bool fds_sent = false;
1569 int max_level;
1536 1570
1537 if (NULL == siocb->scm) 1571 if (NULL == siocb->scm)
1538 siocb->scm = &tmp_scm; 1572 siocb->scm = &tmp_scm;
@@ -1596,10 +1630,11 @@ static int unix_stream_sendmsg(struct kiocb *kiocb, struct socket *sock,
1596 1630
1597 /* Only send the fds in the first buffer */ 1631 /* Only send the fds in the first buffer */
1598 err = unix_scm_to_skb(siocb->scm, skb, !fds_sent); 1632 err = unix_scm_to_skb(siocb->scm, skb, !fds_sent);
1599 if (err) { 1633 if (err < 0) {
1600 kfree_skb(skb); 1634 kfree_skb(skb);
1601 goto out_err; 1635 goto out_err;
1602 } 1636 }
1637 max_level = err + 1;
1603 fds_sent = true; 1638 fds_sent = true;
1604 1639
1605 err = memcpy_fromiovec(skb_put(skb, size), msg->msg_iov, size); 1640 err = memcpy_fromiovec(skb_put(skb, size), msg->msg_iov, size);
@@ -1615,6 +1650,8 @@ static int unix_stream_sendmsg(struct kiocb *kiocb, struct socket *sock,
1615 goto pipe_err_free; 1650 goto pipe_err_free;
1616 1651
1617 skb_queue_tail(&other->sk_receive_queue, skb); 1652 skb_queue_tail(&other->sk_receive_queue, skb);
1653 if (max_level > unix_sk(other)->recursion_level)
1654 unix_sk(other)->recursion_level = max_level;
1618 unix_state_unlock(other); 1655 unix_state_unlock(other);
1619 other->sk_data_ready(other, size); 1656 other->sk_data_ready(other, size);
1620 sent += size; 1657 sent += size;
@@ -1713,6 +1750,9 @@ static int unix_dgram_recvmsg(struct kiocb *iocb, struct socket *sock,
1713 if (err) 1750 if (err)
1714 goto out_free; 1751 goto out_free;
1715 1752
1753 if (sock_flag(sk, SOCK_RCVTSTAMP))
1754 __sock_recv_timestamp(msg, sk, skb);
1755
1716 if (!siocb->scm) { 1756 if (!siocb->scm) {
1717 siocb->scm = &tmp_scm; 1757 siocb->scm = &tmp_scm;
1718 memset(&tmp_scm, 0, sizeof(tmp_scm)); 1758 memset(&tmp_scm, 0, sizeof(tmp_scm));
@@ -1831,6 +1871,7 @@ static int unix_stream_recvmsg(struct kiocb *iocb, struct socket *sock,
1831 unix_state_lock(sk); 1871 unix_state_lock(sk);
1832 skb = skb_dequeue(&sk->sk_receive_queue); 1872 skb = skb_dequeue(&sk->sk_receive_queue);
1833 if (skb == NULL) { 1873 if (skb == NULL) {
1874 unix_sk(sk)->recursion_level = 0;
1834 if (copied >= target) 1875 if (copied >= target)
1835 goto unlock; 1876 goto unlock;
1836 1877
@@ -2024,11 +2065,10 @@ static unsigned int unix_poll(struct file *file, struct socket *sock, poll_table
2024 if (sk->sk_shutdown == SHUTDOWN_MASK) 2065 if (sk->sk_shutdown == SHUTDOWN_MASK)
2025 mask |= POLLHUP; 2066 mask |= POLLHUP;
2026 if (sk->sk_shutdown & RCV_SHUTDOWN) 2067 if (sk->sk_shutdown & RCV_SHUTDOWN)
2027 mask |= POLLRDHUP; 2068 mask |= POLLRDHUP | POLLIN | POLLRDNORM;
2028 2069
2029 /* readable? */ 2070 /* readable? */
2030 if (!skb_queue_empty(&sk->sk_receive_queue) || 2071 if (!skb_queue_empty(&sk->sk_receive_queue))
2031 (sk->sk_shutdown & RCV_SHUTDOWN))
2032 mask |= POLLIN | POLLRDNORM; 2072 mask |= POLLIN | POLLRDNORM;
2033 2073
2034 /* Connection-based need to check for termination and startup */ 2074 /* Connection-based need to check for termination and startup */
diff --git a/net/unix/garbage.c b/net/unix/garbage.c
index c8df6fda0b1f..f89f83bf828e 100644
--- a/net/unix/garbage.c
+++ b/net/unix/garbage.c
@@ -96,7 +96,7 @@ static DECLARE_WAIT_QUEUE_HEAD(unix_gc_wait);
96unsigned int unix_tot_inflight; 96unsigned int unix_tot_inflight;
97 97
98 98
99static struct sock *unix_get_socket(struct file *filp) 99struct sock *unix_get_socket(struct file *filp)
100{ 100{
101 struct sock *u_sock = NULL; 101 struct sock *u_sock = NULL;
102 struct inode *inode = filp->f_path.dentry->d_inode; 102 struct inode *inode = filp->f_path.dentry->d_inode;
@@ -259,9 +259,16 @@ static void inc_inflight_move_tail(struct unix_sock *u)
259} 259}
260 260
261static bool gc_in_progress = false; 261static bool gc_in_progress = false;
262#define UNIX_INFLIGHT_TRIGGER_GC 16000
262 263
263void wait_for_unix_gc(void) 264void wait_for_unix_gc(void)
264{ 265{
266 /*
267 * If number of inflight sockets is insane,
268 * force a garbage collect right now.
269 */
270 if (unix_tot_inflight > UNIX_INFLIGHT_TRIGGER_GC && !gc_in_progress)
271 unix_gc();
265 wait_event(unix_gc_wait, gc_in_progress == false); 272 wait_event(unix_gc_wait, gc_in_progress == false);
266} 273}
267 274