summaryrefslogtreecommitdiffstats
path: root/sys/cddl/contrib/opensolaris/uts/common
diff options
context:
space:
mode:
authormav <mav@FreeBSD.org>2016-10-28 18:25:32 +0000
committermav <mav@FreeBSD.org>2016-10-28 18:25:32 +0000
commitc12394dc80b2b30e2c76deb5e0559fff9d3c57ac (patch)
tree5f44797268aed769b43b3764a0c95f7c55e4332b /sys/cddl/contrib/opensolaris/uts/common
parent748b013188753a4b409720c333b6786231ac801f (diff)
downloadFreeBSD-src-c12394dc80b2b30e2c76deb5e0559fff9d3c57ac.zip
FreeBSD-src-c12394dc80b2b30e2c76deb5e0559fff9d3c57ac.tar.gz
MFC r300881, r302058 (by asomers):
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
Diffstat (limited to 'sys/cddl/contrib/opensolaris/uts/common')
-rw-r--r--sys/cddl/contrib/opensolaris/uts/common/fs/zfs/vdev_geom.c63
1 files changed, 42 insertions, 21 deletions
diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/vdev_geom.c b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/vdev_geom.c
index 9ae07d1..fa38d08 100644
--- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/vdev_geom.c
+++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/vdev_geom.c
@@ -87,32 +87,17 @@ vdev_geom_set_rotation_rate(vdev_t *vd, struct g_consumer *cp)
}
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 = B_FALSE;
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);
@@ -124,12 +109,46 @@ vdev_geom_attrchanged(struct g_consumer *cp, const char *attr)
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
@@ -259,8 +278,10 @@ vdev_geom_attach(struct g_provider *pp, vdev_t *vd)
* 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);
OpenPOWER on IntegriCloud