Add a new GEOM method, resize(), which is called after provider size changes.
Add a new routine, g_resize_provider(), to use to notify GEOM about provider change. Reviewed by: mav Sponsored by: FreeBSD Foundation
This commit is contained in:
parent
80dc0e94a4
commit
f2e3e9e073
@ -79,6 +79,7 @@ typedef void g_attrchanged_t (struct g_consumer *, const char *attr);
|
||||
typedef void g_provgone_t (struct g_provider *);
|
||||
typedef void g_dumpconf_t (struct sbuf *, const char *indent, struct g_geom *,
|
||||
struct g_consumer *, struct g_provider *);
|
||||
typedef void g_resize_t(struct g_consumer *cp);
|
||||
|
||||
/*
|
||||
* The g_class structure describes a transformation class. In other words
|
||||
@ -108,7 +109,7 @@ struct g_class {
|
||||
g_orphan_t *orphan;
|
||||
g_ioctl_t *ioctl;
|
||||
g_provgone_t *providergone;
|
||||
void *spare2;
|
||||
g_resize_t *resize;
|
||||
/*
|
||||
* The remaining elements are private
|
||||
*/
|
||||
@ -139,7 +140,7 @@ struct g_geom {
|
||||
g_orphan_t *orphan;
|
||||
g_ioctl_t *ioctl;
|
||||
g_provgone_t *providergone;
|
||||
void *spare1;
|
||||
g_resize_t *resize;
|
||||
void *softc;
|
||||
unsigned flags;
|
||||
#define G_GEOM_WITHER 1
|
||||
@ -265,6 +266,7 @@ int g_handleattr_str(struct bio *bp, const char *attribute, const 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, ...);
|
||||
void g_resize_provider(struct g_provider *pp, off_t size);
|
||||
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);
|
||||
|
@ -68,9 +68,11 @@ static struct g_tailq_head geoms = TAILQ_HEAD_INITIALIZER(geoms);
|
||||
char *g_wait_event, *g_wait_up, *g_wait_down, *g_wait_sim;
|
||||
|
||||
struct g_hh00 {
|
||||
struct g_class *mp;
|
||||
int error;
|
||||
int post;
|
||||
struct g_class *mp;
|
||||
struct g_provider *pp;
|
||||
off_t size;
|
||||
int error;
|
||||
int post;
|
||||
};
|
||||
|
||||
/*
|
||||
@ -356,6 +358,7 @@ g_new_geomf(struct g_class *mp, const char *fmt, ...)
|
||||
gp->access = mp->access;
|
||||
gp->orphan = mp->orphan;
|
||||
gp->ioctl = mp->ioctl;
|
||||
gp->resize = mp->resize;
|
||||
return (gp);
|
||||
}
|
||||
|
||||
@ -601,6 +604,76 @@ g_error_provider(struct g_provider *pp, int error)
|
||||
pp->error = error;
|
||||
}
|
||||
|
||||
static void
|
||||
g_resize_provider_event(void *arg, int flag)
|
||||
{
|
||||
struct g_hh00 *hh;
|
||||
struct g_class *mp;
|
||||
struct g_geom *gp;
|
||||
struct g_provider *pp;
|
||||
struct g_consumer *cp, *cp2;
|
||||
off_t size;
|
||||
|
||||
g_topology_assert();
|
||||
if (flag == EV_CANCEL)
|
||||
return;
|
||||
if (g_shutdown)
|
||||
return;
|
||||
|
||||
hh = arg;
|
||||
pp = hh->pp;
|
||||
size = hh->size;
|
||||
|
||||
G_VALID_PROVIDER(pp);
|
||||
g_trace(G_T_TOPOLOGY, "g_resize_provider_event(%p)", pp);
|
||||
|
||||
LIST_FOREACH_SAFE(cp, &pp->consumers, consumers, cp2) {
|
||||
gp = cp->geom;
|
||||
if (gp->resize == NULL && size < pp->mediasize)
|
||||
cp->geom->orphan(cp);
|
||||
}
|
||||
|
||||
pp->mediasize = size;
|
||||
|
||||
LIST_FOREACH_SAFE(cp, &pp->consumers, consumers, cp2) {
|
||||
gp = cp->geom;
|
||||
if (gp->resize != NULL)
|
||||
gp->resize(cp);
|
||||
}
|
||||
|
||||
/*
|
||||
* After resizing, the previously invalid GEOM class metadata
|
||||
* might become valid. This means we should retaste.
|
||||
*/
|
||||
LIST_FOREACH(mp, &g_classes, class) {
|
||||
if (mp->taste == NULL)
|
||||
continue;
|
||||
LIST_FOREACH(cp, &pp->consumers, consumers)
|
||||
if (cp->geom->class == mp)
|
||||
break;
|
||||
if (cp != NULL)
|
||||
continue;
|
||||
mp->taste(mp, pp, 0);
|
||||
g_topology_assert();
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
g_resize_provider(struct g_provider *pp, off_t size)
|
||||
{
|
||||
struct g_hh00 *hh;
|
||||
|
||||
G_VALID_PROVIDER(pp);
|
||||
|
||||
if (size == pp->mediasize)
|
||||
return;
|
||||
|
||||
hh = g_malloc(sizeof *hh, M_WAITOK | M_ZERO);
|
||||
hh->pp = pp;
|
||||
hh->size = size;
|
||||
g_post_event(g_resize_provider_event, hh, M_WAITOK, NULL);
|
||||
}
|
||||
|
||||
struct g_provider *
|
||||
g_provider_by_name(char const *arg)
|
||||
{
|
||||
|
Loading…
x
Reference in New Issue
Block a user