aboutsummaryrefslogtreecommitdiffstats
path: root/mm/nommu.c
diff options
context:
space:
mode:
Diffstat (limited to 'mm/nommu.c')
-rw-r--r--mm/nommu.c102
1 files changed, 71 insertions, 31 deletions
diff --git a/mm/nommu.c b/mm/nommu.c
index 17773862619b..48a2ecfaf059 100644
--- a/mm/nommu.c
+++ b/mm/nommu.c
@@ -552,11 +552,11 @@ static void free_page_series(unsigned long from, unsigned long to)
552static void __put_nommu_region(struct vm_region *region) 552static void __put_nommu_region(struct vm_region *region)
553 __releases(nommu_region_sem) 553 __releases(nommu_region_sem)
554{ 554{
555 kenter("%p{%d}", region, atomic_read(&region->vm_usage)); 555 kenter("%p{%d}", region, region->vm_usage);
556 556
557 BUG_ON(!nommu_region_tree.rb_node); 557 BUG_ON(!nommu_region_tree.rb_node);
558 558
559 if (atomic_dec_and_test(&region->vm_usage)) { 559 if (--region->vm_usage == 0) {
560 if (region->vm_top > region->vm_start) 560 if (region->vm_top > region->vm_start)
561 delete_nommu_region(region); 561 delete_nommu_region(region);
562 up_write(&nommu_region_sem); 562 up_write(&nommu_region_sem);
@@ -1205,7 +1205,7 @@ unsigned long do_mmap_pgoff(struct file *file,
1205 if (!vma) 1205 if (!vma)
1206 goto error_getting_vma; 1206 goto error_getting_vma;
1207 1207
1208 atomic_set(&region->vm_usage, 1); 1208 region->vm_usage = 1;
1209 region->vm_flags = vm_flags; 1209 region->vm_flags = vm_flags;
1210 region->vm_pgoff = pgoff; 1210 region->vm_pgoff = pgoff;
1211 1211
@@ -1272,7 +1272,7 @@ unsigned long do_mmap_pgoff(struct file *file,
1272 } 1272 }
1273 1273
1274 /* we've found a region we can share */ 1274 /* we've found a region we can share */
1275 atomic_inc(&pregion->vm_usage); 1275 pregion->vm_usage++;
1276 vma->vm_region = pregion; 1276 vma->vm_region = pregion;
1277 start = pregion->vm_start; 1277 start = pregion->vm_start;
1278 start += (pgoff - pregion->vm_pgoff) << PAGE_SHIFT; 1278 start += (pgoff - pregion->vm_pgoff) << PAGE_SHIFT;
@@ -1289,7 +1289,7 @@ unsigned long do_mmap_pgoff(struct file *file,
1289 vma->vm_region = NULL; 1289 vma->vm_region = NULL;
1290 vma->vm_start = 0; 1290 vma->vm_start = 0;
1291 vma->vm_end = 0; 1291 vma->vm_end = 0;
1292 atomic_dec(&pregion->vm_usage); 1292 pregion->vm_usage--;
1293 pregion = NULL; 1293 pregion = NULL;
1294 goto error_just_free; 1294 goto error_just_free;
1295 } 1295 }
@@ -1441,10 +1441,9 @@ int split_vma(struct mm_struct *mm, struct vm_area_struct *vma,
1441 1441
1442 kenter(""); 1442 kenter("");
1443 1443
1444 /* we're only permitted to split anonymous regions that have a single 1444 /* we're only permitted to split anonymous regions (these should have
1445 * owner */ 1445 * only a single usage on the region) */
1446 if (vma->vm_file || 1446 if (vma->vm_file)
1447 atomic_read(&vma->vm_region->vm_usage) != 1)
1448 return -ENOMEM; 1447 return -ENOMEM;
1449 1448
1450 if (mm->map_count >= sysctl_max_map_count) 1449 if (mm->map_count >= sysctl_max_map_count)
@@ -1518,7 +1517,7 @@ static int shrink_vma(struct mm_struct *mm,
1518 1517
1519 /* cut the backing region down to size */ 1518 /* cut the backing region down to size */
1520 region = vma->vm_region; 1519 region = vma->vm_region;
1521 BUG_ON(atomic_read(&region->vm_usage) != 1); 1520 BUG_ON(region->vm_usage != 1);
1522 1521
1523 down_write(&nommu_region_sem); 1522 down_write(&nommu_region_sem);
1524 delete_nommu_region(region); 1523 delete_nommu_region(region);
@@ -1762,27 +1761,6 @@ void unmap_mapping_range(struct address_space *mapping,
1762EXPORT_SYMBOL(unmap_mapping_range); 1761EXPORT_SYMBOL(unmap_mapping_range);
1763 1762
1764/* 1763/*
1765 * ask for an unmapped area at which to create a mapping on a file
1766 */
1767unsigned long get_unmapped_area(struct file *file, unsigned long addr,
1768 unsigned long len, unsigned long pgoff,
1769 unsigned long flags)
1770{
1771 unsigned long (*get_area)(struct file *, unsigned long, unsigned long,
1772 unsigned long, unsigned long);
1773
1774 get_area = current->mm->get_unmapped_area;
1775 if (file && file->f_op && file->f_op->get_unmapped_area)
1776 get_area = file->f_op->get_unmapped_area;
1777
1778 if (!get_area)
1779 return -ENOSYS;
1780
1781 return get_area(file, addr, len, pgoff, flags);
1782}
1783EXPORT_SYMBOL(get_unmapped_area);
1784
1785/*
1786 * Check that a process has enough memory to allocate a new virtual 1764 * Check that a process has enough memory to allocate a new virtual
1787 * mapping. 0 means there is enough memory for the allocation to 1765 * mapping. 0 means there is enough memory for the allocation to
1788 * succeed and -ENOMEM implies there is not. 1766 * succeed and -ENOMEM implies there is not.
@@ -1936,3 +1914,65 @@ int access_process_vm(struct task_struct *tsk, unsigned long addr, void *buf, in
1936 mmput(mm); 1914 mmput(mm);
1937 return len; 1915 return len;
1938} 1916}
1917
1918/**
1919 * nommu_shrink_inode_mappings - Shrink the shared mappings on an inode
1920 * @inode: The inode to check
1921 * @size: The current filesize of the inode
1922 * @newsize: The proposed filesize of the inode
1923 *
1924 * Check the shared mappings on an inode on behalf of a shrinking truncate to
1925 * make sure that that any outstanding VMAs aren't broken and then shrink the
1926 * vm_regions that extend that beyond so that do_mmap_pgoff() doesn't
1927 * automatically grant mappings that are too large.
1928 */
1929int nommu_shrink_inode_mappings(struct inode *inode, size_t size,
1930 size_t newsize)
1931{
1932 struct vm_area_struct *vma;
1933 struct prio_tree_iter iter;
1934 struct vm_region *region;
1935 pgoff_t low, high;
1936 size_t r_size, r_top;
1937
1938 low = newsize >> PAGE_SHIFT;
1939 high = (size + PAGE_SIZE - 1) >> PAGE_SHIFT;
1940
1941 down_write(&nommu_region_sem);
1942
1943 /* search for VMAs that fall within the dead zone */
1944 vma_prio_tree_foreach(vma, &iter, &inode->i_mapping->i_mmap,
1945 low, high) {
1946 /* found one - only interested if it's shared out of the page
1947 * cache */
1948 if (vma->vm_flags & VM_SHARED) {
1949 up_write(&nommu_region_sem);
1950 return -ETXTBSY; /* not quite true, but near enough */
1951 }
1952 }
1953
1954 /* reduce any regions that overlap the dead zone - if in existence,
1955 * these will be pointed to by VMAs that don't overlap the dead zone
1956 *
1957 * we don't check for any regions that start beyond the EOF as there
1958 * shouldn't be any
1959 */
1960 vma_prio_tree_foreach(vma, &iter, &inode->i_mapping->i_mmap,
1961 0, ULONG_MAX) {
1962 if (!(vma->vm_flags & VM_SHARED))
1963 continue;
1964
1965 region = vma->vm_region;
1966 r_size = region->vm_top - region->vm_start;
1967 r_top = (region->vm_pgoff << PAGE_SHIFT) + r_size;
1968
1969 if (r_top > newsize) {
1970 region->vm_top -= r_top - newsize;
1971 if (region->vm_end > region->vm_top)
1972 region->vm_end = region->vm_top;
1973 }
1974 }
1975
1976 up_write(&nommu_region_sem);
1977 return 0;
1978}