aboutsummaryrefslogtreecommitdiffstats
path: root/net/sunrpc/xprt.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/sunrpc/xprt.c')
-rw-r--r--net/sunrpc/xprt.c71
1 files changed, 57 insertions, 14 deletions
diff --git a/net/sunrpc/xprt.c b/net/sunrpc/xprt.c
index c74a6bb94074..eca92405948f 100644
--- a/net/sunrpc/xprt.c
+++ b/net/sunrpc/xprt.c
@@ -569,8 +569,11 @@ void xprt_connect(struct rpc_task *task)
569 if (xprt->sock != NULL) 569 if (xprt->sock != NULL)
570 schedule_delayed_work(&xprt->sock_connect, 570 schedule_delayed_work(&xprt->sock_connect,
571 RPC_REESTABLISH_TIMEOUT); 571 RPC_REESTABLISH_TIMEOUT);
572 else 572 else {
573 schedule_work(&xprt->sock_connect); 573 schedule_work(&xprt->sock_connect);
574 if (!RPC_IS_ASYNC(task))
575 flush_scheduled_work();
576 }
574 } 577 }
575 return; 578 return;
576 out_write: 579 out_write:
@@ -725,7 +728,8 @@ csum_partial_copy_to_xdr(struct xdr_buf *xdr, struct sk_buff *skb)
725 goto no_checksum; 728 goto no_checksum;
726 729
727 desc.csum = csum_partial(skb->data, desc.offset, skb->csum); 730 desc.csum = csum_partial(skb->data, desc.offset, skb->csum);
728 xdr_partial_copy_from_skb(xdr, 0, &desc, skb_read_and_csum_bits); 731 if (xdr_partial_copy_from_skb(xdr, 0, &desc, skb_read_and_csum_bits) < 0)
732 return -1;
729 if (desc.offset != skb->len) { 733 if (desc.offset != skb->len) {
730 unsigned int csum2; 734 unsigned int csum2;
731 csum2 = skb_checksum(skb, desc.offset, skb->len - desc.offset, 0); 735 csum2 = skb_checksum(skb, desc.offset, skb->len - desc.offset, 0);
@@ -737,7 +741,8 @@ csum_partial_copy_to_xdr(struct xdr_buf *xdr, struct sk_buff *skb)
737 return -1; 741 return -1;
738 return 0; 742 return 0;
739no_checksum: 743no_checksum:
740 xdr_partial_copy_from_skb(xdr, 0, &desc, skb_read_bits); 744 if (xdr_partial_copy_from_skb(xdr, 0, &desc, skb_read_bits) < 0)
745 return -1;
741 if (desc.count) 746 if (desc.count)
742 return -1; 747 return -1;
743 return 0; 748 return 0;
@@ -821,10 +826,15 @@ tcp_copy_data(skb_reader_t *desc, void *p, size_t len)
821{ 826{
822 if (len > desc->count) 827 if (len > desc->count)
823 len = desc->count; 828 len = desc->count;
824 if (skb_copy_bits(desc->skb, desc->offset, p, len)) 829 if (skb_copy_bits(desc->skb, desc->offset, p, len)) {
830 dprintk("RPC: failed to copy %zu bytes from skb. %zu bytes remain\n",
831 len, desc->count);
825 return 0; 832 return 0;
833 }
826 desc->offset += len; 834 desc->offset += len;
827 desc->count -= len; 835 desc->count -= len;
836 dprintk("RPC: copied %zu bytes from skb. %zu bytes remain\n",
837 len, desc->count);
828 return len; 838 return len;
829} 839}
830 840
@@ -863,6 +873,8 @@ tcp_read_fraghdr(struct rpc_xprt *xprt, skb_reader_t *desc)
863static void 873static void
864tcp_check_recm(struct rpc_xprt *xprt) 874tcp_check_recm(struct rpc_xprt *xprt)
865{ 875{
876 dprintk("RPC: xprt = %p, tcp_copied = %lu, tcp_offset = %u, tcp_reclen = %u, tcp_flags = %lx\n",
877 xprt, xprt->tcp_copied, xprt->tcp_offset, xprt->tcp_reclen, xprt->tcp_flags);
866 if (xprt->tcp_offset == xprt->tcp_reclen) { 878 if (xprt->tcp_offset == xprt->tcp_reclen) {
867 xprt->tcp_flags |= XPRT_COPY_RECM; 879 xprt->tcp_flags |= XPRT_COPY_RECM;
868 xprt->tcp_offset = 0; 880 xprt->tcp_offset = 0;
@@ -907,6 +919,7 @@ tcp_read_request(struct rpc_xprt *xprt, skb_reader_t *desc)
907 struct rpc_rqst *req; 919 struct rpc_rqst *req;
908 struct xdr_buf *rcvbuf; 920 struct xdr_buf *rcvbuf;
909 size_t len; 921 size_t len;
922 ssize_t r;
910 923
911 /* Find and lock the request corresponding to this xid */ 924 /* Find and lock the request corresponding to this xid */
912 spin_lock(&xprt->sock_lock); 925 spin_lock(&xprt->sock_lock);
@@ -927,15 +940,40 @@ tcp_read_request(struct rpc_xprt *xprt, skb_reader_t *desc)
927 len = xprt->tcp_reclen - xprt->tcp_offset; 940 len = xprt->tcp_reclen - xprt->tcp_offset;
928 memcpy(&my_desc, desc, sizeof(my_desc)); 941 memcpy(&my_desc, desc, sizeof(my_desc));
929 my_desc.count = len; 942 my_desc.count = len;
930 xdr_partial_copy_from_skb(rcvbuf, xprt->tcp_copied, 943 r = xdr_partial_copy_from_skb(rcvbuf, xprt->tcp_copied,
931 &my_desc, tcp_copy_data); 944 &my_desc, tcp_copy_data);
932 desc->count -= len; 945 desc->count -= r;
933 desc->offset += len; 946 desc->offset += r;
934 } else 947 } else
935 xdr_partial_copy_from_skb(rcvbuf, xprt->tcp_copied, 948 r = xdr_partial_copy_from_skb(rcvbuf, xprt->tcp_copied,
936 desc, tcp_copy_data); 949 desc, tcp_copy_data);
937 xprt->tcp_copied += len; 950
938 xprt->tcp_offset += len; 951 if (r > 0) {
952 xprt->tcp_copied += r;
953 xprt->tcp_offset += r;
954 }
955 if (r != len) {
956 /* Error when copying to the receive buffer,
957 * usually because we weren't able to allocate
958 * additional buffer pages. All we can do now
959 * is turn off XPRT_COPY_DATA, so the request
960 * will not receive any additional updates,
961 * and time out.
962 * Any remaining data from this record will
963 * be discarded.
964 */
965 xprt->tcp_flags &= ~XPRT_COPY_DATA;
966 dprintk("RPC: XID %08x truncated request\n",
967 ntohl(xprt->tcp_xid));
968 dprintk("RPC: xprt = %p, tcp_copied = %lu, tcp_offset = %u, tcp_reclen = %u\n",
969 xprt, xprt->tcp_copied, xprt->tcp_offset, xprt->tcp_reclen);
970 goto out;
971 }
972
973 dprintk("RPC: XID %08x read %u bytes\n",
974 ntohl(xprt->tcp_xid), r);
975 dprintk("RPC: xprt = %p, tcp_copied = %lu, tcp_offset = %u, tcp_reclen = %u\n",
976 xprt, xprt->tcp_copied, xprt->tcp_offset, xprt->tcp_reclen);
939 977
940 if (xprt->tcp_copied == req->rq_private_buf.buflen) 978 if (xprt->tcp_copied == req->rq_private_buf.buflen)
941 xprt->tcp_flags &= ~XPRT_COPY_DATA; 979 xprt->tcp_flags &= ~XPRT_COPY_DATA;
@@ -944,6 +982,7 @@ tcp_read_request(struct rpc_xprt *xprt, skb_reader_t *desc)
944 xprt->tcp_flags &= ~XPRT_COPY_DATA; 982 xprt->tcp_flags &= ~XPRT_COPY_DATA;
945 } 983 }
946 984
985out:
947 if (!(xprt->tcp_flags & XPRT_COPY_DATA)) { 986 if (!(xprt->tcp_flags & XPRT_COPY_DATA)) {
948 dprintk("RPC: %4d received reply complete\n", 987 dprintk("RPC: %4d received reply complete\n",
949 req->rq_task->tk_pid); 988 req->rq_task->tk_pid);
@@ -967,6 +1006,7 @@ tcp_read_discard(struct rpc_xprt *xprt, skb_reader_t *desc)
967 desc->count -= len; 1006 desc->count -= len;
968 desc->offset += len; 1007 desc->offset += len;
969 xprt->tcp_offset += len; 1008 xprt->tcp_offset += len;
1009 dprintk("RPC: discarded %u bytes\n", len);
970 tcp_check_recm(xprt); 1010 tcp_check_recm(xprt);
971} 1011}
972 1012
@@ -1064,8 +1104,7 @@ tcp_state_change(struct sock *sk)
1064 case TCP_SYN_RECV: 1104 case TCP_SYN_RECV:
1065 break; 1105 break;
1066 default: 1106 default:
1067 if (xprt_test_and_clear_connected(xprt)) 1107 xprt_disconnect(xprt);
1068 rpc_wake_up_status(&xprt->pending, -ENOTCONN);
1069 break; 1108 break;
1070 } 1109 }
1071 out: 1110 out:
@@ -1203,6 +1242,8 @@ xprt_transmit(struct rpc_task *task)
1203 list_add_tail(&req->rq_list, &xprt->recv); 1242 list_add_tail(&req->rq_list, &xprt->recv);
1204 spin_unlock_bh(&xprt->sock_lock); 1243 spin_unlock_bh(&xprt->sock_lock);
1205 xprt_reset_majortimeo(req); 1244 xprt_reset_majortimeo(req);
1245 /* Turn off autodisconnect */
1246 del_singleshot_timer_sync(&xprt->timer);
1206 } 1247 }
1207 } else if (!req->rq_bytes_sent) 1248 } else if (!req->rq_bytes_sent)
1208 return; 1249 return;
@@ -1333,8 +1374,6 @@ xprt_reserve(struct rpc_task *task)
1333 spin_lock(&xprt->xprt_lock); 1374 spin_lock(&xprt->xprt_lock);
1334 do_xprt_reserve(task); 1375 do_xprt_reserve(task);
1335 spin_unlock(&xprt->xprt_lock); 1376 spin_unlock(&xprt->xprt_lock);
1336 if (task->tk_rqstp)
1337 del_timer_sync(&xprt->timer);
1338 } 1377 }
1339} 1378}
1340 1379
@@ -1649,6 +1688,10 @@ xprt_shutdown(struct rpc_xprt *xprt)
1649 rpc_wake_up(&xprt->backlog); 1688 rpc_wake_up(&xprt->backlog);
1650 wake_up(&xprt->cong_wait); 1689 wake_up(&xprt->cong_wait);
1651 del_timer_sync(&xprt->timer); 1690 del_timer_sync(&xprt->timer);
1691
1692 /* synchronously wait for connect worker to finish */
1693 cancel_delayed_work(&xprt->sock_connect);
1694 flush_scheduled_work();
1652} 1695}
1653 1696
1654/* 1697/*