+ struct obd_export *exp;
+ struct obd_export *tmp;
+ struct lu_nodemap *new_nodemap;
+
+ ENTRY;
+
+ mutex_lock(&nodemap->nm_member_list_lock);
+
+ list_for_each_entry_safe(exp, tmp, &nodemap->nm_member_list,
+ exp_target_data.ted_nodemap_member) {
+ lnet_nid_t nid;
+
+ /* if no conn assigned to this exp, reconnect will reclassify */
+ spin_lock(&exp->exp_lock);
+ if (exp->exp_connection) {
+ nid = exp->exp_connection->c_peer.nid;
+ } else {
+ spin_unlock(&exp->exp_lock);
+ continue;
+ }
+ spin_unlock(&exp->exp_lock);
+
+ /* nodemap_classify_nid requires nmc_range_tree_lock */
+ new_nodemap = nodemap_classify_nid(nid);
+ if (IS_ERR(new_nodemap))
+ continue;
+
+ if (new_nodemap != nodemap) {
+ /* could deadlock if new_nodemap also reclassifying,
+ * active_config_lock serializes reclassifies
+ */
+ mutex_lock(&new_nodemap->nm_member_list_lock);
+
+ /* don't use member_del because ted_nodemap
+ * should never be NULL with a live export
+ */
+ list_del_init(&exp->exp_target_data.ted_nodemap_member);
+
+ /* keep the new_nodemap ref from classify */
+ spin_lock(&exp->exp_target_data.ted_nodemap_lock);
+ exp->exp_target_data.ted_nodemap = new_nodemap;
+ spin_unlock(&exp->exp_target_data.ted_nodemap_lock);
+ nodemap_putref(nodemap);
+
+ list_add(&exp->exp_target_data.ted_nodemap_member,
+ &new_nodemap->nm_member_list);
+ mutex_unlock(&new_nodemap->nm_member_list_lock);
+
+ if (nodemap_active)
+ nm_member_exp_revoke(exp);
+ } else {
+ nodemap_putref(new_nodemap);
+ }
+ }
+ mutex_unlock(&nodemap->nm_member_list_lock);