From 5d1b821b2bb13adab13fed82ea4621314bdec4c2 Mon Sep 17 00:00:00 2001 From: Brian Foster Date: Fri, 19 Jul 2019 16:05:30 -0400 Subject: [PATCH] xfs: make tr_growdata a permanent transaction Source kernel commit: 945c941fcd82bac3a8ea2b89c635651f323bd609 The growdata transaction is used by growfs operations to increase the data size of the filesystem. Part of this sequence involves extending the size of the last preexisting AG in the fs, if necessary. This is implemented by freeing the newly available physical range to the AG. tr_growdata is not a permanent transaction, however, and block allocation transactions must be permanent to handle deferred frees of AGFL blocks. If the grow operation extends an existing AG that requires AGFL fixing, assert failures occur due to a populated dfops list on a non-permanent transaction and the AGFL free does not occur. This is reproduced (rarely) by xfs/104. Change tr_growdata to a permanent transaction with a default log count. This increases initial transaction reservation size, but growfs is an infrequent and non-performance critical operation and so should have minimal impact. Reported-by: Darrick J. Wong Signed-off-by: Brian Foster Reviewed-by: Darrick J. Wong [darrick: add a comment to the assert] Signed-off-by: Darrick J. Wong Signed-off-by: Eric Sandeen --- libxfs/xfs_trans_resv.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/libxfs/xfs_trans_resv.c b/libxfs/xfs_trans_resv.c index 4ecf7c2e8..5bd258d93 100644 --- a/libxfs/xfs_trans_resv.c +++ b/libxfs/xfs_trans_resv.c @@ -875,9 +875,13 @@ xfs_trans_resv_calc( resp->tr_sb.tr_logres = xfs_calc_sb_reservation(mp); resp->tr_sb.tr_logcount = XFS_DEFAULT_LOG_COUNT; + /* growdata requires permanent res; it can free space to the last AG */ + resp->tr_growdata.tr_logres = xfs_calc_growdata_reservation(mp); + resp->tr_growdata.tr_logcount = XFS_DEFAULT_PERM_LOG_COUNT; + resp->tr_growdata.tr_logflags |= XFS_TRANS_PERM_LOG_RES; + /* The following transaction are logged in logical format */ resp->tr_ichange.tr_logres = xfs_calc_ichange_reservation(mp); - resp->tr_growdata.tr_logres = xfs_calc_growdata_reservation(mp); resp->tr_fsyncts.tr_logres = xfs_calc_swrite_reservation(mp); resp->tr_writeid.tr_logres = xfs_calc_writeid_reservation(mp); resp->tr_attrsetrt.tr_logres = xfs_calc_attrsetrt_reservation(mp); -- 2.47.2