qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Qemu-devel] [net-next RFC PATCH 2/7] tuntap: categorize ioctl


From: Jason Wang
Subject: [Qemu-devel] [net-next RFC PATCH 2/7] tuntap: categorize ioctl
Date: Fri, 12 Aug 2011 09:55:00 +0800
User-agent: StGit/0.15

As we've moved socket related structure to
file->private_data, we can separate system calls that only
touch tfile from others as they don't need hold rtnl lock.

Signed-off-by: Jason Wang <address@hidden>
---
 drivers/net/tun.c |   52 ++++++++++++++++++++++++++++++++++------------------
 1 files changed, 34 insertions(+), 18 deletions(-)

diff --git a/drivers/net/tun.c b/drivers/net/tun.c
index 2739887..4cd292a 100644
--- a/drivers/net/tun.c
+++ b/drivers/net/tun.c
@@ -1240,10 +1240,7 @@ static long __tun_chr_ioctl(struct file *file, unsigned 
int cmd,
        struct tun_file *tfile = file->private_data;
        struct tun_struct *tun;
        void __user* argp = (void __user*)arg;
-       struct sock_fprog fprog;
        struct ifreq ifr;
-       int sndbuf;
-       int vnet_hdr_sz;
        int ret;
 
        if (cmd == TUNSETIFF || _IOC_TYPE(cmd) == 0x89)
@@ -1348,14 +1345,6 @@ static long __tun_chr_ioctl(struct file *file, unsigned 
int cmd,
                ret = set_offload(tun, arg);
                break;
 
-       case TUNSETTXFILTER:
-               /* Can be set only for TAPs */
-               ret = -EINVAL;
-               if ((tfile->flags & TUN_TYPE_MASK) != TUN_TAP_DEV)
-                       break;
-               ret = update_filter(&tfile->txflt, (void __user *)arg);
-               break;
-
        case SIOCGIFHWADDR:
                /* Get hw address */
                memcpy(ifr.ifr_hwaddr.sa_data, tun->dev->dev_addr, ETH_ALEN);
@@ -1372,6 +1361,37 @@ static long __tun_chr_ioctl(struct file *file, unsigned 
int cmd,
                ret = dev_set_mac_address(tun->dev, &ifr.ifr_hwaddr);
                break;
 
+       default:
+               ret = -EINVAL;
+               break;
+       }
+
+unlock:
+       rtnl_unlock();
+       if (tun)
+               tun_put(tun);
+       return ret;
+}
+
+static long __tun_socket_ioctl(struct file *file, unsigned int cmd,
+                              unsigned long arg, int ifreq_len)
+{
+       struct tun_file *tfile = file->private_data;
+       void __user* argp = (void __user*)arg;
+       struct sock_fprog fprog;
+       int sndbuf;
+       int vnet_hdr_sz;
+       int ret = 0;
+
+       switch (cmd) {
+       case TUNSETTXFILTER:
+               /* Can be set only for TAPs */
+               ret = -EINVAL;
+               if ((tfile->flags & TUN_TYPE_MASK) != TUN_TAP_DEV)
+                       break;
+               ret = update_filter(&tfile->txflt, (void __user *)arg);
+               break;
+
        case TUNGETSNDBUF:
                sndbuf = tfile->socket.sk->sk_sndbuf;
                if (copy_to_user(argp, &sndbuf, sizeof(sndbuf)))
@@ -1427,21 +1447,17 @@ static long __tun_chr_ioctl(struct file *file, unsigned 
int cmd,
                break;
 
        default:
-               ret = -EINVAL;
+               ret = __tun_chr_ioctl(file, cmd, arg, ifreq_len);
                break;
        }
 
-unlock:
-       rtnl_unlock();
-       if (tun)
-               tun_put(tun);
        return ret;
 }
 
 static long tun_chr_ioctl(struct file *file,
                          unsigned int cmd, unsigned long arg)
 {
-       return __tun_chr_ioctl(file, cmd, arg, sizeof (struct ifreq));
+       return __tun_socket_ioctl(file, cmd, arg, sizeof (struct ifreq));
 }
 
 #ifdef CONFIG_COMPAT
@@ -1469,7 +1485,7 @@ static long tun_chr_compat_ioctl(struct file *file,
         * driver are compatible though, we don't need to convert the
         * contents.
         */
-       return __tun_chr_ioctl(file, cmd, arg, sizeof(struct compat_ifreq));
+       return __tun_socket_ioctl(file, cmd, arg, sizeof(struct compat_ifreq));
 }
 #endif /* CONFIG_COMPAT */
 




reply via email to

[Prev in Thread] Current Thread [Next in Thread]