summaryrefslogtreecommitdiffstats
path: root/sys/kern/kern_alq.c
diff options
context:
space:
mode:
authorjhb <jhb@FreeBSD.org>2006-03-28 21:30:22 +0000
committerjhb <jhb@FreeBSD.org>2006-03-28 21:30:22 +0000
commit44f0d9f5195c6fba57e25137546f98690ea5f1d2 (patch)
tree4f5f0c0176236c8d422846a1ad3de7d7acc57d6e /sys/kern/kern_alq.c
parent0d8b767dc84c60efc1d4a020824e0fb91f8015e9 (diff)
downloadFreeBSD-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.c12
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);
OpenPOWER on IntegriCloud