Filipe Manana
11023d3f5f
Btrfs: fix infinite loop on inode eviction after deduplication of eof block
...
If we attempt to deduplicate the last block of a file A into the middle of
a file B, and file A's size is not a multiple of the block size, we end
rounding the deduplication length to 0 bytes, to avoid the data corruption
issue fixed by commit de02b9f6bb ("Btrfs: fix data corruption when
deduplicating between different files"). However a length of zero will
cause the insertion of an extent state with a start value greater (by 1)
then the end value, leading to a corrupt extent state that will trigger a
warning and cause chaos such as an infinite loop during inode eviction.
Example trace:
[96049.833585] ------------[ cut here ]------------
[96049.833714] WARNING: CPU: 0 PID: 24448 at fs/btrfs/extent_io.c:436 insert_state+0x101/0x120 [btrfs]
[96049.833767] CPU: 0 PID: 24448 Comm: xfs_io Not tainted 4.19.0-rc7-btrfs-next-39 #1
[96049.833768] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS rel-1.11.2-0-gf9626ccb91-prebuilt.qemu-project.org 04/01/2014
[96049.833780] RIP: 0010:insert_state+0x101/0x120 [btrfs]
[96049.833783] RSP: 0018:ffffafd2c3707af0 EFLAGS: 00010282
[96049.833785] RAX: 0000000000000000 RBX: 000000000004dfff RCX: 0000000000000006
[96049.833786] RDX: 0000000000000007 RSI: ffff99045c143230 RDI: ffff99047b2168a0
[96049.833787] RBP: ffff990457851cd0 R08: 0000000000000001 R09: 0000000000000000
[96049.833787] R10: ffffafd2c3707ab8 R11: 0000000000000000 R12: ffff9903b93b12c8
[96049.833788] R13: 000000000004e000 R14: ffffafd2c3707b80 R15: ffffafd2c3707b78
[96049.833790] FS: 00007f5c14e7d700(0000) GS:ffff99047b200000(0000) knlGS:0000000000000000
[96049.833791] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
[96049.833792] CR2: 00007f5c146abff8 CR3: 0000000115f4c004 CR4: 00000000003606f0
[96049.833795] DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000
[96049.833796] DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400
[96049.833796] Call Trace:
[96049.833809] __set_extent_bit+0x46c/0x6a0 [btrfs]
[96049.833823] lock_extent_bits+0x6b/0x210 [btrfs]
[96049.833831] ? _raw_spin_unlock+0x24/0x30
[96049.833841] ? test_range_bit+0xdf/0x130 [btrfs]
[96049.833853] lock_extent_range+0x8e/0x150 [btrfs]
[96049.833864] btrfs_double_extent_lock+0x78/0xb0 [btrfs]
[96049.833875] btrfs_extent_same_range+0x14e/0x550 [btrfs]
[96049.833885] ? rcu_read_lock_sched_held+0x3f/0x70
[96049.833890] ? __kmalloc_node+0x2b0/0x2f0
[96049.833899] ? btrfs_dedupe_file_range+0x19a/0x280 [btrfs]
[96049.833909] btrfs_dedupe_file_range+0x270/0x280 [btrfs]
[96049.833916] vfs_dedupe_file_range_one+0xd9/0xe0
[96049.833919] vfs_dedupe_file_range+0x131/0x1b0
[96049.833924] do_vfs_ioctl+0x272/0x6e0
[96049.833927] ? __fget+0x113/0x200
[96049.833931] ksys_ioctl+0x70/0x80
[96049.833933] __x64_sys_ioctl+0x16/0x20
[96049.833937] do_syscall_64+0x60/0x1b0
[96049.833939] entry_SYSCALL_64_after_hwframe+0x49/0xbe
[96049.833941] RIP: 0033:0x7f5c1478ddd7
[96049.833943] RSP: 002b:00007ffe15b196a8 EFLAGS: 00000202 ORIG_RAX: 0000000000000010
[96049.833945] RAX: ffffffffffffffda RBX: 0000000000000000 RCX: 00007f5c1478ddd7
[96049.833946] RDX: 00005625ece322d0 RSI: 00000000c0189436 RDI: 0000000000000004
[96049.833947] RBP: 0000000000000000 R08: 00007f5c14a46f48 R09: 0000000000000040
[96049.833948] R10: 0000000000000541 R11: 0000000000000202 R12: 0000000000000000
[96049.833949] R13: 0000000000000000 R14: 0000000000000004 R15: 00005625ece322d0
[96049.833954] irq event stamp: 6196
[96049.833956] hardirqs last enabled at (6195): [<ffffffff91b00663>] console_unlock+0x503/0x640
[96049.833958] hardirqs last disabled at (6196): [<ffffffff91a037dd>] trace_hardirqs_off_thunk+0x1a/0x1c
[96049.833959] softirqs last enabled at (6114): [<ffffffff92600370>] __do_softirq+0x370/0x421
[96049.833964] softirqs last disabled at (6095): [<ffffffff91a8dd4d>] irq_exit+0xcd/0xe0
[96049.833965] ---[ end trace db7b05f01b7fa10c ]---
[96049.935816] R13: 0000000000000000 R14: 00005562e5259240 R15: 00007ffff092b910
[96049.935822] irq event stamp: 6584
[96049.935823] hardirqs last enabled at (6583): [<ffffffff91b00663>] console_unlock+0x503/0x640
[96049.935825] hardirqs last disabled at (6584): [<ffffffff91a037dd>] trace_hardirqs_off_thunk+0x1a/0x1c
[96049.935827] softirqs last enabled at (6328): [<ffffffff92600370>] __do_softirq+0x370/0x421
[96049.935828] softirqs last disabled at (6313): [<ffffffff91a8dd4d>] irq_exit+0xcd/0xe0
[96049.935829] ---[ end trace db7b05f01b7fa123 ]---
[96049.935840] ------------[ cut here ]------------
[96049.936065] WARNING: CPU: 1 PID: 24463 at fs/btrfs/extent_io.c:436 insert_state+0x101/0x120 [btrfs]
[96049.936107] CPU: 1 PID: 24463 Comm: umount Tainted: G W 4.19.0-rc7-btrfs-next-39 #1
[96049.936108] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS rel-1.11.2-0-gf9626ccb91-prebuilt.qemu-project.org 04/01/2014
[96049.936117] RIP: 0010:insert_state+0x101/0x120 [btrfs]
[96049.936119] RSP: 0018:ffffafd2c3637bc0 EFLAGS: 00010282
[96049.936120] RAX: 0000000000000000 RBX: 000000000004dfff RCX: 0000000000000006
[96049.936121] RDX: 0000000000000007 RSI: ffff990445cf88e0 RDI: ffff99047b2968a0
[96049.936122] RBP: ffff990457851cd0 R08: 0000000000000001 R09: 0000000000000000
[96049.936123] R10: ffffafd2c3637b88 R11: 0000000000000000 R12: ffff9904574301e8
[96049.936124] R13: 000000000004e000 R14: ffffafd2c3637c50 R15: ffffafd2c3637c48
[96049.936125] FS: 00007fe4b87e72c0(0000) GS:ffff99047b280000(0000) knlGS:0000000000000000
[96049.936126] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
[96049.936128] CR2: 00005562e52618d8 CR3: 00000001151c8005 CR4: 00000000003606e0
[96049.936129] DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000
[96049.936131] DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400
[96049.936131] Call Trace:
[96049.936141] __set_extent_bit+0x46c/0x6a0 [btrfs]
[96049.936154] lock_extent_bits+0x6b/0x210 [btrfs]
[96049.936167] btrfs_evict_inode+0x1e1/0x5a0 [btrfs]
[96049.936172] evict+0xbf/0x1c0
[96049.936174] dispose_list+0x51/0x80
[96049.936176] evict_inodes+0x193/0x1c0
[96049.936180] generic_shutdown_super+0x3f/0x110
[96049.936182] kill_anon_super+0xe/0x30
[96049.936189] btrfs_kill_super+0x13/0x100 [btrfs]
[96049.936191] deactivate_locked_super+0x3a/0x70
[96049.936193] cleanup_mnt+0x3b/0x80
[96049.936195] task_work_run+0x93/0xc0
[96049.936198] exit_to_usermode_loop+0xfa/0x100
[96049.936201] do_syscall_64+0x17f/0x1b0
[96049.936202] entry_SYSCALL_64_after_hwframe+0x49/0xbe
[96049.936204] RIP: 0033:0x7fe4b80cfb37
[96049.936206] RSP: 002b:00007ffff092b688 EFLAGS: 00000246 ORIG_RAX: 00000000000000a6
[96049.936207] RAX: 0000000000000000 RBX: 00005562e5259060 RCX: 00007fe4b80cfb37
[96049.936208] RDX: 0000000000000001 RSI: 0000000000000000 RDI: 00005562e525faa0
[96049.936209] RBP: 00005562e525faa0 R08: 00005562e525f770 R09: 0000000000000015
[96049.936210] R10: 00000000000006b4 R11: 0000000000000246 R12: 00007fe4b85d1e64
[96049.936211] R13: 0000000000000000 R14: 00005562e5259240 R15: 00007ffff092b910
[96049.936211] R13: 0000000000000000 R14: 00005562e5259240 R15: 00007ffff092b910
[96049.936216] irq event stamp: 6616
[96049.936219] hardirqs last enabled at (6615): [<ffffffff91b00663>] console_unlock+0x503/0x640
[96049.936219] hardirqs last disabled at (6616): [<ffffffff91a037dd>] trace_hardirqs_off_thunk+0x1a/0x1c
[96049.936222] softirqs last enabled at (6328): [<ffffffff92600370>] __do_softirq+0x370/0x421
[96049.936222] softirqs last disabled at (6313): [<ffffffff91a8dd4d>] irq_exit+0xcd/0xe0
[96049.936223] ---[ end trace db7b05f01b7fa124 ]---
The second stack trace, from inode eviction, is repeated forever due to
the infinite loop during eviction.
This is the same type of problem fixed way back in 2015 by commit
113e828386 ("Btrfs: fix inode eviction infinite loop after extent_same
ioctl") and commit ccccf3d672 ("Btrfs: fix inode eviction infinite loop
after cloning into it").
So fix this by returning immediately if the deduplication range length
gets rounded down to 0 bytes, as there is nothing that needs to be done in
such case.
Example reproducer:
$ mkfs.btrfs -f /dev/sdb
$ mount /dev/sdb /mnt
$ xfs_io -f -c "pwrite -S 0xe6 0 100" /mnt/foo
$ xfs_io -f -c "pwrite -S 0xe6 0 1M" /mnt/bar
# Unmount the filesystem and mount it again so that we start without any
# extent state records when we ask for the deduplication.
$ umount /mnt
$ mount /dev/sdb /mnt
$ xfs_io -c "dedupe /mnt/foo 0 500K 100" /mnt/bar
# This unmount triggers the infinite loop.
$ umount /mnt
A test case for fstests will follow soon.
Fixes: de02b9f6bb ("Btrfs: fix data corruption when deduplicating between different files")
CC: <stable@vger.kernel.org> # 4.19+
Reviewed-by: Nikolay Borisov <nborisov@suse.com>
Signed-off-by: Filipe Manana <fdmanana@suse.com>
Signed-off-by: David Sterba <dsterba@suse.com>
2018-11-06 16:42:37 +01:00
arch
libnvdimm/dax 4.19-rc8
2018-10-14 08:34:31 +02:00
block
blk-wbt: wake up all when we scale up, not down
2018-10-11 13:31:28 -06:00
certs
export.h: remove VMLINUX_SYMBOL() and VMLINUX_SYMBOL_STR()
2018-08-22 23:21:44 +09:00
crypto
DMAengine updates for v4.19-rc1
2018-08-18 15:55:59 -07:00
Documentation
Char/Misc fixes for 4.19-rc7
2018-10-07 08:15:57 +02:00
drivers
Merge branch 'i2c/for-current' of git://git.kernel.org/pub/scm/linux/kernel/git/wsa/linux
2018-10-14 08:33:35 +02:00
firmware
kbuild: remove all dummy assignments to obj-
2017-11-18 11:46:06 +09:00
fs
Btrfs: fix infinite loop on inode eviction after deduplication of eof block
2018-11-06 16:42:37 +01:00
include
btrfs: qgroup: Introduce trace event to analyse the number of dirty extents accounted
2018-10-15 17:23:36 +02:00
init
Kbuild updates for v4.19 (2nd)
2018-08-25 13:40:38 -07:00
ipc
ipc/shm.c: use ERR_CAST() for shm_lock() error return
2018-10-05 16:32:04 -07:00
kernel
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/dtor/input
2018-10-12 12:35:02 +02:00
lib
* Fix a stack overflow in lib/bch.c
2018-10-12 12:54:26 +02:00
LICENSES
LICENSES: Add Linux-OpenIB license text
2018-04-27 16:41:53 -06:00
mm
mm/thp: fix call to mmu_notifier in set_pmd_migration_entry() v2
2018-10-13 09:31:02 +02:00
net
Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net
2018-10-12 09:01:59 +02:00
samples
samples: disable CONFIG_SAMPLES for UML
2018-10-11 02:15:46 +09:00
scripts
Kbuild fixes for v4.19 (2nd)
2018-10-11 19:23:07 +02:00
security
Revert "uapi/linux/keyctl.h: don't use C++ reserved keyword as a struct member name"
2018-09-25 13:28:58 +02:00
sound
ALSA: hda/realtek - Cannot adjust speaker's volume on Dell XPS 27 7760
2018-10-04 07:50:48 +02:00
tools
Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net
2018-10-12 09:01:59 +02:00
usr
initramfs: move gen_initramfs_list.sh from scripts/ to usr/
2018-08-22 23:21:44 +09:00
virt
KVM: Remove obsolete kvm_unmap_hva notifier backend
2018-09-07 15:06:02 +02:00
.clang-format
clang-format: Set IndentWrappedFunctionNames false
2018-08-01 18:38:51 +02:00
.cocciconfig
.get_maintainer.ignore
.gitattributes
.gitattributes: set git diff driver for C source code files
2016-10-07 18:46:30 -07:00
.gitignore
Kbuild updates for v4.17 (2nd)
2018-04-15 17:21:30 -07:00
.mailmap
libnvdimm-for-4.19_misc
2018-08-25 18:13:10 -07:00
COPYING
COPYING: use the new text with points to the license files
2018-03-23 12:41:45 -06:00
CREDITS
9p: remove Ron Minnich from MAINTAINERS
2018-08-17 16:20:26 -07:00
Kbuild
Kbuild updates for v4.15
2017-11-17 17:45:29 -08:00
Kconfig
kconfig: move the "Executable file formats" menu to fs/Kconfig.binfmt
2018-08-02 08:06:55 +09:00
MAINTAINERS
MAINTAINERS: update my email address for btrfs
2018-10-19 12:20:02 +02:00
Makefile
Linux 4.19-rc8
2018-10-15 07:20:24 +02:00
README
Docs: Added a pointer to the formatted docs to README
2018-03-21 09:02:53 -06:00