Skip to content

Commit f5fe8d5

Browse files
Alexander Aringteigland
authored andcommitted
fs: dlm: fix race in mhandle deletion
This patch fixes a race between mhandle deletion in case of receiving an acknowledge and flush of all pending mhandle in cases of an timeout or resetting node states. Fixes: 489d8e5 ("fs: dlm: add reliable connection if reconnect") Reported-by: Guillaume Nault <[email protected]> Signed-off-by: Alexander Aring <[email protected]> Signed-off-by: David Teigland <[email protected]>
1 parent d10a0b8 commit f5fe8d5

File tree

1 file changed

+21
-14
lines changed

1 file changed

+21
-14
lines changed

fs/dlm/midcomms.c

Lines changed: 21 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -287,22 +287,26 @@ static void dlm_mhandle_release(struct rcu_head *rcu)
287287
kfree(mh);
288288
}
289289

290+
static void dlm_mhandle_delete(struct midcomms_node *node,
291+
struct dlm_mhandle *mh)
292+
{
293+
list_del_rcu(&mh->list);
294+
atomic_dec(&node->send_queue_cnt);
295+
call_rcu(&mh->rcu, dlm_mhandle_release);
296+
}
297+
290298
static void dlm_send_queue_flush(struct midcomms_node *node)
291299
{
292300
struct dlm_mhandle *mh;
293301

294302
pr_debug("flush midcomms send queue of node %d\n", node->nodeid);
295303

296304
rcu_read_lock();
305+
spin_lock(&node->send_queue_lock);
297306
list_for_each_entry_rcu(mh, &node->send_queue, list) {
298-
spin_lock(&node->send_queue_lock);
299-
list_del_rcu(&mh->list);
300-
spin_unlock(&node->send_queue_lock);
301-
302-
atomic_dec(&node->send_queue_cnt);
303-
304-
call_rcu(&mh->rcu, dlm_mhandle_release);
307+
dlm_mhandle_delete(node, mh);
305308
}
309+
spin_unlock(&node->send_queue_lock);
306310
rcu_read_unlock();
307311
}
308312

@@ -424,21 +428,24 @@ static void dlm_receive_ack(struct midcomms_node *node, uint32_t seq)
424428
rcu_read_lock();
425429
list_for_each_entry_rcu(mh, &node->send_queue, list) {
426430
if (before(mh->seq, seq)) {
427-
spin_lock(&node->send_queue_lock);
428-
list_del_rcu(&mh->list);
429-
spin_unlock(&node->send_queue_lock);
430-
431-
atomic_dec(&node->send_queue_cnt);
432-
433431
if (mh->ack_rcv)
434432
mh->ack_rcv(node);
433+
} else {
434+
/* send queue should be ordered */
435+
break;
436+
}
437+
}
435438

436-
call_rcu(&mh->rcu, dlm_mhandle_release);
439+
spin_lock(&node->send_queue_lock);
440+
list_for_each_entry_rcu(mh, &node->send_queue, list) {
441+
if (before(mh->seq, seq)) {
442+
dlm_mhandle_delete(node, mh);
437443
} else {
438444
/* send queue should be ordered */
439445
break;
440446
}
441447
}
448+
spin_unlock(&node->send_queue_lock);
442449
rcu_read_unlock();
443450
}
444451

0 commit comments

Comments
 (0)