On 9/8/22 4:52 AM, Kanchan Joshi wrote: > On Wed, Sep 07, 2022 at 03:32:26PM +0000, Chaitanya Kulkarni wrote: >> On 9/5/22 23:27, Kanchan Joshi wrote: >>> Add blk_rq_map_user_bvec which maps the bvec iterator into a bio and >>> places that into the request. This helper will be used in nvme for >>> uring-passthrough with fixed-buffer. >>> While at it, create another helper bio_map_get to reduce the code >>> duplication. >>> >>> Signed-off-by: Kanchan Joshi <joshi.k@xxxxxxxxxxx> >>> Signed-off-by: Anuj Gupta <anuj20.g@xxxxxxxxxxx> >>> --- >>> block/blk-map.c | 94 +++++++++++++++++++++++++++++++++++++----- >>> include/linux/blk-mq.h | 1 + >>> 2 files changed, 85 insertions(+), 10 deletions(-) >>> >>> diff --git a/block/blk-map.c b/block/blk-map.c >>> index f3768876d618..e2f268167342 100644 >>> --- a/block/blk-map.c >>> +++ b/block/blk-map.c >>> @@ -241,17 +241,10 @@ static void bio_map_put(struct bio *bio) >>> } >>> } >>> >>> -static int bio_map_user_iov(struct request *rq, struct iov_iter *iter, >>> +static struct bio *bio_map_get(struct request *rq, unsigned int nr_vecs, >>> gfp_t gfp_mask) >>> { >>> - unsigned int max_sectors = queue_max_hw_sectors(rq->q); >>> - unsigned int nr_vecs = iov_iter_npages(iter, BIO_MAX_VECS); >>> struct bio *bio; >>> - int ret; >>> - int j; >>> - >>> - if (!iov_iter_count(iter)) >>> - return -EINVAL; >>> >>> if (rq->cmd_flags & REQ_POLLED) { >>> blk_opf_t opf = rq->cmd_flags | REQ_ALLOC_CACHE; >>> @@ -259,13 +252,31 @@ static int bio_map_user_iov(struct request *rq, struct iov_iter *iter, >>> bio = bio_alloc_bioset(NULL, nr_vecs, opf, gfp_mask, >>> &fs_bio_set); >>> if (!bio) >>> - return -ENOMEM; >>> + return NULL; >>> } else { >>> bio = bio_kmalloc(nr_vecs, gfp_mask); >>> if (!bio) >>> - return -ENOMEM; >>> + return NULL; >>> bio_init(bio, NULL, bio->bi_inline_vecs, nr_vecs, req_op(rq)); >>> } >>> + return bio; >>> +} >>> + >>> +static int bio_map_user_iov(struct request *rq, struct iov_iter *iter, >>> + gfp_t gfp_mask) >>> +{ >>> + unsigned int max_sectors = queue_max_hw_sectors(rq->q); >>> + unsigned int nr_vecs = iov_iter_npages(iter, BIO_MAX_VECS); >>> + struct bio *bio; >>> + int ret; >>> + int j; >>> + >>> + if (!iov_iter_count(iter)) >>> + return -EINVAL; >>> + >>> + bio = bio_map_get(rq, nr_vecs, gfp_mask); >>> + if (bio == NULL) >>> + return -ENOMEM; >>> >>> while (iov_iter_count(iter)) { >>> struct page **pages, *stack_pages[UIO_FASTIOV]; >>> @@ -612,6 +623,69 @@ int blk_rq_map_user(struct request_queue *q, struct request *rq, >>> } >>> EXPORT_SYMBOL(blk_rq_map_user); >>> >>> +/* Prepare bio for passthrough IO given an existing bvec iter */ >>> +int blk_rq_map_user_bvec(struct request *rq, struct iov_iter *iter) >>> +{ >>> + struct request_queue *q = rq->q; >>> + size_t iter_count, nr_segs; >>> + struct bio *bio; >>> + struct bio_vec *bv, *bvec_arr, *bvprvp = NULL; >>> + struct queue_limits *lim = &q->limits; >>> + unsigned int nsegs = 0, bytes = 0; >>> + int ret, i; >>> + >> >> consider this (untested), it also sets the variable i data type same >> as it comparison variable in nr_segs the loop i.e. size_t :- >> >> + struct bio_vec *bv, *bvec_arr, *bvprvp = NULL; >> + struct request_queue *q = rq->q; >> + struct queue_limits *lim = &q->limits; >> + unsigned int nsegs = 0, bytes = 0; >> + size_t iter_count, nr_segs, i; >> + struct bio *bio; >> + int ret; >> >> >>> + iter_count = iov_iter_count(iter); >>> + nr_segs = iter->nr_segs; >>> + >>> + if (!iter_count || (iter_count >> 9) > queue_max_hw_sectors(q)) >>> + return -EINVAL; >> >> can we remove braces for iter_count >> 9 without impacting the intended >> functionality? > > I think removing that make it hard to read. > I will fold all other changes you mentioned in v6. Agree - if you have to think about operator precedence, then that's a sign that the code is less readable and more fragile. -- Jens Axboe