|
@@ -77,6 +77,7 @@
|
|
|
#include <linux/poll.h>
|
|
|
#include <linux/module.h>
|
|
|
#include <linux/init.h>
|
|
|
+#include <linux/mutex.h>
|
|
|
|
|
|
#ifdef CONFIG_INET
|
|
|
#include <net/inet_common.h>
|
|
@@ -175,6 +176,7 @@ struct packet_sock {
|
|
|
#endif
|
|
|
struct packet_type prot_hook;
|
|
|
spinlock_t bind_lock;
|
|
|
+ struct mutex pg_vec_lock;
|
|
|
unsigned int running:1, /* prot_hook is attached*/
|
|
|
auxdata:1,
|
|
|
origdev:1;
|
|
@@ -1069,6 +1071,7 @@ static int packet_create(struct net *net, struct socket *sock, int protocol)
|
|
|
*/
|
|
|
|
|
|
spin_lock_init(&po->bind_lock);
|
|
|
+ mutex_init(&po->pg_vec_lock);
|
|
|
po->prot_hook.func = packet_rcv;
|
|
|
|
|
|
if (sock->type == SOCK_PACKET)
|
|
@@ -1865,6 +1868,7 @@ static int packet_set_ring(struct sock *sk, struct tpacket_req *req, int closing
|
|
|
synchronize_net();
|
|
|
|
|
|
err = -EBUSY;
|
|
|
+ mutex_lock(&po->pg_vec_lock);
|
|
|
if (closing || atomic_read(&po->mapped) == 0) {
|
|
|
err = 0;
|
|
|
#define XC(a, b) ({ __typeof__ ((a)) __t; __t = (a); (a) = (b); __t; })
|
|
@@ -1886,6 +1890,7 @@ static int packet_set_ring(struct sock *sk, struct tpacket_req *req, int closing
|
|
|
if (atomic_read(&po->mapped))
|
|
|
printk(KERN_DEBUG "packet_mmap: vma is busy: %d\n", atomic_read(&po->mapped));
|
|
|
}
|
|
|
+ mutex_unlock(&po->pg_vec_lock);
|
|
|
|
|
|
spin_lock(&po->bind_lock);
|
|
|
if (was_running && !po->running) {
|
|
@@ -1918,7 +1923,7 @@ static int packet_mmap(struct file *file, struct socket *sock, struct vm_area_st
|
|
|
|
|
|
size = vma->vm_end - vma->vm_start;
|
|
|
|
|
|
- lock_sock(sk);
|
|
|
+ mutex_lock(&po->pg_vec_lock);
|
|
|
if (po->pg_vec == NULL)
|
|
|
goto out;
|
|
|
if (size != po->pg_vec_len*po->pg_vec_pages*PAGE_SIZE)
|
|
@@ -1941,7 +1946,7 @@ static int packet_mmap(struct file *file, struct socket *sock, struct vm_area_st
|
|
|
err = 0;
|
|
|
|
|
|
out:
|
|
|
- release_sock(sk);
|
|
|
+ mutex_unlock(&po->pg_vec_lock);
|
|
|
return err;
|
|
|
}
|
|
|
#endif
|