diff options
author | David S. Miller <davem@davemloft.net> | 2012-03-18 23:29:41 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2012-03-18 23:29:41 -0400 |
commit | 4da0bd736552e6377b407b3c3d3ae518ebbdd269 (patch) | |
tree | f0da9f843b8033565c3ca4103fccb17a60688326 /drivers/net/tun.c | |
parent | 81a430ac1b88b0702c57d2513e247317e810e04d (diff) | |
parent | c16fa4f2ad19908a47c63d8fa436a1178438c7e7 (diff) |
Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net
Diffstat (limited to 'drivers/net/tun.c')
-rw-r--r-- | drivers/net/tun.c | 15 |
1 files changed, 12 insertions, 3 deletions
diff --git a/drivers/net/tun.c b/drivers/net/tun.c index 2c5d34957c5..74d7f76d14a 100644 --- a/drivers/net/tun.c +++ b/drivers/net/tun.c @@ -359,7 +359,7 @@ static void tun_free_netdev(struct net_device *dev) { struct tun_struct *tun = netdev_priv(dev); - sock_put(tun->socket.sk); + sk_release_kernel(tun->socket.sk); } /* Net device open. */ @@ -980,10 +980,18 @@ static int tun_recvmsg(struct kiocb *iocb, struct socket *sock, return ret; } +static int tun_release(struct socket *sock) +{ + if (sock->sk) + sock_put(sock->sk); + return 0; +} + /* Ops structure to mimic raw sockets with tun */ static const struct proto_ops tun_socket_ops = { .sendmsg = tun_sendmsg, .recvmsg = tun_recvmsg, + .release = tun_release, }; static struct proto tun_proto = { @@ -1110,10 +1118,11 @@ static int tun_set_iff(struct net *net, struct file *file, struct ifreq *ifr) tun->vnet_hdr_sz = sizeof(struct virtio_net_hdr); err = -ENOMEM; - sk = sk_alloc(net, AF_UNSPEC, GFP_KERNEL, &tun_proto); + sk = sk_alloc(&init_net, AF_UNSPEC, GFP_KERNEL, &tun_proto); if (!sk) goto err_free_dev; + sk_change_net(sk, net); tun->socket.wq = &tun->wq; init_waitqueue_head(&tun->wq.wait); tun->socket.ops = &tun_socket_ops; @@ -1174,7 +1183,7 @@ static int tun_set_iff(struct net *net, struct file *file, struct ifreq *ifr) return 0; err_free_sk: - sock_put(sk); + tun_free_netdev(dev); err_free_dev: free_netdev(dev); failed: |