aboutsummaryrefslogtreecommitdiffstats
path: root/net/unix
diff options
context:
space:
mode:
authorChristoph Hellwig <hch@lst.de>2015-01-28 12:04:53 -0500
committerDavid S. Miller <davem@davemloft.net>2015-01-29 02:15:07 -0500
commit7cc05662682da4b0e0a4fdf3c3f190577803ae81 (patch)
tree0c7fe7b2e90ba7d28cf05d4151813a03fe321b47 /net/unix
parenta154e6f6efdd13d7254679b5a99d9b912017621f (diff)
net: remove sock_iocb
The sock_iocb structure is allocate on stack for each read/write-like operation on sockets, and contains various fields of which only the embedded msghdr and sometimes a pointer to the scm_cookie is ever used. Get rid of the sock_iocb and put a msghdr directly on the stack and pass the scm_cookie explicitly to netlink_mmap_sendmsg. Signed-off-by: Christoph Hellwig <hch@lst.de> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/unix')
-rw-r--r--net/unix/af_unix.c73
1 files changed, 29 insertions, 44 deletions
diff --git a/net/unix/af_unix.c b/net/unix/af_unix.c
index 8e1b10274b02..526b6edab018 100644
--- a/net/unix/af_unix.c
+++ b/net/unix/af_unix.c
@@ -1445,7 +1445,6 @@ static void maybe_add_creds(struct sk_buff *skb, const struct socket *sock,
1445static int unix_dgram_sendmsg(struct kiocb *kiocb, struct socket *sock, 1445static int unix_dgram_sendmsg(struct kiocb *kiocb, struct socket *sock,
1446 struct msghdr *msg, size_t len) 1446 struct msghdr *msg, size_t len)
1447{ 1447{
1448 struct sock_iocb *siocb = kiocb_to_siocb(kiocb);
1449 struct sock *sk = sock->sk; 1448 struct sock *sk = sock->sk;
1450 struct net *net = sock_net(sk); 1449 struct net *net = sock_net(sk);
1451 struct unix_sock *u = unix_sk(sk); 1450 struct unix_sock *u = unix_sk(sk);
@@ -1456,14 +1455,12 @@ static int unix_dgram_sendmsg(struct kiocb *kiocb, struct socket *sock,
1456 unsigned int hash; 1455 unsigned int hash;
1457 struct sk_buff *skb; 1456 struct sk_buff *skb;
1458 long timeo; 1457 long timeo;
1459 struct scm_cookie tmp_scm; 1458 struct scm_cookie scm;
1460 int max_level; 1459 int max_level;
1461 int data_len = 0; 1460 int data_len = 0;
1462 1461
1463 if (NULL == siocb->scm)
1464 siocb->scm = &tmp_scm;
1465 wait_for_unix_gc(); 1462 wait_for_unix_gc();
1466 err = scm_send(sock, msg, siocb->scm, false); 1463 err = scm_send(sock, msg, &scm, false);
1467 if (err < 0) 1464 if (err < 0)
1468 return err; 1465 return err;
1469 1466
@@ -1507,11 +1504,11 @@ static int unix_dgram_sendmsg(struct kiocb *kiocb, struct socket *sock,
1507 if (skb == NULL) 1504 if (skb == NULL)
1508 goto out; 1505 goto out;
1509 1506
1510 err = unix_scm_to_skb(siocb->scm, skb, true); 1507 err = unix_scm_to_skb(&scm, skb, true);
1511 if (err < 0) 1508 if (err < 0)
1512 goto out_free; 1509 goto out_free;
1513 max_level = err + 1; 1510 max_level = err + 1;
1514 unix_get_secdata(siocb->scm, skb); 1511 unix_get_secdata(&scm, skb);
1515 1512
1516 skb_put(skb, len - data_len); 1513 skb_put(skb, len - data_len);
1517 skb->data_len = data_len; 1514 skb->data_len = data_len;
@@ -1606,7 +1603,7 @@ restart:
1606 unix_state_unlock(other); 1603 unix_state_unlock(other);
1607 other->sk_data_ready(other); 1604 other->sk_data_ready(other);
1608 sock_put(other); 1605 sock_put(other);
1609 scm_destroy(siocb->scm); 1606 scm_destroy(&scm);
1610 return len; 1607 return len;
1611 1608
1612out_unlock: 1609out_unlock:
@@ -1616,7 +1613,7 @@ out_free:
1616out: 1613out:
1617 if (other) 1614 if (other)
1618 sock_put(other); 1615 sock_put(other);
1619 scm_destroy(siocb->scm); 1616 scm_destroy(&scm);
1620 return err; 1617 return err;
1621} 1618}
1622 1619
@@ -1628,21 +1625,18 @@ out:
1628static int unix_stream_sendmsg(struct kiocb *kiocb, struct socket *sock, 1625static int unix_stream_sendmsg(struct kiocb *kiocb, struct socket *sock,
1629 struct msghdr *msg, size_t len) 1626 struct msghdr *msg, size_t len)
1630{ 1627{
1631 struct sock_iocb *siocb = kiocb_to_siocb(kiocb);
1632 struct sock *sk = sock->sk; 1628 struct sock *sk = sock->sk;
1633 struct sock *other = NULL; 1629 struct sock *other = NULL;
1634 int err, size; 1630 int err, size;
1635 struct sk_buff *skb; 1631 struct sk_buff *skb;
1636 int sent = 0; 1632 int sent = 0;
1637 struct scm_cookie tmp_scm; 1633 struct scm_cookie scm;
1638 bool fds_sent = false; 1634 bool fds_sent = false;
1639 int max_level; 1635 int max_level;
1640 int data_len; 1636 int data_len;
1641 1637
1642 if (NULL == siocb->scm)
1643 siocb->scm = &tmp_scm;
1644 wait_for_unix_gc(); 1638 wait_for_unix_gc();
1645 err = scm_send(sock, msg, siocb->scm, false); 1639 err = scm_send(sock, msg, &scm, false);
1646 if (err < 0) 1640 if (err < 0)
1647 return err; 1641 return err;
1648 1642
@@ -1683,7 +1677,7 @@ static int unix_stream_sendmsg(struct kiocb *kiocb, struct socket *sock,
1683 goto out_err; 1677 goto out_err;
1684 1678
1685 /* Only send the fds in the first buffer */ 1679 /* Only send the fds in the first buffer */
1686 err = unix_scm_to_skb(siocb->scm, skb, !fds_sent); 1680 err = unix_scm_to_skb(&scm, skb, !fds_sent);
1687 if (err < 0) { 1681 if (err < 0) {
1688 kfree_skb(skb); 1682 kfree_skb(skb);
1689 goto out_err; 1683 goto out_err;
@@ -1715,8 +1709,7 @@ static int unix_stream_sendmsg(struct kiocb *kiocb, struct socket *sock,
1715 sent += size; 1709 sent += size;
1716 } 1710 }
1717 1711
1718 scm_destroy(siocb->scm); 1712 scm_destroy(&scm);
1719 siocb->scm = NULL;
1720 1713
1721 return sent; 1714 return sent;
1722 1715
@@ -1728,8 +1721,7 @@ pipe_err:
1728 send_sig(SIGPIPE, current, 0); 1721 send_sig(SIGPIPE, current, 0);
1729 err = -EPIPE; 1722 err = -EPIPE;
1730out_err: 1723out_err:
1731 scm_destroy(siocb->scm); 1724 scm_destroy(&scm);
1732 siocb->scm = NULL;
1733 return sent ? : err; 1725 return sent ? : err;
1734} 1726}
1735 1727
@@ -1778,8 +1770,7 @@ static int unix_dgram_recvmsg(struct kiocb *iocb, struct socket *sock,
1778 struct msghdr *msg, size_t size, 1770 struct msghdr *msg, size_t size,
1779 int flags) 1771 int flags)
1780{ 1772{
1781 struct sock_iocb *siocb = kiocb_to_siocb(iocb); 1773 struct scm_cookie scm;
1782 struct scm_cookie tmp_scm;
1783 struct sock *sk = sock->sk; 1774 struct sock *sk = sock->sk;
1784 struct unix_sock *u = unix_sk(sk); 1775 struct unix_sock *u = unix_sk(sk);
1785 int noblock = flags & MSG_DONTWAIT; 1776 int noblock = flags & MSG_DONTWAIT;
@@ -1831,16 +1822,14 @@ static int unix_dgram_recvmsg(struct kiocb *iocb, struct socket *sock,
1831 if (sock_flag(sk, SOCK_RCVTSTAMP)) 1822 if (sock_flag(sk, SOCK_RCVTSTAMP))
1832 __sock_recv_timestamp(msg, sk, skb); 1823 __sock_recv_timestamp(msg, sk, skb);
1833 1824
1834 if (!siocb->scm) { 1825 memset(&scm, 0, sizeof(scm));
1835 siocb->scm = &tmp_scm; 1826
1836 memset(&tmp_scm, 0, sizeof(tmp_scm)); 1827 scm_set_cred(&scm, UNIXCB(skb).pid, UNIXCB(skb).uid, UNIXCB(skb).gid);
1837 } 1828 unix_set_secdata(&scm, skb);
1838 scm_set_cred(siocb->scm, UNIXCB(skb).pid, UNIXCB(skb).uid, UNIXCB(skb).gid);
1839 unix_set_secdata(siocb->scm, skb);
1840 1829
1841 if (!(flags & MSG_PEEK)) { 1830 if (!(flags & MSG_PEEK)) {
1842 if (UNIXCB(skb).fp) 1831 if (UNIXCB(skb).fp)
1843 unix_detach_fds(siocb->scm, skb); 1832 unix_detach_fds(&scm, skb);
1844 1833
1845 sk_peek_offset_bwd(sk, skb->len); 1834 sk_peek_offset_bwd(sk, skb->len);
1846 } else { 1835 } else {
@@ -1860,11 +1849,11 @@ static int unix_dgram_recvmsg(struct kiocb *iocb, struct socket *sock,
1860 sk_peek_offset_fwd(sk, size); 1849 sk_peek_offset_fwd(sk, size);
1861 1850
1862 if (UNIXCB(skb).fp) 1851 if (UNIXCB(skb).fp)
1863 siocb->scm->fp = scm_fp_dup(UNIXCB(skb).fp); 1852 scm.fp = scm_fp_dup(UNIXCB(skb).fp);
1864 } 1853 }
1865 err = (flags & MSG_TRUNC) ? skb->len - skip : size; 1854 err = (flags & MSG_TRUNC) ? skb->len - skip : size;
1866 1855
1867 scm_recv(sock, msg, siocb->scm, flags); 1856 scm_recv(sock, msg, &scm, flags);
1868 1857
1869out_free: 1858out_free:
1870 skb_free_datagram(sk, skb); 1859 skb_free_datagram(sk, skb);
@@ -1915,8 +1904,7 @@ static int unix_stream_recvmsg(struct kiocb *iocb, struct socket *sock,
1915 struct msghdr *msg, size_t size, 1904 struct msghdr *msg, size_t size,
1916 int flags) 1905 int flags)
1917{ 1906{
1918 struct sock_iocb *siocb = kiocb_to_siocb(iocb); 1907 struct scm_cookie scm;
1919 struct scm_cookie tmp_scm;
1920 struct sock *sk = sock->sk; 1908 struct sock *sk = sock->sk;
1921 struct unix_sock *u = unix_sk(sk); 1909 struct unix_sock *u = unix_sk(sk);
1922 DECLARE_SOCKADDR(struct sockaddr_un *, sunaddr, msg->msg_name); 1910 DECLARE_SOCKADDR(struct sockaddr_un *, sunaddr, msg->msg_name);
@@ -1943,10 +1931,7 @@ static int unix_stream_recvmsg(struct kiocb *iocb, struct socket *sock,
1943 * while sleeps in memcpy_tomsg 1931 * while sleeps in memcpy_tomsg
1944 */ 1932 */
1945 1933
1946 if (!siocb->scm) { 1934 memset(&scm, 0, sizeof(scm));
1947 siocb->scm = &tmp_scm;
1948 memset(&tmp_scm, 0, sizeof(tmp_scm));
1949 }
1950 1935
1951 err = mutex_lock_interruptible(&u->readlock); 1936 err = mutex_lock_interruptible(&u->readlock);
1952 if (unlikely(err)) { 1937 if (unlikely(err)) {
@@ -2012,13 +1997,13 @@ again:
2012 1997
2013 if (check_creds) { 1998 if (check_creds) {
2014 /* Never glue messages from different writers */ 1999 /* Never glue messages from different writers */
2015 if ((UNIXCB(skb).pid != siocb->scm->pid) || 2000 if ((UNIXCB(skb).pid != scm.pid) ||
2016 !uid_eq(UNIXCB(skb).uid, siocb->scm->creds.uid) || 2001 !uid_eq(UNIXCB(skb).uid, scm.creds.uid) ||
2017 !gid_eq(UNIXCB(skb).gid, siocb->scm->creds.gid)) 2002 !gid_eq(UNIXCB(skb).gid, scm.creds.gid))
2018 break; 2003 break;
2019 } else if (test_bit(SOCK_PASSCRED, &sock->flags)) { 2004 } else if (test_bit(SOCK_PASSCRED, &sock->flags)) {
2020 /* Copy credentials */ 2005 /* Copy credentials */
2021 scm_set_cred(siocb->scm, UNIXCB(skb).pid, UNIXCB(skb).uid, UNIXCB(skb).gid); 2006 scm_set_cred(&scm, UNIXCB(skb).pid, UNIXCB(skb).uid, UNIXCB(skb).gid);
2022 check_creds = 1; 2007 check_creds = 1;
2023 } 2008 }
2024 2009
@@ -2045,7 +2030,7 @@ again:
2045 sk_peek_offset_bwd(sk, chunk); 2030 sk_peek_offset_bwd(sk, chunk);
2046 2031
2047 if (UNIXCB(skb).fp) 2032 if (UNIXCB(skb).fp)
2048 unix_detach_fds(siocb->scm, skb); 2033 unix_detach_fds(&scm, skb);
2049 2034
2050 if (unix_skb_len(skb)) 2035 if (unix_skb_len(skb))
2051 break; 2036 break;
@@ -2053,13 +2038,13 @@ again:
2053 skb_unlink(skb, &sk->sk_receive_queue); 2038 skb_unlink(skb, &sk->sk_receive_queue);
2054 consume_skb(skb); 2039 consume_skb(skb);
2055 2040
2056 if (siocb->scm->fp) 2041 if (scm.fp)
2057 break; 2042 break;
2058 } else { 2043 } else {
2059 /* It is questionable, see note in unix_dgram_recvmsg. 2044 /* It is questionable, see note in unix_dgram_recvmsg.
2060 */ 2045 */
2061 if (UNIXCB(skb).fp) 2046 if (UNIXCB(skb).fp)
2062 siocb->scm->fp = scm_fp_dup(UNIXCB(skb).fp); 2047 scm.fp = scm_fp_dup(UNIXCB(skb).fp);
2063 2048
2064 sk_peek_offset_fwd(sk, chunk); 2049 sk_peek_offset_fwd(sk, chunk);
2065 2050
@@ -2068,7 +2053,7 @@ again:
2068 } while (size); 2053 } while (size);
2069 2054
2070 mutex_unlock(&u->readlock); 2055 mutex_unlock(&u->readlock);
2071 scm_recv(sock, msg, siocb->scm, flags); 2056 scm_recv(sock, msg, &scm, flags);
2072out: 2057out:
2073 return copied ? : err; 2058 return copied ? : err;
2074} 2059}