diff options
Diffstat (limited to 'drivers/net/tun.c')
-rw-r--r-- | drivers/net/tun.c | 19 |
1 files changed, 13 insertions, 6 deletions
diff --git a/drivers/net/tun.c b/drivers/net/tun.c index a639de8401f8..7cb105c103fe 100644 --- a/drivers/net/tun.c +++ b/drivers/net/tun.c | |||
@@ -1293,7 +1293,8 @@ static ssize_t tun_do_read(struct tun_struct *tun, struct tun_file *tfile, | |||
1293 | if (unlikely(!noblock)) | 1293 | if (unlikely(!noblock)) |
1294 | add_wait_queue(&tfile->wq.wait, &wait); | 1294 | add_wait_queue(&tfile->wq.wait, &wait); |
1295 | while (len) { | 1295 | while (len) { |
1296 | current->state = TASK_INTERRUPTIBLE; | 1296 | if (unlikely(!noblock)) |
1297 | current->state = TASK_INTERRUPTIBLE; | ||
1297 | 1298 | ||
1298 | /* Read frames from the queue */ | 1299 | /* Read frames from the queue */ |
1299 | if (!(skb = skb_dequeue(&tfile->socket.sk->sk_receive_queue))) { | 1300 | if (!(skb = skb_dequeue(&tfile->socket.sk->sk_receive_queue))) { |
@@ -1320,9 +1321,10 @@ static ssize_t tun_do_read(struct tun_struct *tun, struct tun_file *tfile, | |||
1320 | break; | 1321 | break; |
1321 | } | 1322 | } |
1322 | 1323 | ||
1323 | current->state = TASK_RUNNING; | 1324 | if (unlikely(!noblock)) { |
1324 | if (unlikely(!noblock)) | 1325 | current->state = TASK_RUNNING; |
1325 | remove_wait_queue(&tfile->wq.wait, &wait); | 1326 | remove_wait_queue(&tfile->wq.wait, &wait); |
1327 | } | ||
1326 | 1328 | ||
1327 | return ret; | 1329 | return ret; |
1328 | } | 1330 | } |
@@ -1641,11 +1643,11 @@ static int tun_set_iff(struct net *net, struct file *file, struct ifreq *ifr) | |||
1641 | INIT_LIST_HEAD(&tun->disabled); | 1643 | INIT_LIST_HEAD(&tun->disabled); |
1642 | err = tun_attach(tun, file, false); | 1644 | err = tun_attach(tun, file, false); |
1643 | if (err < 0) | 1645 | if (err < 0) |
1644 | goto err_free_dev; | 1646 | goto err_free_flow; |
1645 | 1647 | ||
1646 | err = register_netdevice(tun->dev); | 1648 | err = register_netdevice(tun->dev); |
1647 | if (err < 0) | 1649 | if (err < 0) |
1648 | goto err_free_dev; | 1650 | goto err_detach; |
1649 | 1651 | ||
1650 | if (device_create_file(&tun->dev->dev, &dev_attr_tun_flags) || | 1652 | if (device_create_file(&tun->dev->dev, &dev_attr_tun_flags) || |
1651 | device_create_file(&tun->dev->dev, &dev_attr_owner) || | 1653 | device_create_file(&tun->dev->dev, &dev_attr_owner) || |
@@ -1689,7 +1691,12 @@ static int tun_set_iff(struct net *net, struct file *file, struct ifreq *ifr) | |||
1689 | strcpy(ifr->ifr_name, tun->dev->name); | 1691 | strcpy(ifr->ifr_name, tun->dev->name); |
1690 | return 0; | 1692 | return 0; |
1691 | 1693 | ||
1692 | err_free_dev: | 1694 | err_detach: |
1695 | tun_detach_all(dev); | ||
1696 | err_free_flow: | ||
1697 | tun_flow_uninit(tun); | ||
1698 | security_tun_dev_free_security(tun->security); | ||
1699 | err_free_dev: | ||
1693 | free_netdev(dev); | 1700 | free_netdev(dev); |
1694 | return err; | 1701 | return err; |
1695 | } | 1702 | } |