diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2014-12-03 12:36:20 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2014-12-03 12:36:20 -0500 |
commit | 1dd909affbc45412270fd196d1181404d2e416b1 (patch) | |
tree | 9dcd03d002da6b55dc02062dc55df78922d6d2dd | |
parent | 3a18ca061311f2f1ee9c44012f89c7436d392117 (diff) | |
parent | 7c3fbbdd04a681a1992ad6a3d7a36a63ff668753 (diff) |
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()
-rw-r--r-- | drivers/input/evdev.c | 2 | ||||
-rw-r--r-- | fs/fat/namei_vfat.c | 20 | ||||
-rw-r--r-- | ipc/sem.c | 15 | ||||
-rw-r--r-- | lib/genalloc.c | 1 | ||||
-rw-r--r-- | lib/show_mem.c | 2 | ||||
-rw-r--r-- | mm/frontswap.c | 4 | ||||
-rw-r--r-- | mm/memory.c | 26 | ||||
-rw-r--r-- | mm/mmap.c | 10 | ||||
-rw-r--r-- | mm/rmap.c | 6 | ||||
-rw-r--r-- | mm/slab.c | 2 | ||||
-rw-r--r-- | mm/vmpressure.c | 8 |
11 files changed, 55 insertions, 41 deletions
diff --git a/drivers/input/evdev.c b/drivers/input/evdev.c index bc203485716d..8afa28e4570e 100644 --- a/drivers/input/evdev.c +++ b/drivers/input/evdev.c | |||
@@ -421,7 +421,7 @@ static int evdev_open(struct inode *inode, struct file *file) | |||
421 | 421 | ||
422 | err_free_client: | 422 | err_free_client: |
423 | evdev_detach_client(evdev, client); | 423 | evdev_detach_client(evdev, client); |
424 | kfree(client); | 424 | kvfree(client); |
425 | return error; | 425 | return error; |
426 | } | 426 | } |
427 | 427 | ||
diff --git a/fs/fat/namei_vfat.c b/fs/fat/namei_vfat.c index 6df8d3d885e5..b8b92c2f9683 100644 --- a/fs/fat/namei_vfat.c +++ b/fs/fat/namei_vfat.c | |||
@@ -736,7 +736,12 @@ static struct dentry *vfat_lookup(struct inode *dir, struct dentry *dentry, | |||
736 | } | 736 | } |
737 | 737 | ||
738 | alias = d_find_alias(inode); | 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 | * This inode has non anonymous-DCACHE_DISCONNECTED | 746 | * This inode has non anonymous-DCACHE_DISCONNECTED |
742 | * dentry. This means, the user did ->lookup() by an | 747 | * dentry. This means, the user did ->lookup() by an |
@@ -755,12 +760,9 @@ static struct dentry *vfat_lookup(struct inode *dir, struct dentry *dentry, | |||
755 | 760 | ||
756 | out: | 761 | out: |
757 | mutex_unlock(&MSDOS_SB(sb)->s_lock); | 762 | mutex_unlock(&MSDOS_SB(sb)->s_lock); |
758 | dentry->d_time = dentry->d_parent->d_inode->i_version; | 763 | if (!inode) |
759 | dentry = d_splice_alias(inode, dentry); | 764 | dentry->d_time = dir->i_version; |
760 | if (dentry) | 765 | return d_splice_alias(inode, dentry); |
761 | dentry->d_time = dentry->d_parent->d_inode->i_version; | ||
762 | return dentry; | ||
763 | |||
764 | error: | 766 | error: |
765 | mutex_unlock(&MSDOS_SB(sb)->s_lock); | 767 | mutex_unlock(&MSDOS_SB(sb)->s_lock); |
766 | return ERR_PTR(err); | 768 | return ERR_PTR(err); |
@@ -793,7 +795,6 @@ static int vfat_create(struct inode *dir, struct dentry *dentry, umode_t mode, | |||
793 | inode->i_mtime = inode->i_atime = inode->i_ctime = ts; | 795 | inode->i_mtime = inode->i_atime = inode->i_ctime = ts; |
794 | /* timestamp is already written, so mark_inode_dirty() is unneeded. */ | 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 | d_instantiate(dentry, inode); | 798 | d_instantiate(dentry, inode); |
798 | out: | 799 | out: |
799 | mutex_unlock(&MSDOS_SB(sb)->s_lock); | 800 | mutex_unlock(&MSDOS_SB(sb)->s_lock); |
@@ -824,6 +825,7 @@ static int vfat_rmdir(struct inode *dir, struct dentry *dentry) | |||
824 | clear_nlink(inode); | 825 | clear_nlink(inode); |
825 | inode->i_mtime = inode->i_atime = CURRENT_TIME_SEC; | 826 | inode->i_mtime = inode->i_atime = CURRENT_TIME_SEC; |
826 | fat_detach(inode); | 827 | fat_detach(inode); |
828 | dentry->d_time = dir->i_version; | ||
827 | out: | 829 | out: |
828 | mutex_unlock(&MSDOS_SB(sb)->s_lock); | 830 | mutex_unlock(&MSDOS_SB(sb)->s_lock); |
829 | 831 | ||
@@ -849,6 +851,7 @@ static int vfat_unlink(struct inode *dir, struct dentry *dentry) | |||
849 | clear_nlink(inode); | 851 | clear_nlink(inode); |
850 | inode->i_mtime = inode->i_atime = CURRENT_TIME_SEC; | 852 | inode->i_mtime = inode->i_atime = CURRENT_TIME_SEC; |
851 | fat_detach(inode); | 853 | fat_detach(inode); |
854 | dentry->d_time = dir->i_version; | ||
852 | out: | 855 | out: |
853 | mutex_unlock(&MSDOS_SB(sb)->s_lock); | 856 | mutex_unlock(&MSDOS_SB(sb)->s_lock); |
854 | 857 | ||
@@ -889,7 +892,6 @@ static int vfat_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode) | |||
889 | inode->i_mtime = inode->i_atime = inode->i_ctime = ts; | 892 | inode->i_mtime = inode->i_atime = inode->i_ctime = ts; |
890 | /* timestamp is already written, so mark_inode_dirty() is unneeded. */ | 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 | d_instantiate(dentry, inode); | 895 | d_instantiate(dentry, inode); |
894 | 896 | ||
895 | mutex_unlock(&MSDOS_SB(sb)->s_lock); | 897 | mutex_unlock(&MSDOS_SB(sb)->s_lock); |
@@ -507,13 +507,6 @@ static int newary(struct ipc_namespace *ns, struct ipc_params *params) | |||
507 | return retval; | 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 | sma->sem_base = (struct sem *) &sma[1]; | 510 | sma->sem_base = (struct sem *) &sma[1]; |
518 | 511 | ||
519 | for (i = 0; i < nsems; i++) { | 512 | for (i = 0; i < nsems; i++) { |
@@ -528,6 +521,14 @@ static int newary(struct ipc_namespace *ns, struct ipc_params *params) | |||
528 | INIT_LIST_HEAD(&sma->list_id); | 521 | INIT_LIST_HEAD(&sma->list_id); |
529 | sma->sem_nsems = nsems; | 522 | sma->sem_nsems = nsems; |
530 | sma->sem_ctime = get_seconds(); | 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 | sem_unlock(sma, -1); | 532 | sem_unlock(sma, -1); |
532 | rcu_read_unlock(); | 533 | rcu_read_unlock(); |
533 | 534 | ||
diff --git a/lib/genalloc.c b/lib/genalloc.c index cce4dd68c40d..2e65d206b01c 100644 --- a/lib/genalloc.c +++ b/lib/genalloc.c | |||
@@ -598,6 +598,7 @@ struct gen_pool *devm_gen_pool_create(struct device *dev, int min_alloc_order, | |||
598 | 598 | ||
599 | return pool; | 599 | return pool; |
600 | } | 600 | } |
601 | EXPORT_SYMBOL(devm_gen_pool_create); | ||
601 | 602 | ||
602 | /** | 603 | /** |
603 | * dev_get_gen_pool - Obtain the gen_pool (if any) for a device | 604 | * dev_get_gen_pool - Obtain the gen_pool (if any) for a device |
diff --git a/lib/show_mem.c b/lib/show_mem.c index 09225796991a..5e256271b47b 100644 --- a/lib/show_mem.c +++ b/lib/show_mem.c | |||
@@ -28,7 +28,7 @@ void show_mem(unsigned int filter) | |||
28 | continue; | 28 | continue; |
29 | 29 | ||
30 | total += zone->present_pages; | 30 | total += zone->present_pages; |
31 | reserved = zone->present_pages - zone->managed_pages; | 31 | reserved += zone->present_pages - zone->managed_pages; |
32 | 32 | ||
33 | if (is_highmem_idx(zoneid)) | 33 | if (is_highmem_idx(zoneid)) |
34 | highmem += zone->present_pages; | 34 | highmem += zone->present_pages; |
diff --git a/mm/frontswap.c b/mm/frontswap.c index c30eec536f03..f2a3571c6e22 100644 --- a/mm/frontswap.c +++ b/mm/frontswap.c | |||
@@ -244,8 +244,10 @@ int __frontswap_store(struct page *page) | |||
244 | the (older) page from frontswap | 244 | the (older) page from frontswap |
245 | */ | 245 | */ |
246 | inc_frontswap_failed_stores(); | 246 | inc_frontswap_failed_stores(); |
247 | if (dup) | 247 | if (dup) { |
248 | __frontswap_clear(sis, offset); | 248 | __frontswap_clear(sis, offset); |
249 | frontswap_ops->invalidate_page(type, offset); | ||
250 | } | ||
249 | } | 251 | } |
250 | if (frontswap_writethrough_enabled) | 252 | if (frontswap_writethrough_enabled) |
251 | /* report failure so swap also writes to swap device */ | 253 | /* report failure so swap also writes to swap device */ |
diff --git a/mm/memory.c b/mm/memory.c index 3e503831e042..d5f2ae9c4a23 100644 --- a/mm/memory.c +++ b/mm/memory.c | |||
@@ -815,20 +815,20 @@ copy_one_pte(struct mm_struct *dst_mm, struct mm_struct *src_mm, | |||
815 | if (!pte_file(pte)) { | 815 | if (!pte_file(pte)) { |
816 | swp_entry_t entry = pte_to_swp_entry(pte); | 816 | swp_entry_t entry = pte_to_swp_entry(pte); |
817 | 817 | ||
818 | if (swap_duplicate(entry) < 0) | 818 | if (likely(!non_swap_entry(entry))) { |
819 | return entry.val; | 819 | if (swap_duplicate(entry) < 0) |
820 | 820 | return entry.val; | |
821 | /* make sure dst_mm is on swapoff's mmlist. */ | 821 | |
822 | if (unlikely(list_empty(&dst_mm->mmlist))) { | 822 | /* make sure dst_mm is on swapoff's mmlist. */ |
823 | spin_lock(&mmlist_lock); | 823 | if (unlikely(list_empty(&dst_mm->mmlist))) { |
824 | if (list_empty(&dst_mm->mmlist)) | 824 | spin_lock(&mmlist_lock); |
825 | list_add(&dst_mm->mmlist, | 825 | if (list_empty(&dst_mm->mmlist)) |
826 | &src_mm->mmlist); | 826 | list_add(&dst_mm->mmlist, |
827 | spin_unlock(&mmlist_lock); | 827 | &src_mm->mmlist); |
828 | } | 828 | spin_unlock(&mmlist_lock); |
829 | if (likely(!non_swap_entry(entry))) | 829 | } |
830 | rss[MM_SWAPENTS]++; | 830 | rss[MM_SWAPENTS]++; |
831 | else if (is_migration_entry(entry)) { | 831 | } else if (is_migration_entry(entry)) { |
832 | page = migration_entry_to_page(entry); | 832 | page = migration_entry_to_page(entry); |
833 | 833 | ||
834 | if (PageAnon(page)) | 834 | if (PageAnon(page)) |
@@ -776,8 +776,11 @@ again: remove_next = 1 + (end > next->vm_end); | |||
776 | * shrinking vma had, to cover any anon pages imported. | 776 | * shrinking vma had, to cover any anon pages imported. |
777 | */ | 777 | */ |
778 | if (exporter && exporter->anon_vma && !importer->anon_vma) { | 778 | if (exporter && exporter->anon_vma && !importer->anon_vma) { |
779 | if (anon_vma_clone(importer, exporter)) | 779 | int error; |
780 | return -ENOMEM; | 780 | |
781 | error = anon_vma_clone(importer, exporter); | ||
782 | if (error) | ||
783 | return error; | ||
781 | importer->anon_vma = exporter->anon_vma; | 784 | importer->anon_vma = exporter->anon_vma; |
782 | } | 785 | } |
783 | } | 786 | } |
@@ -2469,7 +2472,8 @@ static int __split_vma(struct mm_struct *mm, struct vm_area_struct *vma, | |||
2469 | if (err) | 2472 | if (err) |
2470 | goto out_free_vma; | 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 | goto out_free_mpol; | 2477 | goto out_free_mpol; |
2474 | 2478 | ||
2475 | if (new->vm_file) | 2479 | if (new->vm_file) |
@@ -274,6 +274,7 @@ int anon_vma_fork(struct vm_area_struct *vma, struct vm_area_struct *pvma) | |||
274 | { | 274 | { |
275 | struct anon_vma_chain *avc; | 275 | struct anon_vma_chain *avc; |
276 | struct anon_vma *anon_vma; | 276 | struct anon_vma *anon_vma; |
277 | int error; | ||
277 | 278 | ||
278 | /* Don't bother if the parent process has no anon_vma here. */ | 279 | /* Don't bother if the parent process has no anon_vma here. */ |
279 | if (!pvma->anon_vma) | 280 | if (!pvma->anon_vma) |
@@ -283,8 +284,9 @@ int anon_vma_fork(struct vm_area_struct *vma, struct vm_area_struct *pvma) | |||
283 | * First, attach the new VMA to the parent VMA's anon_vmas, | 284 | * First, attach the new VMA to the parent VMA's anon_vmas, |
284 | * so rmap can find non-COWed pages in child processes. | 285 | * so rmap can find non-COWed pages in child processes. |
285 | */ | 286 | */ |
286 | if (anon_vma_clone(vma, pvma)) | 287 | error = anon_vma_clone(vma, pvma); |
287 | return -ENOMEM; | 288 | if (error) |
289 | return error; | ||
288 | 290 | ||
289 | /* Then add our own anon_vma. */ | 291 | /* Then add our own anon_vma. */ |
290 | anon_vma = anon_vma_alloc(); | 292 | anon_vma = anon_vma_alloc(); |
@@ -3076,7 +3076,7 @@ static void *____cache_alloc_node(struct kmem_cache *cachep, gfp_t flags, | |||
3076 | void *obj; | 3076 | void *obj; |
3077 | int x; | 3077 | int x; |
3078 | 3078 | ||
3079 | VM_BUG_ON(nodeid > num_online_nodes()); | 3079 | VM_BUG_ON(nodeid < 0 || nodeid >= MAX_NUMNODES); |
3080 | n = get_node(cachep, nodeid); | 3080 | n = get_node(cachep, nodeid); |
3081 | BUG_ON(!n); | 3081 | BUG_ON(!n); |
3082 | 3082 | ||
diff --git a/mm/vmpressure.c b/mm/vmpressure.c index d4042e75f7c7..c5afd573d7da 100644 --- a/mm/vmpressure.c +++ b/mm/vmpressure.c | |||
@@ -165,6 +165,7 @@ static void vmpressure_work_fn(struct work_struct *work) | |||
165 | unsigned long scanned; | 165 | unsigned long scanned; |
166 | unsigned long reclaimed; | 166 | unsigned long reclaimed; |
167 | 167 | ||
168 | spin_lock(&vmpr->sr_lock); | ||
168 | /* | 169 | /* |
169 | * Several contexts might be calling vmpressure(), so it is | 170 | * Several contexts might be calling vmpressure(), so it is |
170 | * possible that the work was rescheduled again before the old | 171 | * possible that the work was rescheduled again before the old |
@@ -173,11 +174,12 @@ static void vmpressure_work_fn(struct work_struct *work) | |||
173 | * here. No need for any locks here since we don't care if | 174 | * here. No need for any locks here since we don't care if |
174 | * vmpr->reclaimed is in sync. | 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 | return; | 180 | return; |
181 | } | ||
178 | 182 | ||
179 | spin_lock(&vmpr->sr_lock); | ||
180 | scanned = vmpr->scanned; | ||
181 | reclaimed = vmpr->reclaimed; | 183 | reclaimed = vmpr->reclaimed; |
182 | vmpr->scanned = 0; | 184 | vmpr->scanned = 0; |
183 | vmpr->reclaimed = 0; | 185 | vmpr->reclaimed = 0; |