Skip to content

Commit

Permalink
DLM: fix race condition between dlm_send and dlm_recv
Browse files Browse the repository at this point in the history
When kernel_sendpage(in send_to_sock) and kernel_recvmsg
(in receive_from_sock) return error, close_connection may works at the
same time. At that time, they may wait for each other by cancel_work_sync.

Signed-off-by: Tadashi Miyauchi <[email protected]>
Signed-off-by: Tsutomu Owa <[email protected]>
Signed-off-by: David Teigland <[email protected]>
  • Loading branch information
[email protected] authored and teigland committed Sep 25, 2017
1 parent f0fb83c commit b2a6662
Showing 1 changed file with 6 additions and 2 deletions.
8 changes: 6 additions & 2 deletions fs/dlm/lowcomms.c
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,7 @@ struct connection {
#define CF_IS_OTHERCON 5
#define CF_CLOSE 6
#define CF_APP_LIMITED 7
#define CF_CLOSING 8
struct list_head writequeue; /* List of outgoing writequeue_entries */
spinlock_t writequeue_lock;
int (*rx_action) (struct connection *); /* What to do when active */
Expand Down Expand Up @@ -581,9 +582,11 @@ static void make_sockaddr(struct sockaddr_storage *saddr, uint16_t port,
static void close_connection(struct connection *con, bool and_other,
bool tx, bool rx)
{
if (tx && cancel_work_sync(&con->swork))
bool closing = test_and_set_bit(CF_CLOSING, &con->flags);

if (tx && !closing && cancel_work_sync(&con->swork))
log_print("canceled swork for node %d", con->nodeid);
if (rx && cancel_work_sync(&con->rwork))
if (rx && !closing && cancel_work_sync(&con->rwork))
log_print("canceled rwork for node %d", con->nodeid);

mutex_lock(&con->sock_mutex);
Expand All @@ -603,6 +606,7 @@ static void close_connection(struct connection *con, bool and_other,

con->retries = 0;
mutex_unlock(&con->sock_mutex);
clear_bit(CF_CLOSING, &con->flags);
}

/* Data received from remote end */
Expand Down

0 comments on commit b2a6662

Please sign in to comment.