Message ID | 159353170100.2864648.5747092047346568608.stgit@magnolia (mailing list archive) |
---|---|
State | Accepted, archived |
Headers | show |
Series | xfs: strengthen online checking | expand |
On 6/30/20 8:41 AM, Darrick J. Wong wrote: > From: Darrick J. Wong <darrick.wong@oracle.com> > > Ensure that the realtime bitmap file is backed entirely by written > extents. No holes, no unwritten blocks, etc. > > Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com> Ok, makes sense to me Reviewed-by: Allison Collins <allison.henderson@oracle.com> > --- > fs/xfs/scrub/rtbitmap.c | 40 ++++++++++++++++++++++++++++++++++++++++ > 1 file changed, 40 insertions(+) > > > diff --git a/fs/xfs/scrub/rtbitmap.c b/fs/xfs/scrub/rtbitmap.c > index c642bc206c41..c777c98c50c3 100644 > --- a/fs/xfs/scrub/rtbitmap.c > +++ b/fs/xfs/scrub/rtbitmap.c > @@ -13,6 +13,7 @@ > #include "xfs_trans.h" > #include "xfs_rtalloc.h" > #include "xfs_inode.h" > +#include "xfs_bmap.h" > #include "scrub/scrub.h" > #include "scrub/common.h" > > @@ -58,6 +59,41 @@ xchk_rtbitmap_rec( > return 0; > } > > +/* Make sure the entire rtbitmap file is mapped with written extents. */ > +STATIC int > +xchk_rtbitmap_check_extents( > + struct xfs_scrub *sc) > +{ > + struct xfs_mount *mp = sc->mp; > + struct xfs_bmbt_irec map; > + xfs_rtblock_t off; > + int nmap; > + int error = 0; > + > + for (off = 0; off < mp->m_sb.sb_rbmblocks;) { > + if (xchk_should_terminate(sc, &error) || > + (sc->sm->sm_flags & XFS_SCRUB_OFLAG_CORRUPT)) > + break; > + > + /* Make sure we have a written extent. */ > + nmap = 1; > + error = xfs_bmapi_read(mp->m_rbmip, off, > + mp->m_sb.sb_rbmblocks - off, &map, &nmap, > + XFS_DATA_FORK); > + if (!xchk_fblock_process_error(sc, XFS_DATA_FORK, off, &error)) > + break; > + > + if (nmap != 1 || !xfs_bmap_is_written_extent(&map)) { > + xchk_fblock_set_corrupt(sc, XFS_DATA_FORK, off); > + break; > + } > + > + off += map.br_blockcount; > + } > + > + return error; > +} > + > /* Scrub the realtime bitmap. */ > int > xchk_rtbitmap( > @@ -70,6 +106,10 @@ xchk_rtbitmap( > if (error || (sc->sm->sm_flags & XFS_SCRUB_OFLAG_CORRUPT)) > return error; > > + error = xchk_rtbitmap_check_extents(sc); > + if (error || (sc->sm->sm_flags & XFS_SCRUB_OFLAG_CORRUPT)) > + return error; > + > error = xfs_rtalloc_query_all(sc->tp, xchk_rtbitmap_rec, sc); > if (!xchk_fblock_process_error(sc, XFS_DATA_FORK, 0, &error)) > goto out; >
diff --git a/fs/xfs/scrub/rtbitmap.c b/fs/xfs/scrub/rtbitmap.c index c642bc206c41..c777c98c50c3 100644 --- a/fs/xfs/scrub/rtbitmap.c +++ b/fs/xfs/scrub/rtbitmap.c @@ -13,6 +13,7 @@ #include "xfs_trans.h" #include "xfs_rtalloc.h" #include "xfs_inode.h" +#include "xfs_bmap.h" #include "scrub/scrub.h" #include "scrub/common.h" @@ -58,6 +59,41 @@ xchk_rtbitmap_rec( return 0; } +/* Make sure the entire rtbitmap file is mapped with written extents. */ +STATIC int +xchk_rtbitmap_check_extents( + struct xfs_scrub *sc) +{ + struct xfs_mount *mp = sc->mp; + struct xfs_bmbt_irec map; + xfs_rtblock_t off; + int nmap; + int error = 0; + + for (off = 0; off < mp->m_sb.sb_rbmblocks;) { + if (xchk_should_terminate(sc, &error) || + (sc->sm->sm_flags & XFS_SCRUB_OFLAG_CORRUPT)) + break; + + /* Make sure we have a written extent. */ + nmap = 1; + error = xfs_bmapi_read(mp->m_rbmip, off, + mp->m_sb.sb_rbmblocks - off, &map, &nmap, + XFS_DATA_FORK); + if (!xchk_fblock_process_error(sc, XFS_DATA_FORK, off, &error)) + break; + + if (nmap != 1 || !xfs_bmap_is_written_extent(&map)) { + xchk_fblock_set_corrupt(sc, XFS_DATA_FORK, off); + break; + } + + off += map.br_blockcount; + } + + return error; +} + /* Scrub the realtime bitmap. */ int xchk_rtbitmap( @@ -70,6 +106,10 @@ xchk_rtbitmap( if (error || (sc->sm->sm_flags & XFS_SCRUB_OFLAG_CORRUPT)) return error; + error = xchk_rtbitmap_check_extents(sc); + if (error || (sc->sm->sm_flags & XFS_SCRUB_OFLAG_CORRUPT)) + return error; + error = xfs_rtalloc_query_all(sc->tp, xchk_rtbitmap_rec, sc); if (!xchk_fblock_process_error(sc, XFS_DATA_FORK, 0, &error)) goto out;