diff options
-rw-r--r-- | mm/mmap.c | 36 |
1 files changed, 8 insertions, 28 deletions
@@ -1603,39 +1603,19 @@ struct vm_area_struct *find_vma(struct mm_struct *mm, unsigned long addr) | |||
1603 | 1603 | ||
1604 | EXPORT_SYMBOL(find_vma); | 1604 | EXPORT_SYMBOL(find_vma); |
1605 | 1605 | ||
1606 | /* Same as find_vma, but also return a pointer to the previous VMA in *pprev. */ | 1606 | /* |
1607 | * 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 | */ | ||
1607 | struct vm_area_struct * | 1610 | struct vm_area_struct * |
1608 | find_vma_prev(struct mm_struct *mm, unsigned long addr, | 1611 | find_vma_prev(struct mm_struct *mm, unsigned long addr, |
1609 | struct vm_area_struct **pprev) | 1612 | struct vm_area_struct **pprev) |
1610 | { | 1613 | { |
1611 | struct vm_area_struct *vma = NULL, *prev = NULL; | 1614 | struct vm_area_struct *vma; |
1612 | struct rb_node *rb_node; | ||
1613 | if (!mm) | ||
1614 | goto out; | ||
1615 | |||
1616 | /* Guard against addr being lower than the first VMA */ | ||
1617 | vma = mm->mmap; | ||
1618 | |||
1619 | /* Go through the RB tree quickly. */ | ||
1620 | rb_node = mm->mm_rb.rb_node; | ||
1621 | |||
1622 | while (rb_node) { | ||
1623 | struct vm_area_struct *vma_tmp; | ||
1624 | vma_tmp = rb_entry(rb_node, struct vm_area_struct, vm_rb); | ||
1625 | |||
1626 | if (addr < vma_tmp->vm_end) { | ||
1627 | rb_node = rb_node->rb_left; | ||
1628 | } else { | ||
1629 | prev = vma_tmp; | ||
1630 | if (!prev->vm_next || (addr < prev->vm_next->vm_end)) | ||
1631 | break; | ||
1632 | rb_node = rb_node->rb_right; | ||
1633 | } | ||
1634 | } | ||
1635 | 1615 | ||
1636 | out: | 1616 | vma = find_vma(mm, addr); |
1637 | *pprev = prev; | 1617 | *pprev = vma ? vma->vm_prev : NULL; |
1638 | return prev ? prev->vm_next : vma; | 1618 | return vma; |
1639 | } | 1619 | } |
1640 | 1620 | ||
1641 | /* | 1621 | /* |