diff options
Diffstat (limited to 'mm/mmap.c')
-rw-r--r-- | mm/mmap.c | 17 |
1 files changed, 14 insertions, 3 deletions
@@ -1266,8 +1266,9 @@ munmap_back: | |||
1266 | vma->vm_pgoff = pgoff; | 1266 | vma->vm_pgoff = pgoff; |
1267 | INIT_LIST_HEAD(&vma->anon_vma_chain); | 1267 | INIT_LIST_HEAD(&vma->anon_vma_chain); |
1268 | 1268 | ||
1269 | error = -EINVAL; /* when rejecting VM_GROWSDOWN|VM_GROWSUP */ | ||
1270 | |||
1269 | if (file) { | 1271 | if (file) { |
1270 | error = -EINVAL; | ||
1271 | if (vm_flags & (VM_GROWSDOWN|VM_GROWSUP)) | 1272 | if (vm_flags & (VM_GROWSDOWN|VM_GROWSUP)) |
1272 | goto free_vma; | 1273 | goto free_vma; |
1273 | if (vm_flags & VM_DENYWRITE) { | 1274 | if (vm_flags & VM_DENYWRITE) { |
@@ -1293,6 +1294,8 @@ munmap_back: | |||
1293 | pgoff = vma->vm_pgoff; | 1294 | pgoff = vma->vm_pgoff; |
1294 | vm_flags = vma->vm_flags; | 1295 | vm_flags = vma->vm_flags; |
1295 | } else if (vm_flags & VM_SHARED) { | 1296 | } else if (vm_flags & VM_SHARED) { |
1297 | if (unlikely(vm_flags & (VM_GROWSDOWN|VM_GROWSUP))) | ||
1298 | goto free_vma; | ||
1296 | error = shmem_zero_setup(vma); | 1299 | error = shmem_zero_setup(vma); |
1297 | if (error) | 1300 | if (error) |
1298 | goto free_vma; | 1301 | goto free_vma; |
@@ -1605,7 +1608,6 @@ EXPORT_SYMBOL(find_vma); | |||
1605 | 1608 | ||
1606 | /* | 1609 | /* |
1607 | * Same as find_vma, but also return a pointer to the previous VMA in *pprev. | 1610 | * Same as find_vma, but also return a pointer to the previous VMA in *pprev. |
1608 | * Note: pprev is set to NULL when return value is NULL. | ||
1609 | */ | 1611 | */ |
1610 | struct vm_area_struct * | 1612 | struct vm_area_struct * |
1611 | find_vma_prev(struct mm_struct *mm, unsigned long addr, | 1613 | find_vma_prev(struct mm_struct *mm, unsigned long addr, |
@@ -1614,7 +1616,16 @@ find_vma_prev(struct mm_struct *mm, unsigned long addr, | |||
1614 | struct vm_area_struct *vma; | 1616 | struct vm_area_struct *vma; |
1615 | 1617 | ||
1616 | vma = find_vma(mm, addr); | 1618 | vma = find_vma(mm, addr); |
1617 | *pprev = vma ? vma->vm_prev : NULL; | 1619 | if (vma) { |
1620 | *pprev = vma->vm_prev; | ||
1621 | } else { | ||
1622 | struct rb_node *rb_node = mm->mm_rb.rb_node; | ||
1623 | *pprev = NULL; | ||
1624 | while (rb_node) { | ||
1625 | *pprev = rb_entry(rb_node, struct vm_area_struct, vm_rb); | ||
1626 | rb_node = rb_node->rb_right; | ||
1627 | } | ||
1628 | } | ||
1618 | return vma; | 1629 | return vma; |
1619 | } | 1630 | } |
1620 | 1631 | ||