Commit 98f0bc99 authored by Al Viro's avatar Al Viro
Browse files

bio_map_user_iov(): move alignment check into the main loop



Signed-off-by: default avatarAl Viro <viro@zeniv.linux.org.uk>
parent e2e115d1
Loading
Loading
Loading
Loading
+27 −27
Original line number Diff line number Diff line
@@ -1344,11 +1344,6 @@ struct bio *bio_map_user_iov(struct request_queue *q,
			return ERR_PTR(-EINVAL);

		nr_pages += end - start;
		/*
		 * buffer must be aligned to at least logical block size for now
		 */
		if (uaddr & queue_dma_alignment(q))
			return ERR_PTR(-EINVAL);
	}

	if (!nr_pages)
@@ -1373,14 +1368,19 @@ struct bio *bio_map_user_iov(struct request_queue *q,

		npages = DIV_ROUND_UP(offs + bytes, PAGE_SIZE);

		if (unlikely(offs & queue_dma_alignment(q))) {
			ret = -EINVAL;
			j = 0;
		} else {
			for (j = 0; j < npages; j++) {
				struct page *page = pages[j];
				unsigned int n = PAGE_SIZE - offs;
				unsigned short prev_bi_vcnt = bio->bi_vcnt;

				if (n > bytes)
					n = bytes;

			if (!bio_add_pc_page(q, bio, pages[j], n, offs))
				if (!bio_add_pc_page(q, bio, page, n, offs))
					break;

				/*
@@ -1388,14 +1388,14 @@ struct bio *bio_map_user_iov(struct request_queue *q,
				 * drop page reference if needed
				 */
				if (bio->bi_vcnt == prev_bi_vcnt)
				put_page(pages[j]);
					put_page(page);

				added += n;
				bytes -= n;
				offs = 0;
			}
			iov_iter_advance(&i, added);

		}
		/*
		 * release the pages we didn't map into the bio, if any
		 */