aboutsummaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
authorChuck Lever <chuck.lever@oracle.com>2006-12-05 16:35:19 -0500
committerTrond Myklebust <Trond.Myklebust@netapp.com>2006-12-06 10:46:49 -0500
commit51971139b2342fa1005e87bbfcb52305da3fe891 (patch)
treee3d48890ba589ba9f08c33480a14dfd90db7dba5 /net
parentee0ac0c227c2a2b6dd1b33c23831100ee895dacf (diff)
SUNRPC: Move TCP receive state variables into private data structure
Move the TCP receive state variables from the generic rpc_xprt structure to a private structure maintained inside net/sunrpc/xprtsock.c. Also rename a function/variable pair to refer to RPC fragment headers instead of record markers, to be consistent with types defined in sunrpc/*.h. Signed-off-by: Chuck Lever <chuck.lever@oracle.com> Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
Diffstat (limited to 'net')
-rw-r--r--net/sunrpc/xprtsock.c154
1 files changed, 86 insertions, 68 deletions
diff --git a/net/sunrpc/xprtsock.c b/net/sunrpc/xprtsock.c
index 0f455fd1820c..417bd91ea53e 100644
--- a/net/sunrpc/xprtsock.c
+++ b/net/sunrpc/xprtsock.c
@@ -133,6 +133,18 @@ struct sock_xprt {
133 */ 133 */
134 struct socket * sock; 134 struct socket * sock;
135 struct sock * inet; 135 struct sock * inet;
136
137 /*
138 * State of TCP reply receive
139 */
140 __be32 tcp_fraghdr,
141 tcp_xid;
142
143 u32 tcp_offset,
144 tcp_reclen;
145
146 unsigned long tcp_copied,
147 tcp_flags;
136}; 148};
137 149
138static void xs_format_peer_addresses(struct rpc_xprt *xprt) 150static void xs_format_peer_addresses(struct rpc_xprt *xprt)
@@ -628,73 +640,73 @@ static inline size_t xs_tcp_copy_data(skb_reader_t *desc, void *p, size_t len)
628 640
629static inline void xs_tcp_read_fraghdr(struct rpc_xprt *xprt, skb_reader_t *desc) 641static inline void xs_tcp_read_fraghdr(struct rpc_xprt *xprt, skb_reader_t *desc)
630{ 642{
643 struct sock_xprt *transport = container_of(xprt, struct sock_xprt, xprt);
631 size_t len, used; 644 size_t len, used;
632 char *p; 645 char *p;
633 646
634 p = ((char *) &xprt->tcp_recm) + xprt->tcp_offset; 647 p = ((char *) &transport->tcp_fraghdr) + transport->tcp_offset;
635 len = sizeof(xprt->tcp_recm) - xprt->tcp_offset; 648 len = sizeof(transport->tcp_fraghdr) - transport->tcp_offset;
636 used = xs_tcp_copy_data(desc, p, len); 649 used = xs_tcp_copy_data(desc, p, len);
637 xprt->tcp_offset += used; 650 transport->tcp_offset += used;
638 if (used != len) 651 if (used != len)
639 return; 652 return;
640 653
641 xprt->tcp_reclen = ntohl(xprt->tcp_recm); 654 transport->tcp_reclen = ntohl(transport->tcp_fraghdr);
642 if (xprt->tcp_reclen & RPC_LAST_STREAM_FRAGMENT) 655 if (transport->tcp_reclen & RPC_LAST_STREAM_FRAGMENT)
643 xprt->tcp_flags |= XPRT_LAST_FRAG; 656 transport->tcp_flags |= XPRT_LAST_FRAG;
644 else 657 else
645 xprt->tcp_flags &= ~XPRT_LAST_FRAG; 658 transport->tcp_flags &= ~XPRT_LAST_FRAG;
646 xprt->tcp_reclen &= RPC_FRAGMENT_SIZE_MASK; 659 transport->tcp_reclen &= RPC_FRAGMENT_SIZE_MASK;
647 660
648 xprt->tcp_flags &= ~XPRT_COPY_RECM; 661 transport->tcp_flags &= ~XPRT_COPY_RECM;
649 xprt->tcp_offset = 0; 662 transport->tcp_offset = 0;
650 663
651 /* Sanity check of the record length */ 664 /* Sanity check of the record length */
652 if (unlikely(xprt->tcp_reclen < 4)) { 665 if (unlikely(transport->tcp_reclen < 4)) {
653 dprintk("RPC: invalid TCP record fragment length\n"); 666 dprintk("RPC: invalid TCP record fragment length\n");
654 xprt_disconnect(xprt); 667 xprt_disconnect(xprt);
655 return; 668 return;
656 } 669 }
657 dprintk("RPC: reading TCP record fragment of length %d\n", 670 dprintk("RPC: reading TCP record fragment of length %d\n",
658 xprt->tcp_reclen); 671 transport->tcp_reclen);
659} 672}
660 673
661static void xs_tcp_check_recm(struct rpc_xprt *xprt) 674static void xs_tcp_check_fraghdr(struct sock_xprt *transport)
662{ 675{
663 dprintk("RPC: xprt = %p, tcp_copied = %lu, tcp_offset = %u, tcp_reclen = %u, tcp_flags = %lx\n", 676 if (transport->tcp_offset == transport->tcp_reclen) {
664 xprt, xprt->tcp_copied, xprt->tcp_offset, xprt->tcp_reclen, xprt->tcp_flags); 677 transport->tcp_flags |= XPRT_COPY_RECM;
665 if (xprt->tcp_offset == xprt->tcp_reclen) { 678 transport->tcp_offset = 0;
666 xprt->tcp_flags |= XPRT_COPY_RECM; 679 if (transport->tcp_flags & XPRT_LAST_FRAG) {
667 xprt->tcp_offset = 0; 680 transport->tcp_flags &= ~XPRT_COPY_DATA;
668 if (xprt->tcp_flags & XPRT_LAST_FRAG) { 681 transport->tcp_flags |= XPRT_COPY_XID;
669 xprt->tcp_flags &= ~XPRT_COPY_DATA; 682 transport->tcp_copied = 0;
670 xprt->tcp_flags |= XPRT_COPY_XID;
671 xprt->tcp_copied = 0;
672 } 683 }
673 } 684 }
674} 685}
675 686
676static inline void xs_tcp_read_xid(struct rpc_xprt *xprt, skb_reader_t *desc) 687static inline void xs_tcp_read_xid(struct sock_xprt *transport, skb_reader_t *desc)
677{ 688{
678 size_t len, used; 689 size_t len, used;
679 char *p; 690 char *p;
680 691
681 len = sizeof(xprt->tcp_xid) - xprt->tcp_offset; 692 len = sizeof(transport->tcp_xid) - transport->tcp_offset;
682 dprintk("RPC: reading XID (%Zu bytes)\n", len); 693 dprintk("RPC: reading XID (%Zu bytes)\n", len);
683 p = ((char *) &xprt->tcp_xid) + xprt->tcp_offset; 694 p = ((char *) &transport->tcp_xid) + transport->tcp_offset;
684 used = xs_tcp_copy_data(desc, p, len); 695 used = xs_tcp_copy_data(desc, p, len);
685 xprt->tcp_offset += used; 696 transport->tcp_offset += used;
686 if (used != len) 697 if (used != len)
687 return; 698 return;
688 xprt->tcp_flags &= ~XPRT_COPY_XID; 699 transport->tcp_flags &= ~XPRT_COPY_XID;
689 xprt->tcp_flags |= XPRT_COPY_DATA; 700 transport->tcp_flags |= XPRT_COPY_DATA;
690 xprt->tcp_copied = 4; 701 transport->tcp_copied = 4;
691 dprintk("RPC: reading reply for XID %08x\n", 702 dprintk("RPC: reading reply for XID %08x\n",
692 ntohl(xprt->tcp_xid)); 703 ntohl(transport->tcp_xid));
693 xs_tcp_check_recm(xprt); 704 xs_tcp_check_fraghdr(transport);
694} 705}
695 706
696static inline void xs_tcp_read_request(struct rpc_xprt *xprt, skb_reader_t *desc) 707static inline void xs_tcp_read_request(struct rpc_xprt *xprt, skb_reader_t *desc)
697{ 708{
709 struct sock_xprt *transport = container_of(xprt, struct sock_xprt, xprt);
698 struct rpc_rqst *req; 710 struct rpc_rqst *req;
699 struct xdr_buf *rcvbuf; 711 struct xdr_buf *rcvbuf;
700 size_t len; 712 size_t len;
@@ -702,34 +714,34 @@ static inline void xs_tcp_read_request(struct rpc_xprt *xprt, skb_reader_t *desc
702 714
703 /* Find and lock the request corresponding to this xid */ 715 /* Find and lock the request corresponding to this xid */
704 spin_lock(&xprt->transport_lock); 716 spin_lock(&xprt->transport_lock);
705 req = xprt_lookup_rqst(xprt, xprt->tcp_xid); 717 req = xprt_lookup_rqst(xprt, transport->tcp_xid);
706 if (!req) { 718 if (!req) {
707 xprt->tcp_flags &= ~XPRT_COPY_DATA; 719 transport->tcp_flags &= ~XPRT_COPY_DATA;
708 dprintk("RPC: XID %08x request not found!\n", 720 dprintk("RPC: XID %08x request not found!\n",
709 ntohl(xprt->tcp_xid)); 721 ntohl(transport->tcp_xid));
710 spin_unlock(&xprt->transport_lock); 722 spin_unlock(&xprt->transport_lock);
711 return; 723 return;
712 } 724 }
713 725
714 rcvbuf = &req->rq_private_buf; 726 rcvbuf = &req->rq_private_buf;
715 len = desc->count; 727 len = desc->count;
716 if (len > xprt->tcp_reclen - xprt->tcp_offset) { 728 if (len > transport->tcp_reclen - transport->tcp_offset) {
717 skb_reader_t my_desc; 729 skb_reader_t my_desc;
718 730
719 len = xprt->tcp_reclen - xprt->tcp_offset; 731 len = transport->tcp_reclen - transport->tcp_offset;
720 memcpy(&my_desc, desc, sizeof(my_desc)); 732 memcpy(&my_desc, desc, sizeof(my_desc));
721 my_desc.count = len; 733 my_desc.count = len;
722 r = xdr_partial_copy_from_skb(rcvbuf, xprt->tcp_copied, 734 r = xdr_partial_copy_from_skb(rcvbuf, transport->tcp_copied,
723 &my_desc, xs_tcp_copy_data); 735 &my_desc, xs_tcp_copy_data);
724 desc->count -= r; 736 desc->count -= r;
725 desc->offset += r; 737 desc->offset += r;
726 } else 738 } else
727 r = xdr_partial_copy_from_skb(rcvbuf, xprt->tcp_copied, 739 r = xdr_partial_copy_from_skb(rcvbuf, transport->tcp_copied,
728 desc, xs_tcp_copy_data); 740 desc, xs_tcp_copy_data);
729 741
730 if (r > 0) { 742 if (r > 0) {
731 xprt->tcp_copied += r; 743 transport->tcp_copied += r;
732 xprt->tcp_offset += r; 744 transport->tcp_offset += r;
733 } 745 }
734 if (r != len) { 746 if (r != len) {
735 /* Error when copying to the receive buffer, 747 /* Error when copying to the receive buffer,
@@ -741,77 +753,79 @@ static inline void xs_tcp_read_request(struct rpc_xprt *xprt, skb_reader_t *desc
741 * Any remaining data from this record will 753 * Any remaining data from this record will
742 * be discarded. 754 * be discarded.
743 */ 755 */
744 xprt->tcp_flags &= ~XPRT_COPY_DATA; 756 transport->tcp_flags &= ~XPRT_COPY_DATA;
745 dprintk("RPC: XID %08x truncated request\n", 757 dprintk("RPC: XID %08x truncated request\n",
746 ntohl(xprt->tcp_xid)); 758 ntohl(transport->tcp_xid));
747 dprintk("RPC: xprt = %p, tcp_copied = %lu, tcp_offset = %u, tcp_reclen = %u\n", 759 dprintk("RPC: xprt = %p, tcp_copied = %lu, tcp_offset = %u, tcp_reclen = %u\n",
748 xprt, xprt->tcp_copied, xprt->tcp_offset, xprt->tcp_reclen); 760 xprt, transport->tcp_copied, transport->tcp_offset,
761 transport->tcp_reclen);
749 goto out; 762 goto out;
750 } 763 }
751 764
752 dprintk("RPC: XID %08x read %Zd bytes\n", 765 dprintk("RPC: XID %08x read %Zd bytes\n",
753 ntohl(xprt->tcp_xid), r); 766 ntohl(transport->tcp_xid), r);
754 dprintk("RPC: xprt = %p, tcp_copied = %lu, tcp_offset = %u, tcp_reclen = %u\n", 767 dprintk("RPC: xprt = %p, tcp_copied = %lu, tcp_offset = %u, tcp_reclen = %u\n",
755 xprt, xprt->tcp_copied, xprt->tcp_offset, xprt->tcp_reclen); 768 xprt, transport->tcp_copied, transport->tcp_offset,
756 769 transport->tcp_reclen);
757 if (xprt->tcp_copied == req->rq_private_buf.buflen) 770
758 xprt->tcp_flags &= ~XPRT_COPY_DATA; 771 if (transport->tcp_copied == req->rq_private_buf.buflen)
759 else if (xprt->tcp_offset == xprt->tcp_reclen) { 772 transport->tcp_flags &= ~XPRT_COPY_DATA;
760 if (xprt->tcp_flags & XPRT_LAST_FRAG) 773 else if (transport->tcp_offset == transport->tcp_reclen) {
761 xprt->tcp_flags &= ~XPRT_COPY_DATA; 774 if (transport->tcp_flags & XPRT_LAST_FRAG)
775 transport->tcp_flags &= ~XPRT_COPY_DATA;
762 } 776 }
763 777
764out: 778out:
765 if (!(xprt->tcp_flags & XPRT_COPY_DATA)) 779 if (!(transport->tcp_flags & XPRT_COPY_DATA))
766 xprt_complete_rqst(req->rq_task, xprt->tcp_copied); 780 xprt_complete_rqst(req->rq_task, transport->tcp_copied);
767 spin_unlock(&xprt->transport_lock); 781 spin_unlock(&xprt->transport_lock);
768 xs_tcp_check_recm(xprt); 782 xs_tcp_check_fraghdr(transport);
769} 783}
770 784
771static inline void xs_tcp_read_discard(struct rpc_xprt *xprt, skb_reader_t *desc) 785static inline void xs_tcp_read_discard(struct sock_xprt *transport, skb_reader_t *desc)
772{ 786{
773 size_t len; 787 size_t len;
774 788
775 len = xprt->tcp_reclen - xprt->tcp_offset; 789 len = transport->tcp_reclen - transport->tcp_offset;
776 if (len > desc->count) 790 if (len > desc->count)
777 len = desc->count; 791 len = desc->count;
778 desc->count -= len; 792 desc->count -= len;
779 desc->offset += len; 793 desc->offset += len;
780 xprt->tcp_offset += len; 794 transport->tcp_offset += len;
781 dprintk("RPC: discarded %Zu bytes\n", len); 795 dprintk("RPC: discarded %Zu bytes\n", len);
782 xs_tcp_check_recm(xprt); 796 xs_tcp_check_fraghdr(transport);
783} 797}
784 798
785static int xs_tcp_data_recv(read_descriptor_t *rd_desc, struct sk_buff *skb, unsigned int offset, size_t len) 799static int xs_tcp_data_recv(read_descriptor_t *rd_desc, struct sk_buff *skb, unsigned int offset, size_t len)
786{ 800{
787 struct rpc_xprt *xprt = rd_desc->arg.data; 801 struct rpc_xprt *xprt = rd_desc->arg.data;
802 struct sock_xprt *transport = container_of(xprt, struct sock_xprt, xprt);
788 skb_reader_t desc = { 803 skb_reader_t desc = {
789 .skb = skb, 804 .skb = skb,
790 .offset = offset, 805 .offset = offset,
791 .count = len, 806 .count = len,
792 .csum = 0
793 }; 807 };
794 808
795 dprintk("RPC: xs_tcp_data_recv started\n"); 809 dprintk("RPC: xs_tcp_data_recv started\n");
796 do { 810 do {
797 /* Read in a new fragment marker if necessary */ 811 /* Read in a new fragment marker if necessary */
798 /* Can we ever really expect to get completely empty fragments? */ 812 /* Can we ever really expect to get completely empty fragments? */
799 if (xprt->tcp_flags & XPRT_COPY_RECM) { 813 if (transport->tcp_flags & XPRT_COPY_RECM) {
800 xs_tcp_read_fraghdr(xprt, &desc); 814 xs_tcp_read_fraghdr(xprt, &desc);
801 continue; 815 continue;
802 } 816 }
803 /* Read in the xid if necessary */ 817 /* Read in the xid if necessary */
804 if (xprt->tcp_flags & XPRT_COPY_XID) { 818 if (transport->tcp_flags & XPRT_COPY_XID) {
805 xs_tcp_read_xid(xprt, &desc); 819 xs_tcp_read_xid(transport, &desc);
806 continue; 820 continue;
807 } 821 }
808 /* Read in the request data */ 822 /* Read in the request data */
809 if (xprt->tcp_flags & XPRT_COPY_DATA) { 823 if (transport->tcp_flags & XPRT_COPY_DATA) {
810 xs_tcp_read_request(xprt, &desc); 824 xs_tcp_read_request(xprt, &desc);
811 continue; 825 continue;
812 } 826 }
813 /* Skip over any trailing bytes on short reads */ 827 /* Skip over any trailing bytes on short reads */
814 xs_tcp_read_discard(xprt, &desc); 828 xs_tcp_read_discard(transport, &desc);
815 } while (desc.count); 829 } while (desc.count);
816 dprintk("RPC: xs_tcp_data_recv done\n"); 830 dprintk("RPC: xs_tcp_data_recv done\n");
817 return len - desc.count; 831 return len - desc.count;
@@ -865,11 +879,15 @@ static void xs_tcp_state_change(struct sock *sk)
865 case TCP_ESTABLISHED: 879 case TCP_ESTABLISHED:
866 spin_lock_bh(&xprt->transport_lock); 880 spin_lock_bh(&xprt->transport_lock);
867 if (!xprt_test_and_set_connected(xprt)) { 881 if (!xprt_test_and_set_connected(xprt)) {
882 struct sock_xprt *transport = container_of(xprt,
883 struct sock_xprt, xprt);
884
868 /* Reset TCP record info */ 885 /* Reset TCP record info */
869 xprt->tcp_offset = 0; 886 transport->tcp_offset = 0;
870 xprt->tcp_reclen = 0; 887 transport->tcp_reclen = 0;
871 xprt->tcp_copied = 0; 888 transport->tcp_copied = 0;
872 xprt->tcp_flags = XPRT_COPY_RECM | XPRT_COPY_XID; 889 transport->tcp_flags = XPRT_COPY_RECM | XPRT_COPY_XID;
890
873 xprt->reestablish_timeout = XS_TCP_INIT_REEST_TO; 891 xprt->reestablish_timeout = XS_TCP_INIT_REEST_TO;
874 xprt_wake_pending_tasks(xprt, 0); 892 xprt_wake_pending_tasks(xprt, 0);
875 } 893 }