From d2c9b95115975f77f582f8739d6fd57a401935d1 Mon Sep 17 00:00:00 2001 From: Sasha Levin Date: Sun, 16 May 2021 18:37:48 -0400 Subject: [PATCH] Drop btrfs-fix-deadlock-when-cloning-inline-extents-and-using-qgroups.patch from 5.10 Signed-off-by: Sasha Levin --- ...ing-inline-extents-and-using-qgroups.patch | 229 ------------------ 1 file changed, 229 deletions(-) delete mode 100644 queue-5.10/btrfs-fix-deadlock-when-cloning-inline-extents-and-using-qgroups.patch diff --git a/queue-5.10/btrfs-fix-deadlock-when-cloning-inline-extents-and-using-qgroups.patch b/queue-5.10/btrfs-fix-deadlock-when-cloning-inline-extents-and-using-qgroups.patch deleted file mode 100644 index 048f759ecf5..00000000000 --- a/queue-5.10/btrfs-fix-deadlock-when-cloning-inline-extents-and-using-qgroups.patch +++ /dev/null @@ -1,229 +0,0 @@ -From f9baa501b4fd6962257853d46ddffbc21f27e344 Mon Sep 17 00:00:00 2001 -From: Filipe Manana -Date: Thu, 22 Apr 2021 12:08:05 +0100 -Subject: btrfs: fix deadlock when cloning inline extents and using qgroups - -From: Filipe Manana - -commit f9baa501b4fd6962257853d46ddffbc21f27e344 upstream. - -There are a few exceptional cases where cloning an inline extent needs to -copy the inline extent data into a page of the destination inode. - -When this happens, we end up starting a transaction while having a dirty -page for the destination inode and while having the range locked in the -destination's inode iotree too. Because when reserving metadata space -for a transaction we may need to flush existing delalloc in case there is -not enough free space, we have a mechanism in place to prevent a deadlock, -which was introduced in commit 3d45f221ce627d ("btrfs: fix deadlock when -cloning inline extent and low on free metadata space"). - -However when using qgroups, a transaction also reserves metadata qgroup -space, which can also result in flushing delalloc in case there is not -enough available space at the moment. When this happens we deadlock, since -flushing delalloc requires locking the file range in the inode's iotree -and the range was already locked at the very beginning of the clone -operation, before attempting to start the transaction. - -When this issue happens, stack traces like the following are reported: - - [72747.556262] task:kworker/u81:9 state:D stack: 0 pid: 225 ppid: 2 flags:0x00004000 - [72747.556268] Workqueue: writeback wb_workfn (flush-btrfs-1142) - [72747.556271] Call Trace: - [72747.556273] __schedule+0x296/0x760 - [72747.556277] schedule+0x3c/0xa0 - [72747.556279] io_schedule+0x12/0x40 - [72747.556284] __lock_page+0x13c/0x280 - [72747.556287] ? generic_file_readonly_mmap+0x70/0x70 - [72747.556325] extent_write_cache_pages+0x22a/0x440 [btrfs] - [72747.556331] ? __set_page_dirty_nobuffers+0xe7/0x160 - [72747.556358] ? set_extent_buffer_dirty+0x5e/0x80 [btrfs] - [72747.556362] ? update_group_capacity+0x25/0x210 - [72747.556366] ? cpumask_next_and+0x1a/0x20 - [72747.556391] extent_writepages+0x44/0xa0 [btrfs] - [72747.556394] do_writepages+0x41/0xd0 - [72747.556398] __writeback_single_inode+0x39/0x2a0 - [72747.556403] writeback_sb_inodes+0x1ea/0x440 - [72747.556407] __writeback_inodes_wb+0x5f/0xc0 - [72747.556410] wb_writeback+0x235/0x2b0 - [72747.556414] ? get_nr_inodes+0x35/0x50 - [72747.556417] wb_workfn+0x354/0x490 - [72747.556420] ? newidle_balance+0x2c5/0x3e0 - [72747.556424] process_one_work+0x1aa/0x340 - [72747.556426] worker_thread+0x30/0x390 - [72747.556429] ? create_worker+0x1a0/0x1a0 - [72747.556432] kthread+0x116/0x130 - [72747.556435] ? kthread_park+0x80/0x80 - [72747.556438] ret_from_fork+0x1f/0x30 - - [72747.566958] Workqueue: btrfs-flush_delalloc btrfs_work_helper [btrfs] - [72747.566961] Call Trace: - [72747.566964] __schedule+0x296/0x760 - [72747.566968] ? finish_wait+0x80/0x80 - [72747.566970] schedule+0x3c/0xa0 - [72747.566995] wait_extent_bit.constprop.68+0x13b/0x1c0 [btrfs] - [72747.566999] ? finish_wait+0x80/0x80 - [72747.567024] lock_extent_bits+0x37/0x90 [btrfs] - [72747.567047] btrfs_invalidatepage+0x299/0x2c0 [btrfs] - [72747.567051] ? find_get_pages_range_tag+0x2cd/0x380 - [72747.567076] __extent_writepage+0x203/0x320 [btrfs] - [72747.567102] extent_write_cache_pages+0x2bb/0x440 [btrfs] - [72747.567106] ? update_load_avg+0x7e/0x5f0 - [72747.567109] ? enqueue_entity+0xf4/0x6f0 - [72747.567134] extent_writepages+0x44/0xa0 [btrfs] - [72747.567137] ? enqueue_task_fair+0x93/0x6f0 - [72747.567140] do_writepages+0x41/0xd0 - [72747.567144] __filemap_fdatawrite_range+0xc7/0x100 - [72747.567167] btrfs_run_delalloc_work+0x17/0x40 [btrfs] - [72747.567195] btrfs_work_helper+0xc2/0x300 [btrfs] - [72747.567200] process_one_work+0x1aa/0x340 - [72747.567202] worker_thread+0x30/0x390 - [72747.567205] ? create_worker+0x1a0/0x1a0 - [72747.567208] kthread+0x116/0x130 - [72747.567211] ? kthread_park+0x80/0x80 - [72747.567214] ret_from_fork+0x1f/0x30 - - [72747.569686] task:fsstress state:D stack: 0 pid:841421 ppid:841417 flags:0x00000000 - [72747.569689] Call Trace: - [72747.569691] __schedule+0x296/0x760 - [72747.569694] schedule+0x3c/0xa0 - [72747.569721] try_flush_qgroup+0x95/0x140 [btrfs] - [72747.569725] ? finish_wait+0x80/0x80 - [72747.569753] btrfs_qgroup_reserve_data+0x34/0x50 [btrfs] - [72747.569781] btrfs_check_data_free_space+0x5f/0xa0 [btrfs] - [72747.569804] btrfs_buffered_write+0x1f7/0x7f0 [btrfs] - [72747.569810] ? path_lookupat.isra.48+0x97/0x140 - [72747.569833] btrfs_file_write_iter+0x81/0x410 [btrfs] - [72747.569836] ? __kmalloc+0x16a/0x2c0 - [72747.569839] do_iter_readv_writev+0x160/0x1c0 - [72747.569843] do_iter_write+0x80/0x1b0 - [72747.569847] vfs_writev+0x84/0x140 - [72747.569869] ? btrfs_file_llseek+0x38/0x270 [btrfs] - [72747.569873] do_writev+0x65/0x100 - [72747.569876] do_syscall_64+0x33/0x40 - [72747.569879] entry_SYSCALL_64_after_hwframe+0x44/0xa9 - - [72747.569899] task:fsstress state:D stack: 0 pid:841424 ppid:841417 flags:0x00004000 - [72747.569903] Call Trace: - [72747.569906] __schedule+0x296/0x760 - [72747.569909] schedule+0x3c/0xa0 - [72747.569936] try_flush_qgroup+0x95/0x140 [btrfs] - [72747.569940] ? finish_wait+0x80/0x80 - [72747.569967] __btrfs_qgroup_reserve_meta+0x36/0x50 [btrfs] - [72747.569989] start_transaction+0x279/0x580 [btrfs] - [72747.570014] clone_copy_inline_extent+0x332/0x490 [btrfs] - [72747.570041] btrfs_clone+0x5b7/0x7a0 [btrfs] - [72747.570068] ? lock_extent_bits+0x64/0x90 [btrfs] - [72747.570095] btrfs_clone_files+0xfc/0x150 [btrfs] - [72747.570122] btrfs_remap_file_range+0x3d8/0x4a0 [btrfs] - [72747.570126] do_clone_file_range+0xed/0x200 - [72747.570131] vfs_clone_file_range+0x37/0x110 - [72747.570134] ioctl_file_clone+0x7d/0xb0 - [72747.570137] do_vfs_ioctl+0x138/0x630 - [72747.570140] __x64_sys_ioctl+0x62/0xc0 - [72747.570143] do_syscall_64+0x33/0x40 - [72747.570146] entry_SYSCALL_64_after_hwframe+0x44/0xa9 - -So fix this by skipping the flush of delalloc for an inode that is -flagged with BTRFS_INODE_NO_DELALLOC_FLUSH, meaning it is currently under -such a special case of cloning an inline extent, when flushing delalloc -during qgroup metadata reservation. - -The special cases for cloning inline extents were added in kernel 5.7 by -by commit 05a5a7621ce66c ("Btrfs: implement full reflink support for -inline extents"), while having qgroup metadata space reservation flushing -delalloc when low on space was added in kernel 5.9 by commit -c53e9653605dbf ("btrfs: qgroup: try to flush qgroup space when we get --EDQUOT"). So use a "Fixes:" tag for the later commit to ease stable -kernel backports. - -Reported-by: Wang Yugui -Link: https://lore.kernel.org/linux-btrfs/20210421083137.31E3.409509F4@e16-tech.com/ -Fixes: c53e9653605dbf ("btrfs: qgroup: try to flush qgroup space when we get -EDQUOT") -CC: stable@vger.kernel.org # 5.9+ -Reviewed-by: Qu Wenruo -Signed-off-by: Filipe Manana -Reviewed-by: David Sterba -Signed-off-by: David Sterba -Signed-off-by: Greg Kroah-Hartman ---- - fs/btrfs/ctree.h | 2 +- - fs/btrfs/inode.c | 4 ++-- - fs/btrfs/ioctl.c | 2 +- - fs/btrfs/qgroup.c | 2 +- - fs/btrfs/send.c | 4 ++-- - 5 files changed, 7 insertions(+), 7 deletions(-) - ---- a/fs/btrfs/ctree.h -+++ b/fs/btrfs/ctree.h -@@ -3008,7 +3008,7 @@ int btrfs_truncate_inode_items(struct bt - struct inode *inode, u64 new_size, - u32 min_type); - --int btrfs_start_delalloc_snapshot(struct btrfs_root *root); -+int btrfs_start_delalloc_snapshot(struct btrfs_root *root, bool in_reclaim_context); - int btrfs_start_delalloc_roots(struct btrfs_fs_info *fs_info, u64 nr, - bool in_reclaim_context); - int btrfs_set_extent_delalloc(struct btrfs_inode *inode, u64 start, u64 end, ---- a/fs/btrfs/inode.c -+++ b/fs/btrfs/inode.c -@@ -9474,7 +9474,7 @@ out: - return ret; - } - --int btrfs_start_delalloc_snapshot(struct btrfs_root *root) -+int btrfs_start_delalloc_snapshot(struct btrfs_root *root, bool in_reclaim_context) - { - struct writeback_control wbc = { - .nr_to_write = LONG_MAX, -@@ -9487,7 +9487,7 @@ int btrfs_start_delalloc_snapshot(struct - if (test_bit(BTRFS_FS_STATE_ERROR, &fs_info->fs_state)) - return -EROFS; - -- return start_delalloc_inodes(root, &wbc, true, false); -+ return start_delalloc_inodes(root, &wbc, true, in_reclaim_context); - } - - int btrfs_start_delalloc_roots(struct btrfs_fs_info *fs_info, u64 nr, ---- a/fs/btrfs/ioctl.c -+++ b/fs/btrfs/ioctl.c -@@ -1030,7 +1030,7 @@ static noinline int btrfs_mksnapshot(con - */ - btrfs_drew_read_lock(&root->snapshot_lock); - -- ret = btrfs_start_delalloc_snapshot(root); -+ ret = btrfs_start_delalloc_snapshot(root, false); - if (ret) - goto out; - ---- a/fs/btrfs/qgroup.c -+++ b/fs/btrfs/qgroup.c -@@ -3613,7 +3613,7 @@ static int try_flush_qgroup(struct btrfs - return 0; - } - -- ret = btrfs_start_delalloc_snapshot(root); -+ ret = btrfs_start_delalloc_snapshot(root, true); - if (ret < 0) - goto out; - btrfs_wait_ordered_extents(root, U64_MAX, 0, (u64)-1); ---- a/fs/btrfs/send.c -+++ b/fs/btrfs/send.c -@@ -7159,7 +7159,7 @@ static int flush_delalloc_roots(struct s - int i; - - if (root) { -- ret = btrfs_start_delalloc_snapshot(root); -+ ret = btrfs_start_delalloc_snapshot(root, false); - if (ret) - return ret; - btrfs_wait_ordered_extents(root, U64_MAX, 0, U64_MAX); -@@ -7167,7 +7167,7 @@ static int flush_delalloc_roots(struct s - - for (i = 0; i < sctx->clone_roots_cnt; i++) { - root = sctx->clone_roots[i].root; -- ret = btrfs_start_delalloc_snapshot(root); -+ ret = btrfs_start_delalloc_snapshot(root, false); - if (ret) - return ret; - btrfs_wait_ordered_extents(root, U64_MAX, 0, U64_MAX); -- 2.47.3