svn commit: r338724 - head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs
Mark Johnston
markj at FreeBSD.org
Mon Sep 17 16:16:58 UTC 2018
Author: markj
Date: Mon Sep 17 16:16:57 2018
New Revision: 338724
URL: https://svnweb.freebsd.org/changeset/base/338724
Log:
Fix an nvpair leak in vdev_geom_read_config().
Also change the behaviour slightly: instead of freeing "config" if the
last nvlist doesn't pass the tests, return the last config that did pass
those tests. This matches the comment at the beginning of the function.
PR: 230704
Diagnosed by: avg
Reviewed by: asomers, avg
Tested by: Mark Martinec <Mark.Martinec at ijs.si>
Approved by: re (gjb)
MFC after: 1 week
Sponsored by: The FreeBSD Foundation
Differential revision: https://reviews.freebsd.org/D17202
Modified:
head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/vdev_geom.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 Mon Sep 17 15:53:29 2018 (r338723)
+++ head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/vdev_geom.c Mon Sep 17 16:16:57 2018 (r338724)
@@ -415,9 +415,10 @@ vdev_geom_io(struct g_consumer *cp, int *cmds, void **
* least one valid label was found.
*/
static int
-vdev_geom_read_config(struct g_consumer *cp, nvlist_t **config)
+vdev_geom_read_config(struct g_consumer *cp, nvlist_t **configp)
{
struct g_provider *pp;
+ nvlist_t *config;
vdev_phys_t *vdev_lists[VDEV_LABELS];
char *buf;
size_t buflen;
@@ -442,7 +443,6 @@ vdev_geom_read_config(struct g_consumer *cp, nvlist_t
buflen = sizeof(vdev_lists[0]->vp_nvlist);
- *config = NULL;
/* Create all of the IO requests */
for (l = 0; l < VDEV_LABELS; l++) {
cmds[l] = BIO_READ;
@@ -458,6 +458,7 @@ vdev_geom_read_config(struct g_consumer *cp, nvlist_t
VDEV_LABELS);
/* Parse the labels */
+ config = *configp = NULL;
nlabels = 0;
for (l = 0; l < VDEV_LABELS; l++) {
if (errors[l] != 0)
@@ -465,24 +466,26 @@ vdev_geom_read_config(struct g_consumer *cp, nvlist_t
buf = vdev_lists[l]->vp_nvlist;
- if (nvlist_unpack(buf, buflen, config, 0) != 0)
+ if (nvlist_unpack(buf, buflen, &config, 0) != 0)
continue;
- if (nvlist_lookup_uint64(*config, ZPOOL_CONFIG_POOL_STATE,
+ if (nvlist_lookup_uint64(config, ZPOOL_CONFIG_POOL_STATE,
&state) != 0 || state > POOL_STATE_L2CACHE) {
- nvlist_free(*config);
- *config = NULL;
+ nvlist_free(config);
continue;
}
if (state != POOL_STATE_SPARE &&
state != POOL_STATE_L2CACHE &&
- (nvlist_lookup_uint64(*config, ZPOOL_CONFIG_POOL_TXG,
+ (nvlist_lookup_uint64(config, ZPOOL_CONFIG_POOL_TXG,
&txg) != 0 || txg == 0)) {
- nvlist_free(*config);
- *config = NULL;
+ nvlist_free(config);
continue;
}
+
+ if (*configp != NULL)
+ nvlist_free(*configp);
+ *configp = config;
nlabels++;
}
More information about the svn-src-all
mailing list