From: Greg Kroah-Hartman Date: Sun, 23 Jan 2022 17:19:01 +0000 (+0100) Subject: 5.4-stable patches X-Git-Tag: v4.4.300~105 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=2ee3a5a884f789308e3b7a8536a554f3adaaaab3;p=thirdparty%2Fkernel%2Fstable-queue.git 5.4-stable patches added patches: btrfs-check-the-root-node-for-uptodate-before-returning-it.patch btrfs-fix-deadlock-between-quota-enable-and-other-quota-operations.patch btrfs-respect-the-max-size-in-the-header-when-activating-swap-file.patch ext4-make-sure-quota-gets-properly-shutdown-on-error.patch ext4-make-sure-to-reset-inode-lockdep-class-when-quota-enabling-fails.patch --- diff --git a/queue-5.4/btrfs-check-the-root-node-for-uptodate-before-returning-it.patch b/queue-5.4/btrfs-check-the-root-node-for-uptodate-before-returning-it.patch new file mode 100644 index 00000000000..3db5b9ce586 --- /dev/null +++ b/queue-5.4/btrfs-check-the-root-node-for-uptodate-before-returning-it.patch @@ -0,0 +1,68 @@ +From 120de408e4b97504a2d9b5ca534b383de2c73d49 Mon Sep 17 00:00:00 2001 +From: Josef Bacik +Date: Wed, 24 Nov 2021 14:14:24 -0500 +Subject: btrfs: check the root node for uptodate before returning it + +From: Josef Bacik + +commit 120de408e4b97504a2d9b5ca534b383de2c73d49 upstream. + +Now that we clear the extent buffer uptodate if we fail to write it out +we need to check to see if our root node is uptodate before we search +down it. Otherwise we could return stale data (or potentially corrupt +data that was caught by the write verification step) and think that the +path is OK to search down. + +CC: stable@vger.kernel.org # 5.4+ +Reviewed-by: Nikolay Borisov +Signed-off-by: Josef Bacik +Signed-off-by: David Sterba +Signed-off-by: Greg Kroah-Hartman +--- + fs/btrfs/ctree.c | 19 +++++++++++++++---- + 1 file changed, 15 insertions(+), 4 deletions(-) + +--- a/fs/btrfs/ctree.c ++++ b/fs/btrfs/ctree.c +@@ -2658,12 +2658,9 @@ static struct extent_buffer *btrfs_searc + { + struct btrfs_fs_info *fs_info = root->fs_info; + struct extent_buffer *b; +- int root_lock; ++ int root_lock = 0; + int level = 0; + +- /* We try very hard to do read locks on the root */ +- root_lock = BTRFS_READ_LOCK; +- + if (p->search_commit_root) { + /* + * The commit roots are read only so we always do read locks, +@@ -2701,6 +2698,9 @@ static struct extent_buffer *btrfs_searc + goto out; + } + ++ /* We try very hard to do read locks on the root */ ++ root_lock = BTRFS_READ_LOCK; ++ + /* + * If the level is set to maximum, we can skip trying to get the read + * lock. +@@ -2727,6 +2727,17 @@ static struct extent_buffer *btrfs_searc + level = btrfs_header_level(b); + + out: ++ /* ++ * The root may have failed to write out at some point, and thus is no ++ * longer valid, return an error in this case. ++ */ ++ if (!extent_buffer_uptodate(b)) { ++ if (root_lock) ++ btrfs_tree_unlock_rw(b, root_lock); ++ free_extent_buffer(b); ++ return ERR_PTR(-EIO); ++ } ++ + p->nodes[level] = b; + if (!p->skip_locking) + p->locks[level] = root_lock; diff --git a/queue-5.4/btrfs-fix-deadlock-between-quota-enable-and-other-quota-operations.patch b/queue-5.4/btrfs-fix-deadlock-between-quota-enable-and-other-quota-operations.patch new file mode 100644 index 00000000000..49d37b9d166 --- /dev/null +++ b/queue-5.4/btrfs-fix-deadlock-between-quota-enable-and-other-quota-operations.patch @@ -0,0 +1,128 @@ +From 232796df8c1437c41d308d161007f0715bac0a54 Mon Sep 17 00:00:00 2001 +From: Filipe Manana +Date: Wed, 27 Oct 2021 18:30:25 +0100 +Subject: btrfs: fix deadlock between quota enable and other quota operations + +From: Filipe Manana + +commit 232796df8c1437c41d308d161007f0715bac0a54 upstream. + +When enabling quotas, we attempt to commit a transaction while holding the +mutex fs_info->qgroup_ioctl_lock. This can result on a deadlock with other +quota operations such as: + +- qgroup creation and deletion, ioctl BTRFS_IOC_QGROUP_CREATE; + +- adding and removing qgroup relations, ioctl BTRFS_IOC_QGROUP_ASSIGN. + +This is because these operations join a transaction and after that they +attempt to lock the mutex fs_info->qgroup_ioctl_lock. Acquiring that mutex +after joining or starting a transaction is a pattern followed everywhere +in qgroups, so the quota enablement operation is the one at fault here, +and should not commit a transaction while holding that mutex. + +Fix this by making the transaction commit while not holding the mutex. +We are safe from two concurrent tasks trying to enable quotas because +we are serialized by the rw semaphore fs_info->subvol_sem at +btrfs_ioctl_quota_ctl(), which is the only call site for enabling +quotas. + +When this deadlock happens, it produces a trace like the following: + + INFO: task syz-executor:25604 blocked for more than 143 seconds. + Not tainted 5.15.0-rc6 #4 + "echo 0 > /proc/sys/kernel/hung_task_timeout_secs" disables this message. + task:syz-executor state:D stack:24800 pid:25604 ppid: 24873 flags:0x00004004 + Call Trace: + context_switch kernel/sched/core.c:4940 [inline] + __schedule+0xcd9/0x2530 kernel/sched/core.c:6287 + schedule+0xd3/0x270 kernel/sched/core.c:6366 + btrfs_commit_transaction+0x994/0x2e90 fs/btrfs/transaction.c:2201 + btrfs_quota_enable+0x95c/0x1790 fs/btrfs/qgroup.c:1120 + btrfs_ioctl_quota_ctl fs/btrfs/ioctl.c:4229 [inline] + btrfs_ioctl+0x637e/0x7b70 fs/btrfs/ioctl.c:5010 + vfs_ioctl fs/ioctl.c:51 [inline] + __do_sys_ioctl fs/ioctl.c:874 [inline] + __se_sys_ioctl fs/ioctl.c:860 [inline] + __x64_sys_ioctl+0x193/0x200 fs/ioctl.c:860 + do_syscall_x64 arch/x86/entry/common.c:50 [inline] + do_syscall_64+0x35/0xb0 arch/x86/entry/common.c:80 + entry_SYSCALL_64_after_hwframe+0x44/0xae + RIP: 0033:0x7f86920b2c4d + RSP: 002b:00007f868f61ac58 EFLAGS: 00000246 ORIG_RAX: 0000000000000010 + RAX: ffffffffffffffda RBX: 00007f86921d90a0 RCX: 00007f86920b2c4d + RDX: 0000000020005e40 RSI: 00000000c0109428 RDI: 0000000000000008 + RBP: 00007f869212bd80 R08: 0000000000000000 R09: 0000000000000000 + R10: 0000000000000000 R11: 0000000000000246 R12: 00007f86921d90a0 + R13: 00007fff6d233e4f R14: 00007fff6d233ff0 R15: 00007f868f61adc0 + INFO: task syz-executor:25628 blocked for more than 143 seconds. + Not tainted 5.15.0-rc6 #4 + "echo 0 > /proc/sys/kernel/hung_task_timeout_secs" disables this message. + task:syz-executor state:D stack:29080 pid:25628 ppid: 24873 flags:0x00004004 + Call Trace: + context_switch kernel/sched/core.c:4940 [inline] + __schedule+0xcd9/0x2530 kernel/sched/core.c:6287 + schedule+0xd3/0x270 kernel/sched/core.c:6366 + schedule_preempt_disabled+0xf/0x20 kernel/sched/core.c:6425 + __mutex_lock_common kernel/locking/mutex.c:669 [inline] + __mutex_lock+0xc96/0x1680 kernel/locking/mutex.c:729 + btrfs_remove_qgroup+0xb7/0x7d0 fs/btrfs/qgroup.c:1548 + btrfs_ioctl_qgroup_create fs/btrfs/ioctl.c:4333 [inline] + btrfs_ioctl+0x683c/0x7b70 fs/btrfs/ioctl.c:5014 + vfs_ioctl fs/ioctl.c:51 [inline] + __do_sys_ioctl fs/ioctl.c:874 [inline] + __se_sys_ioctl fs/ioctl.c:860 [inline] + __x64_sys_ioctl+0x193/0x200 fs/ioctl.c:860 + do_syscall_x64 arch/x86/entry/common.c:50 [inline] + do_syscall_64+0x35/0xb0 arch/x86/entry/common.c:80 + entry_SYSCALL_64_after_hwframe+0x44/0xae + +Reported-by: Hao Sun +Link: https://lore.kernel.org/linux-btrfs/CACkBjsZQF19bQ1C6=yetF3BvL10OSORpFUcWXTP6HErshDB4dQ@mail.gmail.com/ +Fixes: 340f1aa27f36 ("btrfs: qgroups: Move transaction management inside btrfs_quota_enable/disable") +CC: stable@vger.kernel.org # 4.19 +Reviewed-by: Qu Wenruo +Signed-off-by: Filipe Manana +Signed-off-by: David Sterba +Signed-off-by: Greg Kroah-Hartman +--- + fs/btrfs/qgroup.c | 19 +++++++++++++++++++ + 1 file changed, 19 insertions(+) + +--- a/fs/btrfs/qgroup.c ++++ b/fs/btrfs/qgroup.c +@@ -890,6 +890,14 @@ int btrfs_quota_enable(struct btrfs_fs_i + int ret = 0; + int slot; + ++ /* ++ * We need to have subvol_sem write locked, to prevent races between ++ * concurrent tasks trying to enable quotas, because we will unlock ++ * and relock qgroup_ioctl_lock before setting fs_info->quota_root ++ * and before setting BTRFS_FS_QUOTA_ENABLED. ++ */ ++ lockdep_assert_held_write(&fs_info->subvol_sem); ++ + mutex_lock(&fs_info->qgroup_ioctl_lock); + if (fs_info->quota_root) + goto out; +@@ -1035,8 +1043,19 @@ out_add_root: + goto out_free_path; + } + ++ mutex_unlock(&fs_info->qgroup_ioctl_lock); ++ /* ++ * Commit the transaction while not holding qgroup_ioctl_lock, to avoid ++ * a deadlock with tasks concurrently doing other qgroup operations, such ++ * adding/removing qgroups or adding/deleting qgroup relations for example, ++ * because all qgroup operations first start or join a transaction and then ++ * lock the qgroup_ioctl_lock mutex. ++ * We are safe from a concurrent task trying to enable quotas, by calling ++ * this function, since we are serialized by fs_info->subvol_sem. ++ */ + ret = btrfs_commit_transaction(trans); + trans = NULL; ++ mutex_lock(&fs_info->qgroup_ioctl_lock); + if (ret) + goto out_free_path; + diff --git a/queue-5.4/btrfs-respect-the-max-size-in-the-header-when-activating-swap-file.patch b/queue-5.4/btrfs-respect-the-max-size-in-the-header-when-activating-swap-file.patch new file mode 100644 index 00000000000..fdd12fb3504 --- /dev/null +++ b/queue-5.4/btrfs-respect-the-max-size-in-the-header-when-activating-swap-file.patch @@ -0,0 +1,65 @@ +From c2f822635df873c510bda6fb7fd1b10b7c31be2d Mon Sep 17 00:00:00 2001 +From: Filipe Manana +Date: Thu, 16 Dec 2021 15:00:32 +0000 +Subject: btrfs: respect the max size in the header when activating swap file + +From: Filipe Manana + +commit c2f822635df873c510bda6fb7fd1b10b7c31be2d upstream. + +If we extended the size of a swapfile after its header was created (by the +mkswap utility) and then try to activate it, we will map the entire file +when activating the swap file, instead of limiting to the max size defined +in the swap file's header. + +Currently test case generic/643 from fstests fails because we do not +respect that size limit defined in the swap file's header. + +So fix this by not mapping file ranges beyond the max size defined in the +swap header. + +This is the same type of bug that iomap used to have, and was fixed in +commit 36ca7943ac18ae ("mm/swap: consider max pages in +iomap_swapfile_add_extent"). + +Fixes: ed46ff3d423780 ("Btrfs: support swap files") +CC: stable@vger.kernel.org # 5.4+ +Reviewed-and-tested-by: Josef Bacik +Reviewed-by: David Sterba +Signed-off-by: David Sterba +Signed-off-by: Greg Kroah-Hartman +--- + fs/btrfs/inode.c | 11 +++++++++++ + 1 file changed, 11 insertions(+) + +--- a/fs/btrfs/inode.c ++++ b/fs/btrfs/inode.c +@@ -10808,9 +10808,19 @@ static int btrfs_add_swap_extent(struct + struct btrfs_swap_info *bsi) + { + unsigned long nr_pages; ++ unsigned long max_pages; + u64 first_ppage, first_ppage_reported, next_ppage; + int ret; + ++ /* ++ * Our swapfile may have had its size extended after the swap header was ++ * written. In that case activating the swapfile should not go beyond ++ * the max size set in the swap header. ++ */ ++ if (bsi->nr_pages >= sis->max) ++ return 0; ++ ++ max_pages = sis->max - bsi->nr_pages; + first_ppage = ALIGN(bsi->block_start, PAGE_SIZE) >> PAGE_SHIFT; + next_ppage = ALIGN_DOWN(bsi->block_start + bsi->block_len, + PAGE_SIZE) >> PAGE_SHIFT; +@@ -10818,6 +10828,7 @@ static int btrfs_add_swap_extent(struct + if (first_ppage >= next_ppage) + return 0; + nr_pages = next_ppage - first_ppage; ++ nr_pages = min(nr_pages, max_pages); + + first_ppage_reported = first_ppage; + if (bsi->start == 0) diff --git a/queue-5.4/ext4-make-sure-quota-gets-properly-shutdown-on-error.patch b/queue-5.4/ext4-make-sure-quota-gets-properly-shutdown-on-error.patch new file mode 100644 index 00000000000..e5c20a20454 --- /dev/null +++ b/queue-5.4/ext4-make-sure-quota-gets-properly-shutdown-on-error.patch @@ -0,0 +1,51 @@ +From 15fc69bbbbbc8c72e5f6cc4e1be0f51283c5448e Mon Sep 17 00:00:00 2001 +From: Jan Kara +Date: Thu, 7 Oct 2021 17:53:35 +0200 +Subject: ext4: make sure quota gets properly shutdown on error + +From: Jan Kara + +commit 15fc69bbbbbc8c72e5f6cc4e1be0f51283c5448e upstream. + +When we hit an error when enabling quotas and setting inode flags, we do +not properly shutdown quota subsystem despite returning error from +Q_QUOTAON quotactl. This can lead to some odd situations like kernel +using quota file while it is still writeable for userspace. Make sure we +properly cleanup the quota subsystem in case of error. + +Signed-off-by: Jan Kara +Cc: stable@kernel.org +Link: https://lore.kernel.org/r/20211007155336.12493-2-jack@suse.cz +Signed-off-by: Theodore Ts'o +Signed-off-by: Greg Kroah-Hartman +--- + fs/ext4/super.c | 10 ++++++---- + 1 file changed, 6 insertions(+), 4 deletions(-) + +--- a/fs/ext4/super.c ++++ b/fs/ext4/super.c +@@ -5912,10 +5912,7 @@ static int ext4_quota_on(struct super_bl + + lockdep_set_quota_inode(path->dentry->d_inode, I_DATA_SEM_QUOTA); + err = dquot_quota_on(sb, type, format_id, path); +- if (err) { +- lockdep_set_quota_inode(path->dentry->d_inode, +- I_DATA_SEM_NORMAL); +- } else { ++ if (!err) { + struct inode *inode = d_inode(path->dentry); + handle_t *handle; + +@@ -5935,7 +5932,12 @@ static int ext4_quota_on(struct super_bl + ext4_journal_stop(handle); + unlock_inode: + inode_unlock(inode); ++ if (err) ++ dquot_quota_off(sb, type); + } ++ if (err) ++ lockdep_set_quota_inode(path->dentry->d_inode, ++ I_DATA_SEM_NORMAL); + return err; + } + diff --git a/queue-5.4/ext4-make-sure-to-reset-inode-lockdep-class-when-quota-enabling-fails.patch b/queue-5.4/ext4-make-sure-to-reset-inode-lockdep-class-when-quota-enabling-fails.patch new file mode 100644 index 00000000000..f1f4a9ba8ed --- /dev/null +++ b/queue-5.4/ext4-make-sure-to-reset-inode-lockdep-class-when-quota-enabling-fails.patch @@ -0,0 +1,49 @@ +From 4013d47a5307fdb5c13370b5392498b00fedd274 Mon Sep 17 00:00:00 2001 +From: Jan Kara +Date: Thu, 7 Oct 2021 17:53:36 +0200 +Subject: ext4: make sure to reset inode lockdep class when quota enabling fails + +From: Jan Kara + +commit 4013d47a5307fdb5c13370b5392498b00fedd274 upstream. + +When we succeed in enabling some quota type but fail to enable another +one with quota feature, we correctly disable all enabled quota types. +However we forget to reset i_data_sem lockdep class. When the inode gets +freed and reused, it will inherit this lockdep class (i_data_sem is +initialized only when a slab is created) and thus eventually lockdep +barfs about possible deadlocks. + +Reported-and-tested-by: syzbot+3b6f9218b1301ddda3e2@syzkaller.appspotmail.com +Signed-off-by: Jan Kara +Cc: stable@kernel.org +Link: https://lore.kernel.org/r/20211007155336.12493-3-jack@suse.cz +Signed-off-by: Theodore Ts'o +Signed-off-by: Greg Kroah-Hartman +--- + fs/ext4/super.c | 13 ++++++++++++- + 1 file changed, 12 insertions(+), 1 deletion(-) + +--- a/fs/ext4/super.c ++++ b/fs/ext4/super.c +@@ -5998,8 +5998,19 @@ static int ext4_enable_quotas(struct sup + "Failed to enable quota tracking " + "(type=%d, err=%d). Please run " + "e2fsck to fix.", type, err); +- for (type--; type >= 0; type--) ++ for (type--; type >= 0; type--) { ++ struct inode *inode; ++ ++ inode = sb_dqopt(sb)->files[type]; ++ if (inode) ++ inode = igrab(inode); + dquot_quota_off(sb, type); ++ if (inode) { ++ lockdep_set_quota_inode(inode, ++ I_DATA_SEM_NORMAL); ++ iput(inode); ++ } ++ } + + return err; + } diff --git a/queue-5.4/series b/queue-5.4/series index 84a5ef7e4fd..45d0f7741ed 100644 --- a/queue-5.4/series +++ b/queue-5.4/series @@ -262,3 +262,8 @@ pci-pci-bridge-emul-properly-mark-reserved-pcie-bits-in-pci-config-space.patch pci-pci-bridge-emul-correctly-set-pcie-capabilities.patch pci-pci-bridge-emul-set-pci_status_cap_list-for-pcie-device.patch xfrm-fix-policy-lookup-for-ipv6-gre-packets.patch +btrfs-fix-deadlock-between-quota-enable-and-other-quota-operations.patch +btrfs-check-the-root-node-for-uptodate-before-returning-it.patch +btrfs-respect-the-max-size-in-the-header-when-activating-swap-file.patch +ext4-make-sure-to-reset-inode-lockdep-class-when-quota-enabling-fails.patch +ext4-make-sure-quota-gets-properly-shutdown-on-error.patch