Cleanup: spa vdev processing should check NULL pointers
The PVS Studio 2016 FreeBSD kernel report stated: \contrib\opensolaris\uts\common\fs\zfs\spa.c (1341): error V595: The 'spa->spa_spares.sav_vdevs' pointer was utilized before it was verified against nullptr. Check lines: 1341, 1342. \sys\cddl\contrib\opensolaris\uts\common\fs\zfs\spa.c (1355): error V595: The 'spa->spa_l2cache.sav_vdevs' pointer was utilized before it was verified against nullptr. Check lines: 1355, 1357. \sys\cddl\contrib\opensolaris\uts\common\fs\zfs\spa.c (1398): error V595: The 'spa->spa_spares.sav_vdevs' pointer was utilized before it was verified against nullptr. Check lines: 1398, 1408. \sys\cddl\contrib\opensolaris\uts\common\fs\zfs\spa.c (1583): error V595: The 'oldvdevs' pointer was utilized before it was verified against nullptr. Check lines: 1583, 1595. In practice, all of these uses were safe because a NULL pointer implied a 0 vdev count, which kept us from iterating over vdevs. However, rearranging the code to check the pointer first is not a terrible micro-optimization and makes it more readable, so let us do that. Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov> Reviewed-by: Brian Atkinson <batkinson@lanl.gov> Signed-off-by: Richard Yao <richard.yao@alumni.stonybrook.edu> Closes #14456
This commit is contained in:
parent
3a7d2a0ce0
commit
cfb49616cd
|
@ -1714,9 +1714,9 @@ spa_unload(spa_t *spa)
|
|||
*/
|
||||
spa_l2cache_drop(spa);
|
||||
|
||||
for (int i = 0; i < spa->spa_spares.sav_count; i++)
|
||||
vdev_free(spa->spa_spares.sav_vdevs[i]);
|
||||
if (spa->spa_spares.sav_vdevs) {
|
||||
for (int i = 0; i < spa->spa_spares.sav_count; i++)
|
||||
vdev_free(spa->spa_spares.sav_vdevs[i]);
|
||||
kmem_free(spa->spa_spares.sav_vdevs,
|
||||
spa->spa_spares.sav_count * sizeof (void *));
|
||||
spa->spa_spares.sav_vdevs = NULL;
|
||||
|
@ -1727,11 +1727,11 @@ spa_unload(spa_t *spa)
|
|||
}
|
||||
spa->spa_spares.sav_count = 0;
|
||||
|
||||
for (int i = 0; i < spa->spa_l2cache.sav_count; i++) {
|
||||
vdev_clear_stats(spa->spa_l2cache.sav_vdevs[i]);
|
||||
vdev_free(spa->spa_l2cache.sav_vdevs[i]);
|
||||
}
|
||||
if (spa->spa_l2cache.sav_vdevs) {
|
||||
for (int i = 0; i < spa->spa_l2cache.sav_count; i++) {
|
||||
vdev_clear_stats(spa->spa_l2cache.sav_vdevs[i]);
|
||||
vdev_free(spa->spa_l2cache.sav_vdevs[i]);
|
||||
}
|
||||
kmem_free(spa->spa_l2cache.sav_vdevs,
|
||||
spa->spa_l2cache.sav_count * sizeof (void *));
|
||||
spa->spa_l2cache.sav_vdevs = NULL;
|
||||
|
@ -1789,20 +1789,21 @@ spa_load_spares(spa_t *spa)
|
|||
/*
|
||||
* First, close and free any existing spare vdevs.
|
||||
*/
|
||||
for (i = 0; i < spa->spa_spares.sav_count; i++) {
|
||||
vd = spa->spa_spares.sav_vdevs[i];
|
||||
if (spa->spa_spares.sav_vdevs) {
|
||||
for (i = 0; i < spa->spa_spares.sav_count; i++) {
|
||||
vd = spa->spa_spares.sav_vdevs[i];
|
||||
|
||||
/* Undo the call to spa_activate() below */
|
||||
if ((tvd = spa_lookup_by_guid(spa, vd->vdev_guid,
|
||||
B_FALSE)) != NULL && tvd->vdev_isspare)
|
||||
spa_spare_remove(tvd);
|
||||
vdev_close(vd);
|
||||
vdev_free(vd);
|
||||
}
|
||||
/* Undo the call to spa_activate() below */
|
||||
if ((tvd = spa_lookup_by_guid(spa, vd->vdev_guid,
|
||||
B_FALSE)) != NULL && tvd->vdev_isspare)
|
||||
spa_spare_remove(tvd);
|
||||
vdev_close(vd);
|
||||
vdev_free(vd);
|
||||
}
|
||||
|
||||
if (spa->spa_spares.sav_vdevs)
|
||||
kmem_free(spa->spa_spares.sav_vdevs,
|
||||
spa->spa_spares.sav_count * sizeof (void *));
|
||||
}
|
||||
|
||||
if (spa->spa_spares.sav_config == NULL)
|
||||
nspares = 0;
|
||||
|
@ -2013,23 +2014,24 @@ out:
|
|||
/*
|
||||
* Purge vdevs that were dropped
|
||||
*/
|
||||
for (i = 0; i < oldnvdevs; i++) {
|
||||
uint64_t pool;
|
||||
if (oldvdevs) {
|
||||
for (i = 0; i < oldnvdevs; i++) {
|
||||
uint64_t pool;
|
||||
|
||||
vd = oldvdevs[i];
|
||||
if (vd != NULL) {
|
||||
ASSERT(vd->vdev_isl2cache);
|
||||
vd = oldvdevs[i];
|
||||
if (vd != NULL) {
|
||||
ASSERT(vd->vdev_isl2cache);
|
||||
|
||||
if (spa_l2cache_exists(vd->vdev_guid, &pool) &&
|
||||
pool != 0ULL && l2arc_vdev_present(vd))
|
||||
l2arc_remove_vdev(vd);
|
||||
vdev_clear_stats(vd);
|
||||
vdev_free(vd);
|
||||
if (spa_l2cache_exists(vd->vdev_guid, &pool) &&
|
||||
pool != 0ULL && l2arc_vdev_present(vd))
|
||||
l2arc_remove_vdev(vd);
|
||||
vdev_clear_stats(vd);
|
||||
vdev_free(vd);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (oldvdevs)
|
||||
kmem_free(oldvdevs, oldnvdevs * sizeof (void *));
|
||||
}
|
||||
|
||||
for (i = 0; i < sav->sav_count; i++)
|
||||
nvlist_free(l2cache[i]);
|
||||
|
|
Loading…
Reference in New Issue