summaryrefslogtreecommitdiffstats
path: root/sys/geom/geom_event.c
diff options
context:
space:
mode:
authorphk <phk@FreeBSD.org>2004-10-23 20:49:17 +0000
committerphk <phk@FreeBSD.org>2004-10-23 20:49:17 +0000
commit93429f2778c1eefb93458add0ccaaa0b4e7dc6dc (patch)
tree1ae80df1885403ab58d62d12a9d391c55a499ee5 /sys/geom/geom_event.c
parent00ae1b0f027fae923a5fc5b6ad862dcb3dcd2384 (diff)
downloadFreeBSD-src-93429f2778c1eefb93458add0ccaaa0b4e7dc6dc.zip
FreeBSD-src-93429f2778c1eefb93458add0ccaaa0b4e7dc6dc.tar.gz
Add a new per-thread private flag: TDP_GEOM.
This flag gets set whenever the thread posts an event on the GEOM event queue, and if the flag is set when the thread is prepared to return to userland from the kernel, g_waitidle() will be called to make sure that the posted events have completed. This can replace an insufficient number of g_waitidle() calls in various other places, and has the advantage of being failsafe: Any system call which does a VOP_OPEN()/VOP_CLOSE will now correctly wait for any geom events it posted as part of spoils or tastes. Assert that topology and Giant is not held in g_waitidle().
Diffstat (limited to 'sys/geom/geom_event.c')
-rw-r--r--sys/geom/geom_event.c9
1 files changed, 8 insertions, 1 deletions
diff --git a/sys/geom/geom_event.c b/sys/geom/geom_event.c
index d26bac0..9166c30 100644
--- a/sys/geom/geom_event.c
+++ b/sys/geom/geom_event.c
@@ -47,12 +47,14 @@ __FBSDID("$FreeBSD$");
#include <sys/kernel.h>
#include <sys/lock.h>
#include <sys/mutex.h>
-#include <machine/stdarg.h>
+#include <sys/proc.h>
#include <sys/errno.h>
#include <sys/time.h>
#include <geom/geom.h>
#include <geom/geom_int.h>
+#include <machine/stdarg.h>
+
TAILQ_HEAD(event_tailq_head, g_event);
static struct event_tailq_head g_events = TAILQ_HEAD_INITIALIZER(g_events);
@@ -79,8 +81,12 @@ void
g_waitidle(void)
{
+ g_topology_assert_not();
+ mtx_assert(&Giant, MA_NOTOWNED);
+
while (g_pending_events)
tsleep(&g_pending_events, PPAUSE, "g_waitidle", hz/5);
+ curthread->td_pflags &= ~TDP_GEOM;
}
void
@@ -279,6 +285,7 @@ g_post_event_x(g_event_t *func, void *arg, int flag, int wuflag, struct g_event
wakeup(&g_wait_event);
if (epp != NULL)
*epp = ep;
+ curthread->td_pflags |= TDP_GEOM;
return (0);
}
OpenPOWER on IntegriCloud