aboutsummaryrefslogtreecommitdiffstats
path: root/fs/btrfs/free-space-cache.c
diff options
context:
space:
mode:
authorOmar Sandoval <osandov@osandov.com>2015-02-24 02:47:05 -0800
committerChris Mason <clm@fb.com>2015-04-26 06:27:00 -0700
commit5ca64f45e92dc52bd3bc1ad93f4f9e5a57955f28 (patch)
tree3e197015904be5b68c3ed94314c4ca2ef0c06051 /fs/btrfs/free-space-cache.c
parentbtrfs: handle ENOMEM in btrfs_alloc_tree_block (diff)
downloadlinux-dev-5ca64f45e92dc52bd3bc1ad93f4f9e5a57955f28.tar.xz
linux-dev-5ca64f45e92dc52bd3bc1ad93f4f9e5a57955f28.zip
btrfs: fix race on ENOMEM in alloc_extent_buffer
Consider the following interleaving of overlapping calls to alloc_extent_buffer: Call 1: - Successfully allocates a few pages with find_or_create_page - find_or_create_page fails, goto free_eb - Unlocks the allocated pages Call 2: - Calls find_or_create_page and gets a page in call 1's extent_buffer - Finds that the page is already associated with an extent_buffer - Grabs a reference to the half-written extent_buffer and calls mark_extent_buffer_accessed on it mark_extent_buffer_accessed will then try to call mark_page_accessed on a null page and panic. The fix is to decrement the reference count on the half-written extent_buffer before unlocking the pages so call 2 won't use it. We should also set exists = NULL in the case that we don't use exists to avoid accidentally returning a freed extent_buffer in an error case. Signed-off-by: Omar Sandoval <osandov@osandov.com> Reviewed-by: David Sterba <dsterba@suse.cz> Reviewed-by: Liu Bo <bo.li.liu@oracle.com> Signed-off-by: Chris Mason <clm@fb.com>
Diffstat (limited to 'fs/btrfs/free-space-cache.c')
0 files changed, 0 insertions, 0 deletions