diff options
| author | Li Zefan <lizf@cn.fujitsu.com> | 2011-07-13 23:18:33 -0400 |
|---|---|---|
| committer | Chris Mason <chris.mason@oracle.com> | 2011-08-01 14:30:50 -0400 |
| commit | 4d2c8f62f12a6652db67cc0c1f4a4a498b05ddbc (patch) | |
| tree | ebc07d75a30f84d4f8c9b8e86720307c02fe9023 /fs/btrfs | |
| parent | ed64f06652210b4a52fe0ea65ac43f9c6af1d988 (diff) | |
Btrfs: clean up code for merging extent maps
unpin_extent_cache() and add_extent_mapping() shares the same code
that merges extent maps.
Signed-off-by: Li Zefan <lizf@cn.fujitsu.com>
Signed-off-by: Chris Mason <chris.mason@oracle.com>
Diffstat (limited to 'fs/btrfs')
| -rw-r--r-- | fs/btrfs/extent_map.c | 59 |
1 files changed, 21 insertions, 38 deletions
diff --git a/fs/btrfs/extent_map.c b/fs/btrfs/extent_map.c index df7a803005fb..7c97b3301459 100644 --- a/fs/btrfs/extent_map.c +++ b/fs/btrfs/extent_map.c | |||
| @@ -183,22 +183,10 @@ static int mergable_maps(struct extent_map *prev, struct extent_map *next) | |||
| 183 | return 0; | 183 | return 0; |
| 184 | } | 184 | } |
| 185 | 185 | ||
| 186 | int unpin_extent_cache(struct extent_map_tree *tree, u64 start, u64 len) | 186 | static void try_merge_map(struct extent_map_tree *tree, struct extent_map *em) |
| 187 | { | 187 | { |
| 188 | int ret = 0; | ||
| 189 | struct extent_map *merge = NULL; | 188 | struct extent_map *merge = NULL; |
| 190 | struct rb_node *rb; | 189 | struct rb_node *rb; |
| 191 | struct extent_map *em; | ||
| 192 | |||
| 193 | write_lock(&tree->lock); | ||
| 194 | em = lookup_extent_mapping(tree, start, len); | ||
| 195 | |||
| 196 | WARN_ON(!em || em->start != start); | ||
| 197 | |||
| 198 | if (!em) | ||
| 199 | goto out; | ||
| 200 | |||
| 201 | clear_bit(EXTENT_FLAG_PINNED, &em->flags); | ||
| 202 | 190 | ||
| 203 | if (em->start != 0) { | 191 | if (em->start != 0) { |
| 204 | rb = rb_prev(&em->rb_node); | 192 | rb = rb_prev(&em->rb_node); |
| @@ -225,6 +213,24 @@ int unpin_extent_cache(struct extent_map_tree *tree, u64 start, u64 len) | |||
| 225 | merge->in_tree = 0; | 213 | merge->in_tree = 0; |
| 226 | free_extent_map(merge); | 214 | free_extent_map(merge); |
| 227 | } | 215 | } |
| 216 | } | ||
| 217 | |||
| 218 | int unpin_extent_cache(struct extent_map_tree *tree, u64 start, u64 len) | ||
| 219 | { | ||
| 220 | int ret = 0; | ||
| 221 | struct extent_map *em; | ||
| 222 | |||
| 223 | write_lock(&tree->lock); | ||
| 224 | em = lookup_extent_mapping(tree, start, len); | ||
| 225 | |||
| 226 | WARN_ON(!em || em->start != start); | ||
| 227 | |||
| 228 | if (!em) | ||
| 229 | goto out; | ||
| 230 | |||
| 231 | clear_bit(EXTENT_FLAG_PINNED, &em->flags); | ||
| 232 | |||
| 233 | try_merge_map(tree, em); | ||
| 228 | 234 | ||
| 229 | free_extent_map(em); | 235 | free_extent_map(em); |
| 230 | out: | 236 | out: |
| @@ -247,7 +253,6 @@ int add_extent_mapping(struct extent_map_tree *tree, | |||
| 247 | struct extent_map *em) | 253 | struct extent_map *em) |
| 248 | { | 254 | { |
| 249 | int ret = 0; | 255 | int ret = 0; |
| 250 | struct extent_map *merge = NULL; | ||
| 251 | struct rb_node *rb; | 256 | struct rb_node *rb; |
| 252 | struct extent_map *exist; | 257 | struct extent_map *exist; |
| 253 | 258 | ||
| @@ -263,30 +268,8 @@ int add_extent_mapping(struct extent_map_tree *tree, | |||
| 263 | goto out; | 268 | goto out; |
| 264 | } | 269 | } |
| 265 | atomic_inc(&em->refs); | 270 | atomic_inc(&em->refs); |
| 266 | if (em->start != 0) { | 271 | |
| 267 | rb = rb_prev(&em->rb_node); | 272 | try_merge_map(tree, em); |
| 268 | if (rb) | ||
| 269 | merge = rb_entry(rb, struct extent_map, rb_node); | ||
| 270 | if (rb && mergable_maps(merge, em)) { | ||
| 271 | em->start = merge->start; | ||
| 272 | em->len += merge->len; | ||
| 273 | em->block_len += merge->block_len; | ||
| 274 | em->block_start = merge->block_start; | ||
| 275 | merge->in_tree = 0; | ||
| 276 | rb_erase(&merge->rb_node, &tree->map); | ||
| 277 | free_extent_map(merge); | ||
| 278 | } | ||
| 279 | } | ||
| 280 | rb = rb_next(&em->rb_node); | ||
| 281 | if (rb) | ||
| 282 | merge = rb_entry(rb, struct extent_map, rb_node); | ||
| 283 | if (rb && mergable_maps(em, merge)) { | ||
| 284 | em->len += merge->len; | ||
| 285 | em->block_len += merge->len; | ||
| 286 | rb_erase(&merge->rb_node, &tree->map); | ||
| 287 | merge->in_tree = 0; | ||
| 288 | free_extent_map(merge); | ||
| 289 | } | ||
| 290 | out: | 273 | out: |
| 291 | return ret; | 274 | return ret; |
| 292 | } | 275 | } |
