aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/tun.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/tun.c')
-rw-r--r--drivers/net/tun.c19
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: 1694err_detach:
1695 tun_detach_all(dev);
1696err_free_flow:
1697 tun_flow_uninit(tun);
1698 security_tun_dev_free_security(tun->security);
1699err_free_dev:
1693 free_netdev(dev); 1700 free_netdev(dev);
1694 return err; 1701 return err;
1695} 1702}