On Thu, Oct 01, 2020 at 09:21:03PM -0700, Darrick J. Wong wrote: > From: Darrick J. Wong <darrick.wong@xxxxxxxxxx> > > 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@xxxxxxxxxx> > --- > v4.2: save only the log reservation, and hardcode logcount and flags. > --- Reviewed-by: Brian Foster <bfoster@xxxxxxxxxx> > fs/xfs/libxfs/xfs_defer.c | 3 +++ > fs/xfs/libxfs/xfs_defer.h | 3 +++ > fs/xfs/xfs_log_recover.c | 17 ++++++++++++++--- > 3 files changed, 20 insertions(+), 3 deletions(-) > > diff --git a/fs/xfs/libxfs/xfs_defer.c b/fs/xfs/libxfs/xfs_defer.c > index 10aeae7353ab..e19dc1ced7e6 100644 > --- a/fs/xfs/libxfs/xfs_defer.c > +++ b/fs/xfs/libxfs/xfs_defer.c > @@ -579,6 +579,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; > } > > diff --git a/fs/xfs/libxfs/xfs_defer.h b/fs/xfs/libxfs/xfs_defer.h > index 5c0e59b69ffa..6cde6f0713f7 100644 > --- a/fs/xfs/libxfs/xfs_defer.h > +++ b/fs/xfs/libxfs/xfs_defer.h > @@ -79,6 +79,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; > }; > > /* > diff --git a/fs/xfs/xfs_log_recover.c b/fs/xfs/xfs_log_recover.c > index 1be5208e2a2f..001e1585ddc6 100644 > --- a/fs/xfs/xfs_log_recover.c > +++ b/fs/xfs/xfs_log_recover.c > @@ -2442,9 +2442,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; > >