diff options
author | alfred <alfred@FreeBSD.org> | 2002-03-15 07:18:09 +0000 |
---|---|---|
committer | alfred <alfred@FreeBSD.org> | 2002-03-15 07:18:09 +0000 |
commit | 2261bd0e24af4f260b3035065b4c7abe7f1fa834 (patch) | |
tree | fb1abccb49526613544ca14290996d9b784cd0b9 /sys/kern/sys_pipe.c | |
parent | 5c81e5d25081820280ff8c446749b545d925d1a1 (diff) | |
download | FreeBSD-src-2261bd0e24af4f260b3035065b4c7abe7f1fa834.zip FreeBSD-src-2261bd0e24af4f260b3035065b4c7abe7f1fa834.tar.gz |
Bug fixes:
Missed a place where the pipe sleep lock was needed in order to safely grab
Giant, fix it and add an assertion to make sure this doesn't happen again.
Fix typos in the PIPE_GET_GIANT/PIPE_DROP_GIANT that could cause the
wrong mutex to get passed to PIPE_LOCK/PIPE_UNLOCK.
Fix a location where the wrong pipe was being passed to
PIPE_GET_GIANT/PIPE_DROP_GIANT.
Diffstat (limited to 'sys/kern/sys_pipe.c')
-rw-r--r-- | sys/kern/sys_pipe.c | 15 |
1 files changed, 10 insertions, 5 deletions
diff --git a/sys/kern/sys_pipe.c b/sys/kern/sys_pipe.c index 6985780..70a6a38 100644 --- a/sys/kern/sys_pipe.c +++ b/sys/kern/sys_pipe.c @@ -116,16 +116,19 @@ static struct filterops pipe_rfiltops = static struct filterops pipe_wfiltops = { 1, NULL, filt_pipedetach, filt_pipewrite }; -#define PIPE_GET_GIANT(pipe) \ +#define PIPE_GET_GIANT(pipe) \ do { \ - PIPE_UNLOCK(wpipe); \ + KASSERT(((pipe)->pipe_state & PIPE_LOCKFL) != 0, \ + ("%s:%d PIPE_GET_GIANT: line pipe not locked", \ + __FILE__, __LINE__)); \ + PIPE_UNLOCK(pipe); \ mtx_lock(&Giant); \ } while (0) #define PIPE_DROP_GIANT(pipe) \ do { \ mtx_unlock(&Giant); \ - PIPE_LOCK(wpipe); \ + PIPE_LOCK(pipe); \ } while (0) /* @@ -770,9 +773,11 @@ retry: wpipe->pipe_state |= PIPE_DIRECTW; + pipelock(wpipe, 0); PIPE_GET_GIANT(wpipe); error = pipe_build_write_buffer(wpipe, uio); PIPE_DROP_GIANT(wpipe); + pipeunlock(wpipe); if (error) { wpipe->pipe_state &= ~PIPE_DIRECTW; goto error1; @@ -856,10 +861,10 @@ pipe_write(fp, uio, cred, flags, td) (wpipe->pipe_buffer.cnt == 0)) { if ((error = pipelock(wpipe,1)) == 0) { - PIPE_GET_GIANT(rpipe); + PIPE_GET_GIANT(wpipe); if (pipespace(wpipe, BIG_PIPE_SIZE) == 0) nbigpipe++; - PIPE_DROP_GIANT(rpipe); + PIPE_DROP_GIANT(wpipe); pipeunlock(wpipe); } } |