]> git.ipfire.org Git - thirdparty/xfsprogs-dev.git/commitdiff
xfs_repair: check the rt bitmap against observations
authorDarrick J. Wong <djwong@kernel.org>
Wed, 13 Jul 2022 22:20:56 +0000 (17:20 -0500)
committerEric Sandeen <sandeen@sandeen.net>
Wed, 13 Jul 2022 22:20:56 +0000 (17:20 -0500)
Teach xfs_repair to check the ondisk realtime bitmap against its own
observations.

Signed-off-by: Darrick J. Wong <djwong@kernel.org>
Reviewed-by: Christoph Hellwig <hch@lst.de>
Reviewed-by: Chandan Babu R <chandan.babu@oracle.com>
Signed-off-by: Eric Sandeen <sandeen@sandeen.net>
repair/phase5.c
repair/rt.c
repair/rt.h

index 273f51a8c3209d2612b660044147cf4c3294e2b2..d1ddd22481f8f8533c9e60dbed19558cf77f4a9b 100644 (file)
@@ -608,6 +608,7 @@ check_rtmetadata(
 {
        rtinit(mp);
        generate_rtinfo(mp, btmcompute, sumcompute);
+       check_rtbitmap(mp);
 }
 
 void
index 3a065f4b98ef18070be7428173712b5bf03649b8..b964d168a2367b4967a84b048074aa7f70ffa486 100644 (file)
@@ -119,6 +119,85 @@ generate_rtinfo(xfs_mount_t        *mp,
        return(0);
 }
 
+static void
+check_rtfile_contents(
+       struct xfs_mount        *mp,
+       const char              *filename,
+       xfs_ino_t               ino,
+       void                    *buf,
+       xfs_fileoff_t           filelen)
+{
+       struct xfs_bmbt_irec    map;
+       struct xfs_buf          *bp;
+       struct xfs_inode        *ip;
+       xfs_fileoff_t           bno = 0;
+       int                     error;
+
+       error = -libxfs_iget(mp, NULL, ino, 0, &ip);
+       if (error) {
+               do_warn(_("unable to open %s file, err %d\n"), filename, error);
+               return;
+       }
+
+       if (ip->i_disk_size != XFS_FSB_TO_B(mp, filelen)) {
+               do_warn(_("expected %s file size %llu, found %llu\n"),
+                               filename,
+                               (unsigned long long)XFS_FSB_TO_B(mp, filelen),
+                               (unsigned long long)ip->i_disk_size);
+       }
+
+       while (bno < filelen)  {
+               xfs_filblks_t   maplen;
+               int             nmap = 1;
+
+               /* Read up to 1MB at a time. */
+               maplen = min(filelen - bno, XFS_B_TO_FSBT(mp, 1048576));
+               error = -libxfs_bmapi_read(ip, bno, maplen, &map, &nmap, 0);
+               if (error) {
+                       do_warn(_("unable to read %s mapping, err %d\n"),
+                                       filename, error);
+                       break;
+               }
+
+               if (map.br_startblock == HOLESTARTBLOCK) {
+                       do_warn(_("hole in %s file at dblock 0x%llx\n"),
+                                       filename, (unsigned long long)bno);
+                       break;
+               }
+
+               error = -libxfs_buf_read_uncached(mp->m_dev,
+                               XFS_FSB_TO_DADDR(mp, map.br_startblock),
+                               XFS_FSB_TO_BB(mp, map.br_blockcount),
+                               0, &bp, NULL);
+               if (error) {
+                       do_warn(_("unable to read %s at dblock 0x%llx, err %d\n"),
+                                       filename, (unsigned long long)bno, error);
+                       break;
+               }
+
+               if (memcmp(bp->b_addr, buf, mp->m_sb.sb_blocksize))
+                       do_warn(_("discrepancy in %s at dblock 0x%llx\n"),
+                                       filename, (unsigned long long)bno);
+
+               buf += XFS_FSB_TO_B(mp, map.br_blockcount);
+               bno += map.br_blockcount;
+               libxfs_buf_relse(bp);
+       }
+
+       libxfs_irele(ip);
+}
+
+void
+check_rtbitmap(
+       struct xfs_mount        *mp)
+{
+       if (need_rbmino)
+               return;
+
+       check_rtfile_contents(mp, "rtbitmap", mp->m_sb.sb_rbmino, btmcompute,
+                       mp->m_sb.sb_rbmblocks);
+}
+
 #if 0
 /*
  * returns 1 if bad, 0 if good
@@ -151,95 +230,6 @@ check_summary(xfs_mount_t *mp)
        return(error);
 }
 
-/*
- * examine the real-time bitmap file and compute summary
- * info off it.  Should probably be changed to compute
- * the summary information off the incore computed bitmap
- * instead of the realtime bitmap file
- */
-void
-process_rtbitmap(
-       struct xfs_mount        *mp,
-       struct xfs_dinode       *dino,
-       blkmap_t                *blkmap)
-{
-       int                     error;
-       int                     bit;
-       int                     bitsperblock;
-       int                     bmbno;
-       int                     end_bmbno;
-       xfs_fsblock_t           bno;
-       struct xfs_buf          *bp;
-       xfs_rtblock_t           extno;
-       int                     i;
-       int                     len;
-       int                     log;
-       int                     offs;
-       int                     prevbit;
-       int                     start_bmbno;
-       int                     start_bit;
-       xfs_rtword_t            *words;
-
-       ASSERT(mp->m_rbmip == NULL);
-
-       bitsperblock = mp->m_sb.sb_blocksize * NBBY;
-       prevbit = 0;
-       extno = 0;
-       error = 0;
-
-       end_bmbno = howmany(be64_to_cpu(dino->di_size),
-                                               mp->m_sb.sb_blocksize);
-
-       for (bmbno = 0; bmbno < end_bmbno; bmbno++) {
-               bno = blkmap_get(blkmap, bmbno);
-
-               if (bno == NULLFSBLOCK) {
-                       do_warn(_("can't find block %d for rtbitmap inode\n"),
-                                       bmbno);
-                       error = 1;
-                       continue;
-               }
-               error = -libxfs_buf_read(mp->m_dev, XFS_FSB_TO_DADDR(mp, bno),
-                               XFS_FSB_TO_BB(mp, 1), 0, NULL, &bp);
-               if (error) {
-                       do_warn(_("can't read block %d for rtbitmap inode\n"),
-                                       bmbno);
-                       error = 1;
-                       continue;
-               }
-               words = (xfs_rtword_t *)bp->b_un.b_addr;
-               for (bit = 0;
-                    bit < bitsperblock && extno < mp->m_sb.sb_rextents;
-                    bit++, extno++) {
-                       if (xfs_isset(words, bit)) {
-                               set_rtbmap(extno, XR_E_FREE);
-                               sb_frextents++;
-                               if (prevbit == 0) {
-                                       start_bmbno = bmbno;
-                                       start_bit = bit;
-                                       prevbit = 1;
-                               }
-                       } else if (prevbit == 1) {
-                               len = (bmbno - start_bmbno) * bitsperblock +
-                                       (bit - start_bit);
-                               log = XFS_RTBLOCKLOG(len);
-                               offs = XFS_SUMOFFS(mp, log, start_bmbno);
-                               sumcompute[offs]++;
-                               prevbit = 0;
-                       }
-               }
-               libxfs_buf_relse(bp);
-               if (extno == mp->m_sb.sb_rextents)
-                       break;
-       }
-       if (prevbit == 1) {
-               len = (bmbno - start_bmbno) * bitsperblock + (bit - start_bit);
-               log = XFS_RTBLOCKLOG(len);
-               offs = XFS_SUMOFFS(mp, log, start_bmbno);
-               sumcompute[offs]++;
-       }
-}
-
 /*
  * copy the real-time summary file data into memory
  */
index f5d8f80c81e2052816f5437f1d18057a09cf943e..2023153f65cdf091ed6f93eea75e42c90f5c9e65 100644 (file)
@@ -3,6 +3,8 @@
  * Copyright (c) 2000-2001,2005 Silicon Graphics, Inc.
  * All Rights Reserved.
  */
+#ifndef _XFS_REPAIR_RT_H_
+#define _XFS_REPAIR_RT_H_
 
 struct blkmap;
 
@@ -14,17 +16,16 @@ generate_rtinfo(xfs_mount_t *mp,
                xfs_rtword_t    *words,
                xfs_suminfo_t   *sumcompute);
 
+void check_rtbitmap(struct xfs_mount *mp);
+
 #if 0
 
 int
 check_summary(xfs_mount_t      *mp);
 
-void
-process_rtbitmap(xfs_mount_t           *mp,
-               struct xfs_dinode       *dino,
-               struct blkmap           *blkmap);
-
 void
 process_rtsummary(xfs_mount_t  *mp,
                struct blkmap   *blkmap);
 #endif
+
+#endif /* _XFS_REPAIR_RT_H_ */