aboutsummaryrefslogtreecommitdiffstats
path: root/fs/btrfs/extent_map.c
diff options
context:
space:
mode:
authorChris Mason <chris.mason@oracle.com>2008-07-22 11:18:09 -0400
committerChris Mason <chris.mason@oracle.com>2008-09-25 11:04:05 -0400
commitf421950f86bf96a11fef932e167ab2e70d4c43a0 (patch)
treea2b62b942b023e37b6aae39891c2b314d8d8a3fb /fs/btrfs/extent_map.c
parenta61e6f29dc7c9d56a776a518eed92bbc61848263 (diff)
Btrfs: Fix some data=ordered related data corruptions
Stress testing was showing data checksum errors, most of which were caused by a lookup bug in the extent_map tree. The tree was caching the last pointer returned, and searches would check the last pointer first. But, search callers also expect the search to return the very first matching extent in the range, which wasn't always true with the last pointer usage. For now, the code to cache the last return value is just removed. It is easy to fix, but I think lookups are rare enough that it isn't required anymore. This commit also replaces do_sync_mapping_range with a local copy of the related functions. Signed-off-by: Chris Mason <chris.mason@oracle.com>
Diffstat (limited to 'fs/btrfs/extent_map.c')
-rw-r--r--fs/btrfs/extent_map.c9
1 files changed, 0 insertions, 9 deletions
diff --git a/fs/btrfs/extent_map.c b/fs/btrfs/extent_map.c
index 71b1ac155355..8a502ee2f231 100644
--- a/fs/btrfs/extent_map.c
+++ b/fs/btrfs/extent_map.c
@@ -42,7 +42,6 @@ void extent_map_exit(void)
42void extent_map_tree_init(struct extent_map_tree *tree, gfp_t mask) 42void extent_map_tree_init(struct extent_map_tree *tree, gfp_t mask)
43{ 43{
44 tree->map.rb_node = NULL; 44 tree->map.rb_node = NULL;
45 tree->last = NULL;
46 spin_lock_init(&tree->lock); 45 spin_lock_init(&tree->lock);
47} 46}
48EXPORT_SYMBOL(extent_map_tree_init); 47EXPORT_SYMBOL(extent_map_tree_init);
@@ -239,7 +238,6 @@ int add_extent_mapping(struct extent_map_tree *tree,
239 merge->in_tree = 0; 238 merge->in_tree = 0;
240 free_extent_map(merge); 239 free_extent_map(merge);
241 } 240 }
242 tree->last = em;
243out: 241out:
244 return ret; 242 return ret;
245} 243}
@@ -273,10 +271,6 @@ struct extent_map *lookup_extent_mapping(struct extent_map_tree *tree,
273 u64 end = range_end(start, len); 271 u64 end = range_end(start, len);
274 272
275 BUG_ON(spin_trylock(&tree->lock)); 273 BUG_ON(spin_trylock(&tree->lock));
276 em = tree->last;
277 if (em && end > em->start && start < extent_map_end(em))
278 goto found;
279
280 rb_node = __tree_search(&tree->map, start, &prev, &next); 274 rb_node = __tree_search(&tree->map, start, &prev, &next);
281 if (!rb_node && prev) { 275 if (!rb_node && prev) {
282 em = rb_entry(prev, struct extent_map, rb_node); 276 em = rb_entry(prev, struct extent_map, rb_node);
@@ -305,7 +299,6 @@ struct extent_map *lookup_extent_mapping(struct extent_map_tree *tree,
305 299
306found: 300found:
307 atomic_inc(&em->refs); 301 atomic_inc(&em->refs);
308 tree->last = em;
309out: 302out:
310 return em; 303 return em;
311} 304}
@@ -327,8 +320,6 @@ int remove_extent_mapping(struct extent_map_tree *tree, struct extent_map *em)
327 BUG_ON(spin_trylock(&tree->lock)); 320 BUG_ON(spin_trylock(&tree->lock));
328 rb_erase(&em->rb_node, &tree->map); 321 rb_erase(&em->rb_node, &tree->map);
329 em->in_tree = 0; 322 em->in_tree = 0;
330 if (tree->last == em)
331 tree->last = NULL;
332 return ret; 323 return ret;
333} 324}
334EXPORT_SYMBOL(remove_extent_mapping); 325EXPORT_SYMBOL(remove_extent_mapping);