Commit 90f1c19a authored by Christoph Hellwig's avatar Christoph Hellwig Committed by David Woodhouse

Btrfs: [PATCH] extent_map: fix locking for bio completion

The bio completion handlers can be run in any context, e.g. when using
the old ide driver they run in hardirq context with irqs disabled so
lockdep rightfully warns about using write_lock_irq useage in these
handlers.

This patch switches clear_extent_bit and set_extent_bit to
write_lock_irqsave to fix this problem.
Signed-off-by: default avatarChristoph Hellwig <hch@lst.de>
Signed-off-by: default avatarChris Mason <chris.mason@oracle.com>
parent 9433063b
...@@ -456,6 +456,7 @@ int clear_extent_bit(struct extent_map_tree *tree, u64 start, u64 end, ...@@ -456,6 +456,7 @@ int clear_extent_bit(struct extent_map_tree *tree, u64 start, u64 end,
struct extent_state *state; struct extent_state *state;
struct extent_state *prealloc = NULL; struct extent_state *prealloc = NULL;
struct rb_node *node; struct rb_node *node;
unsigned long flags;
int err; int err;
int set = 0; int set = 0;
...@@ -466,7 +467,7 @@ int clear_extent_bit(struct extent_map_tree *tree, u64 start, u64 end, ...@@ -466,7 +467,7 @@ int clear_extent_bit(struct extent_map_tree *tree, u64 start, u64 end,
return -ENOMEM; return -ENOMEM;
} }
write_lock_irq(&tree->lock); write_lock_irqsave(&tree->lock, flags);
/* /*
* this search will find the extents that end after * this search will find the extents that end after
* our range starts * our range starts
...@@ -533,7 +534,7 @@ int clear_extent_bit(struct extent_map_tree *tree, u64 start, u64 end, ...@@ -533,7 +534,7 @@ int clear_extent_bit(struct extent_map_tree *tree, u64 start, u64 end,
goto search_again; goto search_again;
out: out:
write_unlock_irq(&tree->lock); write_unlock_irqrestore(&tree->lock, flags);
if (prealloc) if (prealloc)
free_extent_state(prealloc); free_extent_state(prealloc);
...@@ -542,7 +543,7 @@ int clear_extent_bit(struct extent_map_tree *tree, u64 start, u64 end, ...@@ -542,7 +543,7 @@ int clear_extent_bit(struct extent_map_tree *tree, u64 start, u64 end,
search_again: search_again:
if (start >= end) if (start >= end)
goto out; goto out;
write_unlock_irq(&tree->lock); write_unlock_irqrestore(&tree->lock, flags);
if (mask & __GFP_WAIT) if (mask & __GFP_WAIT)
cond_resched(); cond_resched();
goto again; goto again;
...@@ -628,6 +629,7 @@ int set_extent_bit(struct extent_map_tree *tree, u64 start, u64 end, int bits, ...@@ -628,6 +629,7 @@ int set_extent_bit(struct extent_map_tree *tree, u64 start, u64 end, int bits,
struct extent_state *state; struct extent_state *state;
struct extent_state *prealloc = NULL; struct extent_state *prealloc = NULL;
struct rb_node *node; struct rb_node *node;
unsigned long flags;
int err = 0; int err = 0;
int set; int set;
u64 last_start; u64 last_start;
...@@ -639,7 +641,7 @@ int set_extent_bit(struct extent_map_tree *tree, u64 start, u64 end, int bits, ...@@ -639,7 +641,7 @@ int set_extent_bit(struct extent_map_tree *tree, u64 start, u64 end, int bits,
return -ENOMEM; return -ENOMEM;
} }
write_lock_irq(&tree->lock); write_lock_irqsave(&tree->lock, flags);
/* /*
* this search will find all the extents that end after * this search will find all the extents that end after
* our range starts. * our range starts.
...@@ -759,7 +761,7 @@ int set_extent_bit(struct extent_map_tree *tree, u64 start, u64 end, int bits, ...@@ -759,7 +761,7 @@ int set_extent_bit(struct extent_map_tree *tree, u64 start, u64 end, int bits,
goto search_again; goto search_again;
out: out:
write_unlock_irq(&tree->lock); write_unlock_irqrestore(&tree->lock, flags);
if (prealloc) if (prealloc)
free_extent_state(prealloc); free_extent_state(prealloc);
...@@ -768,7 +770,7 @@ int set_extent_bit(struct extent_map_tree *tree, u64 start, u64 end, int bits, ...@@ -768,7 +770,7 @@ int set_extent_bit(struct extent_map_tree *tree, u64 start, u64 end, int bits,
search_again: search_again:
if (start > end) if (start > end)
goto out; goto out;
write_unlock_irq(&tree->lock); write_unlock_irqrestore(&tree->lock, flags);
if (mask & __GFP_WAIT) if (mask & __GFP_WAIT)
cond_resched(); cond_resched();
goto again; goto again;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment