diff options
author | Josef Bacik <jbacik@fusionio.com> | 2012-09-14 12:59:20 -0400 |
---|---|---|
committer | Chris Mason <chris.mason@fusionio.com> | 2012-10-04 09:39:58 -0400 |
commit | ff44c6e36dc9dcc02652a1105b120bdf08cea9f7 (patch) | |
tree | e3be38a3bc4fc628aacc35a361446da8694c1301 /fs/btrfs/extent_map.c | |
parent | 98114659e0d467e2c0ee6f24f2429329328fc312 (diff) | |
download | linux-ff44c6e36dc9dcc02652a1105b120bdf08cea9f7.tar.gz linux-ff44c6e36dc9dcc02652a1105b120bdf08cea9f7.tar.bz2 linux-ff44c6e36dc9dcc02652a1105b120bdf08cea9f7.zip |
Btrfs: do not hold the write_lock on the extent tree while logging
Dave Sterba pointed out a sleeping while atomic bug while doing fsync. This
is because I'm an idiot and didn't realize that rwlock's were spin locks, so
we've been holding this thing while doing allocations and such which is not
good. This patch fixes this by dropping the write lock before we do
anything heavy and re-acquire it when it is done. We also need to take a
ref on the em's in case their corresponding pages are evicted and mark them
as being logged so that releasepage does not remove them and doesn't remove
them from our local list. Thanks,
Reported-by: Dave Sterba <dave@jikos.cz>
Signed-off-by: Josef Bacik <jbacik@fusionio.com>
Diffstat (limited to 'fs/btrfs/extent_map.c')
-rw-r--r-- | fs/btrfs/extent_map.c | 3 |
1 files changed, 2 insertions, 1 deletions
diff --git a/fs/btrfs/extent_map.c b/fs/btrfs/extent_map.c index 8d1364d385d6..b8cbc8d5c7f7 100644 --- a/fs/btrfs/extent_map.c +++ b/fs/btrfs/extent_map.c @@ -407,7 +407,8 @@ int remove_extent_mapping(struct extent_map_tree *tree, struct extent_map *em) WARN_ON(test_bit(EXTENT_FLAG_PINNED, &em->flags)); rb_erase(&em->rb_node, &tree->map); - list_del_init(&em->list); + if (!test_bit(EXTENT_FLAG_LOGGING, &em->flags)) + list_del_init(&em->list); em->in_tree = 0; return ret; } |