diff options
author | Al Viro | 2014-02-05 18:55:11 +0100 |
---|---|---|
committer | Al Viro | 2014-04-02 05:19:28 +0200 |
commit | e21345f9c3f8a806604910cae886e471a860ab86 (patch) | |
tree | 4d60d4dcd35c76066160a12f5277ed07c9e5b783 /mm | |
parent | process_vm_access: take get_user_pages/put_pages one level up (diff) | |
download | kernel-qcow2-linux-e21345f9c3f8a806604910cae886e471a860ab86.tar.gz kernel-qcow2-linux-e21345f9c3f8a806604910cae886e471a860ab86.tar.xz kernel-qcow2-linux-e21345f9c3f8a806604910cae886e471a860ab86.zip |
process_vm_rw_pages(): pass accurate amount of bytes
... makes passing the amount of pages unnecessary
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Diffstat (limited to 'mm')
-rw-r--r-- | mm/process_vm_access.c | 22 |
1 files changed, 14 insertions, 8 deletions
diff --git a/mm/process_vm_access.c b/mm/process_vm_access.c index c2a1916bacbf..83252d783482 100644 --- a/mm/process_vm_access.c +++ b/mm/process_vm_access.c @@ -41,20 +41,22 @@ */ static int process_vm_rw_pages(struct page **pages, unsigned offset, - unsigned long len, + size_t len, struct iov_iter *iter, int vm_write, - unsigned int nr_pages_to_copy, ssize_t *bytes_copied) { *bytes_copied = 0; /* Do the copy for each page */ - while (iov_iter_count(iter) && nr_pages_to_copy--) { + while (iov_iter_count(iter) && len) { struct page *page = *pages++; - size_t copy = min_t(ssize_t, PAGE_SIZE - offset, len); + size_t copy = PAGE_SIZE - offset; size_t copied; + if (copy > len) + copy = len; + if (vm_write) { if (copy > iov_iter_count(iter)) copy = iov_iter_count(iter); @@ -121,6 +123,7 @@ static int process_vm_rw_single_vec(unsigned long addr, while ((nr_pages_copied < nr_pages) && iov_iter_count(iter)) { int nr_pages_to_copy; int pages_pinned; + size_t n; nr_pages_to_copy = min(nr_pages - nr_pages_copied, max_pages_per_loop); @@ -134,18 +137,21 @@ static int process_vm_rw_single_vec(unsigned long addr, if (pages_pinned <= 0) return -EFAULT; + n = pages_pinned * PAGE_SIZE - start_offset; + if (n > len) + n = len; + rc = process_vm_rw_pages(process_pages, - start_offset, len, iter, - vm_write, pages_pinned, + start_offset, n, iter, + vm_write, &bytes_copied_loop); + len -= n; start_offset = 0; *bytes_copied += bytes_copied_loop; - len -= bytes_copied_loop; nr_pages_copied += pages_pinned; pa += pages_pinned * PAGE_SIZE; while (pages_pinned) put_page(process_pages[--pages_pinned]); - if (rc < 0) break; } |