Loading fs/xfs/scrub/inode_repair.c +57 −1 Original line number Diff line number Diff line Loading @@ -38,6 +38,8 @@ #include "xfs_log_priv.h" #include "xfs_health.h" #include "xfs_symlink_remote.h" #include "xfs_rtgroup.h" #include "xfs_rtrmap_btree.h" #include "scrub/xfs_scrub.h" #include "scrub/scrub.h" #include "scrub/common.h" Loading Loading @@ -773,17 +775,71 @@ xrep_dinode_count_ag_rmaps( return error; } /* Count extents and blocks for an inode given an rt rmap. */ STATIC int xrep_dinode_walk_rtrmap( struct xfs_btree_cur *cur, const struct xfs_rmap_irec *rec, void *priv) { struct xrep_inode *ri = priv; int error = 0; if (xchk_should_terminate(ri->sc, &error)) return error; /* We only care about this inode. */ if (rec->rm_owner != ri->sc->sm->sm_ino) return 0; if (rec->rm_flags & (XFS_RMAP_ATTR_FORK | XFS_RMAP_BMBT_BLOCK)) return -EFSCORRUPTED; ri->rt_blocks += rec->rm_blockcount; ri->rt_extents++; return 0; } /* Count extents and blocks for an inode from all realtime rmap data. */ STATIC int xrep_dinode_count_rtgroup_rmaps( struct xrep_inode *ri, struct xfs_rtgroup *rtg) { struct xfs_scrub *sc = ri->sc; int error; error = xrep_rtgroup_init(sc, rtg, &sc->sr, XFS_RTGLOCK_RMAP); if (error) return error; error = xfs_rmap_query_all(sc->sr.rmap_cur, xrep_dinode_walk_rtrmap, ri); xchk_rtgroup_btcur_free(&sc->sr); xchk_rtgroup_free(sc, &sc->sr); return error; } /* Count extents and blocks for a given inode from all rmap data. */ STATIC int xrep_dinode_count_rmaps( struct xrep_inode *ri) { struct xfs_perag *pag = NULL; struct xfs_rtgroup *rtg = NULL; int error; if (!xfs_has_rmapbt(ri->sc->mp) || xfs_has_realtime(ri->sc->mp)) if (!xfs_has_rmapbt(ri->sc->mp)) return -EOPNOTSUPP; while ((rtg = xfs_rtgroup_next(ri->sc->mp, rtg))) { error = xrep_dinode_count_rtgroup_rmaps(ri, rtg); if (error) { xfs_rtgroup_rele(rtg); return error; } } while ((pag = xfs_perag_next(ri->sc->mp, pag))) { error = xrep_dinode_count_ag_rmaps(ri, pag); if (error) { Loading Loading
fs/xfs/scrub/inode_repair.c +57 −1 Original line number Diff line number Diff line Loading @@ -38,6 +38,8 @@ #include "xfs_log_priv.h" #include "xfs_health.h" #include "xfs_symlink_remote.h" #include "xfs_rtgroup.h" #include "xfs_rtrmap_btree.h" #include "scrub/xfs_scrub.h" #include "scrub/scrub.h" #include "scrub/common.h" Loading Loading @@ -773,17 +775,71 @@ xrep_dinode_count_ag_rmaps( return error; } /* Count extents and blocks for an inode given an rt rmap. */ STATIC int xrep_dinode_walk_rtrmap( struct xfs_btree_cur *cur, const struct xfs_rmap_irec *rec, void *priv) { struct xrep_inode *ri = priv; int error = 0; if (xchk_should_terminate(ri->sc, &error)) return error; /* We only care about this inode. */ if (rec->rm_owner != ri->sc->sm->sm_ino) return 0; if (rec->rm_flags & (XFS_RMAP_ATTR_FORK | XFS_RMAP_BMBT_BLOCK)) return -EFSCORRUPTED; ri->rt_blocks += rec->rm_blockcount; ri->rt_extents++; return 0; } /* Count extents and blocks for an inode from all realtime rmap data. */ STATIC int xrep_dinode_count_rtgroup_rmaps( struct xrep_inode *ri, struct xfs_rtgroup *rtg) { struct xfs_scrub *sc = ri->sc; int error; error = xrep_rtgroup_init(sc, rtg, &sc->sr, XFS_RTGLOCK_RMAP); if (error) return error; error = xfs_rmap_query_all(sc->sr.rmap_cur, xrep_dinode_walk_rtrmap, ri); xchk_rtgroup_btcur_free(&sc->sr); xchk_rtgroup_free(sc, &sc->sr); return error; } /* Count extents and blocks for a given inode from all rmap data. */ STATIC int xrep_dinode_count_rmaps( struct xrep_inode *ri) { struct xfs_perag *pag = NULL; struct xfs_rtgroup *rtg = NULL; int error; if (!xfs_has_rmapbt(ri->sc->mp) || xfs_has_realtime(ri->sc->mp)) if (!xfs_has_rmapbt(ri->sc->mp)) return -EOPNOTSUPP; while ((rtg = xfs_rtgroup_next(ri->sc->mp, rtg))) { error = xrep_dinode_count_rtgroup_rmaps(ri, rtg); if (error) { xfs_rtgroup_rele(rtg); return error; } } while ((pag = xfs_perag_next(ri->sc->mp, pag))) { error = xrep_dinode_count_ag_rmaps(ri, pag); if (error) { Loading