diff options
author | Andy Grover <andy.grover@oracle.com> | 2009-07-17 13:13:32 +0000 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2009-07-20 08:03:12 -0700 |
commit | edacaeae52ade6cbb3a0704db32a9fb4a219dee3 (patch) | |
tree | cbc5792cba5b5b757e018570393f76466407c3f7 /net | |
parent | fdf6e6b4afd8a56fa58f70a3950bd7ea7fbaef5f (diff) |
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>
Diffstat (limited to 'net')
-rw-r--r-- | net/rds/recv.c | 24 |
1 files changed, 13 insertions, 11 deletions
diff --git a/net/rds/recv.c b/net/rds/recv.c index f2118c51cfa..86bc1a06ebb 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); |