static int __blk_bios_map_sg(struct request_queue *q, struct bio *bio, struct scatterlist *sglist, struct scatterlist **sg) { struct bio_vec bvec, bvprv = { NULL }; struct bvec_iter iter; int nsegs, cluster; nsegs = 0; cluster = blk_queue_cluster(q); if (bio->bi_rw & REQ_DISCARD) { /* * This is a hack - drivers should be neither modifying the * biovec, nor relying on bi_vcnt - but because of * blk_add_request_payload(), a discard bio may or may not have * a payload we need to set up here (thank you Christoph) and * bi_vcnt is really the only way of telling if we need to. */ if (bio->bi_vcnt) goto single_segment; return 0; } if (bio->bi_rw & REQ_WRITE_SAME) { single_segment: *sg = sglist; bvec = bio_iovec(bio); sg_set_page(*sg, bvec.bv_page, bvec.bv_len, bvec.bv_offset); return 1; } for_each_bio(bio) bio_for_each_segment(bvec, bio, iter) __blk_segment_map_sg(q, &bvec, sglist, &bvprv, sg, &nsegs, &cluster); return nsegs; }
static void pmem_make_request(struct request_queue *q, struct bio *bio) { bool do_acct; unsigned long start; struct bio_vec bvec; struct bvec_iter iter; struct block_device *bdev = bio->bi_bdev; struct pmem_device *pmem = bdev->bd_disk->private_data; do_acct = nd_iostat_start(bio, &start); bio_for_each_segment(bvec, bio, iter) pmem_do_bvec(pmem, bvec.bv_page, bvec.bv_len, bvec.bv_offset, bio_data_dir(bio), iter.bi_sector); if (do_acct) nd_iostat_end(bio, start); if (bio_data_dir(bio)) wmb_pmem(); bio_endio(bio); }