diff options
Diffstat (limited to 'fs/btrfs')
-rw-r--r-- | fs/btrfs/extent_map.c | 85 |
1 files changed, 29 insertions, 56 deletions
diff --git a/fs/btrfs/extent_map.c b/fs/btrfs/extent_map.c index 911a9db801e0..df7a803005fb 100644 --- a/fs/btrfs/extent_map.c +++ b/fs/btrfs/extent_map.c | |||
@@ -299,19 +299,8 @@ static u64 range_end(u64 start, u64 len) | |||
299 | return start + len; | 299 | return start + len; |
300 | } | 300 | } |
301 | 301 | ||
302 | /** | 302 | struct extent_map *__lookup_extent_mapping(struct extent_map_tree *tree, |
303 | * lookup_extent_mapping - lookup extent_map | 303 | u64 start, u64 len, int strict) |
304 | * @tree: tree to lookup in | ||
305 | * @start: byte offset to start the search | ||
306 | * @len: length of the lookup range | ||
307 | * | ||
308 | * Find and return the first extent_map struct in @tree that intersects the | ||
309 | * [start, len] range. There may be additional objects in the tree that | ||
310 | * intersect, so check the object returned carefully to make sure that no | ||
311 | * additional lookups are needed. | ||
312 | */ | ||
313 | struct extent_map *lookup_extent_mapping(struct extent_map_tree *tree, | ||
314 | u64 start, u64 len) | ||
315 | { | 304 | { |
316 | struct extent_map *em; | 305 | struct extent_map *em; |
317 | struct rb_node *rb_node; | 306 | struct rb_node *rb_node; |
@@ -320,38 +309,42 @@ struct extent_map *lookup_extent_mapping(struct extent_map_tree *tree, | |||
320 | u64 end = range_end(start, len); | 309 | u64 end = range_end(start, len); |
321 | 310 | ||
322 | rb_node = __tree_search(&tree->map, start, &prev, &next); | 311 | rb_node = __tree_search(&tree->map, start, &prev, &next); |
323 | if (!rb_node && prev) { | ||
324 | em = rb_entry(prev, struct extent_map, rb_node); | ||
325 | if (end > em->start && start < extent_map_end(em)) | ||
326 | goto found; | ||
327 | } | ||
328 | if (!rb_node && next) { | ||
329 | em = rb_entry(next, struct extent_map, rb_node); | ||
330 | if (end > em->start && start < extent_map_end(em)) | ||
331 | goto found; | ||
332 | } | ||
333 | if (!rb_node) { | 312 | if (!rb_node) { |
334 | em = NULL; | 313 | if (prev) |
335 | goto out; | 314 | rb_node = prev; |
336 | } | 315 | else if (next) |
337 | if (IS_ERR(rb_node)) { | 316 | rb_node = next; |
338 | em = ERR_CAST(rb_node); | 317 | else |
339 | goto out; | 318 | return NULL; |
340 | } | 319 | } |
320 | |||
341 | em = rb_entry(rb_node, struct extent_map, rb_node); | 321 | em = rb_entry(rb_node, struct extent_map, rb_node); |
342 | if (end > em->start && start < extent_map_end(em)) | ||
343 | goto found; | ||
344 | 322 | ||
345 | em = NULL; | 323 | if (strict && !(end > em->start && start < extent_map_end(em))) |
346 | goto out; | 324 | return NULL; |
347 | 325 | ||
348 | found: | ||
349 | atomic_inc(&em->refs); | 326 | atomic_inc(&em->refs); |
350 | out: | ||
351 | return em; | 327 | return em; |
352 | } | 328 | } |
353 | 329 | ||
354 | /** | 330 | /** |
331 | * lookup_extent_mapping - lookup extent_map | ||
332 | * @tree: tree to lookup in | ||
333 | * @start: byte offset to start the search | ||
334 | * @len: length of the lookup range | ||
335 | * | ||
336 | * Find and return the first extent_map struct in @tree that intersects the | ||
337 | * [start, len] range. There may be additional objects in the tree that | ||
338 | * intersect, so check the object returned carefully to make sure that no | ||
339 | * additional lookups are needed. | ||
340 | */ | ||
341 | struct extent_map *lookup_extent_mapping(struct extent_map_tree *tree, | ||
342 | u64 start, u64 len) | ||
343 | { | ||
344 | return __lookup_extent_mapping(tree, start, len, 1); | ||
345 | } | ||
346 | |||
347 | /** | ||
355 | * search_extent_mapping - find a nearby extent map | 348 | * search_extent_mapping - find a nearby extent map |
356 | * @tree: tree to lookup in | 349 | * @tree: tree to lookup in |
357 | * @start: byte offset to start the search | 350 | * @start: byte offset to start the search |
@@ -365,27 +358,7 @@ out: | |||
365 | struct extent_map *search_extent_mapping(struct extent_map_tree *tree, | 358 | struct extent_map *search_extent_mapping(struct extent_map_tree *tree, |
366 | u64 start, u64 len) | 359 | u64 start, u64 len) |
367 | { | 360 | { |
368 | struct extent_map *em; | 361 | return __lookup_extent_mapping(tree, start, len, 0); |
369 | struct rb_node *rb_node; | ||
370 | struct rb_node *prev = NULL; | ||
371 | struct rb_node *next = NULL; | ||
372 | |||
373 | rb_node = __tree_search(&tree->map, start, &prev, &next); | ||
374 | if (!rb_node && prev) { | ||
375 | em = rb_entry(prev, struct extent_map, rb_node); | ||
376 | goto found; | ||
377 | } | ||
378 | if (!rb_node && next) { | ||
379 | em = rb_entry(next, struct extent_map, rb_node); | ||
380 | goto found; | ||
381 | } | ||
382 | if (!rb_node) | ||
383 | return NULL; | ||
384 | |||
385 | em = rb_entry(rb_node, struct extent_map, rb_node); | ||
386 | found: | ||
387 | atomic_inc(&em->refs); | ||
388 | return em; | ||
389 | } | 362 | } |
390 | 363 | ||
391 | /** | 364 | /** |