Patch "xfs: fix unmount hang and memory leak on shutdown during quotaoff" has been added to the 5.4-stable tree

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



This is a note to let you know that I've just added the patch titled

    xfs: fix unmount hang and memory leak on shutdown during quotaoff

to the 5.4-stable tree which can be found at:
    http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=summary

The filename of the patch is:
     xfs-fix-unmount-hang-and-memory-leak-on-shutdown-during-quotaoff.patch
and it can be found in the queue-5.4 subdirectory.

If you, or anyone else, feels it should not be added to the stable tree,
please let <stable@xxxxxxxxxxxxxxx> know about it.


>From foo@baz Wed Oct 26 04:49:40 PM CEST 2022
From: Chandan Babu R <chandan.babu@xxxxxxxxxx>
Date: Wed, 26 Oct 2022 11:58:32 +0530
Subject: xfs: fix unmount hang and memory leak on shutdown during quotaoff
To: gregkh@xxxxxxxxxxxxxxxxxxx
Cc: sashal@xxxxxxxxxx, mcgrof@xxxxxxxxxx, linux-xfs@xxxxxxxxxxxxxxx, stable@xxxxxxxxxxxxxxx, djwong@xxxxxxxxxx, chandan.babu@xxxxxxxxxx, amir73il@xxxxxxxxx, leah.rumancik@xxxxxxxxx
Message-ID: <20221026062843.927600-16-chandan.babu@xxxxxxxxxx>

From: Brian Foster <bfoster@xxxxxxxxxx>

commit 8a62714313391b9b2297d67c341b35edbf46c279 upstream.

AIL removal of the quotaoff start intent and free of both quotaoff
intents is currently limited to the ->iop_committed() handler of the
end intent. This executes when the end intent is committed to the
on-disk log and marks the completion of the operation. The problem
with this is it assumes the success of the operation. If a shutdown
or other error occurs during the quotaoff, it's possible for the
quotaoff task to exit without removing the start intent from the
AIL. This results in an unmount hang as the AIL cannot be emptied.
Further, no other codepath frees the intents and so this is also a
memory leak vector.

First, update the high level quotaoff error path to directly remove
and free the quotaoff start intent if it still exists in the AIL at
the time of the error. Next, update both of the start and end
quotaoff intents with an ->iop_release() callback to properly handle
transaction abort.

This means that If the quotaoff start transaction aborts, it frees
the start intent in the transaction commit path. If the filesystem
shuts down before the end transaction allocates, the quotaoff
sequence removes and frees the start intent. If the end transaction
aborts, it removes the start intent and frees both. This ensures
that a shutdown does not result in a hung unmount and that memory is
not leaked regardless of when a quotaoff error occurs.

Signed-off-by: Brian Foster <bfoster@xxxxxxxxxx>
Reviewed-by: Darrick J. Wong <darrick.wong@xxxxxxxxxx>
Signed-off-by: Darrick J. Wong <darrick.wong@xxxxxxxxxx>
Reviewed-by: Christoph Hellwig <hch@xxxxxx>
Acked-by: Darrick J. Wong <djwong@xxxxxxxxxx>
Signed-off-by: Chandan Babu R <chandan.babu@xxxxxxxxxx>
Signed-off-by: Greg Kroah-Hartman <gregkh@xxxxxxxxxxxxxxxxxxx>
---
 fs/xfs/xfs_dquot_item.c  |   15 +++++++++++++++
 fs/xfs/xfs_qm_syscalls.c |   13 +++++++------
 2 files changed, 22 insertions(+), 6 deletions(-)

--- a/fs/xfs/xfs_dquot_item.c
+++ b/fs/xfs/xfs_dquot_item.c
@@ -315,17 +315,32 @@ xfs_qm_qoffend_logitem_committed(
 	return (xfs_lsn_t)-1;
 }
 
+STATIC void
+xfs_qm_qoff_logitem_release(
+	struct xfs_log_item	*lip)
+{
+	struct xfs_qoff_logitem	*qoff = QOFF_ITEM(lip);
+
+	if (test_bit(XFS_LI_ABORTED, &lip->li_flags)) {
+		if (qoff->qql_start_lip)
+			xfs_qm_qoff_logitem_relse(qoff->qql_start_lip);
+		xfs_qm_qoff_logitem_relse(qoff);
+	}
+}
+
 static const struct xfs_item_ops xfs_qm_qoffend_logitem_ops = {
 	.iop_size	= xfs_qm_qoff_logitem_size,
 	.iop_format	= xfs_qm_qoff_logitem_format,
 	.iop_committed	= xfs_qm_qoffend_logitem_committed,
 	.iop_push	= xfs_qm_qoff_logitem_push,
+	.iop_release	= xfs_qm_qoff_logitem_release,
 };
 
 static const struct xfs_item_ops xfs_qm_qoff_logitem_ops = {
 	.iop_size	= xfs_qm_qoff_logitem_size,
 	.iop_format	= xfs_qm_qoff_logitem_format,
 	.iop_push	= xfs_qm_qoff_logitem_push,
+	.iop_release	= xfs_qm_qoff_logitem_release,
 };
 
 /*
--- a/fs/xfs/xfs_qm_syscalls.c
+++ b/fs/xfs/xfs_qm_syscalls.c
@@ -29,8 +29,6 @@ xfs_qm_log_quotaoff(
 	int			error;
 	struct xfs_qoff_logitem	*qoffi;
 
-	*qoffstartp = NULL;
-
 	error = xfs_trans_alloc(mp, &M_RES(mp)->tr_qm_quotaoff, 0, 0, 0, &tp);
 	if (error)
 		goto out;
@@ -62,7 +60,7 @@ out:
 STATIC int
 xfs_qm_log_quotaoff_end(
 	struct xfs_mount	*mp,
-	struct xfs_qoff_logitem	*startqoff,
+	struct xfs_qoff_logitem	**startqoff,
 	uint			flags)
 {
 	struct xfs_trans	*tp;
@@ -73,9 +71,10 @@ xfs_qm_log_quotaoff_end(
 	if (error)
 		return error;
 
-	qoffi = xfs_trans_get_qoff_item(tp, startqoff,
+	qoffi = xfs_trans_get_qoff_item(tp, *startqoff,
 					flags & XFS_ALL_QUOTA_ACCT);
 	xfs_trans_log_quotaoff_item(tp, qoffi);
+	*startqoff = NULL;
 
 	/*
 	 * We have to make sure that the transaction is secure on disk before we
@@ -103,7 +102,7 @@ xfs_qm_scall_quotaoff(
 	uint			dqtype;
 	int			error;
 	uint			inactivate_flags;
-	struct xfs_qoff_logitem	*qoffstart;
+	struct xfs_qoff_logitem	*qoffstart = NULL;
 
 	/*
 	 * No file system can have quotas enabled on disk but not in core.
@@ -228,7 +227,7 @@ xfs_qm_scall_quotaoff(
 	 * So, we have QUOTAOFF start and end logitems; the start
 	 * logitem won't get overwritten until the end logitem appears...
 	 */
-	error = xfs_qm_log_quotaoff_end(mp, qoffstart, flags);
+	error = xfs_qm_log_quotaoff_end(mp, &qoffstart, flags);
 	if (error) {
 		/* We're screwed now. Shutdown is the only option. */
 		xfs_force_shutdown(mp, SHUTDOWN_CORRUPT_INCORE);
@@ -261,6 +260,8 @@ xfs_qm_scall_quotaoff(
 	}
 
 out_unlock:
+	if (error && qoffstart)
+		xfs_qm_qoff_logitem_relse(qoffstart);
 	mutex_unlock(&q->qi_quotaofflock);
 	return error;
 }


Patches currently in stable-queue which might be from chandan.babu@xxxxxxxxxx are

queue-5.4/xfs-check-owner-of-dir3-blocks.patch
queue-5.4/xfs-throttle-commits-on-delayed-background-cil-push.patch
queue-5.4/xfs-factor-common-ail-item-deletion-code.patch
queue-5.4/xfs-remove-the-xfs_dq_logitem_t-typedef.patch
queue-5.4/xfs-fix-buffer-corruption-reporting-when-xfs_dir3_free_header_check-fails.patch
queue-5.4/xfs-xfs_buf_corruption_error-should-take-__this_address.patch
queue-5.4/xfs-open-code-insert-range-extent-split-helper.patch
queue-5.4/xfs-don-t-write-a-corrupt-unmount-record-to-force-summary-counter-recalc.patch
queue-5.4/xfs-check-owner-of-dir3-data-blocks.patch
queue-5.4/xfs-factor-out-quotaoff-intent-ail-removal-and-memory-free.patch
queue-5.4/xfs-trylock-underlying-buffer-on-dquot-flush.patch
queue-5.4/xfs-remove-the-xfs_disk_dquot_t-and-xfs_dquot_t.patch
queue-5.4/xfs-add-a-function-to-deal-with-corrupt-buffers-post-verifiers.patch
queue-5.4/xfs-fix-use-after-free-on-cil-context-on-shutdown.patch
queue-5.4/xfs-tail-updates-only-need-to-occur-when-lsn-changes.patch
queue-5.4/xfs-use-scnprintf-for-avoiding-potential-buffer-overflow.patch
queue-5.4/xfs-move-inode-flush-to-the-sync-workqueue.patch
queue-5.4/xfs-lower-cil-flush-limit-for-large-logs.patch
queue-5.4/xfs-rework-collapse-range-into-an-atomic-operation.patch
queue-5.4/xfs-remove-the-xfs_qoff_logitem_t-typedef.patch
queue-5.4/xfs-fix-unmount-hang-and-memory-leak-on-shutdown-during-quotaoff.patch
queue-5.4/xfs-preserve-default-grace-interval-during-quotacheck.patch
queue-5.4/xfs-replace-function-declaration-by-actual-definition.patch
queue-5.4/xfs-rework-insert-range-into-an-atomic-operation.patch
queue-5.4/xfs-factor-out-a-new-xfs_log_force_inode-helper.patch
queue-5.4/xfs-reflink-should-force-the-log-out-if-mounted-with-wsync.patch



[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Index of Archives]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux