From 287853e7bc8138209697ddd83dd2c801635ca6de Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Mon, 31 Oct 2022 08:07:38 +0100 Subject: [PATCH] 5.4-stable patches added patches: xfs-clear-xfs_dq_freeing-if-we-can-t-lock-the-dquot-buffer-to-flush.patch xfs-finish-dfops-on-every-insert-range-shift-iteration.patch xfs-force-the-log-after-remapping-a-synchronous-writes-file.patch --- queue-5.4/series | 3 + ...can-t-lock-the-dquot-buffer-to-flush.patch | 77 +++++++++++++++++++ ...n-every-insert-range-shift-iteration.patch | 48 ++++++++++++ ...-remapping-a-synchronous-writes-file.patch | 68 ++++++++++++++++ 4 files changed, 196 insertions(+) create mode 100644 queue-5.4/xfs-clear-xfs_dq_freeing-if-we-can-t-lock-the-dquot-buffer-to-flush.patch create mode 100644 queue-5.4/xfs-finish-dfops-on-every-insert-range-shift-iteration.patch create mode 100644 queue-5.4/xfs-force-the-log-after-remapping-a-synchronous-writes-file.patch diff --git a/queue-5.4/series b/queue-5.4/series index 6b49e9c27b7..331b5dfb7cd 100644 --- a/queue-5.4/series +++ b/queue-5.4/series @@ -20,3 +20,6 @@ kernfs-fix-use-after-free-in-__kernfs_remove.patch perf-auxtrace-fix-address-filter-symbol-name-match-for-modules.patch s390-futex-add-missing-ex_table-entry-to-__futex_atomic_op.patch s390-pci-add-missing-ex_table-entries-to-__pcistg_mio_inuser-__pcilg_mio_inuser.patch +xfs-finish-dfops-on-every-insert-range-shift-iteration.patch +xfs-clear-xfs_dq_freeing-if-we-can-t-lock-the-dquot-buffer-to-flush.patch +xfs-force-the-log-after-remapping-a-synchronous-writes-file.patch diff --git a/queue-5.4/xfs-clear-xfs_dq_freeing-if-we-can-t-lock-the-dquot-buffer-to-flush.patch b/queue-5.4/xfs-clear-xfs_dq_freeing-if-we-can-t-lock-the-dquot-buffer-to-flush.patch new file mode 100644 index 00000000000..9bcc34f6cdc --- /dev/null +++ b/queue-5.4/xfs-clear-xfs_dq_freeing-if-we-can-t-lock-the-dquot-buffer-to-flush.patch @@ -0,0 +1,77 @@ +From foo@baz Mon Oct 31 08:07:17 AM CET 2022 +From: Chandan Babu R +Date: Mon, 31 Oct 2022 10:23:53 +0530 +Subject: xfs: clear XFS_DQ_FREEING if we can't lock the dquot buffer to flush +To: gregkh@linuxfoundation.org +Cc: sashal@kernel.org, mcgrof@kernel.org, linux-xfs@vger.kernel.org, stable@vger.kernel.org, djwong@kernel.org, chandan.babu@oracle.com, amir73il@gmail.com, leah.rumancik@gmail.com +Message-ID: <20221031045354.183020-3-chandan.babu@oracle.com> + +From: Chandan Babu R + +From: "Darrick J. Wong" + +commit c97738a960a86081a147e7d436138e6481757445 upstream. + +In commit 8d3d7e2b35ea, we changed xfs_qm_dqpurge to bail out if we +can't lock the dquot buf to flush the dquot. This prevents the AIL from +blocking on the dquot, but it also forgets to clear the FREEING flag on +its way out. A subsequent purge attempt will see the FREEING flag is +set and bail out, which leads to dqpurge_all failing to purge all the +dquots. + +(copy-pasting from Dave Chinner's identical patch) + +This was found by inspection after having xfs/305 hang 1 in ~50 +iterations in a quotaoff operation: + +[ 8872.301115] xfs_quota D13888 92262 91813 0x00004002 +[ 8872.302538] Call Trace: +[ 8872.303193] __schedule+0x2d2/0x780 +[ 8872.304108] ? do_raw_spin_unlock+0x57/0xd0 +[ 8872.305198] schedule+0x6e/0xe0 +[ 8872.306021] schedule_timeout+0x14d/0x300 +[ 8872.307060] ? __next_timer_interrupt+0xe0/0xe0 +[ 8872.308231] ? xfs_qm_dqusage_adjust+0x200/0x200 +[ 8872.309422] schedule_timeout_uninterruptible+0x2a/0x30 +[ 8872.310759] xfs_qm_dquot_walk.isra.0+0x15a/0x1b0 +[ 8872.311971] xfs_qm_dqpurge_all+0x7f/0x90 +[ 8872.313022] xfs_qm_scall_quotaoff+0x18d/0x2b0 +[ 8872.314163] xfs_quota_disable+0x3a/0x60 +[ 8872.315179] kernel_quotactl+0x7e2/0x8d0 +[ 8872.316196] ? __do_sys_newstat+0x51/0x80 +[ 8872.317238] __x64_sys_quotactl+0x1e/0x30 +[ 8872.318266] do_syscall_64+0x46/0x90 +[ 8872.319193] entry_SYSCALL_64_after_hwframe+0x44/0xa9 +[ 8872.320490] RIP: 0033:0x7f46b5490f2a +[ 8872.321414] Code: Bad RIP value. + +Returning -EAGAIN from xfs_qm_dqpurge() without clearing the +XFS_DQ_FREEING flag means the xfs_qm_dqpurge_all() code can never +free the dquot, and we loop forever waiting for the XFS_DQ_FREEING +flag to go away on the dquot that leaked it via -EAGAIN. + +Fixes: 8d3d7e2b35ea ("xfs: trylock underlying buffer on dquot flush") +Signed-off-by: Darrick J. Wong +Reviewed-by: Allison Collins +Reviewed-by: Chandan Babu R +Reviewed-by: Christoph Hellwig +Reviewed-by: Brian Foster +Signed-off-by: Dave Chinner +Reviewed-by: Dave Chinner +Acked-by: Darrick J. Wong +Signed-off-by: Chandan Babu R +Signed-off-by: Greg Kroah-Hartman +--- + fs/xfs/xfs_qm.c | 1 + + 1 file changed, 1 insertion(+) + +--- a/fs/xfs/xfs_qm.c ++++ b/fs/xfs/xfs_qm.c +@@ -148,6 +148,7 @@ xfs_qm_dqpurge( + error = xfs_bwrite(bp); + xfs_buf_relse(bp); + } else if (error == -EAGAIN) { ++ dqp->dq_flags &= ~XFS_DQ_FREEING; + goto out_unlock; + } + xfs_dqflock(dqp); diff --git a/queue-5.4/xfs-finish-dfops-on-every-insert-range-shift-iteration.patch b/queue-5.4/xfs-finish-dfops-on-every-insert-range-shift-iteration.patch new file mode 100644 index 00000000000..151896536ac --- /dev/null +++ b/queue-5.4/xfs-finish-dfops-on-every-insert-range-shift-iteration.patch @@ -0,0 +1,48 @@ +From foo@baz Mon Oct 31 08:07:17 AM CET 2022 +From: Chandan Babu R +Date: Mon, 31 Oct 2022 10:23:52 +0530 +Subject: xfs: finish dfops on every insert range shift iteration +To: gregkh@linuxfoundation.org +Cc: sashal@kernel.org, mcgrof@kernel.org, linux-xfs@vger.kernel.org, stable@vger.kernel.org, djwong@kernel.org, chandan.babu@oracle.com, amir73il@gmail.com, leah.rumancik@gmail.com +Message-ID: <20221031045354.183020-2-chandan.babu@oracle.com> + +From: Chandan Babu R + +From: Brian Foster + +commit 9c516e0e4554e8f26ab73d46cbc789d7d8db664d upstream. + +The recent change to make insert range an atomic operation used the +incorrect transaction rolling mechanism. The explicit transaction +roll does not finish deferred operations. This means that intents +for rmapbt updates caused by extent shifts are not logged until the +final transaction commits. Thus if a crash occurs during an insert +range, log recovery might leave the rmapbt in an inconsistent state. +This was discovered by repeated runs of generic/455. + +Update insert range to finish dfops on every shift iteration. This +is similar to collapse range and ensures that intents are logged +with the transactions that make associated changes. + +Fixes: dd87f87d87fa ("xfs: rework insert range into an atomic operation") +Signed-off-by: Brian Foster +Reviewed-by: Darrick J. Wong +Signed-off-by: Darrick J. Wong +Acked-by: Darrick J. Wong +Signed-off-by: Chandan Babu R +Signed-off-by: Greg Kroah-Hartman +--- + fs/xfs/xfs_bmap_util.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/fs/xfs/xfs_bmap_util.c ++++ b/fs/xfs/xfs_bmap_util.c +@@ -1340,7 +1340,7 @@ xfs_insert_file_space( + goto out_trans_cancel; + + do { +- error = xfs_trans_roll_inode(&tp, ip); ++ error = xfs_defer_finish(&tp); + if (error) + goto out_trans_cancel; + diff --git a/queue-5.4/xfs-force-the-log-after-remapping-a-synchronous-writes-file.patch b/queue-5.4/xfs-force-the-log-after-remapping-a-synchronous-writes-file.patch new file mode 100644 index 00000000000..9a17a013416 --- /dev/null +++ b/queue-5.4/xfs-force-the-log-after-remapping-a-synchronous-writes-file.patch @@ -0,0 +1,68 @@ +From foo@baz Mon Oct 31 08:07:17 AM CET 2022 +From: Chandan Babu R +Date: Mon, 31 Oct 2022 10:23:54 +0530 +Subject: xfs: force the log after remapping a synchronous-writes file +To: gregkh@linuxfoundation.org +Cc: sashal@kernel.org, mcgrof@kernel.org, linux-xfs@vger.kernel.org, stable@vger.kernel.org, djwong@kernel.org, chandan.babu@oracle.com, amir73il@gmail.com, leah.rumancik@gmail.com +Message-ID: <20221031045354.183020-4-chandan.babu@oracle.com> + +From: Chandan Babu R + +From: "Darrick J. Wong" + +commit 5ffce3cc22a0e89813ed0c7162a68b639aef9ab6 upstream. + +Commit 5833112df7e9 tried to make it so that a remap operation would +force the log out to disk if the filesystem is mounted with mandatory +synchronous writes. Unfortunately, that commit failed to handle the +case where the inode or the file descriptor require mandatory +synchronous writes. + +Refactor the check into into a helper that will look for all three +conditions, and now we can treat reflink just like any other synchronous +write. + +Fixes: 5833112df7e9 ("xfs: reflink should force the log out if mounted with wsync") +Signed-off-by: Darrick J. Wong +Reviewed-by: Brian Foster +Reviewed-by: Christoph Hellwig +Acked-by: Darrick J. Wong +Signed-off-by: Chandan Babu R +Signed-off-by: Greg Kroah-Hartman +--- + fs/xfs/xfs_file.c | 17 ++++++++++++++++- + 1 file changed, 16 insertions(+), 1 deletion(-) + +--- a/fs/xfs/xfs_file.c ++++ b/fs/xfs/xfs_file.c +@@ -990,6 +990,21 @@ xfs_file_fadvise( + return ret; + } + ++/* Does this file, inode, or mount want synchronous writes? */ ++static inline bool xfs_file_sync_writes(struct file *filp) ++{ ++ struct xfs_inode *ip = XFS_I(file_inode(filp)); ++ ++ if (ip->i_mount->m_flags & XFS_MOUNT_WSYNC) ++ return true; ++ if (filp->f_flags & (__O_SYNC | O_DSYNC)) ++ return true; ++ if (IS_SYNC(file_inode(filp))) ++ return true; ++ ++ return false; ++} ++ + STATIC loff_t + xfs_file_remap_range( + struct file *file_in, +@@ -1047,7 +1062,7 @@ xfs_file_remap_range( + if (ret) + goto out_unlock; + +- if (mp->m_flags & XFS_MOUNT_WSYNC) ++ if (xfs_file_sync_writes(file_in) || xfs_file_sync_writes(file_out)) + xfs_log_force_inode(dest); + out_unlock: + xfs_reflink_remap_unlock(file_in, file_out); -- 2.47.3