+void nodemap_config_set_active(struct nodemap_config *config)
+{
+ struct nodemap_config *old_config = active_config;
+ struct lu_nodemap *nodemap;
+ struct lu_nodemap *tmp;
+ bool revoke_locks;
+ LIST_HEAD(nodemap_list_head);
+
+ ENTRY;
+
+ LASSERT(active_config != config);
+ LASSERT(config->nmc_default_nodemap);
+
+ mutex_lock(&active_config_lock);
+
+ /* move proc entries from already existing nms, create for new nms */
+ cfs_hash_for_each_safe(config->nmc_nodemap_hash,
+ nm_hash_list_cb, &nodemap_list_head);
+ list_for_each_entry_safe(nodemap, tmp, &nodemap_list_head, nm_list) {
+ struct lu_nodemap *old_nm = NULL;
+
+ if (active_config != NULL)
+ old_nm = cfs_hash_lookup(
+ active_config->nmc_nodemap_hash,
+ nodemap->nm_name);
+ if (old_nm != NULL) {
+ nodemap->nm_pde_data = old_nm->nm_pde_data;
+ old_nm->nm_pde_data = NULL;
+ nodemap_putref(old_nm);
+ } else {
+ bool is_def = (nodemap == config->nmc_default_nodemap);
+
+ lprocfs_nodemap_register(nodemap, is_def);
+ }
+ }
+
+ /*
+ * 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;
+ active_config = config;
+ if (config->nmc_nodemap_is_active)
+ nodemap_active = true;
+
+ mutex_unlock(&active_config_lock);
+
+ if (old_config != NULL)
+ nodemap_config_dealloc(old_config);
+
+ if (revoke_locks)
+ nm_member_revoke_all();
+
+ EXIT;
+}
+
+/**
+ * Cleanup nodemap module on exit
+ */
+void nodemap_mod_exit(void)
+{
+ nodemap_config_dealloc(active_config);
+ nodemap_procfs_exit();
+}
+
+/**
+ * Initialize the nodemap module
+ */
+int nodemap_mod_init(void)
+{
+ struct nodemap_config *new_config;
+ struct lu_nodemap *nodemap;
+ int rc = 0;
+
+ rc = nodemap_procfs_init();
+ if (rc != 0)
+ return rc;
+
+ new_config = nodemap_config_alloc();
+ if (IS_ERR(new_config)) {
+ nodemap_procfs_exit();
+ GOTO(out, rc = PTR_ERR(new_config));
+ }
+
+ nodemap = nodemap_create(DEFAULT_NODEMAP, new_config, 1);
+ if (IS_ERR(nodemap)) {
+ nodemap_config_dealloc(new_config);
+ nodemap_procfs_exit();
+ GOTO(out, rc = PTR_ERR(nodemap));
+ }
+
+ nodemap_config_set_active(new_config);
+ nodemap_putref(nodemap);
+
+out:
+ return rc;
+}
+