Commit 7de55b7d authored by Johannes Thumshirn's avatar Johannes Thumshirn Committed by Jens Axboe

block: support zone append bvecs

Christoph reported that we'll likely trigger the WARN_ON_ONCE() checking
that we're not submitting a bvec with REQ_OP_ZONE_APPEND in
bio_iov_iter_get_pages() some time ago using zoned btrfs, but I couldn't
reproduce it back then.

Now Naohiro was able to trigger the bug as well with xfstests generic/095
on a zoned btrfs.

There is nothing that prevents bvec submissions via REQ_OP_ZONE_APPEND if
the hardware's zone append limit is met.
Reported-by: default avatarNaohiro Aota <naohiro.aota@wdc.com>
Reported-by: default avatarChristoph Hellwig <hch@lst.de>
Signed-off-by: default avatarJohannes Thumshirn <johannes.thumshirn@wdc.com>
Reviewed-by: default avatarChristoph Hellwig <hch@lst.de>
Link: https://lore.kernel.org/r/10bd414d9326c90cd69029077db63b363854eee5.1616600835.git.johannes.thumshirn@wdc.comSigned-off-by: default avatarJens Axboe <axboe@kernel.dk>
parent a958937f
...@@ -949,7 +949,7 @@ void bio_release_pages(struct bio *bio, bool mark_dirty) ...@@ -949,7 +949,7 @@ void bio_release_pages(struct bio *bio, bool mark_dirty)
} }
EXPORT_SYMBOL_GPL(bio_release_pages); EXPORT_SYMBOL_GPL(bio_release_pages);
static int bio_iov_bvec_set(struct bio *bio, struct iov_iter *iter) static void __bio_iov_bvec_set(struct bio *bio, struct iov_iter *iter)
{ {
WARN_ON_ONCE(bio->bi_max_vecs); WARN_ON_ONCE(bio->bi_max_vecs);
...@@ -959,11 +959,26 @@ static int bio_iov_bvec_set(struct bio *bio, struct iov_iter *iter) ...@@ -959,11 +959,26 @@ static int bio_iov_bvec_set(struct bio *bio, struct iov_iter *iter)
bio->bi_iter.bi_size = iter->count; bio->bi_iter.bi_size = iter->count;
bio_set_flag(bio, BIO_NO_PAGE_REF); bio_set_flag(bio, BIO_NO_PAGE_REF);
bio_set_flag(bio, BIO_CLONED); bio_set_flag(bio, BIO_CLONED);
}
static int bio_iov_bvec_set(struct bio *bio, struct iov_iter *iter)
{
__bio_iov_bvec_set(bio, iter);
iov_iter_advance(iter, iter->count); iov_iter_advance(iter, iter->count);
return 0; return 0;
} }
static int bio_iov_bvec_set_append(struct bio *bio, struct iov_iter *iter)
{
struct request_queue *q = bio->bi_bdev->bd_disk->queue;
struct iov_iter i = *iter;
iov_iter_truncate(&i, queue_max_zone_append_sectors(q) << 9);
__bio_iov_bvec_set(bio, &i);
iov_iter_advance(iter, i.count);
return 0;
}
#define PAGE_PTRS_PER_BVEC (sizeof(struct bio_vec) / sizeof(struct page *)) #define PAGE_PTRS_PER_BVEC (sizeof(struct bio_vec) / sizeof(struct page *))
/** /**
...@@ -1094,8 +1109,8 @@ int bio_iov_iter_get_pages(struct bio *bio, struct iov_iter *iter) ...@@ -1094,8 +1109,8 @@ int bio_iov_iter_get_pages(struct bio *bio, struct iov_iter *iter)
int ret = 0; int ret = 0;
if (iov_iter_is_bvec(iter)) { if (iov_iter_is_bvec(iter)) {
if (WARN_ON_ONCE(bio_op(bio) == REQ_OP_ZONE_APPEND)) if (bio_op(bio) == REQ_OP_ZONE_APPEND)
return -EINVAL; return bio_iov_bvec_set_append(bio, iter);
return bio_iov_bvec_set(bio, iter); return bio_iov_bvec_set(bio, iter);
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment