[RFC v6 PATCH 09/10] xfs: create an error tag for random relog reservation

Brian Foster
2020-04-06T12:36:42Z

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@redhat.com>
---
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 79e6c4fb1d8a..ca7bcadb9455 100644
--- a/fs/xfs/libxfs/xfs_errortag.h
+++ b/fs/xfs/libxfs/xfs_errortag.h
@@ -55,7 +55,8 @@
#define XFS_ERRTAG_FORCE_SCRUB_REPAIR 32
#define XFS_ERRTAG_FORCE_SUMMARY_RECALC 33
#define XFS_ERRTAG_IUNLINK_FALLBACK 34
-#define XFS_ERRTAG_MAX 35
+#define XFS_ERRTAG_RELOG 35
+#define XFS_ERRTAG_MAX 36

/*
* Random factors for above tags, 1 means always, 2 means 1/2 time, etc.
@@ -95,5 +96,6 @@
#define XFS_RANDOM_FORCE_SCRUB_REPAIR 1
#define XFS_RANDOM_FORCE_SUMMARY_RECALC 1
#define XFS_RANDOM_IUNLINK_FALLBACK (XFS_RANDOM_DEFAULT/10)
+#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 a21e9cc6516a..9d1f9b4c50ea 100644
--- a/fs/xfs/xfs_error.c
+++ b/fs/xfs/xfs_error.c
@@ -53,6 +53,7 @@ static unsigned int xfs_errortag_random_default[] = {
XFS_RANDOM_FORCE_SCRUB_REPAIR,
XFS_RANDOM_FORCE_SUMMARY_RECALC,
XFS_RANDOM_IUNLINK_FALLBACK,
+ XFS_RANDOM_RELOG,
};

struct xfs_errortag_attr {
@@ -162,6 +163,7 @@ XFS_ERRORTAG_ATTR_RW(buf_lru_ref, XFS_ERRTAG_BUF_LRU_REF);
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(relog, XFS_ERRTAG_RELOG);

static struct attribute *xfs_errortag_attrs[] = {
XFS_ERRORTAG_ATTR_LIST(noerror),
@@ -199,6 +201,7 @@ static struct attribute *xfs_errortag_attrs[] = {
XFS_ERRORTAG_ATTR_LIST(force_repair),
XFS_ERRORTAG_ATTR_LIST(bad_summary),
XFS_ERRORTAG_ATTR_LIST(iunlink_fallback),
+ XFS_ERRORTAG_ATTR_LIST(relog),
NULL,
};

diff --git a/fs/xfs/xfs_trans.c b/fs/xfs/xfs_trans.c
index 31ef5f671341..d7ca70a35d33 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;

@@ -179,9 +180,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);

@@ -197,9 +199,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);
}
@@ -207,7 +218,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.1