Index: sys/geom/geom.h =================================================================== --- sys/geom/geom.h (wersja 221858) +++ sys/geom/geom.h (kopia robocza) @@ -67,6 +67,7 @@ typedef void g_fini_t (struct g_class *mp); typedef struct g_geom * g_taste_t (struct g_class *, struct g_provider *, int flags); typedef int g_ioctl_t(struct g_provider *pp, u_long cmd, void *data, int fflag, struct thread *td); +typedef void g_property_change_t(struct g_consumer *cp, u_int properties); #define G_TF_NORMAL 0 #define G_TF_INSIST 1 #define G_TF_TRANSPARENT 2 @@ -104,6 +105,7 @@ g_access_t *access; g_orphan_t *orphan; g_ioctl_t *ioctl; + g_property_change_t *property_change; /* * The remaining elements are private */ @@ -132,6 +134,7 @@ g_access_t *access; g_orphan_t *orphan; g_ioctl_t *ioctl; + g_property_change_t *property_change; void *softc; unsigned flags; #define G_GEOM_WITHER 1 @@ -257,6 +260,8 @@ 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); +#define G_PROPERTY_MEDIASIZE 0x01 +void g_property_change(struct g_provider *pp, u_int properties); int g_std_access(struct g_provider *pp, int dr, int dw, int de); void g_std_done(struct bio *bp); void g_std_spoiled(struct g_consumer *cp); Index: sys/geom/geom_subr.c =================================================================== --- sys/geom/geom_subr.c (wersja 221858) +++ sys/geom/geom_subr.c (kopia robocza) @@ -44,6 +44,7 @@ #include #include #include +#include #include #include #include @@ -354,6 +355,7 @@ gp->access = mp->access; gp->orphan = mp->orphan; gp->ioctl = mp->ioctl; + gp->property_change = mp->property_change; return (gp); } @@ -1003,6 +1005,74 @@ g_post_event(g_spoil_event, pp, M_WAITOK, pp, NULL); } +struct g_property_change_data { + struct g_provider *provider; + u_int properties; +}; + +static void +g_property_change_event(void *arg, int flag) +{ + struct g_property_change_data *data; + struct g_provider *pp; + struct g_consumer *cp, *cp2; + u_int properties; + + g_topology_assert(); + + data = arg; + pp = data->provider; + properties = data->properties; + g_free(data); + + if (flag == EV_CANCEL) + return; + + G_VALID_PROVIDER(pp); + LIST_FOREACH_SAFE(cp, &pp->consumers, consumers, cp2) { + G_VALID_CONSUMER(cp); + G_VALID_GEOM(cp->geom); + if (cp->geom->property_change == NULL) + continue; + cp->geom->property_change(cp, properties); + g_topology_assert(); + } +} + +static void +g_property_change_notify(struct g_provider *pp, u_int properties) +{ + char data[128]; + + if (cold) + return; + + bzero(data, sizeof(data)); + if (properties & G_PROPERTY_MEDIASIZE) { + snprintf(data, sizeof(data), "mediasize=%jd", + (intmax_t)pp->mediasize); + } + devctl_notify_f("GEOM", pp->name, "PROPERTY_CHANGE", data, M_WAITOK); +} + +void +g_property_change(struct g_provider *pp, u_int properties) +{ + struct g_property_change_data *data; + int error; + + G_VALID_PROVIDER(pp); + + data = g_malloc(sizeof(*data), M_WAITOK); + data->provider = pp; + data->properties = properties; + + error = g_post_event(g_property_change_event, data, M_WAITOK, NULL); + KASSERT(error == 0, ("Unable to send property change event (error=%d).", + error)); + g_property_change_notify(pp, properties); +} + int g_getattr__(const char *attr, struct g_consumer *cp, void *var, int len) { Index: sys/geom/part/g_part.c =================================================================== --- sys/geom/part/g_part.c (wersja 221858) +++ sys/geom/part/g_part.c (kopia robocza) @@ -1216,6 +1216,7 @@ /* update mediasize of changed provider */ pp->mediasize = (entry->gpe_end - entry->gpe_start + 1) * pp->sectorsize; + g_property_change(pp, G_PROPERTY_MEDIASIZE); /* Provide feedback if so requested. */ if (gpp->gpp_parms & G_PART_PARM_OUTPUT) { Index: sys/cddl/contrib/opensolaris/uts/common/fs/zfs/vdev_geom.c =================================================================== --- sys/cddl/contrib/opensolaris/uts/common/fs/zfs/vdev_geom.c (wersja 221858) +++ sys/cddl/contrib/opensolaris/uts/common/fs/zfs/vdev_geom.c (kopia robocza) @@ -84,6 +84,25 @@ spa_async_request(vd->vdev_spa, SPA_ASYNC_REMOVE); } +static void +vdev_geom_property_change(struct g_consumer *cp, u_int properties) +{ + vdev_t *vd; + + g_topology_assert(); + + vd = cp->private; + + if (properties & G_PROPERTY_MEDIASIZE) { + g_topology_unlock(); + spa_config_enter(vd->vdev_spa, SCL_ALL, FTAG, RW_WRITER); + vdev_reopen(vd); + spa_config_exit(vd->vdev_spa, SCL_ALL, FTAG); + vdev_load(vd); + g_topology_lock(); + } +} + static struct g_consumer * vdev_geom_attach(struct g_provider *pp) { @@ -104,6 +123,7 @@ if (gp == NULL) { gp = g_new_geomf(&zfs_vdev_class, "zfs::vdev"); gp->orphan = vdev_geom_orphan; + gp->property_change = vdev_geom_property_change; cp = g_new_consumer(gp); if (g_attach(cp, pp) != 0) { g_wither_geom(gp, ENXIO); Index: sys/cddl/contrib/opensolaris/uts/common/fs/zfs/spa.c =================================================================== --- sys/cddl/contrib/opensolaris/uts/common/fs/zfs/spa.c (wersja 221858) +++ sys/cddl/contrib/opensolaris/uts/common/fs/zfs/spa.c (kopia robocza) @@ -2098,6 +2098,12 @@ spa->spa_autoreplace = (autoreplace != 0); } + if (spa->spa_autoexpand) { + spa_config_enter(spa, SCL_ALL, FTAG, RW_WRITER); + vdev_reopen(rvd); + spa_config_exit(spa, SCL_ALL, FTAG); + } + /* * If the 'autoreplace' property is set, then post a resource notifying * the ZFS DE that it should not issue any faults for unopenable