]> git.proxmox.com Git - mirror_ubuntu-kernels.git/commitdiff
fs: dlm: move sending fin message into state change handling
authorAlexander Aring <aahringo@redhat.com>
Thu, 12 Jan 2023 22:10:36 +0000 (17:10 -0500)
committerAndrea Righi <andrea.righi@canonical.com>
Tue, 14 Mar 2023 15:47:22 +0000 (16:47 +0100)
BugLink: https://bugs.launchpad.net/bugs/2011425
commit a58496361802070996f9bd76e941d109c4a85ebd upstream.

This patch moves the send fin handling, which should appear in a specific
state change, into the state change handling while the per node
state_lock is held. I experienced issues with other messages because
we changed the state and a fin message was sent out in a different state.

Cc: stable@vger.kernel.org
Fixes: 489d8e559c65 ("fs: dlm: add reliable connection if reconnect")
Signed-off-by: Alexander Aring <aahringo@redhat.com>
Signed-off-by: David Teigland <teigland@redhat.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Signed-off-by: Andrea Righi <andrea.righi@canonical.com>
fs/dlm/midcomms.c

index 1fef99214204038be2d89feda4f09134bfd62f86..fd9f413cabcde3fde5ea2f488a4ad63afb110b05 100644 (file)
@@ -402,7 +402,7 @@ static int dlm_send_fin(struct midcomms_node *node,
        struct dlm_mhandle *mh;
        char *ppc;
 
-       mh = dlm_midcomms_get_mhandle(node->nodeid, mb_len, GFP_NOFS, &ppc);
+       mh = dlm_midcomms_get_mhandle(node->nodeid, mb_len, GFP_ATOMIC, &ppc);
        if (!mh)
                return -ENOMEM;
 
@@ -518,8 +518,8 @@ static void dlm_midcomms_receive_buffer(union dlm_packet *p,
                                        node->state = DLM_LAST_ACK;
                                        pr_debug("switch node %d to state %s case 1\n",
                                                 node->nodeid, dlm_state_str(node->state));
-                                       spin_unlock(&node->state_lock);
-                                       goto send_fin;
+                                       set_bit(DLM_NODE_FLAG_STOP_RX, &node->flags);
+                                       dlm_send_fin(node, dlm_pas_fin_ack_rcv);
                                }
                                break;
                        case DLM_FIN_WAIT1:
@@ -563,12 +563,6 @@ static void dlm_midcomms_receive_buffer(union dlm_packet *p,
                log_print_ratelimited("ignore dlm msg because seq mismatch, seq: %u, expected: %u, nodeid: %d",
                                      seq, node->seq_next, node->nodeid);
        }
-
-       return;
-
-send_fin:
-       set_bit(DLM_NODE_FLAG_STOP_RX, &node->flags);
-       dlm_send_fin(node, dlm_pas_fin_ack_rcv);
 }
 
 static struct midcomms_node *
@@ -1368,11 +1362,11 @@ void dlm_midcomms_remove_member(int nodeid)
                case DLM_CLOSE_WAIT:
                        /* passive shutdown DLM_LAST_ACK case 2 */
                        node->state = DLM_LAST_ACK;
-                       spin_unlock(&node->state_lock);
-
                        pr_debug("switch node %d to state %s case 2\n",
                                 node->nodeid, dlm_state_str(node->state));
-                       goto send_fin;
+                       set_bit(DLM_NODE_FLAG_STOP_RX, &node->flags);
+                       dlm_send_fin(node, dlm_pas_fin_ack_rcv);
+                       break;
                case DLM_LAST_ACK:
                        /* probably receive fin caught it, do nothing */
                        break;
@@ -1388,12 +1382,6 @@ void dlm_midcomms_remove_member(int nodeid)
        spin_unlock(&node->state_lock);
 
        srcu_read_unlock(&nodes_srcu, idx);
-       return;
-
-send_fin:
-       set_bit(DLM_NODE_FLAG_STOP_RX, &node->flags);
-       dlm_send_fin(node, dlm_pas_fin_ack_rcv);
-       srcu_read_unlock(&nodes_srcu, idx);
 }
 
 static void midcomms_node_release(struct rcu_head *rcu)
@@ -1425,6 +1413,7 @@ static void midcomms_shutdown(struct midcomms_node *node)
                node->state = DLM_FIN_WAIT1;
                pr_debug("switch node %d to state %s case 2\n",
                         node->nodeid, dlm_state_str(node->state));
+               dlm_send_fin(node, dlm_act_fin_ack_rcv);
                break;
        case DLM_CLOSED:
                /* we have what we want */
@@ -1438,12 +1427,8 @@ static void midcomms_shutdown(struct midcomms_node *node)
        }
        spin_unlock(&node->state_lock);
 
-       if (node->state == DLM_FIN_WAIT1) {
-               dlm_send_fin(node, dlm_act_fin_ack_rcv);
-
-               if (DLM_DEBUG_FENCE_TERMINATION)
-                       msleep(5000);
-       }
+       if (DLM_DEBUG_FENCE_TERMINATION)
+               msleep(5000);
 
        /* wait for other side dlm + fin */
        ret = wait_event_timeout(node->shutdown_wait,