diff options
author | jhb <jhb@FreeBSD.org> | 2006-03-28 21:30:22 +0000 |
---|---|---|
committer | jhb <jhb@FreeBSD.org> | 2006-03-28 21:30:22 +0000 |
commit | 44f0d9f5195c6fba57e25137546f98690ea5f1d2 (patch) | |
tree | 4f5f0c0176236c8d422846a1ad3de7d7acc57d6e /sys/kern/kern_alq.c | |
parent | 0d8b767dc84c60efc1d4a020824e0fb91f8015e9 (diff) | |
download | FreeBSD-src-44f0d9f5195c6fba57e25137546f98690ea5f1d2.zip FreeBSD-src-44f0d9f5195c6fba57e25137546f98690ea5f1d2.tar.gz |
- Conditionalize Giant around VFS operations for ALQ, ktrace, and
generating a coredump as the result of a signal.
- Fix a bug where we could leak a Giant lock if vn_start_write() failed
in coredump().
Reported by: jmg (2)
Diffstat (limited to 'sys/kern/kern_alq.c')
-rw-r--r-- | sys/kern/kern_alq.c | 12 |
1 files changed, 8 insertions, 4 deletions
diff --git a/sys/kern/kern_alq.c b/sys/kern/kern_alq.c index fbedf08..b6b24de 100644 --- a/sys/kern/kern_alq.c +++ b/sys/kern/kern_alq.c @@ -35,6 +35,7 @@ __FBSDID("$FreeBSD$"); #include <sys/kthread.h> #include <sys/lock.h> #include <sys/mac.h> +#include <sys/mount.h> #include <sys/mutex.h> #include <sys/namei.h> #include <sys/proc.h> @@ -172,8 +173,6 @@ ald_daemon(void) int needwakeup; struct alq *alq; - mtx_lock(&Giant); - ald_thread = FIRST_THREAD_IN_PROC(ald_proc); EVENTHANDLER_REGISTER(shutdown_pre_sync, ald_shutdown, NULL, @@ -250,6 +249,7 @@ alq_doio(struct alq *alq) struct ale *alstart; int totlen; int iov; + int vfslocked; vp = alq->aq_vp; td = curthread; @@ -291,6 +291,7 @@ alq_doio(struct alq *alq) /* * Do all of the junk required to write now. */ + vfslocked = VFS_LOCK_GIANT(vp->v_mount); vn_start_write(vp, &mp, V_WAIT); vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, td); VOP_LEASE(vp, td, alq->aq_cred, LEASE_WRITE); @@ -303,6 +304,7 @@ alq_doio(struct alq *alq) VOP_WRITE(vp, &auio, IO_UNIT | IO_APPEND, alq->aq_cred); VOP_UNLOCK(vp, 0, td); vn_finished_write(mp); + VFS_UNLOCK_GIANT(vfslocked); ALQ_LOCK(alq); alq->aq_flags &= ~AQ_FLUSHING; @@ -345,21 +347,23 @@ alq_open(struct alq **alqp, const char *file, struct ucred *cred, int cmode, char *bufp; int flags; int error; - int i; + int i, vfslocked; *alqp = NULL; td = curthread; - NDINIT(&nd, LOOKUP, NOFOLLOW, UIO_SYSSPACE, file, td); + NDINIT(&nd, LOOKUP, NOFOLLOW | MPSAFE, UIO_SYSSPACE, file, td); flags = FWRITE | O_NOFOLLOW | O_CREAT; error = vn_open_cred(&nd, &flags, cmode, cred, -1); if (error) return (error); + vfslocked = NDHASGIANT(&nd); NDFREE(&nd, NDF_ONLY_PNBUF); /* We just unlock so we hold a reference */ VOP_UNLOCK(nd.ni_vp, 0, td); + VFS_UNLOCK_GIANT(vfslocked); alq = malloc(sizeof(*alq), M_ALD, M_WAITOK|M_ZERO); alq->aq_entbuf = malloc(count * size, M_ALD, M_WAITOK|M_ZERO); |