summaryrefslogtreecommitdiffstats
path: root/sys
diff options
context:
space:
mode:
authoralfred <alfred@FreeBSD.org>2002-02-27 11:27:48 +0000
committeralfred <alfred@FreeBSD.org>2002-02-27 11:27:48 +0000
commitd56a374cacbd7e5f7e35bde56fe44b4699b6ccfb (patch)
treeab78fa8d325582570c6d204112bf6d8f5e329f8f /sys
parent002f46389dccab77c463a410173fdf9357fde93e (diff)
downloadFreeBSD-src-d56a374cacbd7e5f7e35bde56fe44b4699b6ccfb.zip
FreeBSD-src-d56a374cacbd7e5f7e35bde56fe44b4699b6ccfb.tar.gz
MPsafe fixes:
use SYSINIT to initialize pipe_zone. use PIPE_LOCK to protect kevent ops.
Diffstat (limited to 'sys')
-rw-r--r--sys/kern/sys_pipe.c27
1 files changed, 23 insertions, 4 deletions
diff --git a/sys/kern/sys_pipe.c b/sys/kern/sys_pipe.c
index cfe0f14..e1f981c 100644
--- a/sys/kern/sys_pipe.c
+++ b/sys/kern/sys_pipe.c
@@ -55,6 +55,7 @@
#include <sys/file.h>
#include <sys/filedesc.h>
#include <sys/filio.h>
+#include <sys/kernel.h>
#include <sys/lock.h>
#include <sys/mutex.h>
#include <sys/ttycom.h>
@@ -155,6 +156,7 @@ static int nbigpipe;
static int amountpipekva;
+static void pipeinit __P((void *dummy __unused));
static void pipeclose __P((struct pipe *cpipe));
static void pipe_free_kmem __P((struct pipe *cpipe));
static int pipe_create __P((struct pipe **cpipep));
@@ -171,6 +173,15 @@ static int pipespace __P((struct pipe *cpipe, int size));
static vm_zone_t pipe_zone;
+SYSINIT(vfs, SI_SUB_VFS, SI_ORDER_ANY, pipeinit, NULL);
+
+static void
+pipeinit(void *dummy __unused)
+{
+
+ pipe_zone = zinit("PIPE", sizeof(struct pipe), 0, 0, 4);
+}
+
/*
* The pipe system call for the DTYPE_PIPE type of pipes
*/
@@ -188,9 +199,7 @@ pipe(td, uap)
struct pipe *rpipe, *wpipe;
int fd, error;
- /* XXX: SYSINIT this! */
- if (pipe_zone == NULL)
- pipe_zone = zinit("PIPE", sizeof(struct pipe), 0, 0, 4);
+ KASSERT(pipe_zone != NULL, ("pipe_zone not initialized"));
rpipe = wpipe = NULL;
if (pipe_create(&rpipe) || pipe_create(&wpipe)) {
@@ -1313,7 +1322,9 @@ pipe_kqfilter(struct file *fp, struct knote *kn)
}
kn->kn_hook = (caddr_t)cpipe;
+ PIPE_LOCK(cpipe);
SLIST_INSERT_HEAD(&cpipe->pipe_sel.si_note, kn, kn_selnext);
+ PIPE_UNLOCK(cpipe);
return (0);
}
@@ -1322,7 +1333,9 @@ filt_pipedetach(struct knote *kn)
{
struct pipe *cpipe = (struct pipe *)kn->kn_hook;
+ PIPE_LOCK(cpipe);
SLIST_REMOVE(&cpipe->pipe_sel.si_note, kn, knote, kn_selnext);
+ PIPE_UNLOCK(cpipe);
}
/*ARGSUSED*/
@@ -1332,15 +1345,18 @@ filt_piperead(struct knote *kn, long hint)
struct pipe *rpipe = (struct pipe *)kn->kn_fp->f_data;
struct pipe *wpipe = rpipe->pipe_peer;
+ PIPE_LOCK(rpipe);
kn->kn_data = rpipe->pipe_buffer.cnt;
if ((kn->kn_data == 0) && (rpipe->pipe_state & PIPE_DIRECTW))
kn->kn_data = rpipe->pipe_map.cnt;
if ((rpipe->pipe_state & PIPE_EOF) ||
(wpipe == NULL) || (wpipe->pipe_state & PIPE_EOF)) {
- kn->kn_flags |= EV_EOF;
+ kn->kn_flags |= EV_EOF;
+ PIPE_UNLOCK(rpipe);
return (1);
}
+ PIPE_UNLOCK(rpipe);
return (kn->kn_data > 0);
}
@@ -1351,14 +1367,17 @@ filt_pipewrite(struct knote *kn, long hint)
struct pipe *rpipe = (struct pipe *)kn->kn_fp->f_data;
struct pipe *wpipe = rpipe->pipe_peer;
+ PIPE_LOCK(rpipe);
if ((wpipe == NULL) || (wpipe->pipe_state & PIPE_EOF)) {
kn->kn_data = 0;
kn->kn_flags |= EV_EOF;
+ PIPE_UNLOCK(rpipe);
return (1);
}
kn->kn_data = wpipe->pipe_buffer.size - wpipe->pipe_buffer.cnt;
if (wpipe->pipe_state & PIPE_DIRECTW)
kn->kn_data = 0;
+ PIPE_UNLOCK(rpipe);
return (kn->kn_data >= PIPE_BUF);
}
OpenPOWER on IntegriCloud