diff options
Diffstat (limited to 'drivers/net/macvtap.c')
-rw-r--r-- | drivers/net/macvtap.c | 26 |
1 files changed, 15 insertions, 11 deletions
diff --git a/drivers/net/macvtap.c b/drivers/net/macvtap.c index 070e3290aa6e..52a9d811be06 100644 --- a/drivers/net/macvtap.c +++ b/drivers/net/macvtap.c @@ -437,7 +437,7 @@ static int macvtap_get_minor(struct macvlan_dev *vlan) if (retval >= 0) { vlan->minor = retval; } else if (retval == -ENOSPC) { - printk(KERN_ERR "too many macvtap devices\n"); + netdev_err(vlan->dev, "Too many macvtap devices\n"); retval = -EINVAL; } mutex_unlock(&minor_lock); @@ -491,7 +491,13 @@ static int macvtap_newlink(struct net *src_net, /* Don't put anything that may fail after macvlan_common_newlink * because we can't undo what it does. */ - return macvlan_common_newlink(src_net, dev, tb, data); + err = macvlan_common_newlink(src_net, dev, tb, data); + if (err) { + netdev_rx_handler_unregister(dev); + return err; + } + + return 0; } static void macvtap_dellink(struct net_device *dev, @@ -736,13 +742,8 @@ static ssize_t macvtap_get_user(struct macvtap_queue *q, struct msghdr *m, if (zerocopy) err = zerocopy_sg_from_iter(skb, from); - else { + else err = skb_copy_datagram_from_iter(skb, 0, from, len); - if (!err && m && m->msg_control) { - struct ubuf_info *uarg = m->msg_control; - uarg->callback(uarg, false); - } - } if (err) goto err_kfree; @@ -773,7 +774,11 @@ static ssize_t macvtap_get_user(struct macvtap_queue *q, struct msghdr *m, skb_shinfo(skb)->destructor_arg = m->msg_control; skb_shinfo(skb)->tx_flags |= SKBTX_DEV_ZEROCOPY; skb_shinfo(skb)->tx_flags |= SKBTX_SHARED_FRAG; + } else if (m && m->msg_control) { + struct ubuf_info *uarg = m->msg_control; + uarg->callback(uarg, false); } + if (vlan) { skb->dev = vlan->dev; dev_queue_xmit(skb); @@ -821,9 +826,8 @@ static ssize_t macvtap_put_user(struct macvtap_queue *q, if (iov_iter_count(iter) < vnet_hdr_len) return -EINVAL; - ret = virtio_net_hdr_from_skb(skb, &vnet_hdr, - macvtap_is_little_endian(q)); - if (ret) + if (virtio_net_hdr_from_skb(skb, &vnet_hdr, + macvtap_is_little_endian(q))) BUG(); if (copy_to_iter(&vnet_hdr, sizeof(vnet_hdr), iter) != |