Page MenuHomeFreeBSD

D26590.1793812670.diff
No OneTemporary

Authored By
Unknown
Size
3 KB
Referenced Files
None
Subscribers
None

D26590.1793812670.diff

Index: sys/kern/imgact_elf.c
===================================================================
--- sys/kern/imgact_elf.c
+++ sys/kern/imgact_elf.c
@@ -1533,33 +1533,57 @@
}
static int
-core_output(void *base, size_t len, off_t offset, struct coredump_params *p,
+core_output(char *base, size_t len, off_t offset, struct coredump_params *p,
void *tmpbuf)
{
- int error;
+ vm_map_t map;
+ struct mount *mp;
+ size_t runlen;
+ int error, error1;
if (p->comp != NULL)
return (compress_chunk(p, base, tmpbuf, len));
- /*
- * EFAULT is a non-fatal error that we can get, for example,
- * if the segment is backed by a file but extends beyond its
- * end.
- */
- error = core_write(p, base, len, offset, UIO_USERSPACE);
- if (error == EFAULT) {
- log(LOG_WARNING, "Failed to fully fault in a core file segment "
- "at VA %p with size 0x%zx to be written at offset 0x%jx "
- "for process %s\n", base, len, offset, curproc->p_comm);
-
+ map = &p->td->td_proc->p_vmspace->vm_map;
+ do {
/*
- * Write a "real" zero byte at the end of the target region
- * in the case this is the last segment.
- * The intermediate space will be implicitly zero-filled.
+ * Attempt to page in all virtual pages in the range. If a
+ * virtual page is not backed by the pager, it is represented as
+ * a hole in the file. This can occur with zero-filled
+ * anonymous memory or truncated files, for example.
*/
- error = core_write(p, zero_region, 1, offset + len - 1,
- UIO_SYSSPACE);
- }
+ for (runlen = 0; runlen < len; runlen += PAGE_SIZE) {
+ error1 = vm_fault(map, (uintptr_t)base + runlen,
+ VM_PROT_READ, VM_FAULT_NOFILL, NULL);
+ if (runlen == 0)
+ error = error1;
+ else if (error != error1)
+ break;
+ }
+
+ if (error == KERN_SUCCESS) {
+ error = core_write(p, base, runlen, offset,
+ UIO_USERSPACE);
+ if (error != 0)
+ break;
+ } else {
+ error = vn_start_write(p->vp, &mp, V_WAIT);
+ if (error != 0)
+ break;
+ vn_lock(p->vp, LK_EXCLUSIVE | LK_RETRY);
+ error = vn_truncate_locked(p->vp, offset + runlen,
+ false, p->td->td_ucred);
+ VOP_UNLOCK(p->vp);
+ vn_finished_write(mp);
+ if (error != 0)
+ break;
+ }
+
+ base += runlen;
+ offset += runlen;
+ len -= runlen;
+ } while (len > 0);
+
return (error);
}
Index: sys/vm/vm_fault.c
===================================================================
--- sys/vm/vm_fault.c
+++ sys/vm/vm_fault.c
@@ -1476,6 +1476,12 @@
*/
if (vm_fault_next(&fs))
continue;
+ if ((fs.fault_flags & VM_FAULT_NOFILL) != 0) {
+ if (fs.first_object == fs.object)
+ fault_page_free(&fs.first_m);
+ unlock_and_deallocate(&fs);
+ return (KERN_RESTART);
+ }
VM_OBJECT_WUNLOCK(fs.object);
vm_fault_zerofill(&fs);
/* Don't try to prefault neighboring pages. */
Index: sys/vm/vm_map.h
===================================================================
--- sys/vm/vm_map.h
+++ sys/vm/vm_map.h
@@ -384,9 +384,10 @@
/*
* vm_fault option flags
*/
-#define VM_FAULT_NORMAL 0 /* Nothing special */
-#define VM_FAULT_WIRE 1 /* Wire the mapped page */
-#define VM_FAULT_DIRTY 2 /* Dirty the page; use w/VM_PROT_COPY */
+#define VM_FAULT_NORMAL 0x00 /* Nothing special */
+#define VM_FAULT_WIRE 0x01 /* Wire the mapped page */
+#define VM_FAULT_DIRTY 0x02 /* Dirty the page; use w/VM_PROT_COPY */
+#define VM_FAULT_NOFILL 0x04 /* Fail if the pager doesn't have a copy */
/*
* Initially, mappings are slightly sequential. The maximum window size must

File Metadata

Mime Type
text/plain
Expires
Wed, Nov 4, 5:17 PM (4 h, 53 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
41444577
Default Alt Text
D26590.1793812670.diff (3 KB)

Event Timeline