Fix up recent get_user_pages() handling

The VM_FAULT_WRITE thing is an extra bit, not a valid return value, and
has to be treated as such by get_user_pages().

Signed-off-by: Linus Torvalds <torvalds@osdl.org>

+13 -9
+13 -9
mm/memory.c
··· 949 949 950 950 cond_resched_lock(&mm->page_table_lock); 951 951 while (!(page = follow_page(mm, start, write_access))) { 952 + int ret; 953 + 952 954 /* 953 955 * Shortcut for anonymous pages. We don't want 954 956 * to force the creation of pages tables for ··· 963 961 break; 964 962 } 965 963 spin_unlock(&mm->page_table_lock); 966 - switch (__handle_mm_fault(mm, vma, start, 967 - write_access)) { 968 - case VM_FAULT_WRITE: 969 - /* 970 - * do_wp_page has broken COW when 971 - * necessary, even if maybe_mkwrite 972 - * decided not to set pte_write 973 - */ 964 + ret = __handle_mm_fault(mm, vma, start, write_access); 965 + 966 + /* 967 + * The VM_FAULT_WRITE bit tells us that do_wp_page has 968 + * broken COW when necessary, even if maybe_mkwrite 969 + * decided not to set pte_write. We can thus safely do 970 + * subsequent page lookups as if they were reads. 971 + */ 972 + if (ret & VM_FAULT_WRITE) 974 973 write_access = 0; 975 - /* FALLTHRU */ 974 + 975 + switch (ret & ~VM_FAULT_WRITE) { 976 976 case VM_FAULT_MINOR: 977 977 tsk->min_flt++; 978 978 break;