aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2014-12-03 12:36:20 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2014-12-03 12:36:20 -0500
commit1dd909affbc45412270fd196d1181404d2e416b1 (patch)
tree9dcd03d002da6b55dc02062dc55df78922d6d2dd
parent3a18ca061311f2f1ee9c44012f89c7436d392117 (diff)
parent7c3fbbdd04a681a1992ad6a3d7a36a63ff668753 (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.c2
-rw-r--r--fs/fat/namei_vfat.c20
-rw-r--r--ipc/sem.c15
-rw-r--r--lib/genalloc.c1
-rw-r--r--lib/show_mem.c2
-rw-r--r--mm/frontswap.c4
-rw-r--r--mm/memory.c26
-rw-r--r--mm/mmap.c10
-rw-r--r--mm/rmap.c6
-rw-r--r--mm/slab.c2
-rw-r--r--mm/vmpressure.c8
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
756out: 761out:
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
764error: 766error:
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);
798out: 799out:
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;
827out: 829out:
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;
852out: 855out:
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);
diff --git a/ipc/sem.c b/ipc/sem.c
index 454f6c6020a8..53c3310f41c6 100644
--- a/ipc/sem.c
+++ b/ipc/sem.c
@@ -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}
601EXPORT_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))
diff --git a/mm/mmap.c b/mm/mmap.c
index 87e82b38453c..ae919891a087 100644
--- a/mm/mmap.c
+++ b/mm/mmap.c
@@ -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)
diff --git a/mm/rmap.c b/mm/rmap.c
index 19886fb2f13a..3e4c7213210c 100644
--- a/mm/rmap.c
+++ b/mm/rmap.c
@@ -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();
diff --git a/mm/slab.c b/mm/slab.c
index eb2b2ea30130..f34e053ec46e 100644
--- a/mm/slab.c
+++ b/mm/slab.c
@@ -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;