|
@@ -1002,33 +1002,27 @@ static int do_pages_stat(struct mm_struct *mm, unsigned long nr_pages,
|
|
|
#define DO_PAGES_STAT_CHUNK_NR 16
|
|
|
const void __user *chunk_pages[DO_PAGES_STAT_CHUNK_NR];
|
|
|
int chunk_status[DO_PAGES_STAT_CHUNK_NR];
|
|
|
- unsigned long i, chunk_nr = DO_PAGES_STAT_CHUNK_NR;
|
|
|
- int err;
|
|
|
|
|
|
- for (i = 0; i < nr_pages; i += chunk_nr) {
|
|
|
- if (chunk_nr > nr_pages - i)
|
|
|
- chunk_nr = nr_pages - i;
|
|
|
+ while (nr_pages) {
|
|
|
+ unsigned long chunk_nr;
|
|
|
|
|
|
- err = copy_from_user(chunk_pages, &pages[i],
|
|
|
- chunk_nr * sizeof(*chunk_pages));
|
|
|
- if (err) {
|
|
|
- err = -EFAULT;
|
|
|
- goto out;
|
|
|
- }
|
|
|
+ chunk_nr = nr_pages;
|
|
|
+ if (chunk_nr > DO_PAGES_STAT_CHUNK_NR)
|
|
|
+ chunk_nr = DO_PAGES_STAT_CHUNK_NR;
|
|
|
+
|
|
|
+ if (copy_from_user(chunk_pages, pages, chunk_nr * sizeof(*chunk_pages)))
|
|
|
+ break;
|
|
|
|
|
|
do_pages_stat_array(mm, chunk_nr, chunk_pages, chunk_status);
|
|
|
|
|
|
- err = copy_to_user(&status[i], chunk_status,
|
|
|
- chunk_nr * sizeof(*chunk_status));
|
|
|
- if (err) {
|
|
|
- err = -EFAULT;
|
|
|
- goto out;
|
|
|
- }
|
|
|
- }
|
|
|
- err = 0;
|
|
|
+ if (copy_to_user(status, chunk_status, chunk_nr * sizeof(*status)))
|
|
|
+ break;
|
|
|
|
|
|
-out:
|
|
|
- return err;
|
|
|
+ pages += chunk_nr;
|
|
|
+ status += chunk_nr;
|
|
|
+ nr_pages -= chunk_nr;
|
|
|
+ }
|
|
|
+ return nr_pages ? -EFAULT : 0;
|
|
|
}
|
|
|
|
|
|
/*
|