summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDarrick J. Wong <djwong@kernel.org>2022-08-19 11:28:42 -0700
committerDarrick J. Wong <djwong@kernel.org>2022-11-09 19:07:29 -0800
commit82a4c586d6889700fd8f02722451fe4d1e7b7ede (patch)
treea6a2ae57870ae5eba7b8d162aa168025cdce6ab9
parent59199afd0c6bc9f0ecb349698f46ccbf2d3c0063 (diff)
xfs: online repair of realtime bitmaps
Rebuild the realtime bitmap from the realtime rmap btree. Signed-off-by: Darrick J. Wong <djwong@kernel.org>
-rw-r--r--fs/xfs/Makefile4
-rw-r--r--fs/xfs/scrub/repair.h13
-rw-r--r--fs/xfs/scrub/rtbitmap.c10
-rw-r--r--fs/xfs/scrub/rtbitmap_repair.c56
-rw-r--r--fs/xfs/scrub/scrub.c2
5 files changed, 83 insertions, 2 deletions
diff --git a/fs/xfs/Makefile b/fs/xfs/Makefile
index b0a36ebb0a3b..74fcf2b4dc86 100644
--- a/fs/xfs/Makefile
+++ b/fs/xfs/Makefile
@@ -187,5 +187,9 @@ xfs-y += $(addprefix scrub/, \
refcount_repair.o \
repair.o \
)
+
+xfs-$(CONFIG_XFS_RT) += $(addprefix scrub/, \
+ rtbitmap_repair.o \
+ )
endif
endif
diff --git a/fs/xfs/scrub/repair.h b/fs/xfs/scrub/repair.h
index 5cf47388315a..43af62556352 100644
--- a/fs/xfs/scrub/repair.h
+++ b/fs/xfs/scrub/repair.h
@@ -80,6 +80,7 @@ int xrep_setup_ag_allocbt(struct xfs_scrub *sc);
struct xfs_imap;
int xrep_setup_inode(struct xfs_scrub *sc, struct xfs_imap *imap);
+int xrep_setup_rtbitmap(struct xfs_scrub *sc, unsigned int *resblks);
void xrep_ag_btcur_init(struct xfs_scrub *sc, struct xchk_ag *sa);
int xrep_ag_init(struct xfs_scrub *sc, struct xfs_perag *pag,
@@ -105,6 +106,12 @@ int xrep_bmap_data(struct xfs_scrub *sc);
int xrep_bmap_attr(struct xfs_scrub *sc);
int xrep_bmap_cow(struct xfs_scrub *sc);
+#ifdef CONFIG_XFS_RT
+int xrep_rtbitmap(struct xfs_scrub *sc);
+#else
+# define xrep_rtbitmap xrep_notsupported
+#endif /* CONFIG_XFS_RT */
+
int xrep_reinit_pagf(struct xfs_scrub *sc);
int xrep_reinit_pagi(struct xfs_scrub *sc);
@@ -150,6 +157,11 @@ xrep_setup_nothing(
#define xrep_setup_inode(sc, imap) ((void)0)
+static inline int xrep_setup_rtbitmap(struct xfs_scrub *sc, unsigned int *x)
+{
+ return 0;
+}
+
#define xrep_revalidate_allocbt (NULL)
#define xrep_revalidate_iallocbt (NULL)
@@ -165,6 +177,7 @@ xrep_setup_nothing(
#define xrep_bmap_data xrep_notsupported
#define xrep_bmap_attr xrep_notsupported
#define xrep_bmap_cow xrep_notsupported
+#define xrep_rtbitmap xrep_notsupported
#endif /* CONFIG_XFS_ONLINE_REPAIR */
diff --git a/fs/xfs/scrub/rtbitmap.c b/fs/xfs/scrub/rtbitmap.c
index 851039588fe3..f08b6b379343 100644
--- a/fs/xfs/scrub/rtbitmap.c
+++ b/fs/xfs/scrub/rtbitmap.c
@@ -16,15 +16,23 @@
#include "xfs_bmap.h"
#include "scrub/scrub.h"
#include "scrub/common.h"
+#include "scrub/repair.h"
/* Set us up with the realtime metadata locked. */
int
xchk_setup_rtbitmap(
struct xfs_scrub *sc)
{
+ unsigned int resblks = 0;
int error;
- error = xchk_trans_alloc(sc, 0);
+ if (xchk_could_repair(sc)) {
+ error = xrep_setup_rtbitmap(sc, &resblks);
+ if (error)
+ return error;
+ }
+
+ error = xchk_trans_alloc(sc, resblks);
if (error)
return error;
diff --git a/fs/xfs/scrub/rtbitmap_repair.c b/fs/xfs/scrub/rtbitmap_repair.c
new file mode 100644
index 000000000000..c88c49b03e86
--- /dev/null
+++ b/fs/xfs/scrub/rtbitmap_repair.c
@@ -0,0 +1,56 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Copyright (C) 2022 Oracle. All Rights Reserved.
+ * Author: Darrick J. Wong <djwong@kernel.org>
+ */
+#include "xfs.h"
+#include "xfs_fs.h"
+#include "xfs_shared.h"
+#include "xfs_format.h"
+#include "xfs_trans_resv.h"
+#include "xfs_mount.h"
+#include "xfs_btree.h"
+#include "xfs_log_format.h"
+#include "xfs_trans.h"
+#include "xfs_inode.h"
+#include "xfs_bit.h"
+#include "xfs_bmap.h"
+#include "xfs_bmap_btree.h"
+#include "scrub/scrub.h"
+#include "scrub/common.h"
+#include "scrub/trace.h"
+#include "scrub/repair.h"
+#include "scrub/xfile.h"
+
+/* Set up to repair the realtime bitmap file metadata. */
+int
+xrep_setup_rtbitmap(
+ struct xfs_scrub *sc,
+ unsigned int *resblks)
+{
+ struct xfs_mount *mp = sc->mp;
+ unsigned long long blocks = 0;
+
+ /*
+ * Reserve enough blocks to write out a completely new bmbt for the
+ * bitmap file.
+ */
+ blocks = xfs_bmbt_calc_size(mp, mp->m_sb.sb_rbmblocks);
+ if (blocks > UINT_MAX)
+ return -EOPNOTSUPP;
+
+ *resblks += blocks;
+ return 0;
+}
+
+/* Repair the realtime bitmap file metadata. */
+int
+xrep_rtbitmap(
+ struct xfs_scrub *sc)
+{
+ /*
+ * The only thing we know how to fix right now is problems with the
+ * inode or its fork data.
+ */
+ return xrep_metadata_inode_forks(sc);
+}
diff --git a/fs/xfs/scrub/scrub.c b/fs/xfs/scrub/scrub.c
index 1fed319b4f7a..06da054bf9e4 100644
--- a/fs/xfs/scrub/scrub.c
+++ b/fs/xfs/scrub/scrub.c
@@ -330,7 +330,7 @@ static const struct xchk_meta_ops meta_scrub_ops[] = {
.setup = xchk_setup_rtbitmap,
.scrub = xchk_rtbitmap,
.has = xfs_has_realtime,
- .repair = xrep_notsupported,
+ .repair = xrep_rtbitmap,
},
[XFS_SCRUB_TYPE_RTSUM] = { /* realtime summary */
.type = ST_FS,