Skip to content

Commit

Permalink
Btrfs: don't return true in releasepage unless we actually freed the eb
Browse files Browse the repository at this point in the history
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: Josef Bacik <jbacik@fusionio.com>
  • Loading branch information
Josef Bacik authored and Chris Mason committed Jul 23, 2012
1 parent a98cdb8 commit e64860a
Showing 1 changed file with 5 additions and 4 deletions.
9 changes: 5 additions & 4 deletions fs/btrfs/extent_io.c
Original file line number Diff line number Diff line change
Expand Up @@ -4300,7 +4300,7 @@ static inline void btrfs_release_extent_buffer_rcu(struct rcu_head *head)
}

/* 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);
if (atomic_dec_and_test(&eb->refs)) {
Expand All @@ -4321,9 +4321,11 @@ static void release_extent_buffer(struct extent_buffer *eb, gfp_t mask)
btrfs_release_extent_buffer_page(eb, 0);

call_rcu(&eb->rcu_head, btrfs_release_extent_buffer_rcu);
return;
return 1;
}
spin_unlock(&eb->refs_lock);

return 0;
}

void free_extent_buffer(struct extent_buffer *eb)
Expand Down Expand Up @@ -4962,7 +4964,6 @@ int try_release_extent_buffer(struct page *page, gfp_t mask)
spin_unlock(&eb->refs_lock);
return 0;
}
release_extent_buffer(eb, mask);

return 1;
return release_extent_buffer(eb, mask);
}

0 comments on commit e64860a

Please sign in to comment.