]> www.infradead.org Git - users/hch/xfs.git/commitdiff
xfs: move metadata health tracking to the generic group structure
authorChristoph Hellwig <hch@lst.de>
Fri, 20 Sep 2024 13:40:20 +0000 (15:40 +0200)
committerChristoph Hellwig <hch@lst.de>
Sun, 22 Sep 2024 05:37:31 +0000 (07:37 +0200)
Prepare for also tracking the health status of the upcoming realtime
groups by moving the health tracking code to the generic xfs_group
structure.

Signed-off-by: Christoph Hellwig <hch@lst.de>
fs/xfs/libxfs/xfs_ag.c
fs/xfs/libxfs/xfs_ag.h
fs/xfs/libxfs/xfs_group.c
fs/xfs/libxfs/xfs_group.h
fs/xfs/libxfs/xfs_health.h
fs/xfs/scrub/health.c
fs/xfs/xfs_health.c
fs/xfs/xfs_trace.h

index 93c8f87aaefcef90f1425ffecba9121dd2998d19..a4f5aacf575a8ee7224fd5758bf0e93c5c501d97 100644 (file)
@@ -209,7 +209,6 @@ xfs_perag_alloc(
        /* Place kernel structure only init below this point. */
        spin_lock_init(&pag->pag_ici_lock);
        spin_lock_init(&pag->pagb_lock);
-       spin_lock_init(&pag->pag_state_lock);
        INIT_DELAYED_WORK(&pag->pag_blockgc_work, xfs_blockgc_worker);
        INIT_RADIX_TREE(&pag->pag_ici_root, GFP_ATOMIC);
        xfs_defer_drain_init(&pag->pag_intents_drain);
index 5e1f2c59740ddb45423c233f34deb19538391333..d95af53e10d7e9ed5118e0facf4d3b5e1986b7fe 100644 (file)
@@ -69,13 +69,6 @@ struct xfs_perag {
 #ifdef __KERNEL__
        /* -- kernel only structures below this line -- */
 
-       /*
-        * Bitsets of per-ag metadata that have been checked and/or are sick.
-        * Callers should hold pag_state_lock before accessing this field.
-        */
-       uint16_t        pag_checked;
-       uint16_t        pag_sick;
-
 #ifdef CONFIG_XFS_ONLINE_REPAIR
        /*
         * Alternate btree heights so that online repair won't trip the write
@@ -87,8 +80,6 @@ struct xfs_perag {
        uint8_t         pagf_repair_rmap_level;
 #endif
 
-       spinlock_t      pag_state_lock;
-
        spinlock_t      pagb_lock;      /* lock for pagb_tree */
        struct rb_root  pagb_tree;      /* ordered tree of busy extents */
        unsigned int    pagb_gen;       /* generation count for pagb_tree */
index 9b2fb5285c7eaa6d492121d95f000cd1e42f7c6f..a68477639fd025f255bc9ed9ac3e82c64d5a6773 100644 (file)
@@ -182,6 +182,10 @@ xfs_group_insert(
        xg->xg_index = index;
        xg->xg_type = type;
 
+#ifdef __KERNEL__
+       spin_lock_init(&xg->xg_state_lock);
+#endif
+
        /* Active ref owned by mount indicates group is online. */
        atomic_set(&xg->xg_active_ref, 1);
 
index 8c4169520c6c7a2cf33a1663ea0ed444f01d5118..93b247dd12c4308b4031a74d26588aedeae389f9 100644 (file)
@@ -11,6 +11,18 @@ struct xfs_group {
        enum xfs_group_type     xg_type;
        atomic_t                xg_ref;         /* passive reference count */
        atomic_t                xg_active_ref;  /* active reference count */
+
+#ifdef __KERNEL__
+       /* -- kernel only structures below this line -- */
+
+       /*
+        * Bitsets of per-ag metadata that have been checked and/or are sick.
+        * Callers should hold xg_state_lock before accessing this field.
+        */
+       uint16_t                xg_checked;
+       uint16_t                xg_sick;
+       spinlock_t              xg_state_lock;
+#endif /* __KERNEL__ */
 };
 
 struct xfs_group *xfs_group_get(struct xfs_mount *mp, uint32_t index,
index b0edb4288e59297ea5a6a54c67da1d70ea471d0c..9443b703d837a9361b39d8035a4be168acf4440c 100644 (file)
@@ -6,6 +6,8 @@
 #ifndef __XFS_HEALTH_H__
 #define __XFS_HEALTH_H__
 
+struct xfs_group;
+
 /*
  * In-Core Filesystem Health Assessments
  * =====================================
@@ -197,10 +199,12 @@ void xfs_rt_measure_sickness(struct xfs_mount *mp, unsigned int *sick,
 
 void xfs_agno_mark_sick(struct xfs_mount *mp, xfs_agnumber_t agno,
                unsigned int mask);
-void xfs_ag_mark_sick(struct xfs_perag *pag, unsigned int mask);
-void xfs_ag_mark_corrupt(struct xfs_perag *pag, unsigned int mask);
-void xfs_ag_mark_healthy(struct xfs_perag *pag, unsigned int mask);
-void xfs_ag_measure_sickness(struct xfs_perag *pag, unsigned int *sick,
+void xfs_group_mark_sick(struct xfs_group *xg, unsigned int mask);
+#define xfs_ag_mark_sick(pag, mask) \
+       xfs_group_mark_sick(&(pag)->pag_group, (mask))
+void xfs_group_mark_corrupt(struct xfs_group *xg, unsigned int mask);
+void xfs_group_mark_healthy(struct xfs_group *xg, unsigned int mask);
+void xfs_group_measure_sickness(struct xfs_group *xg, unsigned int *sick,
                unsigned int *checked);
 
 void xfs_inode_mark_sick(struct xfs_inode *ip, unsigned int mask);
@@ -227,22 +231,19 @@ xfs_fs_has_sickness(struct xfs_mount *mp, unsigned int mask)
 }
 
 static inline bool
-xfs_rt_has_sickness(struct xfs_mount *mp, unsigned int mask)
+xfs_group_has_sickness(
+       struct xfs_group        *xg,
+       unsigned int            mask)
 {
-       unsigned int    sick, checked;
-
-       xfs_rt_measure_sickness(mp, &sick, &checked);
-       return sick & mask;
-}
-
-static inline bool
-xfs_ag_has_sickness(struct xfs_perag *pag, unsigned int mask)
-{
-       unsigned int    sick, checked;
+       unsigned int            sick, checked;
 
-       xfs_ag_measure_sickness(pag, &sick, &checked);
+       xfs_group_measure_sickness(xg, &sick, &checked);
        return sick & mask;
 }
+#define xfs_ag_has_sickness(pag, mask) \
+       xfs_group_has_sickness(&(pag)->pag_group, (mask))
+#define xfs_ag_is_healthy(pag) \
+       (!xfs_ag_has_sickness((pag), UINT_MAX))
 
 static inline bool
 xfs_inode_has_sickness(struct xfs_inode *ip, unsigned int mask)
@@ -259,18 +260,6 @@ xfs_fs_is_healthy(struct xfs_mount *mp)
        return !xfs_fs_has_sickness(mp, -1U);
 }
 
-static inline bool
-xfs_rt_is_healthy(struct xfs_mount *mp)
-{
-       return !xfs_rt_has_sickness(mp, -1U);
-}
-
-static inline bool
-xfs_ag_is_healthy(struct xfs_perag *pag)
-{
-       return !xfs_ag_has_sickness(pag, -1U);
-}
-
 static inline bool
 xfs_inode_is_healthy(struct xfs_inode *ip)
 {
index 112dd05e5551d3c1e39630f2ca3a36af56c98408..9afe630c4b1ee6f21d5696ee7a2fddbaf5ac914a 100644 (file)
@@ -165,7 +165,7 @@ xchk_mark_all_healthy(
        xfs_fs_mark_healthy(mp, XFS_SICK_FS_INDIRECT);
        xfs_rt_mark_healthy(mp, XFS_SICK_RT_INDIRECT);
        while ((pag = xfs_perag_next(mp, pag)))
-               xfs_ag_mark_healthy(pag, XFS_SICK_AG_INDIRECT);
+               xfs_group_mark_healthy(&pag->pag_group, XFS_SICK_AG_INDIRECT);
 }
 
 /*
@@ -206,9 +206,9 @@ xchk_update_health(
        case XHG_AG:
                pag = xfs_perag_get(sc->mp, sc->sm->sm_agno);
                if (bad)
-                       xfs_ag_mark_corrupt(pag, sc->sick_mask);
+                       xfs_group_mark_corrupt(&pag->pag_group, sc->sick_mask);
                else
-                       xfs_ag_mark_healthy(pag, sc->sick_mask);
+                       xfs_group_mark_healthy(&pag->pag_group, sc->sick_mask);
                xfs_perag_put(pag);
                break;
        case XHG_INO:
@@ -306,7 +306,7 @@ xchk_health_record(
                xchk_set_corrupt(sc);
 
        while ((pag = xfs_perag_next(mp, pag))) {
-               xfs_ag_measure_sickness(pag, &sick, &checked);
+               xfs_group_measure_sickness(&pag->pag_group, &sick, &checked);
                if (sick & XFS_SICK_AG_PRIMARY)
                        xchk_set_corrupt(sc);
        }
index ff5aca875ab0d0cb93316dae065989c6dc02bc66..962eec51f95913417f3f56959de1effefb82d150 100644 (file)
@@ -38,9 +38,10 @@ xfs_health_unmount(
 
        /* Measure AG corruption levels. */
        while ((pag = xfs_perag_next(mp, pag))) {
-               xfs_ag_measure_sickness(pag, &sick, &checked);
+               xfs_group_measure_sickness(&pag->pag_group, &sick, &checked);
                if (sick) {
-                       trace_xfs_ag_unfixed_corruption(pag, sick);
+                       trace_xfs_group_unfixed_corruption(&pag->pag_group,
+                                       sick);
                        warn = true;
                }
        }
@@ -227,61 +228,65 @@ xfs_agno_mark_sick(
 
 /* Mark unhealthy per-ag metadata. */
 void
-xfs_ag_mark_sick(
-       struct xfs_perag        *pag,
+xfs_group_mark_sick(
+       struct xfs_group        *xg,
        unsigned int            mask)
 {
        ASSERT(!(mask & ~XFS_SICK_AG_ALL));
-       trace_xfs_ag_mark_sick(pag, mask);
+       trace_xfs_group_mark_sick(xg, mask);
 
-       spin_lock(&pag->pag_state_lock);
-       pag->pag_sick |= mask;
-       spin_unlock(&pag->pag_state_lock);
+       spin_lock(&xg->xg_state_lock);
+       xg->xg_sick |= mask;
+       spin_unlock(&xg->xg_state_lock);
 }
 
-/* Mark per-ag metadata as having been checked and found unhealthy by fsck. */
+/*
+ * Mark per-group metadata as having been checked and found unhealthy by fsck.
+ */
 void
-xfs_ag_mark_corrupt(
-       struct xfs_perag        *pag,
+xfs_group_mark_corrupt(
+       struct xfs_group        *xg,
        unsigned int            mask)
 {
        ASSERT(!(mask & ~XFS_SICK_AG_ALL));
-       trace_xfs_ag_mark_corrupt(pag, mask);
+       trace_xfs_group_mark_corrupt(xg, mask);
 
-       spin_lock(&pag->pag_state_lock);
-       pag->pag_sick |= mask;
-       pag->pag_checked |= mask;
-       spin_unlock(&pag->pag_state_lock);
+       spin_lock(&xg->xg_state_lock);
+       xg->xg_sick |= mask;
+       xg->xg_checked |= mask;
+       spin_unlock(&xg->xg_state_lock);
 }
 
-/* Mark per-ag metadata ok. */
+/*
+ * Mark per-group metadata ok.
+ */
 void
-xfs_ag_mark_healthy(
-       struct xfs_perag        *pag,
+xfs_group_mark_healthy(
+       struct xfs_group        *xg,
        unsigned int            mask)
 {
        ASSERT(!(mask & ~XFS_SICK_AG_ALL));
-       trace_xfs_ag_mark_healthy(pag, mask);
-
-       spin_lock(&pag->pag_state_lock);
-       pag->pag_sick &= ~mask;
-       if (!(pag->pag_sick & XFS_SICK_AG_PRIMARY))
-               pag->pag_sick &= ~XFS_SICK_AG_SECONDARY;
-       pag->pag_checked |= mask;
-       spin_unlock(&pag->pag_state_lock);
+       trace_xfs_group_mark_healthy(xg, mask);
+
+       spin_lock(&xg->xg_state_lock);
+       xg->xg_sick &= ~mask;
+       if (!(xg->xg_sick & XFS_SICK_AG_PRIMARY))
+               xg->xg_sick &= ~XFS_SICK_AG_SECONDARY;
+       xg->xg_checked |= mask;
+       spin_unlock(&xg->xg_state_lock);
 }
 
 /* Sample which per-ag metadata are unhealthy. */
 void
-xfs_ag_measure_sickness(
-       struct xfs_perag        *pag,
+xfs_group_measure_sickness(
+       struct xfs_group        *xg,
        unsigned int            *sick,
        unsigned int            *checked)
 {
-       spin_lock(&pag->pag_state_lock);
-       *sick = pag->pag_sick;
-       *checked = pag->pag_checked;
-       spin_unlock(&pag->pag_state_lock);
+       spin_lock(&xg->xg_state_lock);
+       *sick = xg->xg_sick;
+       *checked = xg->xg_checked;
+       spin_unlock(&xg->xg_state_lock);
 }
 
 /* Mark the unhealthy parts of an inode. */
@@ -447,7 +452,7 @@ xfs_ag_geom_health(
        ageo->ag_sick = 0;
        ageo->ag_checked = 0;
 
-       xfs_ag_measure_sickness(pag, &sick, &checked);
+       xfs_group_measure_sickness(&pag->pag_group, &sick, &checked);
        for (m = ag_map; m->sick_mask; m++) {
                if (checked & m->sick_mask)
                        ageo->ag_checked |= m->ioctl_mask;
index b8604c4e137292f04025ba7a4df99c617b0e4f1c..ac2ec21d3486fef985a67ed0b93edf65260c1120 100644 (file)
@@ -4220,31 +4220,34 @@ DEFINE_FS_CORRUPT_EVENT(xfs_rt_mark_corrupt);
 DEFINE_FS_CORRUPT_EVENT(xfs_rt_mark_healthy);
 DEFINE_FS_CORRUPT_EVENT(xfs_rt_unfixed_corruption);
 
-DECLARE_EVENT_CLASS(xfs_ag_corrupt_class,
-       TP_PROTO(const struct xfs_perag *pag, unsigned int flags),
-       TP_ARGS(pag, flags),
+DECLARE_EVENT_CLASS(xfs_group_corrupt_class,
+       TP_PROTO(const struct xfs_group *xg, unsigned int flags),
+       TP_ARGS(xg, flags),
        TP_STRUCT__entry(
                __field(dev_t, dev)
-               __field(xfs_agnumber_t, agno)
+               __field(enum xfs_group_type, type)
+               __field(uint32_t, index)
                __field(unsigned int, flags)
        ),
        TP_fast_assign(
-               __entry->dev = pag_mount(pag)->m_super->s_dev;
-               __entry->agno = pag_agno(pag);
+               __entry->dev = xg->xg_mount->m_super->s_dev;
+               __entry->type = xg->xg_type;
+               __entry->index = xg->xg_index;
                __entry->flags = flags;
        ),
-       TP_printk("dev %d:%d agno 0x%x flags 0x%x",
+       TP_printk("dev %d:%d %sno 0x%x flags 0x%x",
                  MAJOR(__entry->dev), MINOR(__entry->dev),
-                 __entry->agno, __entry->flags)
+                 __print_symbolic(__entry->type, XG_TYPE_STRINGS),
+                 __entry->index, __entry->flags)
 );
-#define DEFINE_AG_CORRUPT_EVENT(name)  \
-DEFINE_EVENT(xfs_ag_corrupt_class, name,       \
-       TP_PROTO(const struct xfs_perag *pag, unsigned int flags), \
-       TP_ARGS(pag, flags))
-DEFINE_AG_CORRUPT_EVENT(xfs_ag_mark_sick);
-DEFINE_AG_CORRUPT_EVENT(xfs_ag_mark_corrupt);
-DEFINE_AG_CORRUPT_EVENT(xfs_ag_mark_healthy);
-DEFINE_AG_CORRUPT_EVENT(xfs_ag_unfixed_corruption);
+#define DEFINE_GROUP_CORRUPT_EVENT(name)       \
+DEFINE_EVENT(xfs_group_corrupt_class, name,    \
+       TP_PROTO(const struct xfs_group *xg, unsigned int flags), \
+       TP_ARGS(xg, flags))
+DEFINE_GROUP_CORRUPT_EVENT(xfs_group_mark_sick);
+DEFINE_GROUP_CORRUPT_EVENT(xfs_group_mark_corrupt);
+DEFINE_GROUP_CORRUPT_EVENT(xfs_group_mark_healthy);
+DEFINE_GROUP_CORRUPT_EVENT(xfs_group_unfixed_corruption);
 
 DECLARE_EVENT_CLASS(xfs_inode_corrupt_class,
        TP_PROTO(struct xfs_inode *ip, unsigned int flags),