diff options
Diffstat (limited to 'sys/kern/kern_sig.c')
-rw-r--r-- | sys/kern/kern_sig.c | 11 |
1 files changed, 11 insertions, 0 deletions
diff --git a/sys/kern/kern_sig.c b/sys/kern/kern_sig.c index e96f47113b3a..2d87b630561c 100644 --- a/sys/kern/kern_sig.c +++ b/sys/kern/kern_sig.c @@ -1599,6 +1599,7 @@ coredump(p) struct nameidata nd; struct vattr vattr; int error, error1, flags; + struct mount *mp; char *name; /* name of corefile */ off_t limit; @@ -1619,6 +1620,7 @@ coredump(p) if (limit == 0) return 0; +restart: name = expand_name(p->p_comm, p->p_ucred->cr_uid, p->p_pid); NDINIT(&nd, LOOKUP, NOFOLLOW, UIO_SYSSPACE, name, p); flags = O_CREAT | FWRITE | O_NOFOLLOW; @@ -1628,6 +1630,14 @@ coredump(p) return (error); NDFREE(&nd, NDF_ONLY_PNBUF); vp = nd.ni_vp; + if (vn_start_write(vp, &mp, V_NOWAIT) != 0) { + VOP_UNLOCK(vp, 0, p); + if ((error = vn_close(vp, FWRITE, cred, p)) != 0) + return (error); + if ((error = vn_start_write(NULL, &mp, V_XSLEEP | PCATCH)) != 0) + return (error); + goto restart; + } /* Don't dump to non-regular files or files with links. */ if (vp->v_type != VREG || @@ -1647,6 +1657,7 @@ coredump(p) out: VOP_UNLOCK(vp, 0, p); + vn_finished_write(mp); error1 = vn_close(vp, FWRITE, cred, p); if (error == 0) error = error1; |