@@ -913,22 +913,29 @@ static const struct block_device_operations ub_fops = {
913913 .report_zones = ublk_report_zones ,
914914};
915915
916- struct ublk_io_iter {
917- struct bio * bio ;
918- struct bvec_iter iter ;
919- };
920-
921- /* return how many bytes are copied */
922- static size_t ublk_copy_io_pages (struct ublk_io_iter * data ,
923- struct iov_iter * uiter , int dir )
916+ /*
917+ * Copy data between request pages and io_iter, and 'offset'
918+ * is the start point of linear offset of request.
919+ */
920+ static size_t ublk_copy_user_pages (const struct request * req ,
921+ unsigned offset , struct iov_iter * uiter , int dir )
924922{
923+ struct req_iterator iter ;
924+ struct bio_vec bv ;
925925 size_t done = 0 ;
926926
927- for (;;) {
928- struct bio_vec bv = bio_iter_iovec (data -> bio , data -> iter );
929- void * bv_buf = bvec_kmap_local (& bv );
927+ rq_for_each_segment (bv , req , iter ) {
928+ void * bv_buf ;
930929 size_t copied ;
931930
931+ if (offset >= bv .bv_len ) {
932+ offset -= bv .bv_len ;
933+ continue ;
934+ }
935+
936+ bv .bv_offset += offset ;
937+ bv .bv_len -= offset ;
938+ bv_buf = bvec_kmap_local (& bv );
932939 if (dir == ITER_DEST )
933940 copied = copy_to_iter (bv_buf , bv .bv_len , uiter );
934941 else
@@ -940,50 +947,11 @@ static size_t ublk_copy_io_pages(struct ublk_io_iter *data,
940947 if (copied < bv .bv_len )
941948 break ;
942949
943- /* advance bio */
944- bio_advance_iter_single (data -> bio , & data -> iter , copied );
945- if (!data -> iter .bi_size ) {
946- data -> bio = data -> bio -> bi_next ;
947- if (data -> bio == NULL )
948- break ;
949- data -> iter = data -> bio -> bi_iter ;
950- }
950+ offset = 0 ;
951951 }
952952 return done ;
953953}
954954
955- static bool ublk_advance_io_iter (const struct request * req ,
956- struct ublk_io_iter * iter , unsigned int offset )
957- {
958- struct bio * bio = req -> bio ;
959-
960- for_each_bio (bio ) {
961- if (bio -> bi_iter .bi_size > offset ) {
962- iter -> bio = bio ;
963- iter -> iter = bio -> bi_iter ;
964- bio_advance_iter (iter -> bio , & iter -> iter , offset );
965- return true;
966- }
967- offset -= bio -> bi_iter .bi_size ;
968- }
969- return false;
970- }
971-
972- /*
973- * Copy data between request pages and io_iter, and 'offset'
974- * is the start point of linear offset of request.
975- */
976- static size_t ublk_copy_user_pages (const struct request * req ,
977- unsigned offset , struct iov_iter * uiter , int dir )
978- {
979- struct ublk_io_iter iter ;
980-
981- if (!ublk_advance_io_iter (req , & iter , offset ))
982- return 0 ;
983-
984- return ublk_copy_io_pages (& iter , uiter , dir );
985- }
986-
987955static inline bool ublk_need_map_req (const struct request * req )
988956{
989957 return ublk_rq_has_data (req ) && req_op (req ) == REQ_OP_WRITE ;
0 commit comments