Merge branch 'linus' into x86/urgent
[pandora-kernel.git] / drivers / net / tun.c
index 7ab94c8..eba1271 100644 (file)
@@ -48,6 +48,7 @@
 #include <linux/kernel.h>
 #include <linux/major.h>
 #include <linux/slab.h>
+#include <linux/smp_lock.h>
 #include <linux/poll.h>
 #include <linux/fcntl.h>
 #include <linux/init.h>
@@ -602,6 +603,12 @@ static int tun_set_iff(struct net *net, struct file *file, struct ifreq *ifr)
        tun->attached = 1;
        get_net(dev_net(tun->dev));
 
+       /* Make sure persistent devices do not get stuck in
+        * xoff state.
+        */
+       if (netif_running(tun->dev))
+               netif_wake_queue(tun->dev);
+
        strcpy(ifr->ifr_name, tun->dev->name);
        return 0;
 
@@ -796,22 +803,26 @@ static int tun_chr_fasync(int fd, struct file *file, int on)
 
        DBG(KERN_INFO "%s: tun_chr_fasync %d\n", tun->dev->name, on);
 
+       lock_kernel();
        if ((ret = fasync_helper(fd, file, on, &tun->fasync)) < 0)
-               return ret;
+               goto out;
 
        if (on) {
                ret = __f_setown(file, task_pid(current), PIDTYPE_PID, 0);
                if (ret)
-                       return ret;
+                       goto out;
                tun->flags |= TUN_FASYNC;
        } else
                tun->flags &= ~TUN_FASYNC;
-
-       return 0;
+       ret = 0;
+out:
+       unlock_kernel();
+       return ret;
 }
 
 static int tun_chr_open(struct inode *inode, struct file * file)
 {
+       cycle_kernel_lock();
        DBG1(KERN_INFO "tunX: tun_chr_open\n");
        file->private_data = NULL;
        return 0;