summaryrefslogtreecommitdiff
path: root/fs/dlm/midcomms.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/dlm/midcomms.c')
-rw-r--r--fs/dlm/midcomms.c39
1 files changed, 32 insertions, 7 deletions
diff --git a/fs/dlm/midcomms.c b/fs/dlm/midcomms.c
index f641b36a36db..2247ebb61be1 100644
--- a/fs/dlm/midcomms.c
+++ b/fs/dlm/midcomms.c
@@ -337,13 +337,21 @@ static struct midcomms_node *nodeid2node(int nodeid)
int dlm_midcomms_addr(int nodeid, struct sockaddr_storage *addr, int len)
{
- int ret, r = nodeid_hash(nodeid);
+ int ret, idx, r = nodeid_hash(nodeid);
struct midcomms_node *node;
ret = dlm_lowcomms_addr(nodeid, addr, len);
if (ret)
return ret;
+ idx = srcu_read_lock(&nodes_srcu);
+ node = __find_node(nodeid, r);
+ if (node) {
+ srcu_read_unlock(&nodes_srcu, idx);
+ return 0;
+ }
+ srcu_read_unlock(&nodes_srcu, idx);
+
node = kmalloc(sizeof(*node), GFP_NOFS);
if (!node)
return -ENOMEM;
@@ -1030,15 +1038,15 @@ struct dlm_mhandle *dlm_midcomms_get_mhandle(int nodeid, int len,
break;
case DLM_VERSION_3_2:
+ /* send ack back if necessary */
+ dlm_send_ack_threshold(node, DLM_SEND_ACK_BACK_MSG_THRESHOLD);
+
msg = dlm_midcomms_get_msg_3_2(mh, nodeid, len, allocation,
ppc);
if (!msg) {
dlm_free_mhandle(mh);
goto err;
}
-
- /* send ack back if necessary */
- dlm_send_ack_threshold(node, DLM_SEND_ACK_BACK_MSG_THRESHOLD);
break;
default:
dlm_free_mhandle(mh);
@@ -1260,12 +1268,23 @@ void dlm_midcomms_remove_member(int nodeid)
idx = srcu_read_lock(&nodes_srcu);
node = nodeid2node(nodeid);
- if (WARN_ON_ONCE(!node)) {
+ /* in case of dlm_midcomms_close() removes node */
+ if (!node) {
srcu_read_unlock(&nodes_srcu, idx);
return;
}
spin_lock(&node->state_lock);
+ /* case of dlm_midcomms_addr() created node but
+ * was not added before because dlm_midcomms_close()
+ * removed the node
+ */
+ if (!node->users) {
+ spin_unlock(&node->state_lock);
+ srcu_read_unlock(&nodes_srcu, idx);
+ return;
+ }
+
node->users--;
pr_debug("node %d users dec count %d\n", nodeid, node->users);
@@ -1386,10 +1405,16 @@ void dlm_midcomms_shutdown(void)
midcomms_shutdown(node);
}
}
- srcu_read_unlock(&nodes_srcu, idx);
- mutex_unlock(&close_lock);
dlm_lowcomms_shutdown();
+
+ for (i = 0; i < CONN_HASH_SIZE; i++) {
+ hlist_for_each_entry_rcu(node, &node_hash[i], hlist) {
+ midcomms_node_reset(node);
+ }
+ }
+ srcu_read_unlock(&nodes_srcu, idx);
+ mutex_unlock(&close_lock);
}
int dlm_midcomms_close(int nodeid)