summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTheo Buehler <tb@cvs.openbsd.org>2017-11-14 16:01:56 +0000
committerTheo Buehler <tb@cvs.openbsd.org>2017-11-14 16:01:56 +0000
commitc2e95cdaa9b7e2a3f403b0ad578cc58e20165523 (patch)
treec03f5bb3b8ad5530f937fa02be9c00f61dbadf11
parent695fe3935b1642ac91bf7cd2dfa84507a743a324 (diff)
Push the NET_LOCK into ifioctl() and use the NET_RLOCK in ifioctl_get().
In particular, this allows SIOCGIF* requests to run in parallel. lots of help & ok mpi, ok visa, sashan
-rw-r--r--sys/kern/sys_socket.c4
-rw-r--r--sys/net/if.c48
-rw-r--r--sys/nfs/nfs_boot.c8
3 files changed, 41 insertions, 19 deletions
diff --git a/sys/kern/sys_socket.c b/sys/kern/sys_socket.c
index e73fc3f5603..4b1b826b349 100644
--- a/sys/kern/sys_socket.c
+++ b/sys/kern/sys_socket.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: sys_socket.c,v 1.33 2017/08/11 21:24:19 mpi Exp $ */
+/* $OpenBSD: sys_socket.c,v 1.34 2017/11/14 16:01:55 tb Exp $ */
/* $NetBSD: sys_socket.c,v 1.13 1995/08/12 23:59:09 mycroft Exp $ */
/*
@@ -125,9 +125,7 @@ soo_ioctl(struct file *fp, u_long cmd, caddr_t data, struct proc *p)
* different entry since a socket's unnecessary
*/
if (IOCGROUP(cmd) == 'i') {
- NET_LOCK();
error = ifioctl(so, cmd, data, p);
- NET_UNLOCK();
return (error);
}
if (IOCGROUP(cmd) == 'r')
diff --git a/sys/net/if.c b/sys/net/if.c
index 00d81d94894..0a985222d8d 100644
--- a/sys/net/if.c
+++ b/sys/net/if.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: if.c,v 1.527 2017/11/14 04:08:11 dlg Exp $ */
+/* $OpenBSD: if.c,v 1.528 2017/11/14 16:01:55 tb Exp $ */
/* $NetBSD: if.c,v 1.35 1996/05/07 05:26:04 thorpej Exp $ */
/*
@@ -1810,16 +1810,26 @@ ifioctl(struct socket *so, u_long cmd, caddr_t data, struct proc *p)
switch (cmd) {
case SIOCIFCREATE:
+ if ((error = suser(p, 0)) != 0)
+ return (error);
+ NET_LOCK();
+ error = if_clone_create(ifr->ifr_name, 0);
+ NET_UNLOCK();
+ return (error);
case SIOCIFDESTROY:
if ((error = suser(p, 0)) != 0)
return (error);
- return ((cmd == SIOCIFCREATE) ?
- if_clone_create(ifr->ifr_name, 0) :
- if_clone_destroy(ifr->ifr_name));
+ NET_LOCK();
+ error = if_clone_destroy(ifr->ifr_name);
+ NET_UNLOCK();
+ return (error);
case SIOCSIFGATTR:
if ((error = suser(p, 0)) != 0)
return (error);
- return (if_setgroupattribs(data));
+ NET_LOCK();
+ error = if_setgroupattribs(data);
+ NET_UNLOCK();
+ return (error);
case SIOCGIFCONF:
case SIOCIFGCLONERS:
case SIOCGIFGMEMB:
@@ -1845,6 +1855,8 @@ ifioctl(struct socket *so, u_long cmd, caddr_t data, struct proc *p)
oif_flags = ifp->if_flags;
oif_xflags = ifp->if_xflags;
+ NET_LOCK();
+
switch (cmd) {
case SIOCIFAFATTACH:
case SIOCIFAFDETACH:
@@ -2093,6 +2105,8 @@ ifioctl(struct socket *so, u_long cmd, caddr_t data, struct proc *p)
if (((oif_flags ^ ifp->if_flags) & IFF_UP) != 0)
getmicrotime(&ifp->if_lastchange);
+ NET_UNLOCK();
+
return (error);
}
@@ -2109,19 +2123,33 @@ ifioctl_get(u_long cmd, caddr_t data)
switch(cmd) {
case SIOCGIFCONF:
- return (ifconf(data));
+ NET_RLOCK();
+ error = ifconf(data);
+ NET_RUNLOCK();
+ return (error);
case SIOCIFGCLONERS:
- return (if_clone_list((struct if_clonereq *)data));
+ NET_RLOCK();
+ error = if_clone_list((struct if_clonereq *)data);
+ NET_RUNLOCK();
+ return (error);
case SIOCGIFGMEMB:
- return (if_getgroupmembers(data));
+ NET_RLOCK();
+ error = if_getgroupmembers(data);
+ NET_RUNLOCK();
+ return (error);
case SIOCGIFGATTR:
- return (if_getgroupattribs(data));
+ NET_RLOCK();
+ error = if_getgroupattribs(data);
+ NET_RUNLOCK();
+ return (error);
}
ifp = ifunit(ifr->ifr_name);
if (ifp == NULL)
return (ENXIO);
+ NET_RLOCK();
+
switch(cmd) {
case SIOCGIFFLAGS:
ifr->ifr_flags = ifp->if_flags;
@@ -2188,6 +2216,8 @@ ifioctl_get(u_long cmd, caddr_t data)
panic("invalid ioctl %lu", cmd);
}
+ NET_RUNLOCK();
+
return (error);
}
diff --git a/sys/nfs/nfs_boot.c b/sys/nfs/nfs_boot.c
index f4e8dff56a2..0d099cd2500 100644
--- a/sys/nfs/nfs_boot.c
+++ b/sys/nfs/nfs_boot.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: nfs_boot.c,v 1.43 2017/08/11 21:24:20 mpi Exp $ */
+/* $OpenBSD: nfs_boot.c,v 1.44 2017/11/14 16:01:55 tb Exp $ */
/* $NetBSD: nfs_boot.c,v 1.26 1996/05/07 02:51:25 thorpej Exp $ */
/*
@@ -159,15 +159,11 @@ nfs_boot_init(struct nfs_diskless *nd, struct proc *procp)
*/
if ((error = socreate(AF_INET, &so, SOCK_DGRAM, 0)) != 0)
panic("nfs_boot: socreate, error=%d", error);
- NET_LOCK();
error = ifioctl(so, SIOCGIFFLAGS, (caddr_t)&ireq, procp);
- NET_UNLOCK();
if (error)
panic("nfs_boot: GIFFLAGS, error=%d", error);
ireq.ifr_flags |= IFF_UP;
- NET_LOCK();
error = ifioctl(so, SIOCSIFFLAGS, (caddr_t)&ireq, procp);
- NET_UNLOCK();
if (error)
panic("nfs_boot: SIFFLAGS, error=%d", error);
@@ -190,9 +186,7 @@ nfs_boot_init(struct nfs_diskless *nd, struct proc *procp)
sin->sin_len = sizeof(*sin);
sin->sin_family = AF_INET;
sin->sin_addr.s_addr = my_ip.s_addr;
- NET_LOCK();
error = ifioctl(so, SIOCAIFADDR, (caddr_t)&ifra, procp);
- NET_UNLOCK();
if (error)
panic("nfs_boot: set if addr, error=%d", error);