summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--sys/kern/imgact_aout.c4
-rw-r--r--sys/kern/imgact_elf.c4
-rw-r--r--sys/kern/kern_subr.c4
-rw-r--r--sys/kern/vfs_vnops.c5
-rw-r--r--sys/sys/uio.h1
5 files changed, 10 insertions, 8 deletions
diff --git a/sys/kern/imgact_aout.c b/sys/kern/imgact_aout.c
index 3ec8f5f..5a53581 100644
--- a/sys/kern/imgact_aout.c
+++ b/sys/kern/imgact_aout.c
@@ -269,14 +269,14 @@ aout_coredump(td, vp, limit)
error = vn_rdwr(UIO_WRITE, vp, vm->vm_daddr,
(int)ctob(vm->vm_dsize),
(off_t)ctob(UAREA_PAGES + KSTACK_PAGES), UIO_USERSPACE,
- IO_UNIT, cred, (int *) NULL, td);
+ IO_UNIT | IO_DIRECT, cred, (int *) NULL, td);
if (error == 0)
error = vn_rdwr_inchunks(UIO_WRITE, vp,
(caddr_t) trunc_page(USRSTACK - ctob(vm->vm_ssize)),
round_page(ctob(vm->vm_ssize)),
(off_t)ctob(UAREA_PAGES + KSTACK_PAGES) +
ctob(vm->vm_dsize), UIO_USERSPACE,
- IO_UNIT, cred, (int *) NULL, td);
+ IO_UNIT | IO_DIRECT, cred, (int *) NULL, td);
return (error);
}
diff --git a/sys/kern/imgact_elf.c b/sys/kern/imgact_elf.c
index 66a3a34..d7a27ba 100644
--- a/sys/kern/imgact_elf.c
+++ b/sys/kern/imgact_elf.c
@@ -802,7 +802,7 @@ elf_coredump(td, vp, limit)
error = vn_rdwr_inchunks(UIO_WRITE, vp,
(caddr_t)php->p_vaddr,
php->p_filesz, offset, UIO_USERSPACE,
- IO_UNIT, cred, (int *)NULL, curthread); /* XXXKSE */
+ IO_UNIT | IO_DIRECT, cred, (int *)NULL, curthread); /* XXXKSE */
if (error != 0)
break;
offset += php->p_filesz;
@@ -966,7 +966,7 @@ elf_corehdr(td, vp, cred, numsegs, hdr, hdrsize)
/* Write it to the core file. */
return vn_rdwr_inchunks(UIO_WRITE, vp, hdr, hdrsize, (off_t)0,
- UIO_SYSSPACE, IO_UNIT, cred, NULL, td); /* XXXKSE */
+ UIO_SYSSPACE, IO_UNIT | IO_DIRECT, cred, NULL, td); /* XXXKSE */
}
static void
diff --git a/sys/kern/kern_subr.c b/sys/kern/kern_subr.c
index 9f53d2d..cab78c2 100644
--- a/sys/kern/kern_subr.c
+++ b/sys/kern/kern_subr.c
@@ -55,8 +55,6 @@
#include <vm/vm_page.h>
#include <vm/vm_map.h>
-static void uio_yield __P((void));
-
SYSCTL_INT(_kern, KERN_IOV_MAX, iov_max, CTLFLAG_RD, NULL, UIO_MAXIOV,
"Maximum number of elements in an I/O vector; sysconf(_SC_IOV_MAX)");
@@ -381,7 +379,7 @@ phashinit(elements, type, nentries)
return (hashtbl);
}
-static void
+void
uio_yield()
{
struct thread *td;
diff --git a/sys/kern/vfs_vnops.c b/sys/kern/vfs_vnops.c
index b3160b1..2a2bd83 100644
--- a/sys/kern/vfs_vnops.c
+++ b/sys/kern/vfs_vnops.c
@@ -338,7 +338,9 @@ vn_rdwr(rw, vp, base, len, offset, segflg, ioflg, cred, aresid, td)
* Package up an I/O request on a vnode into a uio and do it. The I/O
* request is split up into smaller chunks and we try to avoid saturating
* the buffer cache while potentially holding a vnode locked, so we
- * check bwillwrite() before calling vn_rdwr()
+ * check bwillwrite() before calling vn_rdwr(). We also call uio_yield()
+ * to give other processes a chance to lock the vnode (either other processes
+ * core'ing the same binary, or unrelated processes scanning the directory).
*/
int
vn_rdwr_inchunks(rw, vp, base, len, offset, segflg, ioflg, cred, aresid, td)
@@ -367,6 +369,7 @@ vn_rdwr_inchunks(rw, vp, base, len, offset, segflg, ioflg, cred, aresid, td)
break;
offset += chunk;
base += chunk;
+ uio_yield();
} while (len);
if (aresid)
*aresid += len;
diff --git a/sys/sys/uio.h b/sys/sys/uio.h
index 48f6c97..eec95a2 100644
--- a/sys/sys/uio.h
+++ b/sys/sys/uio.h
@@ -84,6 +84,7 @@ struct uio {
struct vm_object;
+void uio_yield __P((void));
int uiomove __P((caddr_t, int, struct uio *));
int uiomoveco __P((caddr_t, int, struct uio *, struct vm_object *));
int uioread __P((int, struct uio *, struct vm_object *, int *));
OpenPOWER on IntegriCloud