diff options
author | Filipe Manana <fdmanana@suse.com> | 2017-03-06 23:04:20 +0000 |
---|---|---|
committer | Filipe Manana <fdmanana@suse.com> | 2017-04-26 16:27:22 +0100 |
commit | a315e68f6e8b3006c29482dbfc4d928f098c449c (patch) | |
tree | 0e27dfc28bb908b143f1c84a345e87f45372d137 /fs/btrfs/extent_io.h | |
parent | 524272607e882d04e6d1a70d41fcbed819445ab9 (diff) | |
download | talos-obmc-linux-a315e68f6e8b3006c29482dbfc4d928f098c449c.tar.gz talos-obmc-linux-a315e68f6e8b3006c29482dbfc4d928f098c449c.zip |
Btrfs: fix invalid attempt to free reserved space on failure to cow range
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: Filipe Manana <fdmanana@suse.com>
Reviewed-by: Liu Bo <bo.li.liu@oracle.com>
Diffstat (limited to 'fs/btrfs/extent_io.h')
-rw-r--r-- | fs/btrfs/extent_io.h | 4 |
1 files changed, 3 insertions, 1 deletions
diff --git a/fs/btrfs/extent_io.h b/fs/btrfs/extent_io.h index 3e4fad4a909d..48a30d0e71fb 100644 --- a/fs/btrfs/extent_io.h +++ b/fs/btrfs/extent_io.h @@ -14,7 +14,7 @@ #define EXTENT_DEFRAG (1U << 6) #define EXTENT_BOUNDARY (1U << 9) #define EXTENT_NODATASUM (1U << 10) -#define EXTENT_DO_ACCOUNTING (1U << 11) +#define EXTENT_CLEAR_META_RESV (1U << 11) #define EXTENT_FIRST_DELALLOC (1U << 12) #define EXTENT_NEED_WAIT (1U << 13) #define EXTENT_DAMAGED (1U << 14) @@ -22,6 +22,8 @@ #define EXTENT_QGROUP_RESERVED (1U << 16) #define EXTENT_CLEAR_DATA_RESV (1U << 17) #define EXTENT_IOBITS (EXTENT_LOCKED | EXTENT_WRITEBACK) +#define EXTENT_DO_ACCOUNTING (EXTENT_CLEAR_META_RESV | \ + EXTENT_CLEAR_DATA_RESV) #define EXTENT_CTLBITS (EXTENT_DO_ACCOUNTING | EXTENT_FIRST_DELALLOC) /* |