Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 16 additions & 2 deletions lib/iov_iter.c
Original file line number Diff line number Diff line change
Expand Up @@ -1921,15 +1921,29 @@ ssize_t iov_iter_extract_bvecs(struct iov_iter *iter, struct bio_vec *bv,
unsigned short max_vecs, unsigned mem_align_mask,
iov_iter_extraction_t extraction_flags)
{
unsigned long start = (unsigned long)iter_iov_addr(iter);
unsigned short entries_left = max_vecs - *nr_vecs;
unsigned short nr_pages, i = 0;
size_t left, offset, len;
struct page **pages;
ssize_t size;

if ((start | iter_iov_len(iter)) & mem_align_mask)
/*
* DMA engines typically have both memory address and length alignment
* requirements, so check these against the alignment mask. For UBUF,
* IOVEC and KVEC, only the current segment will be extracted from; for
* everything else we might extract from multiple segments, so we need
* to check those too.
*/
if (likely(iter_is_ubuf(iter) ||
iter_is_iovec(iter) ||
iov_iter_is_kvec(iter))) {
unsigned long start = (unsigned long)iter_iov_addr(iter);

if ((start | iter_iov_len(iter)) & mem_align_mask)
return -EINVAL;
} else if (iov_iter_alignment(iter) & mem_align_mask) {
return -EINVAL;
}

/*
* Move page array up in the allocated memory for the bio vecs as far as
Expand Down