2012-10-09 03:31:25 +04:00
/*
* mm / interval_tree . c - interval tree for mapping - > i_mmap
*
* Copyright ( C ) 2012 , Michel Lespinasse < walken @ google . com >
*
* This file is released under the GPL v2 .
*/
# include <linux/mm.h>
# include <linux/fs.h>
2012-10-09 03:31:35 +04:00
# include <linux/interval_tree_generic.h>
2012-10-09 03:31:25 +04:00
2012-10-09 03:31:35 +04:00
static inline unsigned long vma_start_pgoff ( struct vm_area_struct * v )
{
return v - > vm_pgoff ;
}
static inline unsigned long vma_last_pgoff ( struct vm_area_struct * v )
{
return v - > vm_pgoff + ( ( v - > vm_end - v - > vm_start ) > > PAGE_SHIFT ) - 1 ;
}
INTERVAL_TREE_DEFINE ( struct vm_area_struct , shared . linear . rb ,
unsigned long , shared . linear . rb_subtree_last ,
vma_start_pgoff , vma_last_pgoff , , vma_interval_tree )
/* Insert node immediately after prev in the interval tree */
void vma_interval_tree_insert_after ( struct vm_area_struct * node ,
struct vm_area_struct * prev ,
struct rb_root * root )
2012-10-09 03:31:25 +04:00
{
struct rb_node * * link ;
struct vm_area_struct * parent ;
2012-10-09 03:31:35 +04:00
unsigned long last = vma_last_pgoff ( node ) ;
2012-10-09 03:31:25 +04:00
2012-10-09 03:31:35 +04:00
VM_BUG_ON ( vma_start_pgoff ( node ) ! = vma_start_pgoff ( prev ) ) ;
2012-10-09 03:31:25 +04:00
2012-10-09 03:31:35 +04:00
if ( ! prev - > shared . linear . rb . rb_right ) {
parent = prev ;
link = & prev - > shared . linear . rb . rb_right ;
2012-10-09 03:31:25 +04:00
} else {
2012-10-09 03:31:35 +04:00
parent = rb_entry ( prev - > shared . linear . rb . rb_right ,
2012-10-09 03:31:25 +04:00
struct vm_area_struct , shared . linear . rb ) ;
if ( parent - > shared . linear . rb_subtree_last < last )
parent - > shared . linear . rb_subtree_last = last ;
while ( parent - > shared . linear . rb . rb_left ) {
parent = rb_entry ( parent - > shared . linear . rb . rb_left ,
struct vm_area_struct , shared . linear . rb ) ;
if ( parent - > shared . linear . rb_subtree_last < last )
parent - > shared . linear . rb_subtree_last = last ;
}
link = & parent - > shared . linear . rb . rb_left ;
}
2012-10-09 03:31:35 +04:00
node - > shared . linear . rb_subtree_last = last ;
rb_link_node ( & node - > shared . linear . rb , & parent - > shared . linear . rb , link ) ;
rb_insert_augmented ( & node - > shared . linear . rb , root ,
& vma_interval_tree_augment ) ;
2012-10-09 03:31:25 +04:00
}