All pastes #247438 Raw Edit

Someone

public text v1 · immutable
#247438 ·published 2006-11-13 14:48 UTC
rendered paste body
/* This must be called under the mmap_sem. */
int anon_vma_prepare(struct vm_area_struct *vma)
{
    struct anon_vma *anon_vma = vma->anon_vma;

    might_sleep();
    if (unlikely(!anon_vma)) {
        struct mm_struct *mm = vma->vm_mm;
        struct anon_vma *allocated, *locked;

        anon_vma = find_mergeable_anon_vma(vma);
        if (anon_vma) {
            allocated = NULL;
            locked = anon_vma;
            spin_lock(&locked->lock);
        } else {
            anon_vma = anon_vma_alloc();
            if (unlikely(!anon_vma))
                return -ENOMEM;
            allocated = anon_vma;
            locked = NULL;
        }

        /* page_table_lock to protect against threads */
        spin_lock(&mm->page_table_lock);
        if (likely(!vma->anon_vma)) {
            vma->anon_vma = anon_vma;
            list_add(&vma->anon_vma_node, &anon_vma->head);
            allocated = NULL;
        }

#ifdef CONFIG_PAX_SEGMEXEC
        if (vma->vm_flags & VM_MIRROR) {
            struct vm_area_struct *vma_m;

            vma_m = find_vma(vma->vm_mm, vma->vm_start + vma->vm_mirror);
            BUG_ON(!vma_m || vma_m->vm_start != vma->vm_start + vma->vm_mirror);
            BUG_ON(vma_m->anon_vma || vma->vm_pgoff != vma_m->vm_pgoff);
            vma_m->anon_vma = anon_vma;
            __anon_vma_link(vma_m);
        }
#endif

        spin_unlock(&mm->page_table_lock);

        if (locked)
            spin_unlock(&locked->lock);
        if (unlikely(allocated))
            anon_vma_free(allocated);
    }
    return 0;
}