summaryrefslogtreecommitdiffstats
path: root/sys/geom
diff options
context:
space:
mode:
authorasomers <asomers@FreeBSD.org>2016-05-27 22:32:44 +0000
committerasomers <asomers@FreeBSD.org>2016-05-27 22:32:44 +0000
commit6836baf662813f5f6bc11a32238e3f6a6fb3680e (patch)
tree6f05c4dffd9631a8b78519bc2decc49cf3b73d66 /sys/geom
parent9b71bae40e85cea2ab451cf256c287032fc91f2b (diff)
downloadFreeBSD-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.c85
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;
}
}
OpenPOWER on IntegriCloud