aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPatrick Caulfield <pcaulfie@redhat.com>2007-01-24 06:17:59 -0500
committerSteven Whitehouse <swhiteho@redhat.com>2007-02-05 13:37:44 -0500
commitf1f1c1ccf7848a6e25db30ee9216e1a1e7eb6bef (patch)
tree38b5f6ba90143ceea49c62fb824a7b46b1f03636
parentd043e1900c97f7282b71844c8530279913b6ec5a (diff)
[DLM] Make sock_sem into a mutex
Now that there can be multiple dlm_recv threads running we need to prevent two recvs running for the same connection - it's unlikely but it can happen and it causes message corruption. Signed-Off-By: Patrick Caulfield <pcaulfie@redhat.com> Signed-off-by: Steven Whitehouse <swhiteho@redhat.com>
-rw-r--r--fs/dlm/lowcomms-tcp.c44
1 files changed, 22 insertions, 22 deletions
diff --git a/fs/dlm/lowcomms-tcp.c b/fs/dlm/lowcomms-tcp.c
index 8e6a76cf1805..18ade44287e7 100644
--- a/fs/dlm/lowcomms-tcp.c
+++ b/fs/dlm/lowcomms-tcp.c
@@ -96,7 +96,7 @@ static bool cbuf_empty(struct cbuf *cb)
96struct connection { 96struct connection {
97 struct socket *sock; /* NULL if not connected */ 97 struct socket *sock; /* NULL if not connected */
98 uint32_t nodeid; /* So we know who we are in the list */ 98 uint32_t nodeid; /* So we know who we are in the list */
99 struct rw_semaphore sock_sem; /* Stop connect races */ 99 struct mutex sock_mutex;
100 unsigned long flags; /* bit 1,2 = We are on the read/write lists */ 100 unsigned long flags; /* bit 1,2 = We are on the read/write lists */
101#define CF_READ_PENDING 1 101#define CF_READ_PENDING 1
102#define CF_WRITE_PENDING 2 102#define CF_WRITE_PENDING 2
@@ -171,7 +171,7 @@ static struct connection *nodeid2con(int nodeid, gfp_t allocation)
171 goto finish; 171 goto finish;
172 172
173 con->nodeid = nodeid; 173 con->nodeid = nodeid;
174 init_rwsem(&con->sock_sem); 174 mutex_init(&con->sock_mutex);
175 INIT_LIST_HEAD(&con->writequeue); 175 INIT_LIST_HEAD(&con->writequeue);
176 spin_lock_init(&con->writequeue_lock); 176 spin_lock_init(&con->writequeue_lock);
177 INIT_WORK(&con->swork, process_send_sockets); 177 INIT_WORK(&con->swork, process_send_sockets);
@@ -247,7 +247,7 @@ static void make_sockaddr(struct sockaddr_storage *saddr, uint16_t port,
247/* Close a remote connection and tidy up */ 247/* Close a remote connection and tidy up */
248static void close_connection(struct connection *con, bool and_other) 248static void close_connection(struct connection *con, bool and_other)
249{ 249{
250 down_write(&con->sock_sem); 250 mutex_lock(&con->sock_mutex);
251 251
252 if (con->sock) { 252 if (con->sock) {
253 sock_release(con->sock); 253 sock_release(con->sock);
@@ -262,7 +262,7 @@ static void close_connection(struct connection *con, bool and_other)
262 con->rx_page = NULL; 262 con->rx_page = NULL;
263 } 263 }
264 con->retries = 0; 264 con->retries = 0;
265 up_write(&con->sock_sem); 265 mutex_unlock(&con->sock_mutex);
266} 266}
267 267
268/* Data received from remote end */ 268/* Data received from remote end */
@@ -276,7 +276,7 @@ static int receive_from_sock(struct connection *con)
276 int r; 276 int r;
277 int call_again_soon = 0; 277 int call_again_soon = 0;
278 278
279 down_read(&con->sock_sem); 279 mutex_lock(&con->sock_mutex);
280 280
281 if (con->sock == NULL) 281 if (con->sock == NULL)
282 goto out; 282 goto out;
@@ -355,17 +355,17 @@ static int receive_from_sock(struct connection *con)
355out: 355out:
356 if (call_again_soon) 356 if (call_again_soon)
357 goto out_resched; 357 goto out_resched;
358 up_read(&con->sock_sem); 358 mutex_unlock(&con->sock_mutex);
359 return 0; 359 return 0;
360 360
361out_resched: 361out_resched:
362 if (!test_and_set_bit(CF_READ_PENDING, &con->flags)) 362 if (!test_and_set_bit(CF_READ_PENDING, &con->flags))
363 queue_work(recv_workqueue, &con->rwork); 363 queue_work(recv_workqueue, &con->rwork);
364 up_read(&con->sock_sem); 364 mutex_unlock(&con->sock_mutex);
365 return -EAGAIN; 365 return -EAGAIN;
366 366
367out_close: 367out_close:
368 up_read(&con->sock_sem); 368 mutex_unlock(&con->sock_mutex);
369 if (ret != -EAGAIN && !test_bit(CF_IS_OTHERCON, &con->flags)) { 369 if (ret != -EAGAIN && !test_bit(CF_IS_OTHERCON, &con->flags)) {
370 close_connection(con, false); 370 close_connection(con, false);
371 /* Reconnect when there is something to send */ 371 /* Reconnect when there is something to send */
@@ -391,7 +391,7 @@ static int accept_from_sock(struct connection *con)
391 if (result < 0) 391 if (result < 0)
392 return -ENOMEM; 392 return -ENOMEM;
393 393
394 down_read_nested(&con->sock_sem, 0); 394 mutex_lock_nested(&con->sock_mutex, 0);
395 395
396 result = -ENOTCONN; 396 result = -ENOTCONN;
397 if (con->sock == NULL) 397 if (con->sock == NULL)
@@ -417,7 +417,7 @@ static int accept_from_sock(struct connection *con)
417 if (dlm_addr_to_nodeid(&peeraddr, &nodeid)) { 417 if (dlm_addr_to_nodeid(&peeraddr, &nodeid)) {
418 printk("dlm: connect from non cluster node\n"); 418 printk("dlm: connect from non cluster node\n");
419 sock_release(newsock); 419 sock_release(newsock);
420 up_read(&con->sock_sem); 420 mutex_unlock(&con->sock_mutex);
421 return -1; 421 return -1;
422 } 422 }
423 423
@@ -434,7 +434,7 @@ static int accept_from_sock(struct connection *con)
434 result = -ENOMEM; 434 result = -ENOMEM;
435 goto accept_err; 435 goto accept_err;
436 } 436 }
437 down_write_nested(&newcon->sock_sem, 1); 437 mutex_lock_nested(&newcon->sock_mutex, 1);
438 if (newcon->sock) { 438 if (newcon->sock) {
439 struct connection *othercon = newcon->othercon; 439 struct connection *othercon = newcon->othercon;
440 440
@@ -442,13 +442,13 @@ static int accept_from_sock(struct connection *con)
442 othercon = kmem_cache_zalloc(con_cache, GFP_KERNEL); 442 othercon = kmem_cache_zalloc(con_cache, GFP_KERNEL);
443 if (!othercon) { 443 if (!othercon) {
444 printk("dlm: failed to allocate incoming socket\n"); 444 printk("dlm: failed to allocate incoming socket\n");
445 up_write(&newcon->sock_sem); 445 mutex_unlock(&newcon->sock_mutex);
446 result = -ENOMEM; 446 result = -ENOMEM;
447 goto accept_err; 447 goto accept_err;
448 } 448 }
449 othercon->nodeid = nodeid; 449 othercon->nodeid = nodeid;
450 othercon->rx_action = receive_from_sock; 450 othercon->rx_action = receive_from_sock;
451 init_rwsem(&othercon->sock_sem); 451 mutex_init(&othercon->sock_mutex);
452 INIT_WORK(&othercon->swork, process_send_sockets); 452 INIT_WORK(&othercon->swork, process_send_sockets);
453 INIT_WORK(&othercon->rwork, process_recv_sockets); 453 INIT_WORK(&othercon->rwork, process_recv_sockets);
454 set_bit(CF_IS_OTHERCON, &othercon->flags); 454 set_bit(CF_IS_OTHERCON, &othercon->flags);
@@ -466,7 +466,7 @@ static int accept_from_sock(struct connection *con)
466 addcon = newcon; 466 addcon = newcon;
467 } 467 }
468 468
469 up_write(&newcon->sock_sem); 469 mutex_unlock(&newcon->sock_mutex);
470 470
471 /* 471 /*
472 * Add it to the active queue in case we got data 472 * Add it to the active queue in case we got data
@@ -475,12 +475,12 @@ static int accept_from_sock(struct connection *con)
475 */ 475 */
476 if (!test_and_set_bit(CF_READ_PENDING, &addcon->flags)) 476 if (!test_and_set_bit(CF_READ_PENDING, &addcon->flags))
477 queue_work(recv_workqueue, &addcon->rwork); 477 queue_work(recv_workqueue, &addcon->rwork);
478 up_read(&con->sock_sem); 478 mutex_unlock(&con->sock_mutex);
479 479
480 return 0; 480 return 0;
481 481
482accept_err: 482accept_err:
483 up_read(&con->sock_sem); 483 mutex_unlock(&con->sock_mutex);
484 sock_release(newsock); 484 sock_release(newsock);
485 485
486 if (result != -EAGAIN) 486 if (result != -EAGAIN)
@@ -501,7 +501,7 @@ static void connect_to_sock(struct connection *con)
501 return; 501 return;
502 } 502 }
503 503
504 down_write(&con->sock_sem); 504 mutex_lock(&con->sock_mutex);
505 if (con->retries++ > MAX_CONNECT_RETRIES) 505 if (con->retries++ > MAX_CONNECT_RETRIES)
506 goto out; 506 goto out;
507 507
@@ -553,7 +553,7 @@ out_err:
553 result = 0; 553 result = 0;
554 } 554 }
555out: 555out:
556 up_write(&con->sock_sem); 556 mutex_unlock(&con->sock_mutex);
557 return; 557 return;
558} 558}
559 559
@@ -757,7 +757,7 @@ static void send_to_sock(struct connection *con)
757 struct writequeue_entry *e; 757 struct writequeue_entry *e;
758 int len, offset; 758 int len, offset;
759 759
760 down_read(&con->sock_sem); 760 mutex_lock(&con->sock_mutex);
761 if (con->sock == NULL) 761 if (con->sock == NULL)
762 goto out_connect; 762 goto out_connect;
763 763
@@ -803,17 +803,17 @@ static void send_to_sock(struct connection *con)
803 } 803 }
804 spin_unlock(&con->writequeue_lock); 804 spin_unlock(&con->writequeue_lock);
805out: 805out:
806 up_read(&con->sock_sem); 806 mutex_unlock(&con->sock_mutex);
807 return; 807 return;
808 808
809send_error: 809send_error:
810 up_read(&con->sock_sem); 810 mutex_unlock(&con->sock_mutex);
811 close_connection(con, false); 811 close_connection(con, false);
812 lowcomms_connect_sock(con); 812 lowcomms_connect_sock(con);
813 return; 813 return;
814 814
815out_connect: 815out_connect:
816 up_read(&con->sock_sem); 816 mutex_unlock(&con->sock_mutex);
817 connect_to_sock(con); 817 connect_to_sock(con);
818 return; 818 return;
819} 819}