aboutsummaryrefslogtreecommitdiffstats
path: root/fs/xfs
diff options
context:
space:
mode:
authorBrian Foster <bfoster@redhat.com>2019-04-17 11:48:24 -0400
committerDarrick J. Wong <darrick.wong@oracle.com>2019-04-22 19:28:45 -0400
commit945c941fcd82bac3a8ea2b89c635651f323bd609 (patch)
treec7b22f90b58b04992bc8e0f5f69e79384f23c7ff /fs/xfs
parent3994fc48957520df061990ed22fff96023cfd953 (diff)
xfs: make tr_growdata a permanent transaction
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 <darrick.wong@oracle.com> Signed-off-by: Brian Foster <bfoster@redhat.com> Reviewed-by: Darrick J. Wong <darrick.wong@oracle.com> [darrick: add a comment to the assert] Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
Diffstat (limited to 'fs/xfs')
-rw-r--r--fs/xfs/libxfs/xfs_trans_resv.c6
1 files changed, 5 insertions, 1 deletions
diff --git a/fs/xfs/libxfs/xfs_trans_resv.c b/fs/xfs/libxfs/xfs_trans_resv.c
index f99a7aefe418..83f4ee2afc49 100644
--- a/fs/xfs/libxfs/xfs_trans_resv.c
+++ b/fs/xfs/libxfs/xfs_trans_resv.c
@@ -876,9 +876,13 @@ xfs_trans_resv_calc(
876 resp->tr_sb.tr_logres = xfs_calc_sb_reservation(mp); 876 resp->tr_sb.tr_logres = xfs_calc_sb_reservation(mp);
877 resp->tr_sb.tr_logcount = XFS_DEFAULT_LOG_COUNT; 877 resp->tr_sb.tr_logcount = XFS_DEFAULT_LOG_COUNT;
878 878
879 /* growdata requires permanent res; it can free space to the last AG */
880 resp->tr_growdata.tr_logres = xfs_calc_growdata_reservation(mp);
881 resp->tr_growdata.tr_logcount = XFS_DEFAULT_PERM_LOG_COUNT;
882 resp->tr_growdata.tr_logflags |= XFS_TRANS_PERM_LOG_RES;
883
879 /* The following transaction are logged in logical format */ 884 /* The following transaction are logged in logical format */
880 resp->tr_ichange.tr_logres = xfs_calc_ichange_reservation(mp); 885 resp->tr_ichange.tr_logres = xfs_calc_ichange_reservation(mp);
881 resp->tr_growdata.tr_logres = xfs_calc_growdata_reservation(mp);
882 resp->tr_fsyncts.tr_logres = xfs_calc_swrite_reservation(mp); 886 resp->tr_fsyncts.tr_logres = xfs_calc_swrite_reservation(mp);
883 resp->tr_writeid.tr_logres = xfs_calc_writeid_reservation(mp); 887 resp->tr_writeid.tr_logres = xfs_calc_writeid_reservation(mp);
884 resp->tr_attrsetrt.tr_logres = xfs_calc_attrsetrt_reservation(mp); 888 resp->tr_attrsetrt.tr_logres = xfs_calc_attrsetrt_reservation(mp);