Skip to content

Commit

Permalink
Serialize access to spa->spa_feat_stats nvlist
Browse files Browse the repository at this point in the history
The function spa_add_feature_stats() manipulates the shared nvlist
spa->spa_feat_stats in an unsafe concurrent manner. Add a mutex to
protect the list.

Signed-off-by: Ned Bass <[email protected]>
Signed-off-by: Brian Behlendorf <[email protected]>
Closes #3335
  • Loading branch information
nedbass committed Jun 23, 2015
1 parent 71fa174 commit 464c506
Show file tree
Hide file tree
Showing 3 changed files with 9 additions and 1 deletion.
1 change: 1 addition & 0 deletions include/sys/spa_impl.h
Original file line number Diff line number Diff line change
Expand Up @@ -236,6 +236,7 @@ struct spa {
uint64_t spa_feat_for_read_obj; /* required to read from pool */
uint64_t spa_feat_desc_obj; /* Feature descriptions */
uint64_t spa_feat_enabled_txg_obj; /* Feature enabled txg */
kmutex_t spa_feat_stats_lock; /* protects spa_feat_stats */
nvlist_t *spa_feat_stats; /* Cache of enabled features */
/* cache feature refcounts */
uint64_t spa_feat_refcount_cache[SPA_FEATURES];
Expand Down
7 changes: 6 additions & 1 deletion module/zfs/spa.c
Original file line number Diff line number Diff line change
Expand Up @@ -3264,10 +3264,13 @@ spa_feature_stats_from_cache(spa_t *spa, nvlist_t *features)
static void
spa_add_feature_stats(spa_t *spa, nvlist_t *config)
{
nvlist_t *features = spa->spa_feat_stats;
nvlist_t *features;

ASSERT(spa_config_held(spa, SCL_CONFIG, RW_READER));

mutex_enter(&spa->spa_feat_stats_lock);
features = spa->spa_feat_stats;

if (features != NULL) {
spa_feature_stats_from_cache(spa, features);
} else {
Expand All @@ -3278,6 +3281,8 @@ spa_add_feature_stats(spa_t *spa, nvlist_t *config)

VERIFY0(nvlist_add_nvlist(config, ZPOOL_CONFIG_FEATURE_STATS,
features));

mutex_exit(&spa->spa_feat_stats_lock);
}

int
Expand Down
2 changes: 2 additions & 0 deletions module/zfs/spa_misc.c
Original file line number Diff line number Diff line change
Expand Up @@ -531,6 +531,7 @@ spa_add(const char *name, nvlist_t *config, const char *altroot)
mutex_init(&spa->spa_scrub_lock, NULL, MUTEX_DEFAULT, NULL);
mutex_init(&spa->spa_suspend_lock, NULL, MUTEX_DEFAULT, NULL);
mutex_init(&spa->spa_vdev_top_lock, NULL, MUTEX_DEFAULT, NULL);
mutex_init(&spa->spa_feat_stats_lock, NULL, MUTEX_DEFAULT, NULL);

cv_init(&spa->spa_async_cv, NULL, CV_DEFAULT, NULL);
cv_init(&spa->spa_proc_cv, NULL, CV_DEFAULT, NULL);
Expand Down Expand Up @@ -668,6 +669,7 @@ spa_remove(spa_t *spa)
mutex_destroy(&spa->spa_scrub_lock);
mutex_destroy(&spa->spa_suspend_lock);
mutex_destroy(&spa->spa_vdev_top_lock);
mutex_destroy(&spa->spa_feat_stats_lock);

kmem_free(spa, sizeof (spa_t));
}
Expand Down

0 comments on commit 464c506

Please sign in to comment.