]> git.ipfire.org Git - thirdparty/kernel/stable.git/commitdiff
xfs: xfs_defer_capture should absorb remaining transaction reservation
authorDarrick J. Wong <darrick.wong@oracle.com>
Thu, 16 Feb 2023 05:20:07 +0000 (10:50 +0530)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Wed, 22 Feb 2023 11:50:37 +0000 (12:50 +0100)
commit 929b92f64048d90d23e40a59c47adf59f5026903 upstream.

When xfs_defer_capture extracts the deferred ops and transaction state
from a transaction, it should record the transaction reservation type
from the old transaction so that when we continue the dfops chain, we
still use the same reservation parameters.

Doing this means that the log item recovery functions get to determine
the transaction reservation instead of abusing tr_itruncate in yet
another part of xfs.

Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
Reviewed-by: Brian Foster <bfoster@redhat.com>
Reviewed-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Chandan Babu R <chandan.babu@oracle.com>
Acked-by: Darrick J. Wong <djwong@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
fs/xfs/libxfs/xfs_defer.c
fs/xfs/libxfs/xfs_defer.h
fs/xfs/xfs_log_recover.c

index 4c36ab9dd33e82a053dc2afa3439fa9807d548d2..d928637737362c34d36539b84ca3d2f936e215d4 100644 (file)
@@ -593,6 +593,9 @@ xfs_defer_ops_capture(
        dfc->dfc_blkres = tp->t_blk_res - tp->t_blk_res_used;
        dfc->dfc_rtxres = tp->t_rtx_res - tp->t_rtx_res_used;
 
+       /* Preserve the log reservation size. */
+       dfc->dfc_logres = tp->t_log_res;
+
        return dfc;
 }
 
index 7b0794ad58ca3c178db94c62a71b07faf197bbc3..d5b7494513e817b48e97b5359916250b32f72a8e 100644 (file)
@@ -77,6 +77,9 @@ struct xfs_defer_capture {
        /* Block reservations for the data and rt devices. */
        unsigned int            dfc_blkres;
        unsigned int            dfc_rtxres;
+
+       /* Log reservation saved from the transaction. */
+       unsigned int            dfc_logres;
 };
 
 /*
index a591420a2c895078eb7779ee9563327556d706d9..1e6ef00b833a3bae032d020b25a7c9349d343212 100644 (file)
@@ -4769,9 +4769,20 @@ xlog_finish_defer_ops(
        int                     error = 0;
 
        list_for_each_entry_safe(dfc, next, capture_list, dfc_list) {
-               error = xfs_trans_alloc(mp, &M_RES(mp)->tr_itruncate,
-                               dfc->dfc_blkres, dfc->dfc_rtxres,
-                               XFS_TRANS_RESERVE, &tp);
+               struct xfs_trans_res    resv;
+
+               /*
+                * Create a new transaction reservation from the captured
+                * information.  Set logcount to 1 to force the new transaction
+                * to regrant every roll so that we can make forward progress
+                * in recovery no matter how full the log might be.
+                */
+               resv.tr_logres = dfc->dfc_logres;
+               resv.tr_logcount = 1;
+               resv.tr_logflags = XFS_TRANS_PERM_LOG_RES;
+
+               error = xfs_trans_alloc(mp, &resv, dfc->dfc_blkres,
+                               dfc->dfc_rtxres, XFS_TRANS_RESERVE, &tp);
                if (error)
                        return error;