diff options
author | Patrick Caulfield <pcaulfie@redhat.com> | 2007-01-24 06:17:59 -0500 |
---|---|---|
committer | Steven Whitehouse <swhiteho@redhat.com> | 2007-02-05 13:37:44 -0500 |
commit | f1f1c1ccf7848a6e25db30ee9216e1a1e7eb6bef (patch) | |
tree | 38b5f6ba90143ceea49c62fb824a7b46b1f03636 /fs | |
parent | d043e1900c97f7282b71844c8530279913b6ec5a (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>
Diffstat (limited to 'fs')
-rw-r--r-- | fs/dlm/lowcomms-tcp.c | 44 |
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) | |||
96 | struct connection { | 96 | struct 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 */ |
248 | static void close_connection(struct connection *con, bool and_other) | 248 | static 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) | |||
355 | out: | 355 | out: |
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 | ||
361 | out_resched: | 361 | out_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 | ||
367 | out_close: | 367 | out_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 | ||
482 | accept_err: | 482 | accept_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 | } |
555 | out: | 555 | out: |
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); |
805 | out: | 805 | out: |
806 | up_read(&con->sock_sem); | 806 | mutex_unlock(&con->sock_mutex); |
807 | return; | 807 | return; |
808 | 808 | ||
809 | send_error: | 809 | send_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 | ||
815 | out_connect: | 815 | out_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 | } |