]> asedeno.scripts.mit.edu Git - linux.git/blobdiff - mm/process_vm_access.c
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/dtor/input
[linux.git] / mm / process_vm_access.c
index 357aa7bef6c04ab6e924f5eaf17d9f7d19601055..de41e830cdac6a1a4ad55dfe1461fa219bf3c8cc 100644 (file)
@@ -42,12 +42,11 @@ static int process_vm_rw_pages(struct page **pages,
                if (copy > len)
                        copy = len;
 
-               if (vm_write) {
+               if (vm_write)
                        copied = copy_page_from_iter(page, offset, copy, iter);
-                       set_page_dirty_lock(page);
-               } else {
+               else
                        copied = copy_page_to_iter(page, offset, copy, iter);
-               }
+
                len -= copied;
                if (copied < copy && iov_iter_count(iter))
                        return -EFAULT;
@@ -96,7 +95,7 @@ static int process_vm_rw_single_vec(unsigned long addr,
                flags |= FOLL_WRITE;
 
        while (!rc && nr_pages && iov_iter_count(iter)) {
-               int pages = min(nr_pages, max_pages_per_loop);
+               int pinned_pages = min(nr_pages, max_pages_per_loop);
                int locked = 1;
                size_t bytes;
 
@@ -106,14 +105,15 @@ static int process_vm_rw_single_vec(unsigned long addr,
                 * current/current->mm
                 */
                down_read(&mm->mmap_sem);
-               pages = get_user_pages_remote(task, mm, pa, pages, flags,
-                                             process_pages, NULL, &locked);
+               pinned_pages = pin_user_pages_remote(task, mm, pa, pinned_pages,
+                                                    flags, process_pages,
+                                                    NULL, &locked);
                if (locked)
                        up_read(&mm->mmap_sem);
-               if (pages <= 0)
+               if (pinned_pages <= 0)
                        return -EFAULT;
 
-               bytes = pages * PAGE_SIZE - start_offset;
+               bytes = pinned_pages * PAGE_SIZE - start_offset;
                if (bytes > len)
                        bytes = len;
 
@@ -122,10 +122,12 @@ static int process_vm_rw_single_vec(unsigned long addr,
                                         vm_write);
                len -= bytes;
                start_offset = 0;
-               nr_pages -= pages;
-               pa += pages * PAGE_SIZE;
-               while (pages)
-                       put_page(process_pages[--pages]);
+               nr_pages -= pinned_pages;
+               pa += pinned_pages * PAGE_SIZE;
+
+               /* If vm_write is set, the pages need to be made dirty: */
+               unpin_user_pages_dirty_lock(process_pages, pinned_pages,
+                                           vm_write);
        }
 
        return rc;