• David Sterba's avatar
    btrfs: mask out gfp flags in releasepage · 0c4e538b
    David Sterba authored
    btree_releasepage is a callback and can be passed unknown gfp flags and then
    they may end up in kmem_cache_alloc called from alloc_extent_state, slab
    allocator will BUG_ON when there is HIGHMEM or DMA32 flag set.
    
    This may happen when btrfs is mounted from a loop device, which masks out
    __GFP_IO flag. The check in try_release_extent_state
    
    3399                 if ((mask & GFP_NOFS) == GFP_NOFS)
    3400                         mask = GFP_NOFS;
    
    will not work and passes unfiltered flags further resulting in crash at
    mm/slab.c:2963
    
     [<000000000024ae4c>] cache_alloc_refill+0x3b4/0x5c8
     [<000000000024c810>] kmem_cache_alloc+0x204/0x294
     [<00000000001fd3c2>] mempool_alloc+0x52/0x170
     [<000003c000ced0b0>] alloc_extent_state+0x40/0xd4 [btrfs]
     [<000003c000cee5ae>] __clear_extent_bit+0x38a/0x4cc [btrfs]
     [<000003c000cee78c>] try_release_extent_state+0x9c/0xd4 [btrfs]
     [<000003c000cc4c66>] btree_releasepage+0x7e/0xd0 [btrfs]
     [<0000000000210d84>] shrink_page_list+0x6a0/0x724
     [<0000000000211394>] shrink_inactive_list+0x230/0x578
     [<0000000000211bb8>] shrink_list+0x6c/0x120
     [<0000000000211e4e>] shrink_zone+0x1e2/0x228
     [<0000000000211f24>] shrink_zones+0x90/0x254
     [<0000000000213410>] do_try_to_free_pages+0xac/0x420
     [<0000000000213ae0>] try_to_free_pages+0x13c/0x1b0
     [<0000000000204e6c>] __alloc_pages_nodemask+0x5b4/0x9a8
     [<00000000001fb04a>] grab_cache_page_write_begin+0x7e/0xe8
    Signed-off-by: default avatarDavid Sterba <dsterba@suse.cz>
    Signed-off-by: default avatarChris Mason <chris.mason@oracle.com>
    0c4e538b
disk-io.c 97.3 KB