fs: dlm: move sending fin message into state change handling
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: 489d8e559c
("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>
This commit is contained in:
parent
83c8cb2ba0
commit
e3df326f8c
@ -401,7 +401,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;
|
||||
|
||||
@ -503,8 +503,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:
|
||||
@ -547,12 +547,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 *
|
||||
@ -1286,11 +1280,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;
|
||||
@ -1306,12 +1300,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)
|
||||
@ -1342,6 +1330,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 */
|
||||
@ -1355,12 +1344,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,
|
||||
|
Loading…
Reference in New Issue
Block a user