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 | |
| 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>
| -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 | ||
