diff options
author | Patrick Caulfield <pcaulfie@redhat.com> | 2007-01-22 17:51:33 +0300 |
---|---|---|
committer | Steven Whitehouse <swhiteho@redhat.com> | 2007-02-05 21:37:29 +0300 |
commit | bd44e2b007bc9024bce3357c185b38c73f87c3dd (patch) | |
tree | 6359c8eb02e4cb1ce26dd8da88e1f032c187ec04 /fs | |
parent | b5d32bead1578afc5ca817d40c320764d50a8600 (diff) | |
download | linux-bd44e2b007bc9024bce3357c185b38c73f87c3dd.tar.xz |
[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) if (ret <= 0) goto out_close; + if (ret == -EAGAIN) + goto out_resched; + if (ret == len) call_again_soon = 1; cbuf_add(&con->cb, ret); @@ -359,8 +362,7 @@ out_resched: if (!test_and_set_bit(CF_READ_PENDING, &con->flags)) queue_work(recv_workqueue, &con->rwork); up_read(&con->sock_sem); - cond_resched(); - return 0; + return -EAGAIN; out_close: up_read(&con->sock_sem); @@ -381,6 +383,7 @@ static int accept_from_sock(struct connection *con) int len; int nodeid; struct connection *newcon; + struct connection *addcon; memset(&peeraddr, 0, sizeof(peeraddr)); result = sock_create_kern(dlm_local_addr.ss_family, SOCK_STREAM, @@ -454,12 +457,13 @@ static int accept_from_sock(struct connection *con) othercon->sock = newsock; newsock->sk->sk_user_data = othercon; add_sock(newsock, othercon); + addcon = othercon; } else { newsock->sk->sk_user_data = newcon; newcon->rx_action = receive_from_sock; add_sock(newsock, newcon); - + addcon = newcon; } up_write(&newcon->sock_sem); @@ -469,8 +473,8 @@ static int accept_from_sock(struct connection *con) * beween processing the accept adding the socket * to the read_sockets list */ - if (!test_and_set_bit(CF_READ_PENDING, &newcon->flags)) - queue_work(recv_workqueue, &newcon->rwork); + if (!test_and_set_bit(CF_READ_PENDING, &addcon->flags)) + queue_work(recv_workqueue, &addcon->rwork); up_read(&con->sock_sem); return 0; @@ -610,8 +614,7 @@ static struct socket *create_listen_sock(struct connection *con, result = sock->ops->listen(sock, 5); if (result < 0) { - printk("dlm: Can't listen on port %d\n", - dlm_config.ci_tcp_port); + printk("dlm: Can't listen on port %d\n", dlm_config.ci_tcp_port); sock_release(sock); sock = NULL; goto create_out; @@ -811,7 +814,7 @@ send_error: out_connect: up_read(&con->sock_sem); - lowcomms_connect_sock(con); + connect_to_sock(con); return; } @@ -873,9 +876,8 @@ static void process_send_sockets(struct work_struct *work) connect_to_sock(con); } - if (test_and_clear_bit(CF_WRITE_PENDING, &con->flags)) { - send_to_sock(con); - } + clear_bit(CF_WRITE_PENDING, &con->flags); + send_to_sock(con); } |