@@ -767,10 +767,86 @@ static bool svc_rdma_is_reverse_direction_reply(struct svc_xprt *xprt,
767
767
return true;
768
768
}
769
769
770
+ /* Finish constructing the RPC Call message in rqstp::rq_arg.
771
+ *
772
+ * The incoming RPC/RDMA message is an RDMA_MSG type message
773
+ * with a single Read chunk (only the upper layer data payload
774
+ * was conveyed via RDMA Read).
775
+ */
776
+ static void svc_rdma_read_complete_one (struct svc_rqst * rqstp ,
777
+ struct svc_rdma_recv_ctxt * ctxt )
778
+ {
779
+ struct svc_rdma_chunk * chunk = pcl_first_chunk (& ctxt -> rc_read_pcl );
780
+ struct xdr_buf * buf = & rqstp -> rq_arg ;
781
+ unsigned int length ;
782
+
783
+ /* Split the Receive buffer between the head and tail
784
+ * buffers at Read chunk's position. XDR roundup of the
785
+ * chunk is not included in either the pagelist or in
786
+ * the tail.
787
+ */
788
+ buf -> tail [0 ].iov_base = buf -> head [0 ].iov_base + chunk -> ch_position ;
789
+ buf -> tail [0 ].iov_len = buf -> head [0 ].iov_len - chunk -> ch_position ;
790
+ buf -> head [0 ].iov_len = chunk -> ch_position ;
791
+
792
+ /* Read chunk may need XDR roundup (see RFC 8166, s. 3.4.5.2).
793
+ *
794
+ * If the client already rounded up the chunk length, the
795
+ * length does not change. Otherwise, the length of the page
796
+ * list is increased to include XDR round-up.
797
+ *
798
+ * Currently these chunks always start at page offset 0,
799
+ * thus the rounded-up length never crosses a page boundary.
800
+ */
801
+ buf -> pages = & rqstp -> rq_pages [0 ];
802
+ length = xdr_align_size (chunk -> ch_length );
803
+ buf -> page_len = length ;
804
+ buf -> len += length ;
805
+ buf -> buflen += length ;
806
+ }
807
+
808
+ /* Finish constructing the RPC Call message in rqstp::rq_arg.
809
+ *
810
+ * The incoming RPC/RDMA message is an RDMA_MSG type message
811
+ * with payload in multiple Read chunks and no PZRC.
812
+ */
813
+ static void svc_rdma_read_complete_multiple (struct svc_rqst * rqstp ,
814
+ struct svc_rdma_recv_ctxt * ctxt )
815
+ {
816
+ struct xdr_buf * buf = & rqstp -> rq_arg ;
817
+
818
+ buf -> len += ctxt -> rc_readbytes ;
819
+ buf -> buflen += ctxt -> rc_readbytes ;
820
+
821
+ buf -> head [0 ].iov_base = page_address (rqstp -> rq_pages [0 ]);
822
+ buf -> head [0 ].iov_len = min_t (size_t , PAGE_SIZE , ctxt -> rc_readbytes );
823
+ buf -> pages = & rqstp -> rq_pages [1 ];
824
+ buf -> page_len = ctxt -> rc_readbytes - buf -> head [0 ].iov_len ;
825
+ }
826
+
827
+ /* Finish constructing the RPC Call message in rqstp::rq_arg.
828
+ *
829
+ * The incoming RPC/RDMA message is an RDMA_NOMSG type message
830
+ * (the RPC message body was conveyed via RDMA Read).
831
+ */
832
+ static void svc_rdma_read_complete_pzrc (struct svc_rqst * rqstp ,
833
+ struct svc_rdma_recv_ctxt * ctxt )
834
+ {
835
+ struct xdr_buf * buf = & rqstp -> rq_arg ;
836
+
837
+ buf -> len += ctxt -> rc_readbytes ;
838
+ buf -> buflen += ctxt -> rc_readbytes ;
839
+
840
+ buf -> head [0 ].iov_base = page_address (rqstp -> rq_pages [0 ]);
841
+ buf -> head [0 ].iov_len = min_t (size_t , PAGE_SIZE , ctxt -> rc_readbytes );
842
+ buf -> pages = & rqstp -> rq_pages [1 ];
843
+ buf -> page_len = ctxt -> rc_readbytes - buf -> head [0 ].iov_len ;
844
+ }
845
+
770
846
static noinline void svc_rdma_read_complete (struct svc_rqst * rqstp ,
771
847
struct svc_rdma_recv_ctxt * ctxt )
772
848
{
773
- int i ;
849
+ unsigned int i ;
774
850
775
851
/* Transfer the Read chunk pages into @rqstp.rq_pages, replacing
776
852
* the rq_pages that were already allocated for this rqstp.
@@ -789,6 +865,21 @@ static noinline void svc_rdma_read_complete(struct svc_rqst *rqstp,
789
865
* pages in ctxt::rc_pages a second time.
790
866
*/
791
867
ctxt -> rc_page_count = 0 ;
868
+
869
+ /* Finish constructing the RPC Call message. The exact
870
+ * procedure for that depends on what kind of RPC/RDMA
871
+ * chunks were provided by the client.
872
+ */
873
+ if (pcl_is_empty (& ctxt -> rc_call_pcl )) {
874
+ if (ctxt -> rc_read_pcl .cl_count == 1 )
875
+ svc_rdma_read_complete_one (rqstp , ctxt );
876
+ else
877
+ svc_rdma_read_complete_multiple (rqstp , ctxt );
878
+ } else {
879
+ svc_rdma_read_complete_pzrc (rqstp , ctxt );
880
+ }
881
+
882
+ trace_svcrdma_read_finished (& ctxt -> rc_cid );
792
883
}
793
884
794
885
/**
0 commit comments