• Filipe Manana's avatar
    Btrfs: fix invalid attempt to free reserved space on failure to cow range · a315e68f
    Filipe Manana authored
    When attempting to COW a file range (we are starting writeback and doing
    COW), if we manage to reserve an extent for the range we will write into
    but fail after reserving it and before creating the respective ordered
    extent, we end up in an error path where we attempt to decrement the
    data space's bytes_may_use counter after we already did it while
    reserving the extent, leading to a warning/trace like the following:
    
    [  847.621524] ------------[ cut here ]------------
    [  847.625441] WARNING: CPU: 5 PID: 4905 at fs/btrfs/extent-tree.c:4316 btrfs_free_reserved_data_space_noquota+0x60/0x9f [btrfs]
    [  847.633704] Modules linked in: btrfs crc32c_generic xor raid6_pq acpi_cpufreq i2c_piix4 ppdev psmouse tpm_tis serio_raw pcspkr parport_pc tpm_tis_core i2c_core sg
    [  847.644616] CPU: 5 PID: 4905 Comm: xfs_io Not tainted 4.10.0-rc8-btrfs-next-37+ #2
    [  847.648601] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS rel-1.9.1-0-gb3ef39f-prebuilt.qemu-project.org 04/01/2014
    [  847.648601] Call Trace:
    [  847.648601]  dump_stack+0x67/0x90
    [  847.648601]  __warn+0xc2/0xdd
    [  847.648601]  warn_slowpath_null+0x1d/0x1f
    [  847.648601]  btrfs_free_reserved_data_space_noquota+0x60/0x9f [btrfs]
    [  847.648601]  btrfs_clear_bit_hook+0x140/0x258 [btrfs]
    [  847.648601]  clear_state_bit+0x87/0x128 [btrfs]
    [  847.648601]  __clear_extent_bit+0x222/0x2b7 [btrfs]
    [  847.648601]  clear_extent_bit+0x17/0x19 [btrfs]
    [  847.648601]  extent_clear_unlock_delalloc+0x3b/0x6b [btrfs]
    [  847.648601]  cow_file_range.isra.39+0x387/0x39a [btrfs]
    [  847.648601]  run_delalloc_nocow+0x4d7/0x70e [btrfs]
    [  847.648601]  ? arch_local_irq_save+0x9/0xc
    [  847.648601]  run_delalloc_range+0xa7/0x2b5 [btrfs]
    [  847.648601]  writepage_delalloc.isra.31+0xb9/0x15c [btrfs]
    [  847.648601]  __extent_writepage+0x249/0x2e8 [btrfs]
    [  847.648601]  extent_write_cache_pages.constprop.33+0x28b/0x36c [btrfs]
    [  847.648601]  ? arch_local_irq_save+0x9/0xc
    [  847.648601]  ? mark_lock+0x24/0x201
    [  847.648601]  extent_writepages+0x4b/0x5c [btrfs]
    [  847.648601]  ? btrfs_writepage_start_hook+0xed/0xed [btrfs]
    [  847.648601]  btrfs_writepages+0x28/0x2a [btrfs]
    [  847.648601]  do_writepages+0x23/0x2c
    [  847.648601]  __filemap_fdatawrite_range+0x5a/0x61
    [  847.648601]  filemap_fdatawrite_range+0x13/0x15
    [  847.648601]  btrfs_fdatawrite_range+0x20/0x46 [btrfs]
    [  847.648601]  start_ordered_ops+0x19/0x23 [btrfs]
    [  847.648601]  btrfs_sync_file+0x136/0x42c [btrfs]
    [  847.648601]  vfs_fsync_range+0x8c/0x9e
    [  847.648601]  vfs_fsync+0x1c/0x1e
    [  847.648601]  do_fsync+0x31/0x4a
    [  847.648601]  SyS_fsync+0x10/0x14
    [  847.648601]  entry_SYSCALL_64_fastpath+0x18/0xad
    [  847.648601] RIP: 0033:0x7f5b05200800
    [  847.648601] RSP: 002b:00007ffe204f71c8 EFLAGS: 00000246 ORIG_RAX: 000000000000004a
    [  847.648601] RAX: ffffffffffffffda RBX: ffffffff8109637b RCX: 00007f5b05200800
    [  847.648601] RDX: 00000000008bd0a0 RSI: 00000000008bd2e0 RDI: 0000000000000003
    [  847.648601] RBP: ffffc90001d67f98 R08: 000000000000ffff R09: 000000000000001f
    [  847.648601] R10: 00000000000001f6 R11: 0000000000000246 R12: 0000000000000046
    [  847.648601] R13: ffffc90001d67f78 R14: 00007f5b054be740 R15: 00007f5b054be740
    [  847.648601]  ? trace_hardirqs_off_caller+0x3f/0xaa
    [  847.685787] ---[ end trace 2a4a3e15382508e8 ]---
    
    So fix this by not attempting to decrement the data space info's
    bytes_may_use counter if we already reserved the extent and an error
    happened before creating the ordered extent. We are already correctly
    freeing the reserved extent if an error happens, so there's no additional
    measure needed.
    Signed-off-by: default avatarFilipe Manana <fdmanana@suse.com>
    Reviewed-by: default avatarLiu Bo <bo.li.liu@oracle.com>
    a315e68f
inode.c 286 KB