@ -141,6 +141,8 @@ static void add_extent_changeset(struct extent_state *state, unsigned bits,
return ;
if ( set & & ( state - > state & bits ) = = bits )
return ;
if ( ! set & & ( state - > state & bits ) = = 0 )
return ;
changeset - > bytes_changed + = state - > end - state - > start + 1 ;
ret = ulist_add ( changeset - > range_changed , state - > start , state - > end ,
GFP_ATOMIC ) ;
@ -529,7 +531,8 @@ static struct extent_state *next_state(struct extent_state *state)
*/
static struct extent_state * clear_state_bit ( struct extent_io_tree * tree ,
struct extent_state * state ,
unsigned * bits , int wake )
unsigned * bits , int wake ,
struct extent_changeset * changeset )
{
struct extent_state * next ;
unsigned bits_to_clear = * bits & ~ EXTENT_CTLBITS ;
@ -540,6 +543,7 @@ static struct extent_state *clear_state_bit(struct extent_io_tree *tree,
tree - > dirty_bytes - = range ;
}
clear_state_cb ( tree , state , bits ) ;
add_extent_changeset ( state , bits_to_clear , changeset , 0 ) ;
state - > state & = ~ bits_to_clear ;
if ( wake )
wake_up ( & state - > wq ) ;
@ -587,10 +591,10 @@ static void extent_io_tree_panic(struct extent_io_tree *tree, int err)
*
* This takes the tree lock , and returns 0 on success and < 0 on error .
*/
int clear_extent_bit ( struct extent_io_tree * tree , u64 start , u64 end ,
unsigned bits , int wake , int delete ,
struct extent_state * * cached_state ,
gfp_t mask )
static int __ clear_extent_bit( struct extent_io_tree * tree , u64 start , u64 end ,
unsigned bits , int wake , int delete ,
struct extent_state * * cached_state ,
gfp_t mask , struct extent_changeset * changeset )
{
struct extent_state * state ;
struct extent_state * cached ;
@ -689,7 +693,8 @@ hit_next:
if ( err )
goto out ;
if ( state - > end < = end ) {
state = clear_state_bit ( tree , state , & bits , wake ) ;
state = clear_state_bit ( tree , state , & bits , wake ,
changeset ) ;
goto next ;
}
goto search_again ;
@ -710,13 +715,13 @@ hit_next:
if ( wake )
wake_up ( & state - > wq ) ;
clear_state_bit ( tree , prealloc , & bits , wake ) ;
clear_state_bit ( tree , prealloc , & bits , wake , changeset ) ;
prealloc = NULL ;
goto out ;
}
state = clear_state_bit ( tree , state , & bits , wake ) ;
state = clear_state_bit ( tree , state , & bits , wake , changeset ) ;
next :
if ( last_end = = ( u64 ) - 1 )
goto out ;
@ -1151,7 +1156,7 @@ hit_next:
if ( state - > start = = start & & state - > end < = end ) {
set_state_bits ( tree , state , & bits , NULL ) ;
cache_state ( state , cached_state ) ;
state = clear_state_bit ( tree , state , & clear_bits , 0 ) ;
state = clear_state_bit ( tree , state , & clear_bits , 0 , NULL ) ;
if ( last_end = = ( u64 ) - 1 )
goto out ;
start = last_end + 1 ;
@ -1192,7 +1197,8 @@ hit_next:
if ( state - > end < = end ) {
set_state_bits ( tree , state , & bits , NULL ) ;
cache_state ( state , cached_state ) ;
state = clear_state_bit ( tree , state , & clear_bits , 0 ) ;
state = clear_state_bit ( tree , state , & clear_bits , 0 ,
NULL ) ;
if ( last_end = = ( u64 ) - 1 )
goto out ;
start = last_end + 1 ;
@ -1254,7 +1260,7 @@ hit_next:
set_state_bits ( tree , prealloc , & bits , NULL ) ;
cache_state ( prealloc , cached_state ) ;
clear_state_bit ( tree , prealloc , & clear_bits , 0 ) ;
clear_state_bit ( tree , prealloc , & clear_bits , 0 , NULL ) ;
prealloc = NULL ;
goto out ;
}
@ -1309,6 +1315,14 @@ int set_record_extent_bits(struct extent_io_tree *tree, u64 start, u64 end,
changeset ) ;
}
int clear_extent_bit ( struct extent_io_tree * tree , u64 start , u64 end ,
unsigned bits , int wake , int delete ,
struct extent_state * * cached , gfp_t mask )
{
return __clear_extent_bit ( tree , start , end , bits , wake , delete ,
cached , mask , NULL ) ;
}
int clear_extent_bits ( struct extent_io_tree * tree , u64 start , u64 end ,
unsigned bits , gfp_t mask )
{
@ -1320,6 +1334,20 @@ int clear_extent_bits(struct extent_io_tree *tree, u64 start, u64 end,
return clear_extent_bit ( tree , start , end , bits , wake , 0 , NULL , mask ) ;
}
int clear_record_extent_bits ( struct extent_io_tree * tree , u64 start , u64 end ,
unsigned bits , gfp_t mask ,
struct extent_changeset * changeset )
{
/*
* Don ' t support EXTENT_LOCKED case , same reason as
* set_record_extent_bits ( ) .
*/
BUG_ON ( bits & EXTENT_LOCKED ) ;
return __clear_extent_bit ( tree , start , end , bits , 0 , 0 , NULL , mask ,
changeset ) ;
}
int set_extent_delalloc ( struct extent_io_tree * tree , u64 start , u64 end ,
struct extent_state * * cached_state , gfp_t mask )
{