diff options
author | Chuck Lever <chuck.lever@oracle.com> | 2006-12-05 16:35:19 -0500 |
---|---|---|
committer | Trond Myklebust <Trond.Myklebust@netapp.com> | 2006-12-06 10:46:49 -0500 |
commit | 51971139b2342fa1005e87bbfcb52305da3fe891 (patch) | |
tree | e3d48890ba589ba9f08c33480a14dfd90db7dba5 /net/sunrpc | |
parent | ee0ac0c227c2a2b6dd1b33c23831100ee895dacf (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/sunrpc')
-rw-r--r-- | net/sunrpc/xprtsock.c | 154 |
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 | ||
138 | static void xs_format_peer_addresses(struct rpc_xprt *xprt) | 150 | static 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 | ||
629 | static inline void xs_tcp_read_fraghdr(struct rpc_xprt *xprt, skb_reader_t *desc) | 641 | static 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 | ||
661 | static void xs_tcp_check_recm(struct rpc_xprt *xprt) | 674 | static 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 | ||
676 | static inline void xs_tcp_read_xid(struct rpc_xprt *xprt, skb_reader_t *desc) | 687 | static 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 | ||
696 | static inline void xs_tcp_read_request(struct rpc_xprt *xprt, skb_reader_t *desc) | 707 | static 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 | ||
764 | out: | 778 | out: |
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 | ||
771 | static inline void xs_tcp_read_discard(struct rpc_xprt *xprt, skb_reader_t *desc) | 785 | static 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 | ||
785 | static int xs_tcp_data_recv(read_descriptor_t *rd_desc, struct sk_buff *skb, unsigned int offset, size_t len) | 799 | static 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 | } |