Create an errortag to enable relogging on random transactions. Since relogging requires extra transaction reservation, artificially bump the reservation on selected transactions and tag them with the relog flag such that the requisite reservation overhead is added by the ticket allocation code. This allows subsequent random buffer relog events to target transactions where reservation is included. This is necessary to avoid transaction reservation overruns on non-relog transactions. Note that this does not yet enable relogging of any particular items. The tag will be reused in a subsequent patch to enable random buffer relogging. Signed-off-by: Brian Foster <bfoster@xxxxxxxxxx> --- fs/xfs/libxfs/xfs_errortag.h | 4 +++- fs/xfs/xfs_error.c | 3 +++ fs/xfs/xfs_trans.c | 21 ++++++++++++++++----- 3 files changed, 22 insertions(+), 6 deletions(-) diff --git a/fs/xfs/libxfs/xfs_errortag.h b/fs/xfs/libxfs/xfs_errortag.h index 53b305dea381..8f360cfc666c 100644 --- a/fs/xfs/libxfs/xfs_errortag.h +++ b/fs/xfs/libxfs/xfs_errortag.h @@ -56,7 +56,8 @@ #define XFS_ERRTAG_FORCE_SUMMARY_RECALC 33 #define XFS_ERRTAG_IUNLINK_FALLBACK 34 #define XFS_ERRTAG_BUF_IOERROR 35 -#define XFS_ERRTAG_MAX 36 +#define XFS_ERRTAG_RELOG 36 +#define XFS_ERRTAG_MAX 37 /* * Random factors for above tags, 1 means always, 2 means 1/2 time, etc. @@ -97,5 +98,6 @@ #define XFS_RANDOM_FORCE_SUMMARY_RECALC 1 #define XFS_RANDOM_IUNLINK_FALLBACK (XFS_RANDOM_DEFAULT/10) #define XFS_RANDOM_BUF_IOERROR XFS_RANDOM_DEFAULT +#define XFS_RANDOM_RELOG XFS_RANDOM_DEFAULT #endif /* __XFS_ERRORTAG_H_ */ diff --git a/fs/xfs/xfs_error.c b/fs/xfs/xfs_error.c index 7f6e20899473..562e00f7dcf5 100644 --- a/fs/xfs/xfs_error.c +++ b/fs/xfs/xfs_error.c @@ -54,6 +54,7 @@ static unsigned int xfs_errortag_random_default[] = { XFS_RANDOM_FORCE_SUMMARY_RECALC, XFS_RANDOM_IUNLINK_FALLBACK, XFS_RANDOM_BUF_IOERROR, + XFS_RANDOM_RELOG, }; struct xfs_errortag_attr { @@ -164,6 +165,7 @@ XFS_ERRORTAG_ATTR_RW(force_repair, XFS_ERRTAG_FORCE_SCRUB_REPAIR); XFS_ERRORTAG_ATTR_RW(bad_summary, XFS_ERRTAG_FORCE_SUMMARY_RECALC); XFS_ERRORTAG_ATTR_RW(iunlink_fallback, XFS_ERRTAG_IUNLINK_FALLBACK); XFS_ERRORTAG_ATTR_RW(buf_ioerror, XFS_ERRTAG_BUF_IOERROR); +XFS_ERRORTAG_ATTR_RW(relog, XFS_ERRTAG_RELOG); static struct attribute *xfs_errortag_attrs[] = { XFS_ERRORTAG_ATTR_LIST(noerror), @@ -202,6 +204,7 @@ static struct attribute *xfs_errortag_attrs[] = { XFS_ERRORTAG_ATTR_LIST(bad_summary), XFS_ERRORTAG_ATTR_LIST(iunlink_fallback), XFS_ERRORTAG_ATTR_LIST(buf_ioerror), + XFS_ERRORTAG_ATTR_LIST(relog), NULL, }; diff --git a/fs/xfs/xfs_trans.c b/fs/xfs/xfs_trans.c index 310beaccbc4c..df94ca45c7c8 100644 --- a/fs/xfs/xfs_trans.c +++ b/fs/xfs/xfs_trans.c @@ -21,6 +21,7 @@ #include "xfs_error.h" #include "xfs_defer.h" #include "xfs_log_priv.h" +#include "xfs_errortag.h" kmem_zone_t *xfs_trans_zone; @@ -176,9 +177,10 @@ xfs_trans_reserve( if (resp->tr_logres > 0) { bool permanent = false; bool relog = (tp->t_flags & XFS_TRANS_RELOG); + int logres = resp->tr_logres; ASSERT(tp->t_log_res == 0 || - tp->t_log_res == resp->tr_logres); + tp->t_log_res == logres); ASSERT(tp->t_log_count == 0 || tp->t_log_count == resp->tr_logcount); @@ -194,9 +196,18 @@ xfs_trans_reserve( ASSERT(resp->tr_logflags & XFS_TRANS_PERM_LOG_RES); error = xfs_log_regrant(mp, tp->t_ticket); } else { - error = xfs_log_reserve(mp, - resp->tr_logres, - resp->tr_logcount, + /* + * Enable relog overhead on random transactions to support + * random item relogging. + */ + if (XFS_TEST_ERROR(false, mp, XFS_ERRTAG_RELOG) && + !relog) { + tp->t_flags |= XFS_TRANS_RELOG; + relog = true; + logres <<= 1; + } + + error = xfs_log_reserve(mp, logres, resp->tr_logcount, &tp->t_ticket, XFS_TRANSACTION, permanent, relog); } @@ -204,7 +215,7 @@ xfs_trans_reserve( if (error) goto undo_blocks; - tp->t_log_res = resp->tr_logres; + tp->t_log_res = logres; tp->t_log_count = resp->tr_logcount; } -- 2.21.3