Commit 17de39ac authored by Josef Bacik's avatar Josef Bacik Committed by Chris Mason

Btrfs: fix page leak when allocing extent buffers

If we happen to alloc a extent buffer and then alloc a page and notice that
page is already attached to an extent buffer, we will only unlock it and
free our existing eb.  Any pages currently attached to that eb will be
properly freed, but we don't do the page_cache_release() on the page where
we noticed the other extent buffer which can cause us to leak pages and I
hope cause the weird issues we've been seeing in this area.  Thanks,
Signed-off-by: default avatarJosef Bacik <josef@redhat.com>
Signed-off-by: default avatarChris Mason <chris.mason@oracle.com>
parent e5846fc6
...@@ -4120,6 +4120,7 @@ struct extent_buffer *alloc_extent_buffer(struct extent_io_tree *tree, ...@@ -4120,6 +4120,7 @@ struct extent_buffer *alloc_extent_buffer(struct extent_io_tree *tree,
if (atomic_inc_not_zero(&exists->refs)) { if (atomic_inc_not_zero(&exists->refs)) {
spin_unlock(&mapping->private_lock); spin_unlock(&mapping->private_lock);
unlock_page(p); unlock_page(p);
page_cache_release(p);
mark_extent_buffer_accessed(exists); mark_extent_buffer_accessed(exists);
goto free_eb; goto free_eb;
} }
...@@ -4199,8 +4200,7 @@ struct extent_buffer *alloc_extent_buffer(struct extent_io_tree *tree, ...@@ -4199,8 +4200,7 @@ struct extent_buffer *alloc_extent_buffer(struct extent_io_tree *tree,
unlock_page(eb->pages[i]); unlock_page(eb->pages[i]);
} }
if (!atomic_dec_and_test(&eb->refs)) WARN_ON(!atomic_dec_and_test(&eb->refs));
return exists;
btrfs_release_extent_buffer(eb); btrfs_release_extent_buffer(eb);
return exists; return exists;
} }
......
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