Skip to content
  • Martin Wilck's avatar
    block: bio_iov_iter_get_pages: pin more pages for multi-segment IOs · ff325dc4
    Martin Wilck authored
    [ Upstream commit 17d51b10 ]
    
    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: 72ecad22
    
     ("block: support a full bio worth of IO for simplified bdev direct-io")
    Reviewed-by: default avatarChristoph Hellwig <hch@lst.de>
    Signed-off-by: default avatarMartin Wilck <mwilck@suse.com>
    Signed-off-by: default avatarJens Axboe <axboe@kernel.dk>
    Signed-off-by: default avatarSasha Levin <sashal@kernel.org>
    ff325dc4