Commit e64860aa authored by Josef Bacik's avatar Josef Bacik Committed by Chris Mason

Btrfs: don't return true in releasepage unless we actually freed the eb

I noticed while looking at an extent_buffer race that we will
unconditionally return 1 if we get down to release_extent_buffer after
clearing the tree ref.  However we can easily race in here and get a ref on
the eb and not actually free the eb.  So make release_extent_buffer return 1
if it free'd the eb and 0 if not so we can be a little kinder to the vm.
Thanks,
Signed-off-by: default avatarJosef Bacik <jbacik@fusionio.com>
parent a98cdb85
...@@ -4300,7 +4300,7 @@ static inline void btrfs_release_extent_buffer_rcu(struct rcu_head *head) ...@@ -4300,7 +4300,7 @@ static inline void btrfs_release_extent_buffer_rcu(struct rcu_head *head)
} }
/* Expects to have eb->eb_lock already held */ /* Expects to have eb->eb_lock already held */
static void release_extent_buffer(struct extent_buffer *eb, gfp_t mask) static int release_extent_buffer(struct extent_buffer *eb, gfp_t mask)
{ {
WARN_ON(atomic_read(&eb->refs) == 0); WARN_ON(atomic_read(&eb->refs) == 0);
if (atomic_dec_and_test(&eb->refs)) { if (atomic_dec_and_test(&eb->refs)) {
...@@ -4321,9 +4321,11 @@ static void release_extent_buffer(struct extent_buffer *eb, gfp_t mask) ...@@ -4321,9 +4321,11 @@ static void release_extent_buffer(struct extent_buffer *eb, gfp_t mask)
btrfs_release_extent_buffer_page(eb, 0); btrfs_release_extent_buffer_page(eb, 0);
call_rcu(&eb->rcu_head, btrfs_release_extent_buffer_rcu); call_rcu(&eb->rcu_head, btrfs_release_extent_buffer_rcu);
return; return 1;
} }
spin_unlock(&eb->refs_lock); spin_unlock(&eb->refs_lock);
return 0;
} }
void free_extent_buffer(struct extent_buffer *eb) void free_extent_buffer(struct extent_buffer *eb)
...@@ -4962,7 +4964,6 @@ int try_release_extent_buffer(struct page *page, gfp_t mask) ...@@ -4962,7 +4964,6 @@ int try_release_extent_buffer(struct page *page, gfp_t mask)
spin_unlock(&eb->refs_lock); spin_unlock(&eb->refs_lock);
return 0; return 0;
} }
release_extent_buffer(eb, mask);
return 1; return release_extent_buffer(eb, mask);
} }
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