Commit 83927ba0 authored by Arnd Bergmann's avatar Arnd Bergmann Committed by David S. Miller

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: default avatarArnd Bergmann <arnd@arndb.de>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent ecced8ba
...@@ -1298,6 +1298,7 @@ static int ipx_setsockopt(struct socket *sock, int level, int optname, ...@@ -1298,6 +1298,7 @@ static int ipx_setsockopt(struct socket *sock, int level, int optname,
int opt; int opt;
int rc = -EINVAL; int rc = -EINVAL;
lock_kernel();
if (optlen != sizeof(int)) if (optlen != sizeof(int))
goto out; goto out;
...@@ -1312,6 +1313,7 @@ static int ipx_setsockopt(struct socket *sock, int level, int optname, ...@@ -1312,6 +1313,7 @@ static int ipx_setsockopt(struct socket *sock, int level, int optname,
ipx_sk(sk)->type = opt; ipx_sk(sk)->type = opt;
rc = 0; rc = 0;
out: out:
unlock_kernel();
return rc; return rc;
} }
...@@ -1323,6 +1325,7 @@ static int ipx_getsockopt(struct socket *sock, int level, int optname, ...@@ -1323,6 +1325,7 @@ static int ipx_getsockopt(struct socket *sock, int level, int optname,
int len; int len;
int rc = -ENOPROTOOPT; int rc = -ENOPROTOOPT;
lock_kernel();
if (!(level == SOL_IPX && optname == IPX_TYPE)) if (!(level == SOL_IPX && optname == IPX_TYPE))
goto out; goto out;
...@@ -1343,6 +1346,7 @@ static int ipx_getsockopt(struct socket *sock, int level, int optname, ...@@ -1343,6 +1346,7 @@ static int ipx_getsockopt(struct socket *sock, int level, int optname,
rc = 0; rc = 0;
out: out:
unlock_kernel();
return rc; return rc;
} }
...@@ -1391,6 +1395,7 @@ static int ipx_release(struct socket *sock) ...@@ -1391,6 +1395,7 @@ static int ipx_release(struct socket *sock)
if (!sk) if (!sk)
goto out; goto out;
lock_kernel();
if (!sock_flag(sk, SOCK_DEAD)) if (!sock_flag(sk, SOCK_DEAD))
sk->sk_state_change(sk); sk->sk_state_change(sk);
...@@ -1398,6 +1403,7 @@ static int ipx_release(struct socket *sock) ...@@ -1398,6 +1403,7 @@ static int ipx_release(struct socket *sock)
sock->sk = NULL; sock->sk = NULL;
sk_refcnt_debug_release(sk); sk_refcnt_debug_release(sk);
ipx_destroy_socket(sk); ipx_destroy_socket(sk);
unlock_kernel();
out: out:
return 0; return 0;
} }
...@@ -1425,7 +1431,8 @@ static __be16 ipx_first_free_socketnum(struct ipx_interface *intrfc) ...@@ -1425,7 +1431,8 @@ static __be16 ipx_first_free_socketnum(struct ipx_interface *intrfc)
return htons(socketNum); return htons(socketNum);
} }
static int ipx_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len) static int __ipx_bind(struct socket *sock,
struct sockaddr *uaddr, int addr_len)
{ {
struct sock *sk = sock->sk; struct sock *sk = sock->sk;
struct ipx_sock *ipxs = ipx_sk(sk); struct ipx_sock *ipxs = ipx_sk(sk);
...@@ -1520,6 +1527,17 @@ out: ...@@ -1520,6 +1527,17 @@ out:
return rc; return rc;
} }
static int ipx_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len)
{
int rc;
lock_kernel();
rc = __ipx_bind(sock, uaddr, addr_len);
unlock_kernel();
return rc;
}
static int ipx_connect(struct socket *sock, struct sockaddr *uaddr, static int ipx_connect(struct socket *sock, struct sockaddr *uaddr,
int addr_len, int flags) int addr_len, int flags)
{ {
...@@ -1532,6 +1550,7 @@ static int ipx_connect(struct socket *sock, struct sockaddr *uaddr, ...@@ -1532,6 +1550,7 @@ static int ipx_connect(struct socket *sock, struct sockaddr *uaddr,
sk->sk_state = TCP_CLOSE; sk->sk_state = TCP_CLOSE;
sock->state = SS_UNCONNECTED; sock->state = SS_UNCONNECTED;
lock_kernel();
if (addr_len != sizeof(*addr)) if (addr_len != sizeof(*addr))
goto out; goto out;
addr = (struct sockaddr_ipx *)uaddr; addr = (struct sockaddr_ipx *)uaddr;
...@@ -1551,7 +1570,7 @@ static int ipx_connect(struct socket *sock, struct sockaddr *uaddr, ...@@ -1551,7 +1570,7 @@ static int ipx_connect(struct socket *sock, struct sockaddr *uaddr,
IPX_NODE_LEN); IPX_NODE_LEN);
#endif /* CONFIG_IPX_INTERN */ #endif /* CONFIG_IPX_INTERN */
rc = ipx_bind(sock, (struct sockaddr *)&uaddr, rc = __ipx_bind(sock, (struct sockaddr *)&uaddr,
sizeof(struct sockaddr_ipx)); sizeof(struct sockaddr_ipx));
if (rc) if (rc)
goto out; goto out;
...@@ -1578,6 +1597,7 @@ static int ipx_connect(struct socket *sock, struct sockaddr *uaddr, ...@@ -1578,6 +1597,7 @@ static int ipx_connect(struct socket *sock, struct sockaddr *uaddr,
ipxrtr_put(rt); ipxrtr_put(rt);
rc = 0; rc = 0;
out: out:
unlock_kernel();
return rc; return rc;
} }
...@@ -1593,6 +1613,7 @@ static int ipx_getname(struct socket *sock, struct sockaddr *uaddr, ...@@ -1593,6 +1613,7 @@ static int ipx_getname(struct socket *sock, struct sockaddr *uaddr,
*uaddr_len = sizeof(struct sockaddr_ipx); *uaddr_len = sizeof(struct sockaddr_ipx);
lock_kernel();
if (peer) { if (peer) {
rc = -ENOTCONN; rc = -ENOTCONN;
if (sk->sk_state != TCP_ESTABLISHED) if (sk->sk_state != TCP_ESTABLISHED)
...@@ -1627,6 +1648,19 @@ static int ipx_getname(struct socket *sock, struct sockaddr *uaddr, ...@@ -1627,6 +1648,19 @@ static int ipx_getname(struct socket *sock, struct sockaddr *uaddr,
rc = 0; rc = 0;
out: out:
unlock_kernel();
return rc;
}
static unsigned int ipx_datagram_poll(struct file *file, struct socket *sock,
poll_table *wait)
{
int rc;
lock_kernel();
rc = datagram_poll(file, sock, wait);
unlock_kernel();
return rc; return rc;
} }
...@@ -1701,6 +1735,7 @@ static int ipx_sendmsg(struct kiocb *iocb, struct socket *sock, ...@@ -1701,6 +1735,7 @@ static int ipx_sendmsg(struct kiocb *iocb, struct socket *sock,
int rc = -EINVAL; int rc = -EINVAL;
int flags = msg->msg_flags; int flags = msg->msg_flags;
lock_kernel();
/* Socket gets bound below anyway */ /* Socket gets bound below anyway */
/* if (sk->sk_zapped) /* if (sk->sk_zapped)
return -EIO; */ /* Socket not bound */ return -EIO; */ /* Socket not bound */
...@@ -1724,7 +1759,7 @@ static int ipx_sendmsg(struct kiocb *iocb, struct socket *sock, ...@@ -1724,7 +1759,7 @@ static int ipx_sendmsg(struct kiocb *iocb, struct socket *sock,
memcpy(uaddr.sipx_node, ipxs->intrfc->if_node, memcpy(uaddr.sipx_node, ipxs->intrfc->if_node,
IPX_NODE_LEN); IPX_NODE_LEN);
#endif #endif
rc = ipx_bind(sock, (struct sockaddr *)&uaddr, rc = __ipx_bind(sock, (struct sockaddr *)&uaddr,
sizeof(struct sockaddr_ipx)); sizeof(struct sockaddr_ipx));
if (rc) if (rc)
goto out; goto out;
...@@ -1752,6 +1787,7 @@ static int ipx_sendmsg(struct kiocb *iocb, struct socket *sock, ...@@ -1752,6 +1787,7 @@ static int ipx_sendmsg(struct kiocb *iocb, struct socket *sock,
if (rc >= 0) if (rc >= 0)
rc = len; rc = len;
out: out:
unlock_kernel();
return rc; return rc;
} }
...@@ -1766,6 +1802,7 @@ static int ipx_recvmsg(struct kiocb *iocb, struct socket *sock, ...@@ -1766,6 +1802,7 @@ static int ipx_recvmsg(struct kiocb *iocb, struct socket *sock,
struct sk_buff *skb; struct sk_buff *skb;
int copied, rc; int copied, rc;
lock_kernel();
/* put the autobinding in */ /* put the autobinding in */
if (!ipxs->port) { if (!ipxs->port) {
struct sockaddr_ipx uaddr; struct sockaddr_ipx uaddr;
...@@ -1780,7 +1817,7 @@ static int ipx_recvmsg(struct kiocb *iocb, struct socket *sock, ...@@ -1780,7 +1817,7 @@ static int ipx_recvmsg(struct kiocb *iocb, struct socket *sock,
memcpy(uaddr.sipx_node, ipxs->intrfc->if_node, IPX_NODE_LEN); memcpy(uaddr.sipx_node, ipxs->intrfc->if_node, IPX_NODE_LEN);
#endif /* CONFIG_IPX_INTERN */ #endif /* CONFIG_IPX_INTERN */
rc = ipx_bind(sock, (struct sockaddr *)&uaddr, rc = __ipx_bind(sock, (struct sockaddr *)&uaddr,
sizeof(struct sockaddr_ipx)); sizeof(struct sockaddr_ipx));
if (rc) if (rc)
goto out; goto out;
...@@ -1824,6 +1861,7 @@ static int ipx_recvmsg(struct kiocb *iocb, struct socket *sock, ...@@ -1824,6 +1861,7 @@ static int ipx_recvmsg(struct kiocb *iocb, struct socket *sock,
out_free: out_free:
skb_free_datagram(sk, skb); skb_free_datagram(sk, skb);
out: out:
unlock_kernel();
return rc; return rc;
} }
...@@ -1835,6 +1873,7 @@ static int ipx_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg) ...@@ -1835,6 +1873,7 @@ static int ipx_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
struct sock *sk = sock->sk; struct sock *sk = sock->sk;
void __user *argp = (void __user *)arg; void __user *argp = (void __user *)arg;
lock_kernel();
switch (cmd) { switch (cmd) {
case TIOCOUTQ: case TIOCOUTQ:
amount = sk->sk_sndbuf - sk_wmem_alloc_get(sk); 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,6 +1936,7 @@ static int ipx_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
rc = -ENOIOCTLCMD; rc = -ENOIOCTLCMD;
break; break;
} }
unlock_kernel();
return rc; return rc;
} }
...@@ -1934,7 +1974,7 @@ static const struct net_proto_family ipx_family_ops = { ...@@ -1934,7 +1974,7 @@ static const struct net_proto_family ipx_family_ops = {
.owner = THIS_MODULE, .owner = THIS_MODULE,
}; };
static const struct proto_ops SOCKOPS_WRAPPED(ipx_dgram_ops) = { static const struct proto_ops ipx_dgram_ops = {
.family = PF_IPX, .family = PF_IPX,
.owner = THIS_MODULE, .owner = THIS_MODULE,
.release = ipx_release, .release = ipx_release,
...@@ -1943,7 +1983,7 @@ static const struct proto_ops SOCKOPS_WRAPPED(ipx_dgram_ops) = { ...@@ -1943,7 +1983,7 @@ static const struct proto_ops SOCKOPS_WRAPPED(ipx_dgram_ops) = {
.socketpair = sock_no_socketpair, .socketpair = sock_no_socketpair,
.accept = sock_no_accept, .accept = sock_no_accept,
.getname = ipx_getname, .getname = ipx_getname,
.poll = datagram_poll, .poll = ipx_datagram_poll,
.ioctl = ipx_ioctl, .ioctl = ipx_ioctl,
#ifdef CONFIG_COMPAT #ifdef CONFIG_COMPAT
.compat_ioctl = ipx_compat_ioctl, .compat_ioctl = ipx_compat_ioctl,
...@@ -1958,8 +1998,6 @@ static const struct proto_ops SOCKOPS_WRAPPED(ipx_dgram_ops) = { ...@@ -1958,8 +1998,6 @@ static const struct proto_ops SOCKOPS_WRAPPED(ipx_dgram_ops) = {
.sendpage = sock_no_sendpage, .sendpage = sock_no_sendpage,
}; };
SOCKOPS_WRAP(ipx_dgram, PF_IPX);
static struct packet_type ipx_8023_packet_type __read_mostly = { static struct packet_type ipx_8023_packet_type __read_mostly = {
.type = cpu_to_be16(ETH_P_802_3), .type = cpu_to_be16(ETH_P_802_3),
.func = ipx_rcv, .func = ipx_rcv,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment