diff options
Diffstat (limited to 'drivers/net/tap.c')
-rw-r--r-- | drivers/net/tap.c | 23 |
1 files changed, 12 insertions, 11 deletions
diff --git a/drivers/net/tap.c b/drivers/net/tap.c index 21b71ae947fd..1b10fcc6a58d 100644 --- a/drivers/net/tap.c +++ b/drivers/net/tap.c | |||
@@ -517,6 +517,10 @@ static int tap_open(struct inode *inode, struct file *file) | |||
517 | &tap_proto, 0); | 517 | &tap_proto, 0); |
518 | if (!q) | 518 | if (!q) |
519 | goto err; | 519 | goto err; |
520 | if (skb_array_init(&q->skb_array, tap->dev->tx_queue_len, GFP_KERNEL)) { | ||
521 | sk_free(&q->sk); | ||
522 | goto err; | ||
523 | } | ||
520 | 524 | ||
521 | RCU_INIT_POINTER(q->sock.wq, &q->wq); | 525 | RCU_INIT_POINTER(q->sock.wq, &q->wq); |
522 | init_waitqueue_head(&q->wq.wait); | 526 | init_waitqueue_head(&q->wq.wait); |
@@ -540,22 +544,18 @@ static int tap_open(struct inode *inode, struct file *file) | |||
540 | if ((tap->dev->features & NETIF_F_HIGHDMA) && (tap->dev->features & NETIF_F_SG)) | 544 | if ((tap->dev->features & NETIF_F_HIGHDMA) && (tap->dev->features & NETIF_F_SG)) |
541 | sock_set_flag(&q->sk, SOCK_ZEROCOPY); | 545 | sock_set_flag(&q->sk, SOCK_ZEROCOPY); |
542 | 546 | ||
543 | err = -ENOMEM; | ||
544 | if (skb_array_init(&q->skb_array, tap->dev->tx_queue_len, GFP_KERNEL)) | ||
545 | goto err_array; | ||
546 | |||
547 | err = tap_set_queue(tap, file, q); | 547 | err = tap_set_queue(tap, file, q); |
548 | if (err) | 548 | if (err) { |
549 | goto err_queue; | 549 | /* tap_sock_destruct() will take care of freeing skb_array */ |
550 | goto err_put; | ||
551 | } | ||
550 | 552 | ||
551 | dev_put(tap->dev); | 553 | dev_put(tap->dev); |
552 | 554 | ||
553 | rtnl_unlock(); | 555 | rtnl_unlock(); |
554 | return err; | 556 | return err; |
555 | 557 | ||
556 | err_queue: | 558 | err_put: |
557 | skb_array_cleanup(&q->skb_array); | ||
558 | err_array: | ||
559 | sock_put(&q->sk); | 559 | sock_put(&q->sk); |
560 | err: | 560 | err: |
561 | if (tap) | 561 | if (tap) |
@@ -1249,8 +1249,8 @@ static int tap_list_add(dev_t major, const char *device_name) | |||
1249 | return 0; | 1249 | return 0; |
1250 | } | 1250 | } |
1251 | 1251 | ||
1252 | int tap_create_cdev(struct cdev *tap_cdev, | 1252 | int tap_create_cdev(struct cdev *tap_cdev, dev_t *tap_major, |
1253 | dev_t *tap_major, const char *device_name) | 1253 | const char *device_name, struct module *module) |
1254 | { | 1254 | { |
1255 | int err; | 1255 | int err; |
1256 | 1256 | ||
@@ -1259,6 +1259,7 @@ int tap_create_cdev(struct cdev *tap_cdev, | |||
1259 | goto out1; | 1259 | goto out1; |
1260 | 1260 | ||
1261 | cdev_init(tap_cdev, &tap_fops); | 1261 | cdev_init(tap_cdev, &tap_fops); |
1262 | tap_cdev->owner = module; | ||
1262 | err = cdev_add(tap_cdev, *tap_major, TAP_NUM_DEVS); | 1263 | err = cdev_add(tap_cdev, *tap_major, TAP_NUM_DEVS); |
1263 | if (err) | 1264 | if (err) |
1264 | goto out2; | 1265 | goto out2; |