}
list_add(&range->rn_list, &nodemap->nm_ranges);
- nm_member_reclassify_nodemap(config->nmc_default_nodemap);
+
+ /* nodemaps have no members if they aren't on the active config */
+ if (config == active_config)
+ nm_member_reclassify_nodemap(config->nmc_default_nodemap);
+
up_write(&config->nmc_range_tree_lock);
/* if range_id is non-zero, we are loading from disk */
if (range_id == 0)
rc = nodemap_idx_range_add(range, nid);
- nm_member_revoke_locks(config->nmc_default_nodemap);
- nm_member_revoke_locks(nodemap);
+ if (config == active_config) {
+ nm_member_revoke_locks(config->nmc_default_nodemap);
+ nm_member_revoke_locks(nodemap);
+ }
out:
return rc;
*/
list_for_each_entry_safe(nodemap, nodemap_temp, &nodemap_list_head,
nm_list) {
+ mutex_lock(&active_config_lock);
down_write(&config->nmc_range_tree_lock);
- /* move members to new config */
+ /* move members to new config, requires ac lock */
nm_member_reclassify_nodemap(nodemap);
list_for_each_entry_safe(range, range_temp, &nodemap->nm_ranges,
rn_list)
range_delete(&config->nmc_range_tree, range);
up_write(&config->nmc_range_tree_lock);
+ mutex_unlock(&active_config_lock);
+ /* putref must be outside of ac lock if nm could be destroyed */
nodemap_putref(nodemap);
}
OBD_FREE_PTR(config);
}
EXPORT_SYMBOL(nodemap_config_dealloc);
-static int nm_hash_list_cb(struct cfs_hash *hs, struct cfs_hash_bd *bd,
- struct hlist_node *hnode,
- void *nodemap_list_head)
+/*
+ * callback for cfs_hash_for_each_safe used to convert a nodemap hash to a
+ * nodemap list, generally for locking purposes as a hash cb can't sleep.
+ */
+int nm_hash_list_cb(struct cfs_hash *hs, struct cfs_hash_bd *bd,
+ struct hlist_node *hnode,
+ void *nodemap_list_head)
{
struct lu_nodemap *nodemap;
struct nodemap_config *old_config = active_config;
struct lu_nodemap *nodemap;
struct lu_nodemap *tmp;
+ bool revoke_locks;
LIST_HEAD(nodemap_list_head);
ENTRY;
}
}
+ /*
+ * We only need to revoke locks if old nodemap was active, and new
+ * config is now nodemap inactive. nodemap_config_dealloc will
+ * reclassify exports, triggering a lock revoke if and only if new
+ * nodemap is active.
+ */
+ revoke_locks = !config->nmc_nodemap_is_active && nodemap_active;
+
/* if new config is inactive, deactivate live config before switching */
if (!config->nmc_nodemap_is_active)
nodemap_active = false;
if (old_config != NULL)
nodemap_config_dealloc(old_config);
- nm_member_revoke_all();
+ if (revoke_locks)
+ nm_member_revoke_all();
EXIT;
}
/* revoke_locks sleeps, so can't call in cfs hash cb */
list_for_each_entry_safe(nodemap, tmp, &nodemap_list_head, nm_list)
- nm_member_revoke_locks(nodemap);
+ nm_member_revoke_locks_always(nodemap);
mutex_unlock(&active_config_lock);
}