VisionFive2 Linux kernel

StarFive Tech Linux Kernel for VisionFive (JH7110) boards (mirror)

More than 9999 Commits   33 Branches   55 Tags
author: tsutomu.owa@toshiba.co.jp <tsutomu.owa@toshiba.co.jp> 2017-09-12 08:55:50 +0000 committer: David Teigland <teigland@redhat.com> 2017-09-25 12:45:21 -0500 commit: b2a6662932c52304eee11323701f8a01aa110e37 parent: f0fb83cb9201a9f272f8ac771eed6b1e5745375c
Commit Summary:
DLM: fix race condition between dlm_send and dlm_recv
Diffstat:
1 file changed, 5 insertions, 2 deletions
diff --git a/fs/dlm/lowcomms.c b/fs/dlm/lowcomms.c
index 980c58befd53..420946dcb7ca 100644
--- a/fs/dlm/lowcomms.c
+++ b/fs/dlm/lowcomms.c
@@ -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 */
@@ -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);
@@ -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 */