RDS: Fix completion notifications on blocking sockets
authorAndy Grover <andy.grover@oracle.com>
Fri, 17 Jul 2009 13:13:32 +0000 (13:13 +0000)
committerDavid S. Miller <davem@davemloft.net>
Mon, 20 Jul 2009 15:03:12 +0000 (08:03 -0700)
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>
net/rds/recv.c

index f2118c5..86bc1a0 100644 (file)
@@ -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);