Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1031309AbbDWXFP (ORCPT ); Thu, 23 Apr 2015 19:05:15 -0400 Received: from mailout4.samsung.com ([203.254.224.34]:45077 "EHLO mailout4.samsung.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1031199AbbDWXFK (ORCPT ); Thu, 23 Apr 2015 19:05:10 -0400 X-AuditID: cbfee61b-f79536d000000f1f-a7-55397aa469d4 From: Ming Lin To: linux-kernel@vger.kernel.org Cc: Christoph Hellwig , Kent Overstreet , Jens Axboe , Dongsu Park , "Hans J. Koch" , Greg Kroah-Hartman , Al Viro , Ming Lin Subject: [PATCH v3 1/4] block: refactor iov_count_pages() from bio_{copy,map}_user_iov() Date: Thu, 23 Apr 2015 16:04:32 -0700 Message-id: <1429830275-6792-2-git-send-email-mlin@kernel.org> X-Mailer: git-send-email 1.9.1 In-reply-to: <1429830275-6792-1-git-send-email-mlin@kernel.org> References: <1429830275-6792-1-git-send-email-mlin@kernel.org> X-Brightmail-Tracker: H4sIAAAAAAAAA+NgFlrHLMWRmVeSWpSXmKPExsVy+t9jQd0lVZahBiduCVusvtvPZnF59Sp2 i+bF69ksTk9YxGRx9Ox0dosjTVUWl3fNYbM4v+0kq8X5v8dZHTg9ds66y+4x/6GXx+YVWh6X z5Z6bFrVyeaxf+4ado8/fz4ze3zeJOex6clbpgDOKC6blNSczLLUIn27BK6MFY8tC3ZJVdxd PYm1gbFJtIuRk0NCwETiyaf9TBC2mMSFe+vZuhi5OIQEpjNKfL79nxHC+ckocbb5HTNIFZuA gsTBdRvAOkSA7M29z1hBipgFdjNJ9C35CFYkLBAl0XxiGguIzSKgKnHo3g+wOK+AnUTDnQts EOvkJE4em8wKYnMK2Et8PfkYLC4EVLPy9hSmCYy8CxgZVjGKphYkFxQnpeca6RUn5haX5qXr JefnbmIEh+Iz6R2MqxosDjEKcDAq8fB+KLIIFWJNLCuuzD3EKMHBrCTCy15uGSrEm5JYWZVa lB9fVJqTWnyIUZqDRUmcd46uXKiQQHpiSWp2ampBahFMlomDU6qBcWq9ON/OUouDvunrOzZ9 O+W+6ux3Zye2eq3yB4dl9344ZLfuR3zlFN2Z7ip3OaQcinpS/Q2WrnC9diD5vvxyh7/vvwpa KGhILVz2gTNupv58YcfoVgOZt8Gfp4rG1qZHcpZ/Mci6GP5jWUfced2Uq5ZiF3aI7l5Q7q0l q3J4flMJn+PqaWw/lViKMxINtZiLihMB6l7xHEECAAA= Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Length: 3510 Lines: 126 From: Kent Overstreet Refactor the common part in bio_copy_user_iov() and __bio_map_user_iov() to separate out iov_count_pages() into the general iov_iter API, instead of open coding iov iterations as done previously. This commit should contain only literal replacements, without functional changes. Cc: Christoph Hellwig Cc: Jens Axboe Cc: "Hans J. Koch" Cc: Greg Kroah-Hartman Cc: Al Viro Signed-off-by: Kent Overstreet [dpark: add more description in commit message] [mlin: move iov_count_pages to block/bio.c] Signed-off-by: Dongsu Park Signed-off-by: Ming Lin --- block/bio.c | 70 +++++++++++++++++++++++++++++-------------------------------- 1 file changed, 33 insertions(+), 37 deletions(-) diff --git a/block/bio.c b/block/bio.c index 05c2864..eb4471a 100644 --- a/block/bio.c +++ b/block/bio.c @@ -1139,6 +1139,33 @@ int bio_uncopy_user(struct bio *bio) } EXPORT_SYMBOL(bio_uncopy_user); +static int iov_count_pages(const struct iov_iter *iter, unsigned align) +{ + struct iov_iter i = *iter; + int nr_pages = 0; + + while (iov_iter_count(&i)) { + unsigned long uaddr = (unsigned long) i.iov->iov_base + + i.iov_offset; + unsigned long len = i.iov->iov_len - i.iov_offset; + + if ((uaddr & align) || (len & align)) + return -EINVAL; + + /* + * Overflow, abort + */ + if (uaddr + len < uaddr) + return -EINVAL; + + nr_pages += DIV_ROUND_UP(len + offset_in_page(uaddr), + PAGE_SIZE); + iov_iter_advance(&i, len); + } + + return nr_pages; +} + /** * bio_copy_user_iov - copy user data to bio * @q: destination block queue @@ -1163,24 +1190,9 @@ struct bio *bio_copy_user_iov(struct request_queue *q, unsigned int len = iter->count; unsigned int offset = map_data ? map_data->offset & ~PAGE_MASK : 0; - for (i = 0; i < iter->nr_segs; i++) { - unsigned long uaddr; - unsigned long end; - unsigned long start; - - uaddr = (unsigned long) iter->iov[i].iov_base; - end = (uaddr + iter->iov[i].iov_len + PAGE_SIZE - 1) - >> PAGE_SHIFT; - start = uaddr >> PAGE_SHIFT; - - /* - * Overflow, abort - */ - if (end < start) - return ERR_PTR(-EINVAL); - - nr_pages += end - start; - } + nr_pages = iov_count_pages(iter, 0); + if (nr_pages < 0) + return ERR_PTR(nr_pages); if (offset) nr_pages++; @@ -1292,25 +1304,9 @@ struct bio *bio_map_user_iov(struct request_queue *q, struct iov_iter i; struct iovec iov; - iov_for_each(iov, i, *iter) { - unsigned long uaddr = (unsigned long) iov.iov_base; - unsigned long len = iov.iov_len; - unsigned long end = (uaddr + len + PAGE_SIZE - 1) >> PAGE_SHIFT; - unsigned long start = uaddr >> PAGE_SHIFT; - - /* - * Overflow, abort - */ - if (end < start) - return ERR_PTR(-EINVAL); - - nr_pages += end - start; - /* - * buffer must be aligned to at least hardsector size for now - */ - if (uaddr & queue_dma_alignment(q)) - return ERR_PTR(-EINVAL); - } + nr_pages = iov_count_pages(iter, queue_dma_alignment(q)); + if (nr_pages < 0) + return ERR_PTR(nr_pages); if (!nr_pages) return ERR_PTR(-EINVAL); -- 1.9.1 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/