diff options
Diffstat (limited to 'net')
-rw-r--r-- | net/sunrpc/svc_xprt.c | 26 |
1 files changed, 14 insertions, 12 deletions
diff --git a/net/sunrpc/svc_xprt.c b/net/sunrpc/svc_xprt.c index a74cb67f15bf..dd61cd02461f 100644 --- a/net/sunrpc/svc_xprt.c +++ b/net/sunrpc/svc_xprt.c | |||
@@ -716,7 +716,10 @@ int svc_recv(struct svc_rqst *rqstp, long timeout) | |||
716 | if (test_bit(XPT_CLOSE, &xprt->xpt_flags)) { | 716 | if (test_bit(XPT_CLOSE, &xprt->xpt_flags)) { |
717 | dprintk("svc_recv: found XPT_CLOSE\n"); | 717 | dprintk("svc_recv: found XPT_CLOSE\n"); |
718 | svc_delete_xprt(xprt); | 718 | svc_delete_xprt(xprt); |
719 | } else if (test_bit(XPT_LISTENER, &xprt->xpt_flags)) { | 719 | /* Leave XPT_BUSY set on the dead xprt: */ |
720 | goto out; | ||
721 | } | ||
722 | if (test_bit(XPT_LISTENER, &xprt->xpt_flags)) { | ||
720 | struct svc_xprt *newxpt; | 723 | struct svc_xprt *newxpt; |
721 | newxpt = xprt->xpt_ops->xpo_accept(xprt); | 724 | newxpt = xprt->xpt_ops->xpo_accept(xprt); |
722 | if (newxpt) { | 725 | if (newxpt) { |
@@ -741,28 +744,23 @@ int svc_recv(struct svc_rqst *rqstp, long timeout) | |||
741 | spin_unlock_bh(&serv->sv_lock); | 744 | spin_unlock_bh(&serv->sv_lock); |
742 | svc_xprt_received(newxpt); | 745 | svc_xprt_received(newxpt); |
743 | } | 746 | } |
744 | svc_xprt_received(xprt); | ||
745 | } else { | 747 | } else { |
746 | dprintk("svc: server %p, pool %u, transport %p, inuse=%d\n", | 748 | dprintk("svc: server %p, pool %u, transport %p, inuse=%d\n", |
747 | rqstp, pool->sp_id, xprt, | 749 | rqstp, pool->sp_id, xprt, |
748 | atomic_read(&xprt->xpt_ref.refcount)); | 750 | atomic_read(&xprt->xpt_ref.refcount)); |
749 | rqstp->rq_deferred = svc_deferred_dequeue(xprt); | 751 | rqstp->rq_deferred = svc_deferred_dequeue(xprt); |
750 | if (rqstp->rq_deferred) { | 752 | if (rqstp->rq_deferred) |
751 | svc_xprt_received(xprt); | ||
752 | len = svc_deferred_recv(rqstp); | 753 | len = svc_deferred_recv(rqstp); |
753 | } else { | 754 | else |
754 | len = xprt->xpt_ops->xpo_recvfrom(rqstp); | 755 | len = xprt->xpt_ops->xpo_recvfrom(rqstp); |
755 | svc_xprt_received(xprt); | ||
756 | } | ||
757 | dprintk("svc: got len=%d\n", len); | 756 | dprintk("svc: got len=%d\n", len); |
758 | } | 757 | } |
758 | svc_xprt_received(xprt); | ||
759 | 759 | ||
760 | /* No data, incomplete (TCP) read, or accept() */ | 760 | /* No data, incomplete (TCP) read, or accept() */ |
761 | if (len == 0 || len == -EAGAIN) { | 761 | if (len == 0 || len == -EAGAIN) |
762 | rqstp->rq_res.len = 0; | 762 | goto out; |
763 | svc_xprt_release(rqstp); | 763 | |
764 | return -EAGAIN; | ||
765 | } | ||
766 | clear_bit(XPT_OLD, &xprt->xpt_flags); | 764 | clear_bit(XPT_OLD, &xprt->xpt_flags); |
767 | 765 | ||
768 | rqstp->rq_secure = svc_port_is_privileged(svc_addr(rqstp)); | 766 | rqstp->rq_secure = svc_port_is_privileged(svc_addr(rqstp)); |
@@ -771,6 +769,10 @@ int svc_recv(struct svc_rqst *rqstp, long timeout) | |||
771 | if (serv->sv_stats) | 769 | if (serv->sv_stats) |
772 | serv->sv_stats->netcnt++; | 770 | serv->sv_stats->netcnt++; |
773 | return len; | 771 | return len; |
772 | out: | ||
773 | rqstp->rq_res.len = 0; | ||
774 | svc_xprt_release(rqstp); | ||
775 | return -EAGAIN; | ||
774 | } | 776 | } |
775 | EXPORT_SYMBOL_GPL(svc_recv); | 777 | EXPORT_SYMBOL_GPL(svc_recv); |
776 | 778 | ||