aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDarrick J. Wong <djwong@kernel.org>2022-07-13 17:20:56 -0500
committerEric Sandeen <sandeen@sandeen.net>2022-07-13 17:20:56 -0500
commit9d454cca0503d39eebc7944c0c22758bf2c1e741 (patch)
tree8d728ff7733004ba2df6fbe51663a7cb007719a4
parentf2e388616d7491254e410571d7e54e5e94bf07f0 (diff)
downloadxfsprogs-dev-9d454cca0503d39eebc7944c0c22758bf2c1e741.tar.gz
xfs_repair: check the rt bitmap against observations
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>
-rw-r--r--repair/phase5.c1
-rw-r--r--repair/rt.c168
-rw-r--r--repair/rt.h11
3 files changed, 86 insertions, 94 deletions
diff --git a/repair/phase5.c b/repair/phase5.c
index 273f51a8c3..d1ddd22481 100644
--- a/repair/phase5.c
+++ b/repair/phase5.c
@@ -608,6 +608,7 @@ check_rtmetadata(
{
rtinit(mp);
generate_rtinfo(mp, btmcompute, sumcompute);
+ check_rtbitmap(mp);
}
void
diff --git a/repair/rt.c b/repair/rt.c
index 3a065f4b98..b964d168a2 100644
--- a/repair/rt.c
+++ b/repair/rt.c
@@ -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
@@ -152,95 +231,6 @@ check_summary(xfs_mount_t *mp)
}
/*
- * 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
*/
void
diff --git a/repair/rt.h b/repair/rt.h
index f5d8f80c81..2023153f65 100644
--- a/repair/rt.h
+++ b/repair/rt.h
@@ -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_ */