1
0
mirror of https://git.FreeBSD.org/src.git synced 2024-12-16 10:20:30 +00:00

geom_slice: fix r325227, protect against multiple calls to g_slice_free

This geom does not immediately detach its consumer relying on the
wither-washer to do that.  Since that happens asynchronously we may get
additional spoiling events.  So, we need to account for that.

There are multiple options for fixing this issue like detaching
immediately or checking for G_CF_ORPHAN in g_slice_spoiled().
The most reliable and least intrusive fix seems to be setting
geom->softc to NULL on the first call and checking for NULL on
subsequent calls.  This is something that the code did before r325227.

Reported by:	David Wolfskill <david@catwhisker.org>,
		O. Hartmann <o.hartmann@walstatt.org>
Tested by:	David Wolfskill <david@catwhisker.org> (earlier version)
Discussed with:	mav
MFC after:	1 week
X-MFC with:	r325227
This commit is contained in:
Andriy Gapon 2017-11-01 10:53:10 +00:00
parent 1cfbc451b9
commit f0fa2af656
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=325272

View File

@ -71,10 +71,19 @@ g_slice_alloc(unsigned nslice, unsigned scsize)
}
static void
g_slice_free(struct g_slicer *gsp)
g_slice_free(struct g_geom *gp)
{
struct g_slicer *gsp;
if (gsp == NULL) /* XXX: phk thinks about this */
gsp = gp->softc;
gp->softc = NULL;
/*
* We can get multiple spoiled events before wither-washer
* detaches our consumer, so this can get called multiple
* times.
*/
if (gsp == NULL)
return;
g_free(gsp->slices);
if (gsp->hotspot != NULL)
@ -133,7 +142,7 @@ g_slice_access(struct g_provider *pp, int dr, int dw, int de)
*/
if (error == 0 && (gp->flags & G_GEOM_WITHER) != 0 &&
(cp->acr + cp->acw + cp->ace) == 0)
g_slice_free(gsp);
g_slice_free(gp);
return (error);
}
@ -492,7 +501,7 @@ g_slice_orphan(struct g_consumer *cp)
* otherwise g_slice_access() will do that after the last close.
*/
if ((cp->acr + cp->acw + cp->ace) == 0)
g_slice_free(gp->softc);
g_slice_free(gp);
}
void