block: bio_iov_iter_get_pages: pin more pages for multi-segment IOs
authorMartin Wilck <mwilck@suse.com>
Wed, 25 Jul 2018 21:15:09 +0000 (23:15 +0200)
committerJens Axboe <axboe@kernel.dk>
Thu, 26 Jul 2018 17:52:36 +0000 (11:52 -0600)
commit17d51b10d7773e4618bcac64648f30f12d4078fb
treec6b76e08ffb36ffac6e7e82047333316935bf0a4
parent9362dd1109f87a9d0a798fbc890cb339c171ed35
block: bio_iov_iter_get_pages: pin more pages for multi-segment IOs

bio_iov_iter_get_pages() currently only adds pages for the next non-zero
segment from the iov_iter to the bio. That's suboptimal for callers,
which typically try to pin as many pages as fit into the bio. This patch
converts the current bio_iov_iter_get_pages() into a static helper, and
introduces a new helper that allocates as many pages as

 1) fit into the bio,
 2) are present in the iov_iter,
 3) and can be pinned by MM.

Error is returned only if zero pages could be pinned. Because of 3), a
zero return value doesn't necessarily mean all pages have been pinned.
Callers that have to pin every page in the iov_iter must still call this
function in a loop (this is currently the case).

This change matters most for __blkdev_direct_IO_simple(), which calls
bio_iov_iter_get_pages() only once. If it obtains less pages than
requested, it returns a "short write" or "short read", and
__generic_file_write_iter() falls back to buffered writes, which may
lead to data corruption.

Fixes: 72ecad22d9f1 ("block: support a full bio worth of IO for simplified bdev direct-io")
Reviewed-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Martin Wilck <mwilck@suse.com>
Signed-off-by: Jens Axboe <axboe@kernel.dk>
block/bio.c