diff options
author | asomers <asomers@FreeBSD.org> | 2016-05-27 22:32:44 +0000 |
---|---|---|
committer | asomers <asomers@FreeBSD.org> | 2016-05-27 22:32:44 +0000 |
commit | 6836baf662813f5f6bc11a32238e3f6a6fb3680e (patch) | |
tree | 6f05c4dffd9631a8b78519bc2decc49cf3b73d66 /sys/geom | |
parent | 9b71bae40e85cea2ab451cf256c287032fc91f2b (diff) | |
download | FreeBSD-src-6836baf662813f5f6bc11a32238e3f6a6fb3680e.zip FreeBSD-src-6836baf662813f5f6bc11a32238e3f6a6fb3680e.tar.gz |
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
Diffstat (limited to 'sys/geom')
-rw-r--r-- | sys/geom/geom_dev.c | 85 |
1 files changed, 49 insertions, 36 deletions
diff --git a/sys/geom/geom_dev.c b/sys/geom/geom_dev.c index 005cc3c..d74b92e 100644 --- a/sys/geom/geom_dev.c +++ b/sys/geom/geom_dev.c @@ -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; } } |