diff options
author | Darrick J. Wong <darrick.wong@oracle.com> | 2020-05-01 16:00:57 -0700 |
---|---|---|
committer | Darrick J. Wong <darrick.wong@oracle.com> | 2020-05-06 17:58:40 -0700 |
commit | c5ac0365c6615beab6d14102849a8f8171dfcbe8 (patch) | |
tree | de19148971e7e3a49519070b0f00a8cf02979156 | |
parent | 5b5ef9f9b8a64b8cb31520af4a4cfa48a20a2a09 (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.c | 47 |
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); } |