svn commit: r300881 - in head/sys: cddl/contrib/opensolaris/uts/common/fs/zfs geom
Alan Somers
asomers at FreeBSD.org
Fri May 27 22:32:46 UTC 2016
Author: asomers
Date: Fri May 27 22:32:44 2016
New Revision: 300881
URL: https://svnweb.freebsd.org/changeset/base/300881
Log:
Avoid issuing spa config updates for physical path when not necessary
ZFS's configuration needs to be updated whenever the physical path for a
device changes, but not when a new device is introduced. This is because new
devices necessarily cause config updates, but only if they are actually
accepted into the pool.
sys/cddl/contrib/opensolaris/uts/common/fs/zfs/vdev_geom.c
Split vdev_geom_set_physpath out of vdev_geom_attrchanged. When
setting the vdev's physical path, only request a config update if
the physical path has changed. Don't request it when opening a
device for the first time, because the config sync will happen
anyway upstack.
sys/geom/geom_dev.c
Split g_dev_set_physpath and g_dev_set_media out of
g_dev_attrchanged
Submitted by: will, asomers
MFC after: 4 weeks
Sponsored by: Spectra Logic Corp
Differential Revision: https://reviews.freebsd.org/D6428
Modified:
head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/vdev_geom.c
head/sys/geom/geom_dev.c
Modified: head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/vdev_geom.c
==============================================================================
--- head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/vdev_geom.c Fri May 27 22:26:43 2016 (r300880)
+++ head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/vdev_geom.c Fri May 27 22:32:44 2016 (r300881)
@@ -85,32 +85,17 @@ vdev_geom_set_rotation_rate(vdev_t *vd,
}
static void
-vdev_geom_attrchanged(struct g_consumer *cp, const char *attr)
+vdev_geom_set_physpath(struct g_consumer *cp, boolean_t do_null_update)
{
+ boolean_t needs_update;
vdev_t *vd;
- spa_t *spa;
char *physpath;
int error, physpath_len;
- vd = cp->private;
- if (vd == NULL)
- return;
-
- if (strcmp(attr, "GEOM::rotation_rate") == 0) {
- vdev_geom_set_rotation_rate(vd, cp);
- return;
- }
-
- if (strcmp(attr, "GEOM::physpath") != 0)
- return;
-
if (g_access(cp, 1, 0, 0) != 0)
return;
- /*
- * Record/Update physical path information for this device.
- */
- spa = vd->vdev_spa;
+ vd = cp->private;
physpath_len = MAXPATHLEN;
physpath = g_malloc(physpath_len, M_WAITOK|M_ZERO);
error = g_io_getattr("GEOM::physpath", cp, &physpath_len, physpath);
@@ -122,12 +107,46 @@ vdev_geom_attrchanged(struct g_consumer
g_topology_assert();
old_physpath = vd->vdev_physpath;
vd->vdev_physpath = spa_strdup(physpath);
- spa_async_request(spa, SPA_ASYNC_CONFIG_UPDATE);
- if (old_physpath != NULL)
+ if (old_physpath != NULL) {
+ needs_update = (strcmp(old_physpath,
+ vd->vdev_physpath) != 0);
spa_strfree(old_physpath);
+ } else
+ needs_update = do_null_update;
}
g_free(physpath);
+
+ /*
+ * If the physical path changed, update the config.
+ * Only request an update for previously unset physpaths if
+ * requested by the caller.
+ */
+ if (needs_update)
+ spa_async_request(vd->vdev_spa, SPA_ASYNC_CONFIG_UPDATE);
+
+}
+
+static void
+vdev_geom_attrchanged(struct g_consumer *cp, const char *attr)
+{
+ vdev_t *vd;
+ char *old_physpath;
+ int error;
+
+ vd = cp->private;
+ if (vd == NULL)
+ return;
+
+ if (strcmp(attr, "GEOM::rotation_rate") == 0) {
+ vdev_geom_set_rotation_rate(vd, cp);
+ return;
+ }
+
+ if (strcmp(attr, "GEOM::physpath") == 0) {
+ vdev_geom_set_physpath(cp, /*do_null_update*/B_TRUE);
+ return;
+ }
}
static void
@@ -257,8 +276,10 @@ vdev_geom_attach(struct g_provider *pp,
* 2) Set it to a linked list of vdevs, not just a single vdev
*/
cp->private = vd;
- if (vd != NULL)
+ if (vd != NULL) {
vd->vdev_tsd = cp;
+ vdev_geom_set_physpath(cp, /*do_null_update*/B_FALSE);
+ }
cp->flags |= G_CF_DIRECT_SEND | G_CF_DIRECT_RECEIVE;
return (cp);
Modified: head/sys/geom/geom_dev.c
==============================================================================
--- head/sys/geom/geom_dev.c Fri May 27 22:26:43 2016 (r300880)
+++ head/sys/geom/geom_dev.c Fri May 27 22:32:44 2016 (r300881)
@@ -222,55 +222,68 @@ g_dev_print(void)
}
static void
-g_dev_attrchanged(struct g_consumer *cp, const char *attr)
+g_dev_set_physpath(struct g_consumer *cp)
+{
+ struct g_dev_softc *sc;
+ char *physpath;
+ int error, physpath_len;
+
+ if (g_access(cp, 1, 0, 0) != 0)
+ return;
+
+ sc = cp->private;
+ physpath_len = MAXPATHLEN;
+ physpath = g_malloc(physpath_len, M_WAITOK|M_ZERO);
+ error = g_io_getattr("GEOM::physpath", cp, &physpath_len, physpath);
+ g_access(cp, -1, 0, 0);
+ if (error == 0 && strlen(physpath) != 0) {
+ struct cdev *dev, *old_alias_dev;
+ struct cdev **alias_devp;
+
+ dev = sc->sc_dev;
+ old_alias_dev = sc->sc_alias;
+ alias_devp = (struct cdev **)&sc->sc_alias;
+ make_dev_physpath_alias(MAKEDEV_WAITOK, alias_devp, dev,
+ old_alias_dev, physpath);
+ } else if (sc->sc_alias) {
+ destroy_dev((struct cdev *)sc->sc_alias);
+ sc->sc_alias = NULL;
+ }
+ g_free(physpath);
+}
+
+static void
+g_dev_set_media(struct g_consumer *cp)
{
struct g_dev_softc *sc;
struct cdev *dev;
char buf[SPECNAMELEN + 6];
sc = cp->private;
- if (strcmp(attr, "GEOM::media") == 0) {
- dev = sc->sc_dev;
+ dev = sc->sc_dev;
+ snprintf(buf, sizeof(buf), "cdev=%s", dev->si_name);
+ devctl_notify_f("DEVFS", "CDEV", "MEDIACHANGE", buf, M_WAITOK);
+ devctl_notify_f("GEOM", "DEV", "MEDIACHANGE", buf, M_WAITOK);
+ dev = sc->sc_alias;
+ if (dev != NULL) {
snprintf(buf, sizeof(buf), "cdev=%s", dev->si_name);
devctl_notify_f("DEVFS", "CDEV", "MEDIACHANGE", buf, M_WAITOK);
devctl_notify_f("GEOM", "DEV", "MEDIACHANGE", buf, M_WAITOK);
- dev = sc->sc_alias;
- if (dev != NULL) {
- snprintf(buf, sizeof(buf), "cdev=%s", dev->si_name);
- devctl_notify_f("DEVFS", "CDEV", "MEDIACHANGE", buf,
- M_WAITOK);
- devctl_notify_f("GEOM", "DEV", "MEDIACHANGE", buf,
- M_WAITOK);
- }
- return;
}
+}
- if (strcmp(attr, "GEOM::physpath") != 0)
+static void
+g_dev_attrchanged(struct g_consumer *cp, const char *attr)
+{
+
+ if (strcmp(attr, "GEOM::media") == 0) {
+ g_dev_set_media(cp);
return;
+ }
- if (g_access(cp, 1, 0, 0) == 0) {
- char *physpath;
- int error, physpath_len;
-
- physpath_len = MAXPATHLEN;
- physpath = g_malloc(physpath_len, M_WAITOK|M_ZERO);
- error =
- g_io_getattr("GEOM::physpath", cp, &physpath_len, physpath);
- g_access(cp, -1, 0, 0);
- if (error == 0 && strlen(physpath) != 0) {
- struct cdev *old_alias_dev;
- struct cdev **alias_devp;
-
- dev = sc->sc_dev;
- old_alias_dev = sc->sc_alias;
- alias_devp = (struct cdev **)&sc->sc_alias;
- make_dev_physpath_alias(MAKEDEV_WAITOK, alias_devp,
- dev, old_alias_dev, physpath);
- } else if (sc->sc_alias) {
- destroy_dev((struct cdev *)sc->sc_alias);
- sc->sc_alias = NULL;
- }
- g_free(physpath);
+ if (strcmp(attr, "GEOM::physpath") == 0) {
+ g_dev_set_physpath(cp);
+ return;
}
}
More information about the svn-src-head
mailing list