diff options
author | Patrick Caulfield <pcaulfie@redhat.com> | 2007-01-22 09:51:33 -0500 |
---|---|---|
committer | Steven Whitehouse <swhiteho@redhat.com> | 2007-02-05 13:37:29 -0500 |
commit | bd44e2b007bc9024bce3357c185b38c73f87c3dd (patch) | |
tree | 6359c8eb02e4cb1ce26dd8da88e1f032c187ec04 /fs | |
parent | b5d32bead1578afc5ca817d40c320764d50a8600 (diff) |
[DLM] fix lowcomms receiving
This patch fixes a bug whereby data on a newly accepted connection would be
ignored if it arrived soon after the accept.
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 | 24 |
1 files changed, 13 insertions, 11 deletions
diff --git a/fs/dlm/lowcomms-tcp.c b/fs/dlm/lowcomms-tcp.c index 6e27201f2f95..8e6a76cf1805 100644 --- a/fs/dlm/lowcomms-tcp.c +++ b/fs/dlm/lowcomms-tcp.c | |||
@@ -327,6 +327,9 @@ static int receive_from_sock(struct connection *con) | |||
327 | 327 | ||
328 | if (ret <= 0) | 328 | if (ret <= 0) |
329 | goto out_close; | 329 | goto out_close; |
330 | if (ret == -EAGAIN) | ||
331 | goto out_resched; | ||
332 | |||
330 | if (ret == len) | 333 | if (ret == len) |
331 | call_again_soon = 1; | 334 | call_again_soon = 1; |
332 | cbuf_add(&con->cb, ret); | 335 | cbuf_add(&con->cb, ret); |
@@ -359,8 +362,7 @@ out_resched: | |||
359 | if (!test_and_set_bit(CF_READ_PENDING, &con->flags)) | 362 | if (!test_and_set_bit(CF_READ_PENDING, &con->flags)) |
360 | queue_work(recv_workqueue, &con->rwork); | 363 | queue_work(recv_workqueue, &con->rwork); |
361 | up_read(&con->sock_sem); | 364 | up_read(&con->sock_sem); |
362 | cond_resched(); | 365 | return -EAGAIN; |
363 | return 0; | ||
364 | 366 | ||
365 | out_close: | 367 | out_close: |
366 | up_read(&con->sock_sem); | 368 | up_read(&con->sock_sem); |
@@ -381,6 +383,7 @@ static int accept_from_sock(struct connection *con) | |||
381 | int len; | 383 | int len; |
382 | int nodeid; | 384 | int nodeid; |
383 | struct connection *newcon; | 385 | struct connection *newcon; |
386 | struct connection *addcon; | ||
384 | 387 | ||
385 | memset(&peeraddr, 0, sizeof(peeraddr)); | 388 | memset(&peeraddr, 0, sizeof(peeraddr)); |
386 | result = sock_create_kern(dlm_local_addr.ss_family, SOCK_STREAM, | 389 | result = sock_create_kern(dlm_local_addr.ss_family, SOCK_STREAM, |
@@ -454,12 +457,13 @@ static int accept_from_sock(struct connection *con) | |||
454 | othercon->sock = newsock; | 457 | othercon->sock = newsock; |
455 | newsock->sk->sk_user_data = othercon; | 458 | newsock->sk->sk_user_data = othercon; |
456 | add_sock(newsock, othercon); | 459 | add_sock(newsock, othercon); |
460 | addcon = othercon; | ||
457 | } | 461 | } |
458 | else { | 462 | else { |
459 | newsock->sk->sk_user_data = newcon; | 463 | newsock->sk->sk_user_data = newcon; |
460 | newcon->rx_action = receive_from_sock; | 464 | newcon->rx_action = receive_from_sock; |
461 | add_sock(newsock, newcon); | 465 | add_sock(newsock, newcon); |
462 | 466 | addcon = newcon; | |
463 | } | 467 | } |
464 | 468 | ||
465 | up_write(&newcon->sock_sem); | 469 | up_write(&newcon->sock_sem); |
@@ -469,8 +473,8 @@ static int accept_from_sock(struct connection *con) | |||
469 | * beween processing the accept adding the socket | 473 | * beween processing the accept adding the socket |
470 | * to the read_sockets list | 474 | * to the read_sockets list |
471 | */ | 475 | */ |
472 | if (!test_and_set_bit(CF_READ_PENDING, &newcon->flags)) | 476 | if (!test_and_set_bit(CF_READ_PENDING, &addcon->flags)) |
473 | queue_work(recv_workqueue, &newcon->rwork); | 477 | queue_work(recv_workqueue, &addcon->rwork); |
474 | up_read(&con->sock_sem); | 478 | up_read(&con->sock_sem); |
475 | 479 | ||
476 | return 0; | 480 | return 0; |
@@ -610,8 +614,7 @@ static struct socket *create_listen_sock(struct connection *con, | |||
610 | 614 | ||
611 | result = sock->ops->listen(sock, 5); | 615 | result = sock->ops->listen(sock, 5); |
612 | if (result < 0) { | 616 | if (result < 0) { |
613 | printk("dlm: Can't listen on port %d\n", | 617 | printk("dlm: Can't listen on port %d\n", dlm_config.ci_tcp_port); |
614 | dlm_config.ci_tcp_port); | ||
615 | sock_release(sock); | 618 | sock_release(sock); |
616 | sock = NULL; | 619 | sock = NULL; |
617 | goto create_out; | 620 | goto create_out; |
@@ -811,7 +814,7 @@ send_error: | |||
811 | 814 | ||
812 | out_connect: | 815 | out_connect: |
813 | up_read(&con->sock_sem); | 816 | up_read(&con->sock_sem); |
814 | lowcomms_connect_sock(con); | 817 | connect_to_sock(con); |
815 | return; | 818 | return; |
816 | } | 819 | } |
817 | 820 | ||
@@ -873,9 +876,8 @@ static void process_send_sockets(struct work_struct *work) | |||
873 | connect_to_sock(con); | 876 | connect_to_sock(con); |
874 | } | 877 | } |
875 | 878 | ||
876 | if (test_and_clear_bit(CF_WRITE_PENDING, &con->flags)) { | 879 | clear_bit(CF_WRITE_PENDING, &con->flags); |
877 | send_to_sock(con); | 880 | send_to_sock(con); |
878 | } | ||
879 | } | 881 | } |
880 | 882 | ||
881 | 883 | ||