On 23/03/2021 13:30, Christoph Hellwig wrote: > On Tue, Mar 23, 2021 at 08:06:56PM +0900, Johannes Thumshirn wrote: >> diff --git a/block/bio.c b/block/bio.c >> index 26b7f721cda8..215fe24a01ee 100644 >> --- a/block/bio.c >> +++ b/block/bio.c >> @@ -1094,8 +1094,14 @@ int bio_iov_iter_get_pages(struct bio *bio, struct iov_iter *iter) >> int ret = 0; >> >> if (iov_iter_is_bvec(iter)) { >> - if (WARN_ON_ONCE(bio_op(bio) == REQ_OP_ZONE_APPEND)) >> - return -EINVAL; >> + if (bio_op(bio) == REQ_OP_ZONE_APPEND) { >> + struct request_queue *q = bio->bi_bdev->bd_disk->queue; >> + unsigned int max_append = >> + queue_max_zone_append_sectors(q) << 9; >> + >> + if (WARN_ON_ONCE(iter->count > max_append)) >> + return -EINVAL; >> + } > > That is not correct. bio_iov_iter_get_pages just fills the bio as far > as we can, and then returns 0 for the next call to continue. Basically > what you want here is a partial version of bio_iov_bvec_set. > Isn't that what I did? The above is checking if we have REQ_OP_ZONE_APPEND and then returns EINVAL if iter->count is bigger than queue_max_zone_append_sectors(). If the check doesn't fail, its going to call bio_iov_bvec_set().