diff options
Diffstat (limited to 'fs/btrfs/extent_map.c')
| -rw-r--r-- | fs/btrfs/extent_map.c | 24 | 
1 files changed, 10 insertions, 14 deletions
diff --git a/fs/btrfs/extent_map.c b/fs/btrfs/extent_map.c index ce9f7921672..f169d6b11d7 100644 --- a/fs/btrfs/extent_map.c +++ b/fs/btrfs/extent_map.c @@ -49,7 +49,7 @@ void extent_map_tree_init(struct extent_map_tree *tree)  struct extent_map *alloc_extent_map(void)  {  	struct extent_map *em; -	em = kmem_cache_alloc(extent_map_cache, GFP_NOFS); +	em = kmem_cache_zalloc(extent_map_cache, GFP_NOFS);  	if (!em)  		return NULL;  	em->in_tree = 0; @@ -198,16 +198,15 @@ static void try_merge_map(struct extent_map_tree *tree, struct extent_map *em)  			merge = rb_entry(rb, struct extent_map, rb_node);  		if (rb && mergable_maps(merge, em)) {  			em->start = merge->start; +			em->orig_start = merge->orig_start;  			em->len += merge->len;  			em->block_len += merge->block_len;  			em->block_start = merge->block_start;  			merge->in_tree = 0; -			if (merge->generation > em->generation) { -				em->mod_start = em->start; -				em->mod_len = em->len; -				em->generation = merge->generation; -				list_move(&em->list, &tree->modified_extents); -			} +			em->mod_len = (em->mod_len + em->mod_start) - merge->mod_start; +			em->mod_start = merge->mod_start; +			em->generation = max(em->generation, merge->generation); +			list_move(&em->list, &tree->modified_extents);  			list_del_init(&merge->list);  			rb_erase(&merge->rb_node, &tree->map); @@ -223,11 +222,8 @@ static void try_merge_map(struct extent_map_tree *tree, struct extent_map *em)  		em->block_len += merge->len;  		rb_erase(&merge->rb_node, &tree->map);  		merge->in_tree = 0; -		if (merge->generation > em->generation) { -			em->mod_len = em->len; -			em->generation = merge->generation; -			list_move(&em->list, &tree->modified_extents); -		} +		em->mod_len = (merge->mod_start + merge->mod_len) - em->mod_start; +		em->generation = max(em->generation, merge->generation);  		list_del_init(&merge->list);  		free_extent_map(merge);  	} @@ -265,9 +261,9 @@ int unpin_extent_cache(struct extent_map_tree *tree, u64 start, u64 len,  	em->mod_start = em->start;  	em->mod_len = em->len; -	if (test_bit(EXTENT_FLAG_PREALLOC, &em->flags)) { +	if (test_bit(EXTENT_FLAG_FILLING, &em->flags)) {  		prealloc = true; -		clear_bit(EXTENT_FLAG_PREALLOC, &em->flags); +		clear_bit(EXTENT_FLAG_FILLING, &em->flags);  	}  	try_merge_map(tree, em);  |