@@ -725,7 +725,8 @@ csum_partial_copy_to_xdr(struct xdr_buf *xdr, struct sk_buff *skb)
725
725
goto no_checksum ;
726
726
727
727
desc .csum = csum_partial (skb -> data , desc .offset , skb -> csum );
728
- xdr_partial_copy_from_skb (xdr , 0 , & desc , skb_read_and_csum_bits );
728
+ if (xdr_partial_copy_from_skb (xdr , 0 , & desc , skb_read_and_csum_bits ) < 0 )
729
+ return -1 ;
729
730
if (desc .offset != skb -> len ) {
730
731
unsigned int csum2 ;
731
732
csum2 = skb_checksum (skb , desc .offset , skb -> len - desc .offset , 0 );
@@ -737,7 +738,8 @@ csum_partial_copy_to_xdr(struct xdr_buf *xdr, struct sk_buff *skb)
737
738
return -1 ;
738
739
return 0 ;
739
740
no_checksum :
740
- xdr_partial_copy_from_skb (xdr , 0 , & desc , skb_read_bits );
741
+ if (xdr_partial_copy_from_skb (xdr , 0 , & desc , skb_read_bits ) < 0 )
742
+ return -1 ;
741
743
if (desc .count )
742
744
return -1 ;
743
745
return 0 ;
@@ -907,6 +909,7 @@ tcp_read_request(struct rpc_xprt *xprt, skb_reader_t *desc)
907
909
struct rpc_rqst * req ;
908
910
struct xdr_buf * rcvbuf ;
909
911
size_t len ;
912
+ int r ;
910
913
911
914
/* Find and lock the request corresponding to this xid */
912
915
spin_lock (& xprt -> sock_lock );
@@ -927,16 +930,30 @@ tcp_read_request(struct rpc_xprt *xprt, skb_reader_t *desc)
927
930
len = xprt -> tcp_reclen - xprt -> tcp_offset ;
928
931
memcpy (& my_desc , desc , sizeof (my_desc ));
929
932
my_desc .count = len ;
930
- xdr_partial_copy_from_skb (rcvbuf , xprt -> tcp_copied ,
933
+ r = xdr_partial_copy_from_skb (rcvbuf , xprt -> tcp_copied ,
931
934
& my_desc , tcp_copy_data );
932
935
desc -> count -= len ;
933
936
desc -> offset += len ;
934
937
} else
935
- xdr_partial_copy_from_skb (rcvbuf , xprt -> tcp_copied ,
938
+ r = xdr_partial_copy_from_skb (rcvbuf , xprt -> tcp_copied ,
936
939
desc , tcp_copy_data );
937
940
xprt -> tcp_copied += len ;
938
941
xprt -> tcp_offset += len ;
939
942
943
+ if (r < 0 ) {
944
+ /* Error when copying to the receive buffer,
945
+ * usually because we weren't able to allocate
946
+ * additional buffer pages. All we can do now
947
+ * is turn off XPRT_COPY_DATA, so the request
948
+ * will not receive any additional updates,
949
+ * and time out.
950
+ * Any remaining data from this record will
951
+ * be discarded.
952
+ */
953
+ xprt -> tcp_flags &= ~XPRT_COPY_DATA ;
954
+ goto out ;
955
+ }
956
+
940
957
if (xprt -> tcp_copied == req -> rq_private_buf .buflen )
941
958
xprt -> tcp_flags &= ~XPRT_COPY_DATA ;
942
959
else if (xprt -> tcp_offset == xprt -> tcp_reclen ) {
@@ -949,6 +966,7 @@ tcp_read_request(struct rpc_xprt *xprt, skb_reader_t *desc)
949
966
req -> rq_task -> tk_pid );
950
967
xprt_complete_rqst (xprt , req , xprt -> tcp_copied );
951
968
}
969
+ out :
952
970
spin_unlock (& xprt -> sock_lock );
953
971
tcp_check_recm (xprt );
954
972
}
0 commit comments