diff options
author | Christoph Hellwig <hch@lst.de> | 2015-01-28 12:04:53 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2015-01-29 02:15:07 -0500 |
commit | 7cc05662682da4b0e0a4fdf3c3f190577803ae81 (patch) | |
tree | 0c7fe7b2e90ba7d28cf05d4151813a03fe321b47 /net/unix | |
parent | a154e6f6efdd13d7254679b5a99d9b912017621f (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.c | 73 |
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, | |||
1445 | static int unix_dgram_sendmsg(struct kiocb *kiocb, struct socket *sock, | 1445 | static 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 | ||
1612 | out_unlock: | 1609 | out_unlock: |
@@ -1616,7 +1613,7 @@ out_free: | |||
1616 | out: | 1613 | out: |
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: | |||
1628 | static int unix_stream_sendmsg(struct kiocb *kiocb, struct socket *sock, | 1625 | static 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; |
1730 | out_err: | 1723 | out_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 | ||
1869 | out_free: | 1858 | out_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); |
2072 | out: | 2057 | out: |
2073 | return copied ? : err; | 2058 | return copied ? : err; |
2074 | } | 2059 | } |