1
0
mirror of https://git.FreeBSD.org/src.git synced 2025-02-03 17:11:32 +00:00

Add g_retaste(), which given a class will present all non-open providers

to it for tasting. This is useful when the class, through means outside
the scope of GEOM, can claim providers previously unclaimed.

The g_retaste() function posts an event which is handled by the
g_retaste_event().

Event suggested by: phk
This commit is contained in:
Marcel Moolenaar 2008-03-23 01:23:35 +00:00
parent 2c361379e4
commit 8a8fcb0089
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=177509
2 changed files with 61 additions and 0 deletions

View File

@ -234,6 +234,7 @@ int g_handleattr_str(struct bio *bp, const char *attribute, char *str);
struct g_consumer * g_new_consumer(struct g_geom *gp);
struct g_geom * g_new_geomf(struct g_class *mp, const char *fmt, ...);
struct g_provider * g_new_providerf(struct g_geom *gp, const char *fmt, ...);
int g_retaste(struct g_class *mp);
void g_spoil(struct g_provider *pp, struct g_consumer *cp);
int g_std_access(struct g_provider *pp, int dr, int dw, int de);
void g_std_done(struct bio *bp);

View File

@ -249,6 +249,66 @@ g_modevent(module_t mod, int type, void *data)
return (error);
}
static void
g_retaste_event(void *arg, int flag)
{
struct g_class *cp, *mp;
struct g_geom *gp;
struct g_hh00 *hh;
struct g_provider *pp;
g_topology_assert();
if (flag == EV_CANCEL) /* XXX: can't happen ? */
return;
if (g_shutdown)
return;
hh = arg;
mp = hh->mp;
hh->error = 0;
if (hh->post) {
g_free(hh);
hh = NULL;
}
g_trace(G_T_TOPOLOGY, "g_retaste(%s)", mp->name);
LIST_FOREACH(cp, &g_classes, class) {
LIST_FOREACH(gp, &cp->geom, geom) {
LIST_FOREACH(pp, &gp->provider, provider) {
if (pp->acr || pp->acw || pp->ace)
continue;
mp->taste(mp, pp, 0);
g_topology_assert();
}
}
}
}
int
g_retaste(struct g_class *mp)
{
struct g_hh00 *hh;
int error;
if (mp->taste == NULL)
return (EINVAL);
hh = g_malloc(sizeof *hh, M_WAITOK | M_ZERO);
hh->mp = mp;
if (cold) {
hh->post = 1;
error = g_post_event(g_retaste_event, hh, M_WAITOK, NULL);
} else {
error = g_waitfor_event(g_retaste_event, hh, M_WAITOK, NULL);
if (error == 0)
error = hh->error;
g_free(hh);
}
return (error);
}
struct g_geom *
g_new_geomf(struct g_class *mp, const char *fmt, ...)
{