diff options
-rw-r--r-- | fs/btrfs/extent_map.c | 13 | ||||
-rw-r--r-- | fs/btrfs/extent_map.h | 1 | ||||
-rw-r--r-- | fs/btrfs/tree-log.c | 5 |
3 files changed, 16 insertions, 3 deletions
diff --git a/fs/btrfs/extent_map.c b/fs/btrfs/extent_map.c index fff2c28497b6..ed88f5ee4bea 100644 --- a/fs/btrfs/extent_map.c +++ b/fs/btrfs/extent_map.c | |||
@@ -171,6 +171,10 @@ static int mergable_maps(struct extent_map *prev, struct extent_map *next) | |||
171 | if (test_bit(EXTENT_FLAG_COMPRESSED, &prev->flags)) | 171 | if (test_bit(EXTENT_FLAG_COMPRESSED, &prev->flags)) |
172 | return 0; | 172 | return 0; |
173 | 173 | ||
174 | if (test_bit(EXTENT_FLAG_LOGGING, &prev->flags) || | ||
175 | test_bit(EXTENT_FLAG_LOGGING, &next->flags)) | ||
176 | return 0; | ||
177 | |||
174 | if (extent_map_end(prev) == next->start && | 178 | if (extent_map_end(prev) == next->start && |
175 | prev->flags == next->flags && | 179 | prev->flags == next->flags && |
176 | prev->bdev == next->bdev && | 180 | prev->bdev == next->bdev && |
@@ -256,7 +260,8 @@ int unpin_extent_cache(struct extent_map_tree *tree, u64 start, u64 len, | |||
256 | if (!em) | 260 | if (!em) |
257 | goto out; | 261 | goto out; |
258 | 262 | ||
259 | list_move(&em->list, &tree->modified_extents); | 263 | if (!test_bit(EXTENT_FLAG_LOGGING, &em->flags)) |
264 | list_move(&em->list, &tree->modified_extents); | ||
260 | em->generation = gen; | 265 | em->generation = gen; |
261 | clear_bit(EXTENT_FLAG_PINNED, &em->flags); | 266 | clear_bit(EXTENT_FLAG_PINNED, &em->flags); |
262 | em->mod_start = em->start; | 267 | em->mod_start = em->start; |
@@ -281,6 +286,12 @@ out: | |||
281 | 286 | ||
282 | } | 287 | } |
283 | 288 | ||
289 | void clear_em_logging(struct extent_map_tree *tree, struct extent_map *em) | ||
290 | { | ||
291 | clear_bit(EXTENT_FLAG_LOGGING, &em->flags); | ||
292 | try_merge_map(tree, em); | ||
293 | } | ||
294 | |||
284 | /** | 295 | /** |
285 | * add_extent_mapping - add new extent map to the extent tree | 296 | * add_extent_mapping - add new extent map to the extent tree |
286 | * @tree: tree to insert new map in | 297 | * @tree: tree to insert new map in |
diff --git a/fs/btrfs/extent_map.h b/fs/btrfs/extent_map.h index 922943ce29e8..c6598c89cff8 100644 --- a/fs/btrfs/extent_map.h +++ b/fs/btrfs/extent_map.h | |||
@@ -69,6 +69,7 @@ void free_extent_map(struct extent_map *em); | |||
69 | int __init extent_map_init(void); | 69 | int __init extent_map_init(void); |
70 | void extent_map_exit(void); | 70 | void extent_map_exit(void); |
71 | int unpin_extent_cache(struct extent_map_tree *tree, u64 start, u64 len, u64 gen); | 71 | int unpin_extent_cache(struct extent_map_tree *tree, u64 start, u64 len, u64 gen); |
72 | void clear_em_logging(struct extent_map_tree *tree, struct extent_map *em); | ||
72 | struct extent_map *search_extent_mapping(struct extent_map_tree *tree, | 73 | struct extent_map *search_extent_mapping(struct extent_map_tree *tree, |
73 | u64 start, u64 len); | 74 | u64 start, u64 len); |
74 | #endif | 75 | #endif |
diff --git a/fs/btrfs/tree-log.c b/fs/btrfs/tree-log.c index 83186c7e45d4..de8899b04d69 100644 --- a/fs/btrfs/tree-log.c +++ b/fs/btrfs/tree-log.c | |||
@@ -3410,13 +3410,13 @@ static int btrfs_log_changed_extents(struct btrfs_trans_handle *trans, | |||
3410 | em = list_entry(extents.next, struct extent_map, list); | 3410 | em = list_entry(extents.next, struct extent_map, list); |
3411 | 3411 | ||
3412 | list_del_init(&em->list); | 3412 | list_del_init(&em->list); |
3413 | clear_bit(EXTENT_FLAG_LOGGING, &em->flags); | ||
3414 | 3413 | ||
3415 | /* | 3414 | /* |
3416 | * If we had an error we just need to delete everybody from our | 3415 | * If we had an error we just need to delete everybody from our |
3417 | * private list. | 3416 | * private list. |
3418 | */ | 3417 | */ |
3419 | if (ret) { | 3418 | if (ret) { |
3419 | clear_em_logging(tree, em); | ||
3420 | free_extent_map(em); | 3420 | free_extent_map(em); |
3421 | continue; | 3421 | continue; |
3422 | } | 3422 | } |
@@ -3424,8 +3424,9 @@ static int btrfs_log_changed_extents(struct btrfs_trans_handle *trans, | |||
3424 | write_unlock(&tree->lock); | 3424 | write_unlock(&tree->lock); |
3425 | 3425 | ||
3426 | ret = log_one_extent(trans, inode, root, em, path); | 3426 | ret = log_one_extent(trans, inode, root, em, path); |
3427 | free_extent_map(em); | ||
3428 | write_lock(&tree->lock); | 3427 | write_lock(&tree->lock); |
3428 | clear_em_logging(tree, em); | ||
3429 | free_extent_map(em); | ||
3429 | } | 3430 | } |
3430 | WARN_ON(!list_empty(&extents)); | 3431 | WARN_ON(!list_empty(&extents)); |
3431 | write_unlock(&tree->lock); | 3432 | write_unlock(&tree->lock); |