Commit a5849636 authored by Alexander Aring's avatar Alexander Aring Committed by David Teigland
Browse files

fs: dlm: move sending fin message into state change handling



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: 489d8e55 ("fs: dlm: add reliable connection if reconnect")
Signed-off-by: default avatarAlexander Aring <aahringo@redhat.com>
Signed-off-by: default avatarDavid Teigland <teigland@redhat.com>
parent 15c63db8
Loading
Loading
Loading
Loading
+9 −24
Original line number Diff line number Diff line
@@ -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);
	}

	/* wait for other side dlm + fin */
	ret = wait_event_timeout(node->shutdown_wait,