diff options
| author | Al Viro <viro@zeniv.linux.org.uk> | 2014-02-05 12:55:11 -0500 |
|---|---|---|
| committer | Al Viro <viro@zeniv.linux.org.uk> | 2014-04-01 23:19:28 -0400 |
| commit | e21345f9c3f8a806604910cae886e471a860ab86 (patch) | |
| tree | 4d60d4dcd35c76066160a12f5277ed07c9e5b783 | |
| parent | 70eca12d80a8b51800b4ebfbc629e0ee34166779 (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>
| -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 @@ | |||
| 41 | */ | 41 | */ |
| 42 | static int process_vm_rw_pages(struct page **pages, | 42 | static 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 | } |
