Commit 1dd909affbc45412270fd196d1181404d2e416b1
Exists in
ti-lsk-linux-4.1.y
and in
10 other branches
Merge branch 'akpm' (patches from Andrew Morton)
Merge misc fixes from Andrew Morton: "10 fixes" * emailed patches from Andrew Morton <akpm@linux-foundation.org>: slab: fix nodeid bounds check for non-contiguous node IDs lib/genalloc.c: export devm_gen_pool_create() for modules mm: fix anon_vma_clone() error treatment mm: fix swapoff hang after page migration and fork fat: fix oops on corrupted vfat fs ipc/sem.c: fully initialize sem_array before making it visible drivers/input/evdev.c: don't kfree() a vmalloc address mm/vmpressure.c: fix race in vmpressure_work_fn() mm: frontswap: invalidate expired data on a dup-store failure mm: do not overwrite reserved pages counter at show_mem()
Showing 11 changed files Side-by-side Diff
drivers/input/evdev.c
fs/fat/namei_vfat.c
... | ... | @@ -736,7 +736,12 @@ |
736 | 736 | } |
737 | 737 | |
738 | 738 | alias = d_find_alias(inode); |
739 | - if (alias && !vfat_d_anon_disconn(alias)) { | |
739 | + /* | |
740 | + * Checking "alias->d_parent == dentry->d_parent" to make sure | |
741 | + * FS is not corrupted (especially double linked dir). | |
742 | + */ | |
743 | + if (alias && alias->d_parent == dentry->d_parent && | |
744 | + !vfat_d_anon_disconn(alias)) { | |
740 | 745 | /* |
741 | 746 | * This inode has non anonymous-DCACHE_DISCONNECTED |
742 | 747 | * dentry. This means, the user did ->lookup() by an |
... | ... | @@ -755,12 +760,9 @@ |
755 | 760 | |
756 | 761 | out: |
757 | 762 | mutex_unlock(&MSDOS_SB(sb)->s_lock); |
758 | - dentry->d_time = dentry->d_parent->d_inode->i_version; | |
759 | - dentry = d_splice_alias(inode, dentry); | |
760 | - if (dentry) | |
761 | - dentry->d_time = dentry->d_parent->d_inode->i_version; | |
762 | - return dentry; | |
763 | - | |
763 | + if (!inode) | |
764 | + dentry->d_time = dir->i_version; | |
765 | + return d_splice_alias(inode, dentry); | |
764 | 766 | error: |
765 | 767 | mutex_unlock(&MSDOS_SB(sb)->s_lock); |
766 | 768 | return ERR_PTR(err); |
... | ... | @@ -793,7 +795,6 @@ |
793 | 795 | inode->i_mtime = inode->i_atime = inode->i_ctime = ts; |
794 | 796 | /* timestamp is already written, so mark_inode_dirty() is unneeded. */ |
795 | 797 | |
796 | - dentry->d_time = dentry->d_parent->d_inode->i_version; | |
797 | 798 | d_instantiate(dentry, inode); |
798 | 799 | out: |
799 | 800 | mutex_unlock(&MSDOS_SB(sb)->s_lock); |
... | ... | @@ -824,6 +825,7 @@ |
824 | 825 | clear_nlink(inode); |
825 | 826 | inode->i_mtime = inode->i_atime = CURRENT_TIME_SEC; |
826 | 827 | fat_detach(inode); |
828 | + dentry->d_time = dir->i_version; | |
827 | 829 | out: |
828 | 830 | mutex_unlock(&MSDOS_SB(sb)->s_lock); |
829 | 831 | |
... | ... | @@ -849,6 +851,7 @@ |
849 | 851 | clear_nlink(inode); |
850 | 852 | inode->i_mtime = inode->i_atime = CURRENT_TIME_SEC; |
851 | 853 | fat_detach(inode); |
854 | + dentry->d_time = dir->i_version; | |
852 | 855 | out: |
853 | 856 | mutex_unlock(&MSDOS_SB(sb)->s_lock); |
854 | 857 | |
... | ... | @@ -889,7 +892,6 @@ |
889 | 892 | inode->i_mtime = inode->i_atime = inode->i_ctime = ts; |
890 | 893 | /* timestamp is already written, so mark_inode_dirty() is unneeded. */ |
891 | 894 | |
892 | - dentry->d_time = dentry->d_parent->d_inode->i_version; | |
893 | 895 | d_instantiate(dentry, inode); |
894 | 896 | |
895 | 897 | mutex_unlock(&MSDOS_SB(sb)->s_lock); |
ipc/sem.c
... | ... | @@ -507,13 +507,6 @@ |
507 | 507 | return retval; |
508 | 508 | } |
509 | 509 | |
510 | - id = ipc_addid(&sem_ids(ns), &sma->sem_perm, ns->sc_semmni); | |
511 | - if (id < 0) { | |
512 | - ipc_rcu_putref(sma, sem_rcu_free); | |
513 | - return id; | |
514 | - } | |
515 | - ns->used_sems += nsems; | |
516 | - | |
517 | 510 | sma->sem_base = (struct sem *) &sma[1]; |
518 | 511 | |
519 | 512 | for (i = 0; i < nsems; i++) { |
... | ... | @@ -528,6 +521,14 @@ |
528 | 521 | INIT_LIST_HEAD(&sma->list_id); |
529 | 522 | sma->sem_nsems = nsems; |
530 | 523 | sma->sem_ctime = get_seconds(); |
524 | + | |
525 | + id = ipc_addid(&sem_ids(ns), &sma->sem_perm, ns->sc_semmni); | |
526 | + if (id < 0) { | |
527 | + ipc_rcu_putref(sma, sem_rcu_free); | |
528 | + return id; | |
529 | + } | |
530 | + ns->used_sems += nsems; | |
531 | + | |
531 | 532 | sem_unlock(sma, -1); |
532 | 533 | rcu_read_unlock(); |
533 | 534 |
lib/genalloc.c
lib/show_mem.c
mm/frontswap.c
... | ... | @@ -244,8 +244,10 @@ |
244 | 244 | the (older) page from frontswap |
245 | 245 | */ |
246 | 246 | inc_frontswap_failed_stores(); |
247 | - if (dup) | |
247 | + if (dup) { | |
248 | 248 | __frontswap_clear(sis, offset); |
249 | + frontswap_ops->invalidate_page(type, offset); | |
250 | + } | |
249 | 251 | } |
250 | 252 | if (frontswap_writethrough_enabled) |
251 | 253 | /* report failure so swap also writes to swap device */ |
mm/memory.c
... | ... | @@ -815,20 +815,20 @@ |
815 | 815 | if (!pte_file(pte)) { |
816 | 816 | swp_entry_t entry = pte_to_swp_entry(pte); |
817 | 817 | |
818 | - if (swap_duplicate(entry) < 0) | |
819 | - return entry.val; | |
818 | + if (likely(!non_swap_entry(entry))) { | |
819 | + if (swap_duplicate(entry) < 0) | |
820 | + return entry.val; | |
820 | 821 | |
821 | - /* make sure dst_mm is on swapoff's mmlist. */ | |
822 | - if (unlikely(list_empty(&dst_mm->mmlist))) { | |
823 | - spin_lock(&mmlist_lock); | |
824 | - if (list_empty(&dst_mm->mmlist)) | |
825 | - list_add(&dst_mm->mmlist, | |
826 | - &src_mm->mmlist); | |
827 | - spin_unlock(&mmlist_lock); | |
828 | - } | |
829 | - if (likely(!non_swap_entry(entry))) | |
822 | + /* make sure dst_mm is on swapoff's mmlist. */ | |
823 | + if (unlikely(list_empty(&dst_mm->mmlist))) { | |
824 | + spin_lock(&mmlist_lock); | |
825 | + if (list_empty(&dst_mm->mmlist)) | |
826 | + list_add(&dst_mm->mmlist, | |
827 | + &src_mm->mmlist); | |
828 | + spin_unlock(&mmlist_lock); | |
829 | + } | |
830 | 830 | rss[MM_SWAPENTS]++; |
831 | - else if (is_migration_entry(entry)) { | |
831 | + } else if (is_migration_entry(entry)) { | |
832 | 832 | page = migration_entry_to_page(entry); |
833 | 833 | |
834 | 834 | if (PageAnon(page)) |
mm/mmap.c
... | ... | @@ -776,8 +776,11 @@ |
776 | 776 | * shrinking vma had, to cover any anon pages imported. |
777 | 777 | */ |
778 | 778 | if (exporter && exporter->anon_vma && !importer->anon_vma) { |
779 | - if (anon_vma_clone(importer, exporter)) | |
780 | - return -ENOMEM; | |
779 | + int error; | |
780 | + | |
781 | + error = anon_vma_clone(importer, exporter); | |
782 | + if (error) | |
783 | + return error; | |
781 | 784 | importer->anon_vma = exporter->anon_vma; |
782 | 785 | } |
783 | 786 | } |
... | ... | @@ -2469,7 +2472,8 @@ |
2469 | 2472 | if (err) |
2470 | 2473 | goto out_free_vma; |
2471 | 2474 | |
2472 | - if (anon_vma_clone(new, vma)) | |
2475 | + err = anon_vma_clone(new, vma); | |
2476 | + if (err) | |
2473 | 2477 | goto out_free_mpol; |
2474 | 2478 | |
2475 | 2479 | if (new->vm_file) |
mm/rmap.c
... | ... | @@ -274,6 +274,7 @@ |
274 | 274 | { |
275 | 275 | struct anon_vma_chain *avc; |
276 | 276 | struct anon_vma *anon_vma; |
277 | + int error; | |
277 | 278 | |
278 | 279 | /* Don't bother if the parent process has no anon_vma here. */ |
279 | 280 | if (!pvma->anon_vma) |
... | ... | @@ -283,8 +284,9 @@ |
283 | 284 | * First, attach the new VMA to the parent VMA's anon_vmas, |
284 | 285 | * so rmap can find non-COWed pages in child processes. |
285 | 286 | */ |
286 | - if (anon_vma_clone(vma, pvma)) | |
287 | - return -ENOMEM; | |
287 | + error = anon_vma_clone(vma, pvma); | |
288 | + if (error) | |
289 | + return error; | |
288 | 290 | |
289 | 291 | /* Then add our own anon_vma. */ |
290 | 292 | anon_vma = anon_vma_alloc(); |
mm/slab.c
mm/vmpressure.c
... | ... | @@ -165,6 +165,7 @@ |
165 | 165 | unsigned long scanned; |
166 | 166 | unsigned long reclaimed; |
167 | 167 | |
168 | + spin_lock(&vmpr->sr_lock); | |
168 | 169 | /* |
169 | 170 | * Several contexts might be calling vmpressure(), so it is |
170 | 171 | * possible that the work was rescheduled again before the old |
171 | 172 | |
172 | 173 | |
... | ... | @@ -173,11 +174,12 @@ |
173 | 174 | * here. No need for any locks here since we don't care if |
174 | 175 | * vmpr->reclaimed is in sync. |
175 | 176 | */ |
176 | - if (!vmpr->scanned) | |
177 | + scanned = vmpr->scanned; | |
178 | + if (!scanned) { | |
179 | + spin_unlock(&vmpr->sr_lock); | |
177 | 180 | return; |
181 | + } | |
178 | 182 | |
179 | - spin_lock(&vmpr->sr_lock); | |
180 | - scanned = vmpr->scanned; | |
181 | 183 | reclaimed = vmpr->reclaimed; |
182 | 184 | vmpr->scanned = 0; |
183 | 185 | vmpr->reclaimed = 0; |