summaryrefslogtreecommitdiffstats
path: root/sys/geom/geom_event.c
diff options
context:
space:
mode:
authorphk <phk@FreeBSD.org>2004-07-08 16:17:14 +0000
committerphk <phk@FreeBSD.org>2004-07-08 16:17:14 +0000
commit042d10f8ef48e69d0af980b7709a295d34a9d987 (patch)
treea2bc0c14b24fa444e03a2cf0a77ec7bc53390e33 /sys/geom/geom_event.c
parentee6a790d1159a338d31f43dc0373c731d1106bb8 (diff)
downloadFreeBSD-src-042d10f8ef48e69d0af980b7709a295d34a9d987.zip
FreeBSD-src-042d10f8ef48e69d0af980b7709a295d34a9d987.tar.gz
Make withering water tight.
When we orphan/wither a provider, an attached geom+consumer could end up being withered as a result and it may be in front of us in the normal object scanning order so we need to do multi-pass. On the other hand, there may be withering stuff we can't get rid off (yet), so we need to keep track of both the existence of withering stuff and if there is more we can do at this time.
Diffstat (limited to 'sys/geom/geom_event.c')
-rw-r--r--sys/geom/geom_event.c16
1 files changed, 16 insertions, 0 deletions
diff --git a/sys/geom/geom_event.c b/sys/geom/geom_event.c
index afb214f..d26bac0 100644
--- a/sys/geom/geom_event.c
+++ b/sys/geom/geom_event.c
@@ -59,6 +59,7 @@ static struct event_tailq_head g_events = TAILQ_HEAD_INITIALIZER(g_events);
static u_int g_pending_events;
static TAILQ_HEAD(,g_provider) g_doorstep = TAILQ_HEAD_INITIALIZER(g_doorstep);
static struct mtx g_eventlock;
+static int g_wither_work;
#define G_N_EVENTREFS 20
@@ -194,9 +195,18 @@ one_event(void)
void
g_run_events()
{
+ int i;
while (one_event())
;
+ g_topology_lock();
+ i = g_wither_work;
+ while (i) {
+ i = g_wither_washer();
+ g_wither_work = i & 1;
+ i &= 2;
+ }
+ g_topology_unlock();
}
void
@@ -286,6 +296,12 @@ g_post_event(g_event_t *func, void *arg, int flag, ...)
return (i);
}
+void
+g_do_wither() {
+
+ g_wither_work = 1;
+ wakeup(&g_wait_event);
+}
/*
* XXX: It might actually be useful to call this function with topology held.
OpenPOWER on IntegriCloud