@@ -691,78 +691,6 @@ static int svc_rdma_build_read_chunk(struct svc_rqst *rqstp,
691
691
return ret ;
692
692
}
693
693
694
- /* If there is inline content following the Read chunk, append it to
695
- * the page list immediately following the data payload. This has to
696
- * be done after the reader function has determined how many pages
697
- * were consumed for RDMA Read.
698
- *
699
- * On entry, ri_pageno and ri_pageoff point directly to the end of the
700
- * page list. On exit, both have been updated to the new "next byte".
701
- *
702
- * Assumptions:
703
- * - Inline content fits entirely in rq_pages[0]
704
- * - Trailing content is only a handful of bytes
705
- */
706
- static int svc_rdma_copy_tail (struct svc_rqst * rqstp ,
707
- struct svc_rdma_read_info * info )
708
- {
709
- struct svc_rdma_op_ctxt * head = info -> ri_readctxt ;
710
- unsigned int tail_length , remaining ;
711
- u8 * srcp , * destp ;
712
-
713
- /* Assert that all inline content fits in page 0. This is an
714
- * implementation limit, not a protocol limit.
715
- */
716
- if (head -> arg .head [0 ].iov_len > PAGE_SIZE ) {
717
- pr_warn_once ("svcrdma: too much trailing inline content\n" );
718
- return - EINVAL ;
719
- }
720
-
721
- srcp = head -> arg .head [0 ].iov_base ;
722
- srcp += info -> ri_position ;
723
- tail_length = head -> arg .head [0 ].iov_len - info -> ri_position ;
724
- remaining = tail_length ;
725
-
726
- /* If there is room on the last page in the page list, try to
727
- * fit the trailing content there.
728
- */
729
- if (info -> ri_pageoff > 0 ) {
730
- unsigned int len ;
731
-
732
- len = min_t (unsigned int , remaining ,
733
- PAGE_SIZE - info -> ri_pageoff );
734
- destp = page_address (rqstp -> rq_pages [info -> ri_pageno ]);
735
- destp += info -> ri_pageoff ;
736
-
737
- memcpy (destp , srcp , len );
738
- srcp += len ;
739
- destp += len ;
740
- info -> ri_pageoff += len ;
741
- remaining -= len ;
742
-
743
- if (info -> ri_pageoff == PAGE_SIZE ) {
744
- info -> ri_pageno ++ ;
745
- info -> ri_pageoff = 0 ;
746
- }
747
- }
748
-
749
- /* Otherwise, a fresh page is needed. */
750
- if (remaining ) {
751
- head -> arg .pages [info -> ri_pageno ] =
752
- rqstp -> rq_pages [info -> ri_pageno ];
753
- head -> count ++ ;
754
-
755
- destp = page_address (rqstp -> rq_pages [info -> ri_pageno ]);
756
- memcpy (destp , srcp , remaining );
757
- info -> ri_pageoff += remaining ;
758
- }
759
-
760
- head -> arg .page_len += tail_length ;
761
- head -> arg .len += tail_length ;
762
- head -> arg .buflen += tail_length ;
763
- return 0 ;
764
- }
765
-
766
694
/* Construct RDMA Reads to pull over a normal Read chunk. The chunk
767
695
* data lands in the page list of head->arg.pages.
768
696
*
@@ -787,34 +715,28 @@ static int svc_rdma_build_normal_read_chunk(struct svc_rqst *rqstp,
787
715
if (ret < 0 )
788
716
goto out ;
789
717
790
- /* Read chunk may need XDR round-up (see RFC 5666, s. 3.7).
718
+ /* Split the Receive buffer between the head and tail
719
+ * buffers at Read chunk's position. XDR roundup of the
720
+ * chunk is not included in either the pagelist or in
721
+ * the tail.
791
722
*/
792
- if (info -> ri_chunklen & 3 ) {
793
- u32 padlen = 4 - (info -> ri_chunklen & 3 );
794
-
795
- info -> ri_chunklen += padlen ;
723
+ head -> arg .tail [0 ].iov_base =
724
+ head -> arg .head [0 ].iov_base + info -> ri_position ;
725
+ head -> arg .tail [0 ].iov_len =
726
+ head -> arg .head [0 ].iov_len - info -> ri_position ;
727
+ head -> arg .head [0 ].iov_len = info -> ri_position ;
796
728
797
- /* NB: data payload always starts on XDR alignment,
798
- * thus the pad can never contain a page boundary.
799
- */
800
- info -> ri_pageoff += padlen ;
801
- if (info -> ri_pageoff == PAGE_SIZE ) {
802
- info -> ri_pageno ++ ;
803
- info -> ri_pageoff = 0 ;
804
- }
805
- }
729
+ /* Read chunk may need XDR roundup (see RFC 5666, s. 3.7).
730
+ *
731
+ * NFSv2/3 write decoders need the length of the tail to
732
+ * contain the size of the roundup padding.
733
+ */
734
+ head -> arg .tail [0 ].iov_len += 4 - (info -> ri_chunklen & 3 );
806
735
807
736
head -> arg .page_len = info -> ri_chunklen ;
808
737
head -> arg .len += info -> ri_chunklen ;
809
738
head -> arg .buflen += info -> ri_chunklen ;
810
739
811
- if (info -> ri_position < head -> arg .head [0 ].iov_len ) {
812
- ret = svc_rdma_copy_tail (rqstp , info );
813
- if (ret < 0 )
814
- goto out ;
815
- }
816
- head -> arg .head [0 ].iov_len = info -> ri_position ;
817
-
818
740
out :
819
741
return ret ;
820
742
}
0 commit comments