summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPatrick Caulfield <pcaulfie@redhat.com>2007-01-22 14:51:33 +0000
committerSteven Whitehouse <swhiteho@redhat.com>2007-02-05 13:37:29 -0500
commitbd44e2b007bc9024bce3357c185b38c73f87c3dd (patch)
tree6359c8eb02e4cb1ce26dd8da88e1f032c187ec04
parentb5d32bead1578afc5ca817d40c320764d50a8600 (diff)
downloadlinux-bd44e2b007bc9024bce3357c185b38c73f87c3dd.tar.gz
linux-bd44e2b007bc9024bce3357c185b38c73f87c3dd.tar.bz2
linux-bd44e2b007bc9024bce3357c185b38c73f87c3dd.zip
[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.c24
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);
}