Message ID | 1595605762-17010-6-git-send-email-joshi.k@samsung.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Series | [v4,1/6] fs: introduce FMODE_ZONE_APPEND and IOCB_ZONE_APPEND | expand |
On Fri, Jul 24, 2020 at 09:19:21PM +0530, Kanchan Joshi wrote: > zone-append with bvec iov_iter gives WARN_ON, and returns -EINVAL. > Add new helper to process such iov_iter and add pages in bio honoring > zone-append specific constraints. > This is used to enable zone-append with io-uring fixed-buffer. > > Signed-off-by: Kanchan Joshi <joshi.k@samsung.com> > Signed-off-by: Selvakumar S <selvakuma.s1@samsung.com> > Signed-off-by: Nitesh Shetty <nj.shetty@samsung.com> > Signed-off-by: Javier Gonzalez <javier.gonz@samsung.com> > --- > block/bio.c | 31 ++++++++++++++++++++++++++++--- > 1 file changed, 28 insertions(+), 3 deletions(-) > > diff --git a/block/bio.c b/block/bio.c > index 0cecdbc..ade9da7 100644 > --- a/block/bio.c > +++ b/block/bio.c > @@ -975,6 +975,30 @@ static int __bio_iov_bvec_add_pages(struct bio *bio, struct iov_iter *iter) > iov_iter_advance(iter, size); > return 0; > } > +static int __bio_iov_bvec_append_add_pages(struct bio *bio, struct iov_iter *iter) Missing empty line and too long line, please stick to 80 chars for this code. Otherwise this looks sensible.
diff --git a/block/bio.c b/block/bio.c index 0cecdbc..ade9da7 100644 --- a/block/bio.c +++ b/block/bio.c @@ -975,6 +975,30 @@ static int __bio_iov_bvec_add_pages(struct bio *bio, struct iov_iter *iter) iov_iter_advance(iter, size); return 0; } +static int __bio_iov_bvec_append_add_pages(struct bio *bio, struct iov_iter *iter) +{ + const struct bio_vec *bv = iter->bvec; + unsigned int len; + size_t size; + struct request_queue *q = bio->bi_disk->queue; + unsigned int max_append_sectors = queue_max_zone_append_sectors(q); + bool same_page = false; + + if (WARN_ON_ONCE(!max_append_sectors)) + return -EINVAL; + + if (WARN_ON_ONCE(iter->iov_offset > bv->bv_len)) + return -EINVAL; + + len = min_t(size_t, bv->bv_len - iter->iov_offset, iter->count); + size = bio_add_hw_page(q, bio, bv->bv_page, len, + bv->bv_offset + iter->iov_offset, + max_append_sectors, &same_page); + if (unlikely(size != len)) + return -EINVAL; + iov_iter_advance(iter, size); + return 0; +} #define PAGE_PTRS_PER_BVEC (sizeof(struct bio_vec) / sizeof(struct page *)) @@ -1105,9 +1129,10 @@ int bio_iov_iter_get_pages(struct bio *bio, struct iov_iter *iter) do { if (bio_op(bio) == REQ_OP_ZONE_APPEND) { - if (WARN_ON_ONCE(is_bvec)) - return -EINVAL; - ret = __bio_iov_append_get_pages(bio, iter); + if (is_bvec) + ret = __bio_iov_bvec_append_add_pages(bio, iter); + else + ret = __bio_iov_append_get_pages(bio, iter); } else { if (is_bvec) ret = __bio_iov_bvec_add_pages(bio, iter);