lkml.org 
[lkml]   [2011]   [Aug]   [11]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    Subject[net-next RFC PATCH 2/7] tuntap: categorize ioctl
    From
    Date
    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 <jasowang@redhat.com>
    ---
    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 */



    \
     
     \ /
      Last update: 2011-08-12 04:01    [W:0.024 / U:1.432 seconds]
    ©2003-2016 Jasper Spaans. hosted at Digital OceanAdvertise on this site