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 | ||
