aboutsummaryrefslogtreecommitdiffstats
path: root/mm/process_vm_access.c
diff options
context:
space:
mode:
authorAl Viro <viro@zeniv.linux.org.uk>2014-02-05 12:55:11 -0500
committerAl Viro <viro@zeniv.linux.org.uk>2014-04-01 23:19:28 -0400
commite21345f9c3f8a806604910cae886e471a860ab86 (patch)
tree4d60d4dcd35c76066160a12f5277ed07c9e5b783 /mm/process_vm_access.c
parent70eca12d80a8b51800b4ebfbc629e0ee34166779 (diff)
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/process_vm_access.c')
-rw-r--r--mm/process_vm_access.c22
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 @@
41 */ 41 */
42static int process_vm_rw_pages(struct page **pages, 42static int process_vm_rw_pages(struct page **pages,
43 unsigned offset, 43 unsigned offset,
44 unsigned long len, 44 size_t len,
45 struct iov_iter *iter, 45 struct iov_iter *iter,
46 int vm_write, 46 int vm_write,
47 unsigned int nr_pages_to_copy,
48 ssize_t *bytes_copied) 47 ssize_t *bytes_copied)
49{ 48{
50 *bytes_copied = 0; 49 *bytes_copied = 0;
51 50
52 /* Do the copy for each page */ 51 /* Do the copy for each page */
53 while (iov_iter_count(iter) && nr_pages_to_copy--) { 52 while (iov_iter_count(iter) && len) {
54 struct page *page = *pages++; 53 struct page *page = *pages++;
55 size_t copy = min_t(ssize_t, PAGE_SIZE - offset, len); 54 size_t copy = PAGE_SIZE - offset;
56 size_t copied; 55 size_t copied;
57 56
57 if (copy > len)
58 copy = len;
59
58 if (vm_write) { 60 if (vm_write) {
59 if (copy > iov_iter_count(iter)) 61 if (copy > iov_iter_count(iter))
60 copy = iov_iter_count(iter); 62 copy = iov_iter_count(iter);
@@ -121,6 +123,7 @@ static int process_vm_rw_single_vec(unsigned long addr,
121 while ((nr_pages_copied < nr_pages) && iov_iter_count(iter)) { 123 while ((nr_pages_copied < nr_pages) && iov_iter_count(iter)) {
122 int nr_pages_to_copy; 124 int nr_pages_to_copy;
123 int pages_pinned; 125 int pages_pinned;
126 size_t n;
124 nr_pages_to_copy = min(nr_pages - nr_pages_copied, 127 nr_pages_to_copy = min(nr_pages - nr_pages_copied,
125 max_pages_per_loop); 128 max_pages_per_loop);
126 129
@@ -134,18 +137,21 @@ static int process_vm_rw_single_vec(unsigned long addr,
134 if (pages_pinned <= 0) 137 if (pages_pinned <= 0)
135 return -EFAULT; 138 return -EFAULT;
136 139
140 n = pages_pinned * PAGE_SIZE - start_offset;
141 if (n > len)
142 n = len;
143
137 rc = process_vm_rw_pages(process_pages, 144 rc = process_vm_rw_pages(process_pages,
138 start_offset, len, iter, 145 start_offset, n, iter,
139 vm_write, pages_pinned, 146 vm_write,
140 &bytes_copied_loop); 147 &bytes_copied_loop);
148 len -= n;
141 start_offset = 0; 149 start_offset = 0;
142 *bytes_copied += bytes_copied_loop; 150 *bytes_copied += bytes_copied_loop;
143 len -= bytes_copied_loop;
144 nr_pages_copied += pages_pinned; 151 nr_pages_copied += pages_pinned;
145 pa += pages_pinned * PAGE_SIZE; 152 pa += pages_pinned * PAGE_SIZE;
146 while (pages_pinned) 153 while (pages_pinned)
147 put_page(process_pages[--pages_pinned]); 154 put_page(process_pages[--pages_pinned]);
148
149 if (rc < 0) 155 if (rc < 0)
150 break; 156 break;
151 } 157 }