summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorpjd <pjd@FreeBSD.org>2007-09-27 20:18:34 +0000
committerpjd <pjd@FreeBSD.org>2007-09-27 20:18:34 +0000
commite429b3be958c9ec5b83a5bb1b1163e66d8241687 (patch)
treeb3d990f8b67f26c454fa3bce08c11a3c74f45c42
parente41a7e0247c842b8923871a73d41357ecad9018c (diff)
downloadFreeBSD-src-e429b3be958c9ec5b83a5bb1b1163e66d8241687.zip
FreeBSD-src-e429b3be958c9ec5b83a5bb1b1163e66d8241687.tar.gz
When orphaning a provider, cancel events related to it.
Without this change the following situation was possible: 1. Provider is orphaned from within class' access() method on last write close - orphan provider event is send. 2. GEOM detects last write close on a provider and sends new provider event. 3. g_orphan_register() is called, and calls all orphan methods of attached consumers. 4. New provider event is executed on orphaned provider, all classes can taste already orphaned provider, and some may attach consumers to it. Those consumers will never go away, because the g_orphan_register() was already called. We end up with a zombie provider. With this change, at step 3, we will cancel new provider event. How to repeat this problem: # mdconfig -a -t malloc -s 10m # geli init -i 0 md0 # geli attach md0 # newfs -L test /dev/md0.eli # mount /dev/ufs/test /mnt/tmp # geli detach -l md0.eli # umount /mnt/tmp # glabel status Name Status Components ufs/test N/A N/A Reviewed by: phk Approved by: re (kensmith)
-rw-r--r--sys/geom/geom_event.c2
1 files changed, 2 insertions, 0 deletions
diff --git a/sys/geom/geom_event.c b/sys/geom/geom_event.c
index 5288e32..9880454 100644
--- a/sys/geom/geom_event.c
+++ b/sys/geom/geom_event.c
@@ -145,6 +145,8 @@ g_orphan_register(struct g_provider *pp)
G_VALID_PROVIDER(pp);
g_trace(G_T_TOPOLOGY, "g_orphan_register(%s)", pp->name);
+ g_cancel_event(pp);
+
wf = pp->flags & G_PF_WITHER;
pp->flags &= ~G_PF_WITHER;
OpenPOWER on IntegriCloud