@@ -924,6 +924,18 @@ next_readbuf:
_("would clear realtime summary inode %" PRIu64 "\n"),
ino);
}
+ } else if (mp->m_sb.sb_rrmapino == ino) {
+ need_rrmapino = 1;
+
+ if (!no_modify) {
+ do_warn(
+ _("cleared realtime rmap inode %" PRIu64 "\n"),
+ ino);
+ } else {
+ do_warn(
+ _("would clear realtime rmap inode %" PRIu64 "\n"),
+ ino);
+ }
} else if (!no_modify) {
do_warn(_("cleared inode %" PRIu64 "\n"),
ino);
@@ -266,6 +266,12 @@ clear_dinode(xfs_mount_t *mp, xfs_dinode_t *dino, xfs_ino_t ino_num)
dirty = clear_dinode_core(mp, dino, ino_num);
dirty += clear_dinode_unlinked(mp, dino);
+ if (ino_num == mp->m_sb.sb_rrmapino) {
+ mp->m_sb.sb_rrmapino = NULLFSINO;
+ need_rrmapino = 1;
+ rmap_avoid_check();
+ }
+
/* and clear the forks */
if (dirty && !no_modify)
@@ -1838,6 +1844,27 @@ _("bad # of extents (%u) for realtime bitmap inode %" PRIu64 "\n"),
}
return 0;
}
+ if (lino == mp->m_sb.sb_rrmapino) {
+ if (*type != XR_INO_RTRMAP) {
+ do_warn(
+_("realtime rmap inode %" PRIu64 " has bad type 0x%x, "),
+ lino, dinode_fmt(dinoc));
+ if (!no_modify) {
+ do_warn(_("resetting to regular file\n"));
+ change_dinode_fmt(dinoc, S_IFREG);
+ *dirty = 1;
+ } else {
+ do_warn(_("would reset to regular file\n"));
+ }
+ }
+ if (mp->m_sb.sb_rblocks == 0 && dinoc->di_nextents != 0) {
+ do_warn(
+_("bad # of extents (%u) for realtime rmap inode %" PRIu64 "\n"),
+ be32_to_cpu(dinoc->di_nextents), lino);
+ return 1;
+ }
+ return 0;
+ }
return 0;
}
@@ -1928,6 +1955,18 @@ _("realtime summary inode %" PRIu64 " has bad size %" PRId64 " (should be %d)\n"
}
break;
+ case XR_INO_RTRMAP:
+ /*
+ * if we have no rmapbt, any inode claiming
+ * to be a real-time file is bogus
+ */
+ if (!xfs_sb_version_hasrmapbt(&mp->m_sb)) {
+ do_warn(
+_("found inode %" PRIu64 " claiming to be a rtrmapbt file, but rmapbt is disabled\n"), lino);
+ return 1;
+ }
+ break;
+
default:
break;
}
@@ -2774,6 +2813,8 @@ _("bad (negative) size %" PRId64 " on inode %" PRIu64 "\n"),
type = XR_INO_RTBITMAP;
else if (lino == mp->m_sb.sb_rsumino)
type = XR_INO_RTSUM;
+ else if (lino == mp->m_sb.sb_rrmapino)
+ type = XR_INO_RTRMAP;
else
type = XR_INO_DATA;
break;
@@ -236,6 +236,9 @@ process_sf_dir2(
} else if (lino == mp->m_sb.sb_rsumino) {
junkit = 1;
junkreason = _("realtime summary");
+ } else if (lino == mp->m_sb.sb_rrmapino) {
+ junkit = 1;
+ junkreason = _("realtime rmap");
} else if (lino == mp->m_sb.sb_uquotino) {
junkit = 1;
junkreason = _("user quota");
@@ -695,6 +698,8 @@ process_dir2_data(
clearreason = _("realtime bitmap");
} else if (ent_ino == mp->m_sb.sb_rsumino) {
clearreason = _("realtime summary");
+ } else if (ent_ino == mp->m_sb.sb_rrmapino) {
+ clearreason = _("realtime rmap");
} else if (ent_ino == mp->m_sb.sb_uquotino) {
clearreason = _("user quota");
} else if (ent_ino == mp->m_sb.sb_gquotino) {
@@ -118,6 +118,7 @@ EXTERN int need_root_dotdot;
EXTERN int need_rbmino;
EXTERN int need_rsumino;
+EXTERN int need_rrmapino;
EXTERN int lost_quotas;
EXTERN int have_uquotino;
@@ -229,6 +229,7 @@ int count_bcnt_extents(xfs_agnumber_t);
#define XR_INO_SOCK 9 /* socket */
#define XR_INO_FIFO 10 /* fifo */
#define XR_INO_MOUNTPOINT 11 /* mountpoint */
+#define XR_INO_RTRMAP 12 /* realtime rmap */
/* inode allocation tree */
@@ -62,6 +62,7 @@ phase1(xfs_mount_t *mp)
need_root_dotdot = 0;
need_rbmino = 0;
need_rsumino = 0;
+ need_rrmapino = 0;
lost_quotas = 0;
/*
@@ -3074,6 +3074,19 @@ mark_standalone_inodes(xfs_mount_t *mp)
add_inode_reached(irec, offset);
}
}
+
+ if (xfs_sb_version_hasrmapbt(&mp->m_sb) && mp->m_sb.sb_rblocks > 0) {
+ irec = find_inode_rec(mp,
+ XFS_INO_TO_AGNO(mp, mp->m_sb.sb_rrmapino),
+ XFS_INO_TO_AGINO(mp, mp->m_sb.sb_rrmapino));
+
+ offset = XFS_INO_TO_AGINO(mp, mp->m_sb.sb_rrmapino) -
+ irec->ino_startnum;
+
+ ASSERT(irec != NULL);
+
+ add_inode_reached(irec, offset);
+ }
}
static void
@@ -1035,6 +1035,7 @@ rmaps_verify_btree(
mp->m_sb.sb_rrmapino == NULLFSINO) {
do_warn(
_("garbage in sb_rrmapino, not checking realtime rmaps\n"));
+ need_rrmapino = 1;
goto err;
}
@@ -37,6 +37,7 @@ copy_sb(xfs_sb_t *source, xfs_sb_t *dest)
xfs_ino_t rootino;
xfs_ino_t rbmino;
xfs_ino_t rsumino;
+ xfs_ino_t rrmapino;
xfs_ino_t uquotino;
xfs_ino_t gquotino;
xfs_ino_t pquotino;
@@ -45,6 +46,7 @@ copy_sb(xfs_sb_t *source, xfs_sb_t *dest)
rootino = dest->sb_rootino;
rbmino = dest->sb_rbmino;
rsumino = dest->sb_rsumino;
+ rrmapino = dest->sb_rrmapino;
uquotino = dest->sb_uquotino;
gquotino = dest->sb_gquotino;
pquotino = dest->sb_pquotino;
@@ -56,6 +58,7 @@ copy_sb(xfs_sb_t *source, xfs_sb_t *dest)
dest->sb_rootino = rootino;
dest->sb_rbmino = rbmino;
dest->sb_rsumino = rsumino;
+ dest->sb_rrmapino = rrmapino;
dest->sb_uquotino = uquotino;
dest->sb_gquotino = gquotino;
dest->sb_pquotino = pquotino;
Make sure that we find the realtime rmapbt inode and mark it appropriately, just in case we find a rogue inode claiming to be an rtrmap, or just plain garbage in the superblock field. Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com> --- repair/dino_chunks.c | 12 ++++++++++++ repair/dinode.c | 41 +++++++++++++++++++++++++++++++++++++++++ repair/dir2.c | 5 +++++ repair/globals.h | 1 + repair/incore.h | 1 + repair/phase1.c | 1 + repair/phase6.c | 13 +++++++++++++ repair/rmap.c | 1 + repair/sb.c | 3 +++ 9 files changed, 78 insertions(+)