diff options
Diffstat (limited to 'mm/migrate.c')
-rw-r--r-- | mm/migrate.c | 64 |
1 files changed, 47 insertions, 17 deletions
diff --git a/mm/migrate.c b/mm/migrate.c index 385db89f0c33..037b0967c1e3 100644 --- a/mm/migrate.c +++ b/mm/migrate.c | |||
@@ -522,15 +522,12 @@ static int writeout(struct address_space *mapping, struct page *page) | |||
522 | remove_migration_ptes(page, page); | 522 | remove_migration_ptes(page, page); |
523 | 523 | ||
524 | rc = mapping->a_ops->writepage(page, &wbc); | 524 | rc = mapping->a_ops->writepage(page, &wbc); |
525 | if (rc < 0) | ||
526 | /* I/O Error writing */ | ||
527 | return -EIO; | ||
528 | 525 | ||
529 | if (rc != AOP_WRITEPAGE_ACTIVATE) | 526 | if (rc != AOP_WRITEPAGE_ACTIVATE) |
530 | /* unlocked. Relock */ | 527 | /* unlocked. Relock */ |
531 | lock_page(page); | 528 | lock_page(page); |
532 | 529 | ||
533 | return -EAGAIN; | 530 | return (rc < 0) ? -EIO : -EAGAIN; |
534 | } | 531 | } |
535 | 532 | ||
536 | /* | 533 | /* |
@@ -990,25 +987,18 @@ out: | |||
990 | /* | 987 | /* |
991 | * Determine the nodes of an array of pages and store it in an array of status. | 988 | * Determine the nodes of an array of pages and store it in an array of status. |
992 | */ | 989 | */ |
993 | static int do_pages_stat(struct mm_struct *mm, unsigned long nr_pages, | 990 | static void do_pages_stat_array(struct mm_struct *mm, unsigned long nr_pages, |
994 | const void __user * __user *pages, | 991 | const void __user **pages, int *status) |
995 | int __user *status) | ||
996 | { | 992 | { |
997 | unsigned long i; | 993 | unsigned long i; |
998 | int err; | ||
999 | 994 | ||
1000 | down_read(&mm->mmap_sem); | 995 | down_read(&mm->mmap_sem); |
1001 | 996 | ||
1002 | for (i = 0; i < nr_pages; i++) { | 997 | for (i = 0; i < nr_pages; i++) { |
1003 | const void __user *p; | 998 | unsigned long addr = (unsigned long)(*pages); |
1004 | unsigned long addr; | ||
1005 | struct vm_area_struct *vma; | 999 | struct vm_area_struct *vma; |
1006 | struct page *page; | 1000 | struct page *page; |
1007 | 1001 | int err = -EFAULT; | |
1008 | err = -EFAULT; | ||
1009 | if (get_user(p, pages+i)) | ||
1010 | goto out; | ||
1011 | addr = (unsigned long) p; | ||
1012 | 1002 | ||
1013 | vma = find_vma(mm, addr); | 1003 | vma = find_vma(mm, addr); |
1014 | if (!vma) | 1004 | if (!vma) |
@@ -1027,12 +1017,52 @@ static int do_pages_stat(struct mm_struct *mm, unsigned long nr_pages, | |||
1027 | 1017 | ||
1028 | err = page_to_nid(page); | 1018 | err = page_to_nid(page); |
1029 | set_status: | 1019 | set_status: |
1030 | put_user(err, status+i); | 1020 | *status = err; |
1021 | |||
1022 | pages++; | ||
1023 | status++; | ||
1024 | } | ||
1025 | |||
1026 | up_read(&mm->mmap_sem); | ||
1027 | } | ||
1028 | |||
1029 | /* | ||
1030 | * Determine the nodes of a user array of pages and store it in | ||
1031 | * a user array of status. | ||
1032 | */ | ||
1033 | static int do_pages_stat(struct mm_struct *mm, unsigned long nr_pages, | ||
1034 | const void __user * __user *pages, | ||
1035 | int __user *status) | ||
1036 | { | ||
1037 | #define DO_PAGES_STAT_CHUNK_NR 16 | ||
1038 | const void __user *chunk_pages[DO_PAGES_STAT_CHUNK_NR]; | ||
1039 | int chunk_status[DO_PAGES_STAT_CHUNK_NR]; | ||
1040 | unsigned long i, chunk_nr = DO_PAGES_STAT_CHUNK_NR; | ||
1041 | int err; | ||
1042 | |||
1043 | for (i = 0; i < nr_pages; i += chunk_nr) { | ||
1044 | if (chunk_nr + i > nr_pages) | ||
1045 | chunk_nr = nr_pages - i; | ||
1046 | |||
1047 | err = copy_from_user(chunk_pages, &pages[i], | ||
1048 | chunk_nr * sizeof(*chunk_pages)); | ||
1049 | if (err) { | ||
1050 | err = -EFAULT; | ||
1051 | goto out; | ||
1052 | } | ||
1053 | |||
1054 | do_pages_stat_array(mm, chunk_nr, chunk_pages, chunk_status); | ||
1055 | |||
1056 | err = copy_to_user(&status[i], chunk_status, | ||
1057 | chunk_nr * sizeof(*chunk_status)); | ||
1058 | if (err) { | ||
1059 | err = -EFAULT; | ||
1060 | goto out; | ||
1061 | } | ||
1031 | } | 1062 | } |
1032 | err = 0; | 1063 | err = 0; |
1033 | 1064 | ||
1034 | out: | 1065 | out: |
1035 | up_read(&mm->mmap_sem); | ||
1036 | return err; | 1066 | return err; |
1037 | } | 1067 | } |
1038 | 1068 | ||