diff options
author | Arnd Bergmann <arnd@arndb.de> | 2009-11-04 23:37:27 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2009-11-07 03:46:39 -0500 |
commit | 83927ba069a65326f39991a02d6a49ba3b7cea44 (patch) | |
tree | a4286ea9985ba13dbb49a7f3f2898c40d11558ee /net/ipx | |
parent | ecced8ba8759c16337fc6785d7bab8931ca55cf6 (diff) |
net/ipx: push down BKL into a ipx_dgram_ops
Making the BKL usage explicit in ipx makes it more
obvious where it is used, reduces code size and helps
getting rid of the BKL in common code.
I did not analyse how to kill lock_kernel from ipx
entirely, this will involve either proving that it's not
needed, or replacing with a proper mutex or spinlock,
after finding out which data structures are protected
by the lock.
Cc: Arnaldo Carvalho de Melo <acme@ghostprotocols.net>
Cc: David S. Miller <davem@davemloft.net>
Cc: Stephen Hemminger <shemminger@vyatta.com>
Cc: netdev@vger.kernel.org
Signed-off-by: Arnd Bergmann <arnd@arndb.de>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/ipx')
-rw-r--r-- | net/ipx/af_ipx.c | 54 |
1 files changed, 46 insertions, 8 deletions
diff --git a/net/ipx/af_ipx.c b/net/ipx/af_ipx.c index 96d193a24415..975c5a366e55 100644 --- a/net/ipx/af_ipx.c +++ b/net/ipx/af_ipx.c | |||
@@ -1298,6 +1298,7 @@ static int ipx_setsockopt(struct socket *sock, int level, int optname, | |||
1298 | int opt; | 1298 | int opt; |
1299 | int rc = -EINVAL; | 1299 | int rc = -EINVAL; |
1300 | 1300 | ||
1301 | lock_kernel(); | ||
1301 | if (optlen != sizeof(int)) | 1302 | if (optlen != sizeof(int)) |
1302 | goto out; | 1303 | goto out; |
1303 | 1304 | ||
@@ -1312,6 +1313,7 @@ static int ipx_setsockopt(struct socket *sock, int level, int optname, | |||
1312 | ipx_sk(sk)->type = opt; | 1313 | ipx_sk(sk)->type = opt; |
1313 | rc = 0; | 1314 | rc = 0; |
1314 | out: | 1315 | out: |
1316 | unlock_kernel(); | ||
1315 | return rc; | 1317 | return rc; |
1316 | } | 1318 | } |
1317 | 1319 | ||
@@ -1323,6 +1325,7 @@ static int ipx_getsockopt(struct socket *sock, int level, int optname, | |||
1323 | int len; | 1325 | int len; |
1324 | int rc = -ENOPROTOOPT; | 1326 | int rc = -ENOPROTOOPT; |
1325 | 1327 | ||
1328 | lock_kernel(); | ||
1326 | if (!(level == SOL_IPX && optname == IPX_TYPE)) | 1329 | if (!(level == SOL_IPX && optname == IPX_TYPE)) |
1327 | goto out; | 1330 | goto out; |
1328 | 1331 | ||
@@ -1343,6 +1346,7 @@ static int ipx_getsockopt(struct socket *sock, int level, int optname, | |||
1343 | 1346 | ||
1344 | rc = 0; | 1347 | rc = 0; |
1345 | out: | 1348 | out: |
1349 | unlock_kernel(); | ||
1346 | return rc; | 1350 | return rc; |
1347 | } | 1351 | } |
1348 | 1352 | ||
@@ -1391,6 +1395,7 @@ static int ipx_release(struct socket *sock) | |||
1391 | if (!sk) | 1395 | if (!sk) |
1392 | goto out; | 1396 | goto out; |
1393 | 1397 | ||
1398 | lock_kernel(); | ||
1394 | if (!sock_flag(sk, SOCK_DEAD)) | 1399 | if (!sock_flag(sk, SOCK_DEAD)) |
1395 | sk->sk_state_change(sk); | 1400 | sk->sk_state_change(sk); |
1396 | 1401 | ||
@@ -1398,6 +1403,7 @@ static int ipx_release(struct socket *sock) | |||
1398 | sock->sk = NULL; | 1403 | sock->sk = NULL; |
1399 | sk_refcnt_debug_release(sk); | 1404 | sk_refcnt_debug_release(sk); |
1400 | ipx_destroy_socket(sk); | 1405 | ipx_destroy_socket(sk); |
1406 | unlock_kernel(); | ||
1401 | out: | 1407 | out: |
1402 | return 0; | 1408 | return 0; |
1403 | } | 1409 | } |
@@ -1425,7 +1431,8 @@ static __be16 ipx_first_free_socketnum(struct ipx_interface *intrfc) | |||
1425 | return htons(socketNum); | 1431 | return htons(socketNum); |
1426 | } | 1432 | } |
1427 | 1433 | ||
1428 | static int ipx_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len) | 1434 | static int __ipx_bind(struct socket *sock, |
1435 | struct sockaddr *uaddr, int addr_len) | ||
1429 | { | 1436 | { |
1430 | struct sock *sk = sock->sk; | 1437 | struct sock *sk = sock->sk; |
1431 | struct ipx_sock *ipxs = ipx_sk(sk); | 1438 | struct ipx_sock *ipxs = ipx_sk(sk); |
@@ -1520,6 +1527,17 @@ out: | |||
1520 | return rc; | 1527 | return rc; |
1521 | } | 1528 | } |
1522 | 1529 | ||
1530 | static int ipx_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len) | ||
1531 | { | ||
1532 | int rc; | ||
1533 | |||
1534 | lock_kernel(); | ||
1535 | rc = __ipx_bind(sock, uaddr, addr_len); | ||
1536 | unlock_kernel(); | ||
1537 | |||
1538 | return rc; | ||
1539 | } | ||
1540 | |||
1523 | static int ipx_connect(struct socket *sock, struct sockaddr *uaddr, | 1541 | static int ipx_connect(struct socket *sock, struct sockaddr *uaddr, |
1524 | int addr_len, int flags) | 1542 | int addr_len, int flags) |
1525 | { | 1543 | { |
@@ -1532,6 +1550,7 @@ static int ipx_connect(struct socket *sock, struct sockaddr *uaddr, | |||
1532 | sk->sk_state = TCP_CLOSE; | 1550 | sk->sk_state = TCP_CLOSE; |
1533 | sock->state = SS_UNCONNECTED; | 1551 | sock->state = SS_UNCONNECTED; |
1534 | 1552 | ||
1553 | lock_kernel(); | ||
1535 | if (addr_len != sizeof(*addr)) | 1554 | if (addr_len != sizeof(*addr)) |
1536 | goto out; | 1555 | goto out; |
1537 | addr = (struct sockaddr_ipx *)uaddr; | 1556 | addr = (struct sockaddr_ipx *)uaddr; |
@@ -1551,7 +1570,7 @@ static int ipx_connect(struct socket *sock, struct sockaddr *uaddr, | |||
1551 | IPX_NODE_LEN); | 1570 | IPX_NODE_LEN); |
1552 | #endif /* CONFIG_IPX_INTERN */ | 1571 | #endif /* CONFIG_IPX_INTERN */ |
1553 | 1572 | ||
1554 | rc = ipx_bind(sock, (struct sockaddr *)&uaddr, | 1573 | rc = __ipx_bind(sock, (struct sockaddr *)&uaddr, |
1555 | sizeof(struct sockaddr_ipx)); | 1574 | sizeof(struct sockaddr_ipx)); |
1556 | if (rc) | 1575 | if (rc) |
1557 | goto out; | 1576 | goto out; |
@@ -1578,6 +1597,7 @@ static int ipx_connect(struct socket *sock, struct sockaddr *uaddr, | |||
1578 | ipxrtr_put(rt); | 1597 | ipxrtr_put(rt); |
1579 | rc = 0; | 1598 | rc = 0; |
1580 | out: | 1599 | out: |
1600 | unlock_kernel(); | ||
1581 | return rc; | 1601 | return rc; |
1582 | } | 1602 | } |
1583 | 1603 | ||
@@ -1593,6 +1613,7 @@ static int ipx_getname(struct socket *sock, struct sockaddr *uaddr, | |||
1593 | 1613 | ||
1594 | *uaddr_len = sizeof(struct sockaddr_ipx); | 1614 | *uaddr_len = sizeof(struct sockaddr_ipx); |
1595 | 1615 | ||
1616 | lock_kernel(); | ||
1596 | if (peer) { | 1617 | if (peer) { |
1597 | rc = -ENOTCONN; | 1618 | rc = -ENOTCONN; |
1598 | if (sk->sk_state != TCP_ESTABLISHED) | 1619 | if (sk->sk_state != TCP_ESTABLISHED) |
@@ -1627,6 +1648,19 @@ static int ipx_getname(struct socket *sock, struct sockaddr *uaddr, | |||
1627 | 1648 | ||
1628 | rc = 0; | 1649 | rc = 0; |
1629 | out: | 1650 | out: |
1651 | unlock_kernel(); | ||
1652 | return rc; | ||
1653 | } | ||
1654 | |||
1655 | static unsigned int ipx_datagram_poll(struct file *file, struct socket *sock, | ||
1656 | poll_table *wait) | ||
1657 | { | ||
1658 | int rc; | ||
1659 | |||
1660 | lock_kernel(); | ||
1661 | rc = datagram_poll(file, sock, wait); | ||
1662 | unlock_kernel(); | ||
1663 | |||
1630 | return rc; | 1664 | return rc; |
1631 | } | 1665 | } |
1632 | 1666 | ||
@@ -1701,6 +1735,7 @@ static int ipx_sendmsg(struct kiocb *iocb, struct socket *sock, | |||
1701 | int rc = -EINVAL; | 1735 | int rc = -EINVAL; |
1702 | int flags = msg->msg_flags; | 1736 | int flags = msg->msg_flags; |
1703 | 1737 | ||
1738 | lock_kernel(); | ||
1704 | /* Socket gets bound below anyway */ | 1739 | /* Socket gets bound below anyway */ |
1705 | /* if (sk->sk_zapped) | 1740 | /* if (sk->sk_zapped) |
1706 | return -EIO; */ /* Socket not bound */ | 1741 | return -EIO; */ /* Socket not bound */ |
@@ -1724,7 +1759,7 @@ static int ipx_sendmsg(struct kiocb *iocb, struct socket *sock, | |||
1724 | memcpy(uaddr.sipx_node, ipxs->intrfc->if_node, | 1759 | memcpy(uaddr.sipx_node, ipxs->intrfc->if_node, |
1725 | IPX_NODE_LEN); | 1760 | IPX_NODE_LEN); |
1726 | #endif | 1761 | #endif |
1727 | rc = ipx_bind(sock, (struct sockaddr *)&uaddr, | 1762 | rc = __ipx_bind(sock, (struct sockaddr *)&uaddr, |
1728 | sizeof(struct sockaddr_ipx)); | 1763 | sizeof(struct sockaddr_ipx)); |
1729 | if (rc) | 1764 | if (rc) |
1730 | goto out; | 1765 | goto out; |
@@ -1752,6 +1787,7 @@ static int ipx_sendmsg(struct kiocb *iocb, struct socket *sock, | |||
1752 | if (rc >= 0) | 1787 | if (rc >= 0) |
1753 | rc = len; | 1788 | rc = len; |
1754 | out: | 1789 | out: |
1790 | unlock_kernel(); | ||
1755 | return rc; | 1791 | return rc; |
1756 | } | 1792 | } |
1757 | 1793 | ||
@@ -1766,6 +1802,7 @@ static int ipx_recvmsg(struct kiocb *iocb, struct socket *sock, | |||
1766 | struct sk_buff *skb; | 1802 | struct sk_buff *skb; |
1767 | int copied, rc; | 1803 | int copied, rc; |
1768 | 1804 | ||
1805 | lock_kernel(); | ||
1769 | /* put the autobinding in */ | 1806 | /* put the autobinding in */ |
1770 | if (!ipxs->port) { | 1807 | if (!ipxs->port) { |
1771 | struct sockaddr_ipx uaddr; | 1808 | struct sockaddr_ipx uaddr; |
@@ -1780,7 +1817,7 @@ static int ipx_recvmsg(struct kiocb *iocb, struct socket *sock, | |||
1780 | memcpy(uaddr.sipx_node, ipxs->intrfc->if_node, IPX_NODE_LEN); | 1817 | memcpy(uaddr.sipx_node, ipxs->intrfc->if_node, IPX_NODE_LEN); |
1781 | #endif /* CONFIG_IPX_INTERN */ | 1818 | #endif /* CONFIG_IPX_INTERN */ |
1782 | 1819 | ||
1783 | rc = ipx_bind(sock, (struct sockaddr *)&uaddr, | 1820 | rc = __ipx_bind(sock, (struct sockaddr *)&uaddr, |
1784 | sizeof(struct sockaddr_ipx)); | 1821 | sizeof(struct sockaddr_ipx)); |
1785 | if (rc) | 1822 | if (rc) |
1786 | goto out; | 1823 | goto out; |
@@ -1824,6 +1861,7 @@ static int ipx_recvmsg(struct kiocb *iocb, struct socket *sock, | |||
1824 | out_free: | 1861 | out_free: |
1825 | skb_free_datagram(sk, skb); | 1862 | skb_free_datagram(sk, skb); |
1826 | out: | 1863 | out: |
1864 | unlock_kernel(); | ||
1827 | return rc; | 1865 | return rc; |
1828 | } | 1866 | } |
1829 | 1867 | ||
@@ -1835,6 +1873,7 @@ static int ipx_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg) | |||
1835 | struct sock *sk = sock->sk; | 1873 | struct sock *sk = sock->sk; |
1836 | void __user *argp = (void __user *)arg; | 1874 | void __user *argp = (void __user *)arg; |
1837 | 1875 | ||
1876 | lock_kernel(); | ||
1838 | switch (cmd) { | 1877 | switch (cmd) { |
1839 | case TIOCOUTQ: | 1878 | case TIOCOUTQ: |
1840 | amount = sk->sk_sndbuf - sk_wmem_alloc_get(sk); | 1879 | amount = sk->sk_sndbuf - sk_wmem_alloc_get(sk); |
@@ -1897,6 +1936,7 @@ static int ipx_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg) | |||
1897 | rc = -ENOIOCTLCMD; | 1936 | rc = -ENOIOCTLCMD; |
1898 | break; | 1937 | break; |
1899 | } | 1938 | } |
1939 | unlock_kernel(); | ||
1900 | 1940 | ||
1901 | return rc; | 1941 | return rc; |
1902 | } | 1942 | } |
@@ -1934,7 +1974,7 @@ static const struct net_proto_family ipx_family_ops = { | |||
1934 | .owner = THIS_MODULE, | 1974 | .owner = THIS_MODULE, |
1935 | }; | 1975 | }; |
1936 | 1976 | ||
1937 | static const struct proto_ops SOCKOPS_WRAPPED(ipx_dgram_ops) = { | 1977 | static const struct proto_ops ipx_dgram_ops = { |
1938 | .family = PF_IPX, | 1978 | .family = PF_IPX, |
1939 | .owner = THIS_MODULE, | 1979 | .owner = THIS_MODULE, |
1940 | .release = ipx_release, | 1980 | .release = ipx_release, |
@@ -1943,7 +1983,7 @@ static const struct proto_ops SOCKOPS_WRAPPED(ipx_dgram_ops) = { | |||
1943 | .socketpair = sock_no_socketpair, | 1983 | .socketpair = sock_no_socketpair, |
1944 | .accept = sock_no_accept, | 1984 | .accept = sock_no_accept, |
1945 | .getname = ipx_getname, | 1985 | .getname = ipx_getname, |
1946 | .poll = datagram_poll, | 1986 | .poll = ipx_datagram_poll, |
1947 | .ioctl = ipx_ioctl, | 1987 | .ioctl = ipx_ioctl, |
1948 | #ifdef CONFIG_COMPAT | 1988 | #ifdef CONFIG_COMPAT |
1949 | .compat_ioctl = ipx_compat_ioctl, | 1989 | .compat_ioctl = ipx_compat_ioctl, |
@@ -1958,8 +1998,6 @@ static const struct proto_ops SOCKOPS_WRAPPED(ipx_dgram_ops) = { | |||
1958 | .sendpage = sock_no_sendpage, | 1998 | .sendpage = sock_no_sendpage, |
1959 | }; | 1999 | }; |
1960 | 2000 | ||
1961 | SOCKOPS_WRAP(ipx_dgram, PF_IPX); | ||
1962 | |||
1963 | static struct packet_type ipx_8023_packet_type __read_mostly = { | 2001 | static struct packet_type ipx_8023_packet_type __read_mostly = { |
1964 | .type = cpu_to_be16(ETH_P_802_3), | 2002 | .type = cpu_to_be16(ETH_P_802_3), |
1965 | .func = ipx_rcv, | 2003 | .func = ipx_rcv, |