[PATCH v3 1/3] md-cluster: fix lock_comm leak and __sendmsg error path

From: ghuicao

Date: Thu Aug 27 2026 - 04:47:14 EST


From: Cao Guanghui <caoguanghui@xxxxxxxxxx>

Fix two error handling issues in cluster communication:

1. lock_comm() leaks MD_CLUSTER_SEND_LOCK if lock_token() fails.
The bit is set by test_and_set_bit but never cleared on error,
causing all subsequent cluster operations to hang permanently
in wait_event(). Clear the bit before returning the error.

2. __sendmsg() has two problems in the failed_ack cleanup path:
- ack_lockres is left in EX state if the down-conversion to CR
fails, causing a cluster-wide deadlock. Attempt to restore
it to CR and log if that also fails.
- The while loop for message_lockres unlock spins forever if
a previous DLM operation timed out and left a pending request
(dlm_unlock_sync returns -EBUSY immediately). Change to a
single attempt with error logging.

Fixes: 818da59f97d6 ("md-cluster: add the support for resize") (lock_comm)
Fixes: 601b515c5dcc ("Communication Framework: Sending functions") (__sendmsg)
Cc: stable@xxxxxxxxxxxxxxx
Signed-off-by: Cao Guanghui <caoguanghui@xxxxxxxxxx>
---
drivers/md/md-cluster.c | 15 ++++++++++++---
1 file changed, 12 insertions(+), 3 deletions(-)

diff --git a/drivers/md/md-cluster.c b/drivers/md/md-cluster.c
--- a/drivers/md/md-cluster.c
+++ b/drivers/md/md-cluster.c
@@ -735,6 +735,8 @@ static int lock_comm(struct md_cluster_info *cinfo, bool mddev_locked)
wait_event(cinfo->wait,
!test_and_set_bit(MD_CLUSTER_SEND_LOCK, &cinfo->state));
rv = lock_token(cinfo);
+ if (rv)
+ clear_bit_unlock(MD_CLUSTER_SEND_LOCK, &cinfo->state);
if (set_bit)
clear_bit_unlock(MD_CLUSTER_HOLDING_MUTEX_FOR_RECVD, &cinfo->state);
return rv;
@@ -801,7 +803,15 @@ static int __sendmsg(struct md_cluster_info *cinfo, struct cluster_msg *cmsg)
}

failed_ack:
- while ((unlock_error = dlm_unlock_sync(cinfo->message_lockres)))
+ if (error) {
+ int ack_ret = dlm_lock_sync(cinfo->ack_lockres, DLM_LOCK_CR);
+
+ if (ack_ret)
+ pr_err("md-cluster: failed to restore ACK to CR (%d)\n",
+ ack_ret);
+ }
+ unlock_error = dlm_unlock_sync(cinfo->message_lockres);
+ if (unlock_error)
pr_err("md-cluster: failed convert to NL on MESSAGE(%d)\n",
unlock_error);

--
2.34.1