]> www.infradead.org Git - users/hch/xfs.git/commitdiff
xfs: scrub the metadir path of rt rmap btree files
authorDarrick J. Wong <djwong@kernel.org>
Wed, 29 May 2024 04:12:54 +0000 (21:12 -0700)
committerChristoph Hellwig <hch@lst.de>
Sun, 11 Aug 2024 06:28:33 +0000 (08:28 +0200)
Add a new XFS_SCRUB_METAPATH subtype so that we can scrub the metadata
directory tree path to the rmap btree file for each rt group.

Signed-off-by: Darrick J. Wong <djwong@kernel.org>
fs/xfs/libxfs/xfs_fs.h
fs/xfs/scrub/metapath.c

index e6ec09fe3a9a47216652e9b6cbc1eb8e25c1dd8a..09f350b3556243c3769497cba1614105f55173ee 100644 (file)
@@ -823,9 +823,11 @@ struct xfs_scrub_vec_head {
  * path checking.
  */
 #define XFS_SCRUB_METAPATH_PROBE       (0)  /* do we have a metapath scrubber? */
+#define XFS_SCRUB_METAPATH_RTDIR       (1)  /* realtime metadir */
+#define XFS_SCRUB_METAPATH_RTRMAPBT    (2)  /* realtime reverse mapping */
 
 /* Number of metapath sm_ino values */
-#define XFS_SCRUB_METAPATH_NR          1
+#define XFS_SCRUB_METAPATH_NR          (3)
 
 /*
  * ioctl limits
index edc1a395c4015a75ab384ac3ba7087636640511b..f8d108e5abd1b8b721245a9271181b193457579c 100644 (file)
@@ -20,6 +20,8 @@
 #include "xfs_bmap_btree.h"
 #include "xfs_trans_space.h"
 #include "xfs_attr.h"
+#include "xfs_rtgroup.h"
+#include "xfs_rtrmap_btree.h"
 #include "scrub/scrub.h"
 #include "scrub/common.h"
 #include "scrub/trace.h"
@@ -79,6 +81,87 @@ xchk_metapath_cleanup(
        kfree(mpath->path);
 }
 
+static inline int
+xchk_setup_metapath_scan(
+       struct xfs_scrub        *sc,
+       struct xfs_inode        *dp,
+       const char              *path,
+       struct xfs_inode        *ip)
+{
+       struct xchk_metapath    *mpath;
+       int                     error;
+
+       /* The path string can be dynamically allocated. */
+       if (!path)
+               return -ENOMEM;
+
+       error = xchk_install_live_inode(sc, ip);
+       if (error)
+               return error;
+
+       mpath = kzalloc(sizeof(struct xchk_metapath), XCHK_GFP_FLAGS);
+       if (!mpath)
+               return -ENOMEM;
+
+       mpath->sc = sc;
+       sc->buf = mpath;
+       sc->buf_cleanup = xchk_metapath_cleanup;
+
+       mpath->dp = dp;
+       mpath->path = path;
+
+       mpath->xname.name = mpath->path;
+       mpath->xname.len = strlen(mpath->path);
+       mpath->xname.type = xfs_mode_to_ftype(VFS_I(ip)->i_mode);
+
+       return 0;
+}
+
+#ifdef CONFIG_XFS_RT
+/* Scan the /rtgroups directory itself. */
+static int
+xchk_setup_metapath_rtdir(
+       struct xfs_scrub        *sc)
+{
+       if (!sc->mp->m_rtdirip)
+               return -ENOENT;
+
+       return xchk_setup_metapath_scan(sc, sc->mp->m_metadirip,
+                       kasprintf(GFP_KERNEL, "rtgroups"), sc->mp->m_rtdirip);
+}
+
+/* Scan a rtgroup inode under the /rtgroups directory. */
+static int
+xchk_setup_metapath_rtginode(
+       struct xfs_scrub        *sc,
+       enum xfs_rtg_inodes     type)
+{
+       struct xfs_rtgroup      *rtg;
+       struct xfs_inode        *ip;
+       int                     error;
+
+       rtg = xfs_rtgroup_get(sc->mp, sc->sm->sm_agno);
+       if (!rtg)
+               return -ENOENT;
+
+       ip = rtg->rtg_inodes[type];
+       if (!ip) {
+               error = -ENOENT;
+               goto out_put_rtg;
+       }
+
+       error = xchk_setup_metapath_scan(sc, sc->mp->m_rtdirip,
+                       xfs_rtginode_path(rtg->rtg_rgno, type), ip);
+
+out_put_rtg:
+       xfs_rtgroup_put(rtg);
+       return error;
+}
+#else
+# define xchk_setup_metapath_rtdir(...)                (-ENOENT)
+# define xchk_setup_metapath_rtginode(...)     (-ENOENT)
+#endif /* CONFIG_XFS_RT */
+
 int
 xchk_setup_metapath(
        struct xfs_scrub        *sc)
@@ -94,6 +177,10 @@ xchk_setup_metapath(
                if (sc->sm->sm_agno)
                        return -EINVAL;
                return 0;
+       case XFS_SCRUB_METAPATH_RTDIR:
+               return xchk_setup_metapath_rtdir(sc);
+       case XFS_SCRUB_METAPATH_RTRMAPBT:
+               return xchk_setup_metapath_rtginode(sc, XFS_RTG_RMAP);
        default:
                return -ENOENT;
        }