aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDarrick J. Wong <djwong@kernel.org>2021-03-18 16:37:13 -0700
committerDarrick J. Wong <djwong@kernel.org>2021-03-25 17:08:55 -0700
commit2f0ea3b2feee76a1928996f05aba85e7689b6ace (patch)
treef1028977d201ba70a304e5aadec9e683f5efbf94
parentc55285a74e5daf0b95dda6f3881e54076521d477 (diff)
downloadxfs-linux-faster-mount.tar.gz
xfs: parallelise the work we do to make the fs writablefaster-mount_2021-03-25faster-mount
Parallelise all the work that we do at mount time to prepare the filesystem to accept write requests. Signed-off-by: Darrick J. Wong <djwong@kernel.org> Reviewed-by: Chandan Babu R <chandanrlinux@gmail.com>
-rw-r--r--fs/xfs/xfs_fsops.c79
-rw-r--r--fs/xfs/xfs_reflink.c24
-rw-r--r--fs/xfs/xfs_reflink.h1
3 files changed, 73 insertions, 31 deletions
diff --git a/fs/xfs/xfs_fsops.c b/fs/xfs/xfs_fsops.c
index 83c8258e468e4f..b4087b0117c603 100644
--- a/fs/xfs/xfs_fsops.c
+++ b/fs/xfs/xfs_fsops.c
@@ -22,7 +22,8 @@
#include "xfs_inode.h"
#include "xfs_icache.h"
#include "xfs_rtalloc.h"
-#include "xfs_reflink.h"
+#include "xfs_refcount.h"
+#include "xfs_pwork.h"
/*
* growfs operations
@@ -556,21 +557,87 @@ xfs_fs_reserve_ag_blocks(
return error;
}
+struct xfs_make_writable {
+ struct xfs_pwork pwork;
+ xfs_agnumber_t agno;
+};
+
+static int
+xfs_fs_make_ag_writable(
+ struct xfs_mount *mp,
+ struct xfs_pwork *pwork)
+{
+ struct xfs_make_writable *mw;
+ struct xfs_perag *pag;
+ int error;
+
+ mw = container_of(pwork, struct xfs_make_writable, pwork);
+
+ if (xfs_pwork_want_abort(pwork))
+ goto out;
+
+ if (xfs_sb_version_hasreflink(&mp->m_sb)) {
+ error = xfs_refcount_recover_cow_leftovers(mp, mw->agno);
+ if (error) {
+ xfs_warn(mp,
+ "Error %d recovering AG %u leftover CoW staging.", error, mw->agno);
+ xfs_force_shutdown(mp, SHUTDOWN_CORRUPT_INCORE);
+ goto out;
+ }
+ }
+
+ if (mw->agno == NULLAGNUMBER) {
+ error = xfs_rt_resv_init(mp, NULL);
+ } else {
+ pag = xfs_perag_get(mp, mw->agno);
+ error = xfs_ag_resv_init(pag, NULL);
+ xfs_perag_put(pag);
+ }
+
+ if (error == -ENOSPC)
+ error = 0;
+ if (error) {
+ xfs_warn(mp,
+ "Error %d reserving AG %u metadata reserve pool.", error, mw->agno);
+ xfs_force_shutdown(mp, SHUTDOWN_CORRUPT_INCORE);
+ }
+
+out:
+ kmem_free(mw);
+ return error;
+}
+
/* Do all the work required to make the filesystem writable. */
int
xfs_fs_make_writable(
struct xfs_mount *mp)
{
+ struct xfs_pwork_ctl pctl;
+ struct xfs_make_writable *mw;
+ xfs_agnumber_t agno;
int error;
- error = xfs_reflink_recover_cow(mp);
+ error = xfs_pwork_init(mp, &pctl, xfs_fs_make_ag_writable,
+ "xfs-mount-rw");
if (error)
return error;
- error = xfs_fs_reserve_ag_blocks(mp);
- if (error == -ENOSPC)
- return 0;
- return error;
+ if (xfs_sb_version_hasrealtime(&mp->m_sb)) {
+ mw = kmem_zalloc(sizeof(struct xfs_make_writable), 0);
+ mw->agno = NULLAGNUMBER;
+ xfs_pwork_queue(&pctl, &mw->pwork);
+ }
+
+ for (agno = 0; agno < mp->m_sb.sb_agcount; agno++) {
+ if (xfs_pwork_ctl_want_abort(&pctl))
+ break;
+
+ mw = kmem_zalloc(sizeof(struct xfs_make_writable), 0);
+ mw->agno = agno;
+ xfs_pwork_queue(&pctl, &mw->pwork);
+ }
+
+ return xfs_pwork_destroy(&pctl);
}
/*
diff --git a/fs/xfs/xfs_reflink.c b/fs/xfs/xfs_reflink.c
index a30bab84783fac..8108499c0c1b41 100644
--- a/fs/xfs/xfs_reflink.c
+++ b/fs/xfs/xfs_reflink.c
@@ -831,30 +831,6 @@ xfs_reflink_end_cow(
}
/*
- * Free leftover CoW reservations that didn't get cleaned out.
- */
-int
-xfs_reflink_recover_cow(
- struct xfs_mount *mp)
-{
- xfs_agnumber_t agno;
- int error = 0;
-
- if (!xfs_sb_version_hasreflink(&mp->m_sb))
- return 0;
-
- for (agno = 0; agno < mp->m_sb.sb_agcount; agno++) {
- error = xfs_refcount_recover_cow_leftovers(mp, agno);
- if (error)
- return error;
- }
-
- if (xfs_sb_version_hasrealtime(&mp->m_sb))
- return xfs_refcount_recover_cow_leftovers(mp, NULLAGNUMBER);
- return 0;
-}
-
-/*
* Reflinking (Block) Ranges of Two Files Together
*
* First, ensure that the reflink flag is set on both inodes. The flag is an
diff --git a/fs/xfs/xfs_reflink.h b/fs/xfs/xfs_reflink.h
index 666d7e2413b0c3..c8f0c17392e12c 100644
--- a/fs/xfs/xfs_reflink.h
+++ b/fs/xfs/xfs_reflink.h
@@ -24,7 +24,6 @@ extern int xfs_reflink_cancel_cow_range(struct xfs_inode *ip, xfs_off_t offset,
xfs_off_t count, bool cancel_real);
extern int xfs_reflink_end_cow(struct xfs_inode *ip, xfs_off_t offset,
xfs_off_t count);
-extern int xfs_reflink_recover_cow(struct xfs_mount *mp);
extern loff_t xfs_reflink_remap_range(struct file *file_in, loff_t pos_in,
struct file *file_out, loff_t pos_out, loff_t len,
unsigned int remap_flags);