aboutsummaryrefslogtreecommitdiff
path: root/sys/kern/kern_subr.c
diff options
context:
space:
mode:
authorJulian Elischer <julian@FreeBSD.org>1999-03-12 03:09:29 +0000
committerJulian Elischer <julian@FreeBSD.org>1999-03-12 03:09:29 +0000
commitbeef8a367c3c141c1e232b5e792c5bbc8e427b68 (patch)
tree85f8197841f4ea9cb4cc4231b04331fd8823caab /sys/kern/kern_subr.c
parent4ef2094e457b4e11e04bb4e2c70ea3bf57cf9ac3 (diff)
downloadsrc-beef8a367c3c141c1e232b5e792c5bbc8e427b68.tar.gz
src-beef8a367c3c141c1e232b5e792c5bbc8e427b68.zip
This solves a deadlock that can occur when read()ing into a file-mmap()
space. When doing this, it is possible to for another process to attempt to get an exclusive lock on the vnode and deadlock the mmap/read combination when the uiomove() call tries to obtain a second shared lock on the vnode. There is still a potential deadlock situation with write()/mmap(). Submitted by: Matt Dillon <dillon@freebsd.org> Reviewed by: Luoqi Chen <luoqi@freebsd.org> Delimmitted by tag PRE_MATT_MMAP_LOCK and POST_MATT_MMAP_LOCK in kern/kern_lock.c kern/kern_subr.c
Notes
Notes: svn path=/head/; revision=44681
Diffstat (limited to 'sys/kern/kern_subr.c')
-rw-r--r--sys/kern/kern_subr.c16
1 files changed, 12 insertions, 4 deletions
diff --git a/sys/kern/kern_subr.c b/sys/kern/kern_subr.c
index 190706c2ebcf..13faec6a18d3 100644
--- a/sys/kern/kern_subr.c
+++ b/sys/kern/kern_subr.c
@@ -36,7 +36,7 @@
* SUCH DAMAGE.
*
* @(#)kern_subr.c 8.3 (Berkeley) 1/21/94
- * $Id: kern_subr.c,v 1.26 1999/02/22 16:57:47 bde Exp $
+ * $Id: kern_subr.c,v 1.27 1999/02/22 18:39:49 bde Exp $
*/
#include <sys/param.h>
@@ -63,13 +63,19 @@ uiomove(cp, n, uio)
{
register struct iovec *iov;
u_int cnt;
- int error;
+ int error = 0;
+ int save = 0;
KASSERT(uio->uio_rw == UIO_READ || uio->uio_rw == UIO_WRITE,
("uiomove: mode"));
KASSERT(uio->uio_segflg != UIO_USERSPACE || uio->uio_procp == curproc,
("uiomove proc"));
+ if (curproc) {
+ save = curproc->p_flag & P_DEADLKTREAT;
+ curproc->p_flag |= P_DEADLKTREAT;
+ }
+
while (n > 0 && uio->uio_resid) {
iov = uio->uio_iov;
cnt = iov->iov_len;
@@ -92,7 +98,7 @@ uiomove(cp, n, uio)
else
error = copyin(iov->iov_base, cp, cnt);
if (error)
- return (error);
+ break;
break;
case UIO_SYSSPACE:
@@ -111,7 +117,9 @@ uiomove(cp, n, uio)
cp += cnt;
n -= cnt;
}
- return (0);
+ if (curproc)
+ curproc->p_flag = (curproc->p_flag & ~P_DEADLKTREAT) | save;
+ return (error);
}
int