summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDarrick J. Wong <darrick.wong@oracle.com>2020-05-01 16:00:57 -0700
committerDarrick J. Wong <darrick.wong@oracle.com>2020-05-06 17:58:40 -0700
commitc5ac0365c6615beab6d14102849a8f8171dfcbe8 (patch)
treede19148971e7e3a49519070b0f00a8cf02979156
parent5b5ef9f9b8a64b8cb31520af4a4cfa48a20a2a09 (diff)
xfs: use parallel processing to clear unlinked metadatarefactor-unlinked-recovery_2020-05-06
Run all the unlinked metadata clearing work in parallel so that we can take advantage of higher-performance storage devices. Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com> Reviewed-by: Chandan Babu R <chandanrlinux@gmail.com>
-rw-r--r--fs/xfs/xfs_unlink_recover.c47
1 files changed, 41 insertions, 6 deletions
diff --git a/fs/xfs/xfs_unlink_recover.c b/fs/xfs/xfs_unlink_recover.c
index 4ce39ae6a424..7635a9e9f03f 100644
--- a/fs/xfs/xfs_unlink_recover.c
+++ b/fs/xfs/xfs_unlink_recover.c
@@ -21,6 +21,7 @@
#include "xfs_trans_priv.h"
#include "xfs_ialloc.h"
#include "xfs_icache.h"
+#include "xfs_pwork.h"
/*
* This routine performs a transaction to null out a bad inode pointer
@@ -194,20 +195,54 @@ xlog_recover_process_ag_iunlinked(
return 0;
}
+struct xlog_recover_unlinked {
+ struct xfs_pwork pwork;
+ xfs_agnumber_t agno;
+};
+
+static int
+xlog_recover_process_unlinked_ag(
+ struct xfs_mount *mp,
+ struct xfs_pwork *pwork)
+{
+ struct xlog_recover_unlinked *ru;
+ int error = 0;
+
+ ru = container_of(pwork, struct xlog_recover_unlinked, pwork);
+ if (xfs_pwork_want_abort(pwork))
+ goto out;
+
+ error = xlog_recover_process_ag_iunlinked(mp, ru->agno);
+out:
+ kmem_free(ru);
+ return error;
+}
+
int
xlog_recover_process_unlinked(
struct xlog *log)
{
struct xfs_mount *mp = log->l_mp;
+ struct xfs_pwork_ctl pctl;
+ struct xlog_recover_unlinked *ru;
+ unsigned int nr_threads;
xfs_agnumber_t agno;
- int error = 0;
- int err2;
+ int error;
+
+ nr_threads = xfs_pwork_guess_datadev_parallelism(mp);
+ error = xfs_pwork_init(mp, &pctl, xlog_recover_process_unlinked_ag,
+ "xlog_recover", nr_threads);
+ if (error)
+ return error;
for (agno = 0; agno < mp->m_sb.sb_agcount; agno++) {
- err2 = xlog_recover_process_ag_iunlinked(mp, agno);
- if (!error && err2)
- error = err2;
+ if (xfs_pwork_ctl_want_abort(&pctl))
+ break;
+
+ ru = kmem_zalloc(sizeof(struct xlog_recover_unlinked), 0);
+ ru->agno = agno;
+ xfs_pwork_queue(&pctl, &ru->pwork);
}
- return error;
+ return xfs_pwork_destroy(&pctl);
}