summaryrefslogtreecommitdiff
path: root/net/socket.c
diff options
context:
space:
mode:
authorStephen Hemminger <shemminger@osdl.org>2003-04-17 20:40:06 -0700
committerDavid S. Miller <davem@nuts.ninka.net>2003-04-17 20:40:06 -0700
commitbd9056f78415aa24d3dfc32cb91dc90c1fb32258 (patch)
treefda31fa84310a328a4ae997a095c2354b0494d82 /net/socket.c
parent73ee6aab6034a9f4e7593ab284c58cdb773fee49 (diff)
[VLAN]: Cleaner module interface.
Diffstat (limited to 'net/socket.c')
-rw-r--r--net/socket.c16
1 files changed, 15 insertions, 1 deletions
diff --git a/net/socket.c b/net/socket.c
index 0d549c4602b5..1e2d9463c34d 100644
--- a/net/socket.c
+++ b/net/socket.c
@@ -714,6 +714,11 @@ static ssize_t sock_writev(struct file *file, const struct iovec *vector,
}
+/*
+ * Atomic setting of ioctl hooks to avoid race
+ * with module unload.
+ */
+
static DECLARE_MUTEX(br_ioctl_mutex);
static int (*br_ioctl_hook)(unsigned long arg) = NULL;
@@ -724,8 +729,15 @@ void brioctl_set(int (*hook)(unsigned long))
up(&br_ioctl_mutex);
}
+static DECLARE_MUTEX(vlan_ioctl_mutex);
+static int (*vlan_ioctl_hook)(unsigned long arg);
-int (*vlan_ioctl_hook)(unsigned long arg);
+void vlan_ioctl_set(int (*hook)(unsigned long))
+{
+ down(&vlan_ioctl_mutex);
+ vlan_ioctl_hook = hook;
+ up(&vlan_ioctl_mutex);
+}
#ifdef CONFIG_DLCI
extern int dlci_ioctl(unsigned int, void *);
@@ -789,8 +801,10 @@ static int sock_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
if (!vlan_ioctl_hook)
request_module("8021q");
#endif
+ down(&vlan_ioctl_mutex);
if (vlan_ioctl_hook)
err = vlan_ioctl_hook(arg);
+ up(&vlan_ioctl_mutex);
break;
case SIOCGIFDIVERT:
case SIOCSIFDIVERT: