summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAndy Grover <andy.grover@oracle.com>2009-07-17 15:13:32 +0200
committerDavid S. Miller <davem@davemloft.net>2009-07-20 17:03:12 +0200
commitedacaeae52ade6cbb3a0704db32a9fb4a219dee3 (patch)
treecbc5792cba5b5b757e018570393f76466407c3f7
parentRDS/IB: Drop connection when a fatal QP event is received (diff)
downloadlinux-edacaeae52ade6cbb3a0704db32a9fb4a219dee3.tar.xz
linux-edacaeae52ade6cbb3a0704db32a9fb4a219dee3.zip
RDS: Fix completion notifications on blocking sockets
Completion or congestion notifications were not being checked if the socket went to sleep. This patch fixes that. Signed-off-by: Andy Grover <andy.grover@oracle.com> Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--net/rds/recv.c24
1 files changed, 13 insertions, 11 deletions
diff --git a/net/rds/recv.c b/net/rds/recv.c
index f2118c51cfa3..86bc1a06ebbd 100644
--- a/net/rds/recv.c
+++ b/net/rds/recv.c
@@ -409,18 +409,18 @@ int rds_recvmsg(struct kiocb *iocb, struct socket *sock, struct msghdr *msg,
if (msg_flags & MSG_OOB)
goto out;
- /* If there are pending notifications, do those - and nothing else */
- if (!list_empty(&rs->rs_notify_queue)) {
- ret = rds_notify_queue_get(rs, msg);
- goto out;
- }
+ while (1) {
+ /* If there are pending notifications, do those - and nothing else */
+ if (!list_empty(&rs->rs_notify_queue)) {
+ ret = rds_notify_queue_get(rs, msg);
+ break;
+ }
- if (rs->rs_cong_notify) {
- ret = rds_notify_cong(rs, msg);
- goto out;
- }
+ if (rs->rs_cong_notify) {
+ ret = rds_notify_cong(rs, msg);
+ break;
+ }
- while (1) {
if (!rds_next_incoming(rs, &inc)) {
if (nonblock) {
ret = -EAGAIN;
@@ -428,7 +428,9 @@ int rds_recvmsg(struct kiocb *iocb, struct socket *sock, struct msghdr *msg,
}
timeo = wait_event_interruptible_timeout(*sk->sk_sleep,
- rds_next_incoming(rs, &inc),
+ (!list_empty(&rs->rs_notify_queue)
+ || rs->rs_cong_notify
+ || rds_next_incoming(rs, &inc)),
timeo);
rdsdebug("recvmsg woke inc %p timeo %ld\n", inc,
timeo);