Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 184115
b: refs/heads/master
c: 564517e
h: refs/heads/master
i:
  184113: f4200f4
  184111: ed75904
v: v3
  • Loading branch information
Arnd Bergmann authored and David S. Miller committed Feb 16, 2010
1 parent 9791867 commit 8ee44b7
Show file tree
Hide file tree
Showing 2 changed files with 23 additions and 14 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: e9449d85c67127d6f9d01aad8963d567ab02cb96
refs/heads/master: 564517e804c9c6d4e29c270bfc1517404d27107b
35 changes: 22 additions & 13 deletions trunk/drivers/net/macvtap.c
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,8 @@ static struct cdev macvtap_cdev;
* exists.
*
* The callbacks from macvlan are always done with rcu_read_lock held
* already, while in the file_operations, we get it ourselves.
* already. For calls from file_operations, we use the rcu_read_lock_bh
* to get a reference count on the socket and the device.
*
* When destroying a queue, we remove the pointers from the file and
* from the dev and then synchronize_rcu to make sure no thread is
Expand Down Expand Up @@ -159,13 +160,21 @@ static void macvtap_del_queues(struct net_device *dev)

static inline struct macvtap_queue *macvtap_file_get_queue(struct file *file)
{
struct macvtap_queue *q;
rcu_read_lock_bh();
return rcu_dereference(file->private_data);
q = rcu_dereference(file->private_data);
if (q) {
sock_hold(&q->sk);
dev_hold(q->vlan->dev);
}
rcu_read_unlock_bh();
return q;
}

static inline void macvtap_file_put_queue(void)
static inline void macvtap_file_put_queue(struct macvtap_queue *q)
{
rcu_read_unlock_bh();
sock_put(&q->sk);
dev_put(q->vlan->dev);
}

/*
Expand Down Expand Up @@ -314,8 +323,8 @@ static unsigned int macvtap_poll(struct file *file, poll_table * wait)
sock_writeable(&q->sk)))
mask |= POLLOUT | POLLWRNORM;

macvtap_file_put_queue(q);
out:
macvtap_file_put_queue();
return mask;
}

Expand Down Expand Up @@ -366,8 +375,8 @@ static ssize_t macvtap_aio_write(struct kiocb *iocb, const struct iovec *iv,

result = macvtap_get_user(q, iv, iov_length(iv, count),
file->f_flags & O_NONBLOCK);
macvtap_file_put_queue(q);
out:
macvtap_file_put_queue();
return result;
}

Expand Down Expand Up @@ -398,10 +407,8 @@ static ssize_t macvtap_aio_read(struct kiocb *iocb, const struct iovec *iv,
struct sk_buff *skb;
ssize_t len, ret = 0;

if (!q) {
ret = -ENOLINK;
goto out;
}
if (!q)
return -ENOLINK;

len = iov_length(iv, count);
if (len < 0) {
Expand Down Expand Up @@ -437,7 +444,7 @@ static ssize_t macvtap_aio_read(struct kiocb *iocb, const struct iovec *iv,
remove_wait_queue(q->sk.sk_sleep, &wait);

out:
macvtap_file_put_queue();
macvtap_file_put_queue(q);
return ret;
}

Expand Down Expand Up @@ -468,7 +475,7 @@ static long macvtap_ioctl(struct file *file, unsigned int cmd,
if (!q)
return -ENOLINK;
memcpy(devname, q->vlan->dev->name, sizeof(devname));
macvtap_file_put_queue();
macvtap_file_put_queue(q);

if (copy_to_user(&ifr->ifr_name, q->vlan->dev->name, IFNAMSIZ) ||
put_user((TUN_TAP_DEV | TUN_NO_PI), &ifr->ifr_flags))
Expand All @@ -485,8 +492,10 @@ static long macvtap_ioctl(struct file *file, unsigned int cmd,
return -EFAULT;

q = macvtap_file_get_queue(file);
if (!q)
return -ENOLINK;
q->sk.sk_sndbuf = u;
macvtap_file_put_queue();
macvtap_file_put_queue(q);
return 0;

case TUNSETOFFLOAD:
Expand Down

0 comments on commit 8ee44b7

Please sign in to comment.