Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 23 Dec 2003 12:26:45 +0100
From:      Simon Heath <heath@cng.fr>
To:        Poul-Henning Kamp <phk@phk.freebsd.dk>
Cc:        freebsd-current@freebsd.org
Subject:   Re: cd taste crash followup
Message-ID:  <20031223112645.GA14443@madiran.cng.fr>
In-Reply-To: <43106.1072177560@critter.freebsd.dk>
References:  <20031223105208.GA8531@madiran.cng.fr> <43106.1072177560@critter.freebsd.dk>

next in thread | previous in thread | raw e-mail | index | archive | help
On Tue, Dec 23, 2003 at 12:06:00PM +0100, Poul-Henning Kamp wrote:
> In message <20031223105208.GA8531@madiran.cng.fr>, Simon Heath writes:
> 
> >The calls come from g_orphan_register which calls g_dev_orphan() on each
> >element from pp->consumers, which in turn calls g_detach() which calls
> >g_destroy_provider().  g_orphan_register() then calls g_destroy_provider()
> >directly with pp (because G_PF_WITHER is set), but pp has already been
> >passed to g_destroy_provider() in the previous loop, so we end up with the
> >attempt to remove the devstat twice.  As to why pp appears as a provider in
> >pp->consumers I have no idea, but I hope this makes some sense to people who
> >understand GEOM.
> 
> Sigh, I know the per provider wither flag sounded too easy...
> 
> Can you try this patch ?
> 
> Index: geom_event.c
> ===================================================================
> RCS file: /home/ncvs/src/sys/geom/geom_event.c,v
> retrieving revision 1.44
> diff -u -r1.44 geom_event.c
> --- geom_event.c	7 Dec 2003 10:04:43 -0000	1.44
> +++ geom_event.c	23 Dec 2003 11:04:58 -0000
> @@ -126,10 +126,14 @@
>  g_orphan_register(struct g_provider *pp)
>  {
>  	struct g_consumer *cp, *cp2;
> +	int wf;
>  
>  	g_trace(G_T_TOPOLOGY, "g_orphan_register(%s)", pp->name);
>  	g_topology_assert();
>  
> +	wf = pp->flags & G_PF_WITHER;
> +	pp->flags &= ~G_PF_WITHER;
> +
>  	/*
>  	 * Tell all consumers the bad news.
>  	 * Don't be surprised if they self-destruct.
> @@ -143,8 +147,10 @@
>  		cp->geom->orphan(cp);
>  		cp = cp2;
>  	}
> -	if (LIST_EMPTY(&pp->consumers) && (pp->flags & G_PF_WITHER))
> +	if (LIST_EMPTY(&pp->consumers) && wf)
>  		g_destroy_provider(pp);
> +	else
> +		pp->flags |= wf;
>  #ifdef notyet
>  	cp = LIST_FIRST(&pp->consumers);
>  	if (cp != NULL)
> 

That works fine for me - I can't reproduce the crash with this patch.

Thanks,
Simon



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20031223112645.GA14443>