aboutsummaryrefslogtreecommitdiffstats
path: root/mm
diff options
context:
space:
mode:
Diffstat (limited to 'mm')
-rw-r--r--mm/mmap.c17
-rw-r--r--mm/truncate.c11
2 files changed, 22 insertions, 6 deletions
diff --git a/mm/mmap.c b/mm/mmap.c
index c7ed061f4507..d799d896d74a 100644
--- a/mm/mmap.c
+++ b/mm/mmap.c
@@ -30,6 +30,10 @@
30#include <asm/cacheflush.h> 30#include <asm/cacheflush.h>
31#include <asm/tlb.h> 31#include <asm/tlb.h>
32 32
33#ifndef arch_mmap_check
34#define arch_mmap_check(addr, len, flags) (0)
35#endif
36
33static void unmap_region(struct mm_struct *mm, 37static void unmap_region(struct mm_struct *mm,
34 struct vm_area_struct *vma, struct vm_area_struct *prev, 38 struct vm_area_struct *vma, struct vm_area_struct *prev,
35 unsigned long start, unsigned long end); 39 unsigned long start, unsigned long end);
@@ -920,6 +924,10 @@ unsigned long do_mmap_pgoff(struct file * file, unsigned long addr,
920 if (!len) 924 if (!len)
921 return -EINVAL; 925 return -EINVAL;
922 926
927 error = arch_mmap_check(addr, len, flags);
928 if (error)
929 return error;
930
923 /* Careful about overflows.. */ 931 /* Careful about overflows.. */
924 len = PAGE_ALIGN(len); 932 len = PAGE_ALIGN(len);
925 if (!len || len > TASK_SIZE) 933 if (!len || len > TASK_SIZE)
@@ -1866,6 +1874,7 @@ unsigned long do_brk(unsigned long addr, unsigned long len)
1866 unsigned long flags; 1874 unsigned long flags;
1867 struct rb_node ** rb_link, * rb_parent; 1875 struct rb_node ** rb_link, * rb_parent;
1868 pgoff_t pgoff = addr >> PAGE_SHIFT; 1876 pgoff_t pgoff = addr >> PAGE_SHIFT;
1877 int error;
1869 1878
1870 len = PAGE_ALIGN(len); 1879 len = PAGE_ALIGN(len);
1871 if (!len) 1880 if (!len)
@@ -1874,6 +1883,12 @@ unsigned long do_brk(unsigned long addr, unsigned long len)
1874 if ((addr + len) > TASK_SIZE || (addr + len) < addr) 1883 if ((addr + len) > TASK_SIZE || (addr + len) < addr)
1875 return -EINVAL; 1884 return -EINVAL;
1876 1885
1886 flags = VM_DATA_DEFAULT_FLAGS | VM_ACCOUNT | mm->def_flags;
1887
1888 error = arch_mmap_check(addr, len, flags);
1889 if (error)
1890 return error;
1891
1877 /* 1892 /*
1878 * mlock MCL_FUTURE? 1893 * mlock MCL_FUTURE?
1879 */ 1894 */
@@ -1914,8 +1929,6 @@ unsigned long do_brk(unsigned long addr, unsigned long len)
1914 if (security_vm_enough_memory(len >> PAGE_SHIFT)) 1929 if (security_vm_enough_memory(len >> PAGE_SHIFT))
1915 return -ENOMEM; 1930 return -ENOMEM;
1916 1931
1917 flags = VM_DATA_DEFAULT_FLAGS | VM_ACCOUNT | mm->def_flags;
1918
1919 /* Can we just expand an old private anonymous mapping? */ 1932 /* Can we just expand an old private anonymous mapping? */
1920 if (vma_merge(mm, prev, addr, addr + len, flags, 1933 if (vma_merge(mm, prev, addr, addr + len, flags,
1921 NULL, NULL, pgoff, NULL)) 1934 NULL, NULL, pgoff, NULL))
diff --git a/mm/truncate.c b/mm/truncate.c
index cf1b015df4a7..c6ab55ec6883 100644
--- a/mm/truncate.c
+++ b/mm/truncate.c
@@ -68,10 +68,10 @@ invalidate_complete_page(struct address_space *mapping, struct page *page)
68 return 0; 68 return 0;
69 69
70 write_lock_irq(&mapping->tree_lock); 70 write_lock_irq(&mapping->tree_lock);
71 if (PageDirty(page)) { 71 if (PageDirty(page))
72 write_unlock_irq(&mapping->tree_lock); 72 goto failed;
73 return 0; 73 if (page_count(page) != 2) /* caller's ref + pagecache ref */
74 } 74 goto failed;
75 75
76 BUG_ON(PagePrivate(page)); 76 BUG_ON(PagePrivate(page));
77 __remove_from_page_cache(page); 77 __remove_from_page_cache(page);
@@ -79,6 +79,9 @@ invalidate_complete_page(struct address_space *mapping, struct page *page)
79 ClearPageUptodate(page); 79 ClearPageUptodate(page);
80 page_cache_release(page); /* pagecache ref */ 80 page_cache_release(page); /* pagecache ref */
81 return 1; 81 return 1;
82failed:
83 write_unlock_irq(&mapping->tree_lock);
84 return 0;
82} 85}
83 86
84/** 87/**