]> www.infradead.org Git - users/hch/xfs.git/commitdiff
xfs: use a single inode fork format for metadata btree inodes xfs-meta-btree
authorChristoph Hellwig <hch@lst.de>
Tue, 12 Nov 2024 08:31:04 +0000 (09:31 +0100)
committerChristoph Hellwig <hch@lst.de>
Tue, 12 Nov 2024 09:05:03 +0000 (10:05 +0100)
And instead switch based on the metatype for the detailed btree format.

This could probably be done even nicer by sharing the same btree root
structure.

Signed-off-by: Christoph Hellwig <hch@lst.de>
18 files changed:
fs/xfs/libxfs/xfs_format.h
fs/xfs/libxfs/xfs_inode_buf.c
fs/xfs/libxfs/xfs_inode_fork.c
fs/xfs/libxfs/xfs_rtgroup.c
fs/xfs/libxfs/xfs_rtrefcount_btree.c
fs/xfs/libxfs/xfs_rtrmap_btree.c
fs/xfs/scrub/bmap.c
fs/xfs/scrub/bmap_repair.c
fs/xfs/scrub/common.c
fs/xfs/scrub/inode.c
fs/xfs/scrub/inode_repair.c
fs/xfs/scrub/rmap_repair.c
fs/xfs/scrub/rtrefcount_repair.c
fs/xfs/scrub/rtrmap_repair.c
fs/xfs/xfs_inode.c
fs/xfs/xfs_inode_item.c
fs/xfs/xfs_inode_item_recover.c
fs/xfs/xfs_trace.h

index 707d961130372bae5a5253b9a826382978d09d39..b1007fb661ba73822ea39b801937eb9823f1cf40 100644 (file)
@@ -1002,8 +1002,7 @@ enum xfs_dinode_fmt {
        XFS_DINODE_FMT_EXTENTS,         /* struct xfs_bmbt_rec */
        XFS_DINODE_FMT_BTREE,           /* struct xfs_bmdr_block */
        XFS_DINODE_FMT_UUID,            /* added long ago, but never used */
-       XFS_DINODE_FMT_RMAP,            /* reverse mapping btree */
-       XFS_DINODE_FMT_REFCOUNT,        /* reference count btree */
+       XFS_DINODE_FMT_META_BTREE,      /* metadata btree */
 };
 
 #define XFS_INODE_FORMAT_STR \
@@ -1012,8 +1011,7 @@ enum xfs_dinode_fmt {
        { XFS_DINODE_FMT_EXTENTS,       "extent" }, \
        { XFS_DINODE_FMT_BTREE,         "btree" }, \
        { XFS_DINODE_FMT_UUID,          "uuid" }, \
-       { XFS_DINODE_FMT_RMAP,          "rmap" }, \
-       { XFS_DINODE_FMT_REFCOUNT,      "refcount" }
+       { XFS_DINODE_FMT_META_BTREE,    "meta_btree" }
 
 /*
  * Max values for extnum and aextnum.
index 12e5709f8bc0090c312252f2570a8c4a40fb3083..794ed6155162cb98fe0214a84eb338355ee8078b 100644 (file)
@@ -441,20 +441,11 @@ xfs_dinode_verify_fork(
                if (di_nextents > max_extents)
                        return __this_address;
                break;
-       case XFS_DINODE_FMT_RMAP:
+       case XFS_DINODE_FMT_META_BTREE:
                /*
-                * growfs must create the rtrmap inodes before adding a
-                * realtime volume to the filesystem, so we cannot use the
-                * rtrmapbt predicate here.
+                * XXX: do we need a finer grained check here?
                 */
-               if (!xfs_has_rmapbt(mp))
-                       return __this_address;
-               if (!(dip->di_flags2 & cpu_to_be64(XFS_DIFLAG2_METADATA)))
-                       return __this_address;
-               break;
-       case XFS_DINODE_FMT_REFCOUNT:
-               /* same comment about growfs and rmap inodes applies here */
-               if (!xfs_has_reflink(mp))
+               if (!xfs_has_metadir(mp))
                        return __this_address;
                if (!(dip->di_flags2 & cpu_to_be64(XFS_DIFLAG2_METADATA)))
                        return __this_address;
@@ -478,9 +469,8 @@ xfs_dinode_verify_forkoff(
                if (dip->di_forkoff != (roundup(sizeof(xfs_dev_t), 8) >> 3))
                        return __this_address;
                break;
-       case XFS_DINODE_FMT_RMAP:
-       case XFS_DINODE_FMT_REFCOUNT:
-               if (!(xfs_has_metadir(mp) && xfs_has_parent(mp)))
+       case XFS_DINODE_FMT_META_BTREE:
+               if (!xfs_has_metadir(mp) || !xfs_has_parent(mp))
                        return __this_address;
                fallthrough;
        case XFS_DINODE_FMT_LOCAL:      /* fall through ... */
@@ -765,18 +755,10 @@ xfs_dinode_verify(
        }
 
        /* metadata inodes containing btrees always have zero extent count */
-       if (flags2 & XFS_DIFLAG2_METADATA) {
-               switch (XFS_DFORK_FORMAT(dip, XFS_DATA_FORK)) {
-               case XFS_DINODE_FMT_RMAP:
-               case XFS_DINODE_FMT_REFCOUNT:
-                       break;
-               default:
-                       if (nextents + naextents == 0 && nblocks != 0)
-                               return __this_address;
-                       break;
-               }
-       } else if (nextents + naextents == 0 && nblocks != 0)
-               return __this_address;
+       if (XFS_DFORK_FORMAT(dip, XFS_DATA_FORK) != XFS_DINODE_FMT_META_BTREE) {
+               if (nextents + naextents == 0 && nblocks != 0)
+                       return __this_address;
+       }
 
        return NULL;
 }
index 5c5deb9a77c9067b3cd6a4b1541844e885ebe230..28b0f3ec817ddd933082f4423481cabed4ba9f2d 100644 (file)
@@ -270,24 +270,16 @@ xfs_iformat_data_fork(
                        return xfs_iformat_extents(ip, dip, XFS_DATA_FORK);
                case XFS_DINODE_FMT_BTREE:
                        return xfs_iformat_btree(ip, dip, XFS_DATA_FORK);
-               case XFS_DINODE_FMT_RMAP:
-                       /*
-                        * growfs must create the rtrmap inodes before adding a
-                        * realtime volume to the filesystem, so we cannot use
-                        * the rtrmapbt predicate here.
-                        */
-                       if (!xfs_has_rmapbt(ip->i_mount)) {
-                               xfs_inode_mark_sick(ip, XFS_SICK_INO_CORE);
-                               return -EFSCORRUPTED;
-                       }
-                       return xfs_iformat_rtrmap(ip, dip);
-               case XFS_DINODE_FMT_REFCOUNT:
-                       /* same comment about growfs and rmap inodes applies */
-                       if (!xfs_has_reflink(ip->i_mount)) {
-                               xfs_inode_mark_sick(ip, XFS_SICK_INO_CORE);
-                               return -EFSCORRUPTED;
+               case XFS_DINODE_FMT_META_BTREE:
+                       switch (ip->i_metatype) {
+                       case XFS_METAFILE_RTRMAP:
+                               return xfs_iformat_rtrmap(ip, dip);
+                       case XFS_METAFILE_RTREFCOUNT:
+                               return xfs_iformat_rtrefcount(ip, dip);
+                       default:
+                               break;
                        }
-                       return xfs_iformat_rtrefcount(ip, dip);
+                       fallthrough;
                default:
                        xfs_inode_verifier_error(ip, -EFSCORRUPTED, __func__,
                                        dip, sizeof(*dip), __this_address);
@@ -607,16 +599,22 @@ xfs_iflush_fork(
                }
                break;
 
-       case XFS_DINODE_FMT_RMAP:
+       case XFS_DINODE_FMT_META_BTREE:
                ASSERT(whichfork == XFS_DATA_FORK);
-               if (iip->ili_fields & brootflag[whichfork])
-                       xfs_iflush_rtrmap(ip, dip);
-               break;
 
-       case XFS_DINODE_FMT_REFCOUNT:
-               ASSERT(whichfork == XFS_DATA_FORK);
-               if (iip->ili_fields & brootflag[whichfork])
+               if (!(iip->ili_fields & brootflag[whichfork]))
+                       break;
+
+               switch (ip->i_metatype) {
+               case XFS_METAFILE_RTRMAP:
+                       xfs_iflush_rtrmap(ip, dip);
+                       break;
+               case XFS_METAFILE_RTREFCOUNT:
                        xfs_iflush_rtrefcount(ip, dip);
+                       break;
+               default:
+                       ASSERT(0);
+               }
                break;
 
        default:
index 2638d7bd4175248ce9d50c950e8444ccc6482552..1dbd84f53628457232a96ea368eb371859c7b218 100644 (file)
@@ -311,17 +311,8 @@ xfs_rtginode_ilock_print_fn(
        const struct xfs_inode *ip =
                container_of(m, struct xfs_inode, i_lock.dep_map);
 
-       switch (ip->i_df.if_format) {
-       case XFS_DINODE_FMT_RMAP:
-               printk(KERN_CONT " rgno=%u rmapbt", ip->i_projid);
-               break;
-       case XFS_DINODE_FMT_REFCOUNT:
-               printk(KERN_CONT " rgno=%u refcountbt", ip->i_projid);
-               break;
-       default:
-               printk(KERN_CONT " rgno=%u", ip->i_projid);
-               break;
-       }
+       /* XXX: pretty print metatype */
+       printk(KERN_CONT " rgno=%u metatype %u", ip->i_projid, ip->i_metatype);
 }
 
 /*
@@ -386,7 +377,7 @@ static const struct xfs_rtginode_ops xfs_rtginode_ops[XFS_RTGI_MAX] = {
                .name           = "rmap",
                .metafile_type  = XFS_METAFILE_RTRMAP,
                .sick           = XFS_SICK_RG_RMAPBT,
-               .fmt_mask       = 1U << XFS_DINODE_FMT_RMAP,
+               .fmt_mask       = 1U << XFS_DINODE_FMT_META_BTREE,
                /*
                 * growfs must create the rtrmap inodes before adding a
                 * realtime volume to the filesystem, so we cannot use the
@@ -399,7 +390,7 @@ static const struct xfs_rtginode_ops xfs_rtginode_ops[XFS_RTGI_MAX] = {
                .name           = "refcount",
                .metafile_type  = XFS_METAFILE_RTREFCOUNT,
                .sick           = XFS_SICK_RG_REFCNTBT,
-               .fmt_mask       = 1U << XFS_DINODE_FMT_REFCOUNT,
+               .fmt_mask       = 1U << XFS_DINODE_FMT_META_BTREE,
                /* same comment about growfs and rmap inodes applies here */
                .enabled        = xfs_has_reflink,
                .create         = xfs_rtrefcountbt_create,
index 2fe58aaceba68dc283417ccc0bf23e907da11e34..ef7294cfb5f65c7ce9e59b0b1c34c03ff9d6a931 100644 (file)
@@ -437,7 +437,7 @@ xfs_rtrefcountbt_commit_staged_btree(
        int                     flags = XFS_ILOG_CORE | XFS_ILOG_DBROOT;
 
        ASSERT(cur->bc_flags & XFS_BTREE_STAGING);
-       ASSERT(ifake->if_fork->if_format == XFS_DINODE_FMT_REFCOUNT);
+       ASSERT(ifake->if_fork->if_format == XFS_DINODE_FMT_META_BTREE);
 
        /*
         * Free any resources hanging off the real fork, then shallow-copy the
@@ -639,6 +639,11 @@ xfs_iformat_rtrefcount(
        unsigned int            level;
        int                     dsize;
 
+       if (!xfs_has_reflink(mp)) {
+               xfs_inode_mark_sick(ip, XFS_SICK_INO_CORE);
+               return -EFSCORRUPTED;
+       }
+
        dsize = XFS_DFORK_SIZE(dip, mp, XFS_DATA_FORK);
        numrecs = be16_to_cpu(dfp->bb_numrecs);
        level = be16_to_cpu(dfp->bb_level);
@@ -734,7 +739,7 @@ xfs_rtrefcountbt_create(
        struct xfs_mount        *mp = ip->i_mount;
        struct xfs_btree_block  *broot;
 
-       ifp->if_format = XFS_DINODE_FMT_REFCOUNT;
+       ifp->if_format = XFS_DINODE_FMT_META_BTREE;
        ASSERT(ifp->if_broot_bytes == 0);
        ASSERT(ifp->if_bytes == 0);
 
index 86ede1517dde77751818aa8b36b98a715d4dcb8a..1f83a361c6f93ee37684408e911b3f423b19d0d3 100644 (file)
@@ -675,7 +675,7 @@ xfs_rtrmapbt_commit_staged_btree(
        int                     flags = XFS_ILOG_CORE | XFS_ILOG_DBROOT;
 
        ASSERT(cur->bc_flags & XFS_BTREE_STAGING);
-       ASSERT(ifake->if_fork->if_format == XFS_DINODE_FMT_RMAP);
+       ASSERT(ifake->if_fork->if_format == XFS_DINODE_FMT_META_BTREE);
 
        /*
         * Free any resources hanging off the real fork, then shallow-copy the
@@ -896,6 +896,11 @@ xfs_iformat_rtrmap(
        unsigned int            level;
        int                     dsize;
 
+       if (!xfs_has_rmapbt(mp)) {
+               xfs_inode_mark_sick(ip, XFS_SICK_INO_CORE);
+               return -EFSCORRUPTED;
+       }
+
        dsize = XFS_DFORK_SIZE(dip, mp, XFS_DATA_FORK);
        numrecs = be16_to_cpu(dfp->bb_numrecs);
        level = be16_to_cpu(dfp->bb_level);
@@ -987,7 +992,7 @@ xfs_rtrmapbt_create(
        struct xfs_mount        *mp = ip->i_mount;
        struct xfs_btree_block  *broot;
 
-       ifp->if_format = XFS_DINODE_FMT_RMAP;
+       ifp->if_format = XFS_DINODE_FMT_META_BTREE;
        ASSERT(ifp->if_broot_bytes == 0);
        ASSERT(ifp->if_bytes == 0);
 
index 7631bcbe3ecf0bd8dc7e363aa725c03642c62aeb..66da7d4d56ba7401f490b8cb9e4ae3ff65a0e293 100644 (file)
@@ -1064,8 +1064,7 @@ xchk_bmap(
        case XFS_DINODE_FMT_UUID:
        case XFS_DINODE_FMT_DEV:
        case XFS_DINODE_FMT_LOCAL:
-       case XFS_DINODE_FMT_RMAP:
-       case XFS_DINODE_FMT_REFCOUNT:
+       case XFS_DINODE_FMT_META_BTREE:
                /* No mappings to check. */
                if (whichfork == XFS_COW_FORK)
                        xchk_fblock_set_corrupt(sc, whichfork, 0);
index 58fde28125274513cd09ea42d4a60b9c324a80fa..1084213b8e9b8876f461714781d142a12264a758 100644 (file)
@@ -864,8 +864,7 @@ xrep_bmap_check_inputs(
        case XFS_DINODE_FMT_DEV:
        case XFS_DINODE_FMT_LOCAL:
        case XFS_DINODE_FMT_UUID:
-       case XFS_DINODE_FMT_RMAP:
-       case XFS_DINODE_FMT_REFCOUNT:
+       case XFS_DINODE_FMT_META_BTREE:
                return -ECANCELED;
        case XFS_DINODE_FMT_EXTENTS:
        case XFS_DINODE_FMT_BTREE:
index 299c9f841ffafdc221777554ce14840b3042bf94..6ee544fc9b2005b4d355c4baa48a38f77aee719f 100644 (file)
@@ -1679,6 +1679,42 @@ xchk_inode_rootdir_inum(const struct xfs_inode *ip)
        return mp->m_rootip->i_ino;
 }
 
+static int
+xchk_meta_btree_count_blocks(
+       struct xfs_scrub        *sc,
+       xfs_extnum_t            *nextents,
+       xfs_filblks_t           *count)
+{
+       struct xfs_btree_cur    *cur;
+       xfs_extlen_t            btblocks;
+       int                     error;
+
+       if (!sc->sr.rtg) {
+               ASSERT(0);
+               return -EFSCORRUPTED;
+       }
+
+       switch (sc->ip->i_metatype) {
+       case XFS_METAFILE_RTRMAP:
+               cur = xfs_rtrmapbt_init_cursor(sc->tp, sc->sr.rtg);
+               break;
+       case XFS_METAFILE_RTREFCOUNT:
+               cur = xfs_rtrefcountbt_init_cursor(sc->tp, sc->sr.rtg);
+               break;
+       default:
+               ASSERT(0);
+               return -EFSCORRUPTED;
+       }
+
+       error = xfs_btree_count_blocks(cur, &btblocks);
+       xfs_btree_del_cursor(cur, error);
+       if (!error) {
+               *nextents = 0;
+               *count = btblocks - 1;
+       }
+       return error;
+}
+
 /* Count the blocks used by a file, even if it's a metadata inode. */
 int
 xchk_inode_count_blocks(
@@ -1688,9 +1724,6 @@ xchk_inode_count_blocks(
        xfs_filblks_t           *count)
 {
        struct xfs_ifork        *ifp = xfs_ifork_ptr(sc->ip, whichfork);
-       struct xfs_btree_cur    *cur;
-       xfs_extlen_t            btblocks;
-       int                     error;
 
        if (!ifp) {
                *nextents = 0;
@@ -1698,32 +1731,10 @@ xchk_inode_count_blocks(
                return 0;
        }
 
-       switch (ifp->if_format) {
-       case XFS_DINODE_FMT_RMAP:
-               if (!sc->sr.rtg) {
-                       ASSERT(0);
-                       return -EFSCORRUPTED;
-               }
-               cur = xfs_rtrmapbt_init_cursor(sc->tp, sc->sr.rtg);
-               goto meta_btree;
-       case XFS_DINODE_FMT_REFCOUNT:
-               if (!sc->sr.rtg) {
-                       ASSERT(0);
-                       return -EFSCORRUPTED;
-               }
-               cur = xfs_rtrefcountbt_init_cursor(sc->tp, sc->sr.rtg);
-               goto meta_btree;
+       if (ifp->if_format == XFS_DINODE_FMT_META_BTREE) {
+               ASSERT(whichfork == XFS_DATA_FORK);
+               return xchk_meta_btree_count_blocks(sc, nextents, count);
        }
-
        return xfs_bmap_count_blocks(sc->tp, sc->ip, whichfork, nextents,
                        count);
-meta_btree:
-       error = xfs_btree_count_blocks(cur, &btblocks);
-       xfs_btree_del_cursor(cur, error);
-       if (error)
-               return error;
-
-       *nextents = 0;
-       *count = btblocks - 1;
-       return 0;
 }
index 53788a699fa5bdc00a7c7416a69cae31060a4295..db6edd5a5fe5d8f47fc93c28e4efc75443a0f5c1 100644 (file)
@@ -511,8 +511,7 @@ xchk_dinode(
                if (!S_ISREG(mode) && !S_ISDIR(mode))
                        xchk_ino_set_corrupt(sc, ino);
                break;
-       case XFS_DINODE_FMT_RMAP:
-       case XFS_DINODE_FMT_REFCOUNT:
+       case XFS_DINODE_FMT_META_BTREE:
                if (!S_ISREG(mode))
                        xchk_ino_set_corrupt(sc, ino);
                break;
index 4deaaf24c318352f9f551e0e3c83ca40517fc3cf..cd51be00595c687858a423eb42ddfe5768623e53 100644 (file)
@@ -948,19 +948,16 @@ STATIC bool
 xrep_dinode_bad_rmapbt_fork(
        struct xfs_scrub        *sc,
        struct xfs_dinode       *dip,
-       unsigned int            dfork_size,
-       int                     whichfork)
+       unsigned int            dfork_size)
 {
        struct xfs_rtrmap_root  *dfp;
        unsigned int            nrecs;
        unsigned int            level;
 
-       if (whichfork != XFS_DATA_FORK)
-               return true;
        if (dfork_size < sizeof(struct xfs_rtrmap_root))
                return true;
 
-       dfp = XFS_DFORK_PTR(dip, whichfork);
+       dfp = XFS_DFORK_PTR(dip, XFS_DATA_FORK);
        nrecs = be16_to_cpu(dfp->bb_numrecs);
        level = be16_to_cpu(dfp->bb_level);
 
@@ -979,19 +976,16 @@ STATIC bool
 xrep_dinode_bad_refcountbt_fork(
        struct xfs_scrub        *sc,
        struct xfs_dinode       *dip,
-       unsigned int            dfork_size,
-       int                     whichfork)
+       unsigned int            dfork_size)
 {
        struct xfs_rtrefcount_root *dfp;
        unsigned int            nrecs;
        unsigned int            level;
 
-       if (whichfork != XFS_DATA_FORK)
-               return true;
        if (dfork_size < sizeof(struct xfs_rtrefcount_root))
                return true;
 
-       dfp = XFS_DFORK_PTR(dip, whichfork);
+       dfp = XFS_DFORK_PTR(dip, XFS_DATA_FORK);
        nrecs = be16_to_cpu(dfp->bb_numrecs);
        level = be16_to_cpu(dfp->bb_level);
 
@@ -1005,6 +999,26 @@ xrep_dinode_bad_refcountbt_fork(
        return false;
 }
 
+STATIC bool
+xrep_dinode_bad_metabt_fork(
+       struct xfs_scrub        *sc,
+       struct xfs_dinode       *dip,
+       unsigned int            dfork_size,
+       int                     whichfork)
+{
+       if (whichfork != XFS_DATA_FORK)
+               return true;
+
+       switch (be16_to_cpu(dip->di_metatype)) {
+       case XFS_METAFILE_RTRMAP:
+               return xrep_dinode_bad_rmapbt_fork(sc, dip, dfork_size);
+       case XFS_METAFILE_RTREFCOUNT:
+               return xrep_dinode_bad_refcountbt_fork(sc, dip, dfork_size);
+       default:
+               return true;
+       }
+}
+
 /*
  * Check the data fork for things that will fail the ifork verifiers or the
  * ifork formatters.
@@ -1085,13 +1099,8 @@ xrep_dinode_check_dfork(
                                XFS_DATA_FORK))
                        return true;
                break;
-       case XFS_DINODE_FMT_RMAP:
-               if (xrep_dinode_bad_rmapbt_fork(sc, dip, dfork_size,
-                               XFS_DATA_FORK))
-                       return true;
-               break;
-       case XFS_DINODE_FMT_REFCOUNT:
-               if (xrep_dinode_bad_refcountbt_fork(sc, dip, dfork_size,
+       case XFS_DINODE_FMT_META_BTREE:
+               if (xrep_dinode_bad_metabt_fork(sc, dip, dfork_size,
                                XFS_DATA_FORK))
                        return true;
                break;
@@ -1215,13 +1224,8 @@ xrep_dinode_check_afork(
                                        XFS_ATTR_FORK))
                        return true;
                break;
-       case XFS_DINODE_FMT_RMAP:
-               if (xrep_dinode_bad_rmapbt_fork(sc, dip, afork_size,
-                               XFS_ATTR_FORK))
-                       return true;
-               break;
-       case XFS_DINODE_FMT_REFCOUNT:
-               if (xrep_dinode_bad_refcountbt_fork(sc, dip, afork_size,
+       case XFS_DINODE_FMT_META_BTREE:
+               if (xrep_dinode_bad_metabt_fork(sc, dip, afork_size,
                                XFS_ATTR_FORK))
                        return true;
                break;
@@ -1380,13 +1384,19 @@ xrep_dinode_ensure_forkoff(
                bmdr = XFS_DFORK_PTR(dip, XFS_DATA_FORK);
                dfork_min = xfs_bmap_broot_space(sc->mp, bmdr);
                break;
-       case XFS_DINODE_FMT_RMAP:
-               rmdr = XFS_DFORK_PTR(dip, XFS_DATA_FORK);
-               dfork_min = xfs_rtrmap_broot_space(sc->mp, rmdr);
-               break;
-       case XFS_DINODE_FMT_REFCOUNT:
-               rcdr = XFS_DFORK_PTR(dip, XFS_DATA_FORK);
-               dfork_min = xfs_rtrefcount_broot_space(sc->mp, rcdr);
+       case XFS_DINODE_FMT_META_BTREE:
+               switch (be16_to_cpu(dip->di_metatype)) {
+               case XFS_METAFILE_RTRMAP:
+                       rmdr = XFS_DFORK_PTR(dip, XFS_DATA_FORK);
+                       dfork_min = xfs_rtrmap_broot_space(sc->mp, rmdr);
+                       break;
+               case XFS_METAFILE_RTREFCOUNT:
+                       rcdr = XFS_DFORK_PTR(dip, XFS_DATA_FORK);
+                       dfork_min = xfs_rtrefcount_broot_space(sc->mp, rcdr);
+                       break;
+               default:
+                       break;
+               }
                break;
        default:
                dfork_min = 0;
index 5f93aaa4fcfef4af37ed66ae34e41ce8be8b91bb..7f735b361191fd8a94c0dc35caf1e819588236d0 100644 (file)
@@ -503,62 +503,35 @@ xrep_rmap_scan_iext(
 }
 
 static int
-xrep_rmap_scan_rtrmapbt(
+xrep_rmap_scan_meta_btree(
        struct xrep_rmap_ifork  *rf,
        struct xfs_inode        *ip)
 {
        struct xfs_scrub        *sc = rf->rr->sc;
        struct xfs_rtgroup      *rtg = NULL;
        struct xfs_btree_cur    *cur;
+       enum xfs_rtg_inodes     type;
        int                     error;
 
        if (rf->whichfork != XFS_DATA_FORK)
                return -EFSCORRUPTED;
 
-       while ((rtg = xfs_rtgroup_next(sc->mp, rtg))) {
-               if (ip == rtg->rtg_inodes[XFS_RTGI_RMAP]) {
-                       cur = xfs_rtrmapbt_init_cursor(sc->tp, rtg);
-                       error = xrep_rmap_scan_iroot_btree(rf, cur);
-                       xfs_btree_del_cursor(cur, error);
-                       xfs_rtgroup_rele(rtg);
-                       return error;
-               }
-       }
-
-       /*
-        * We shouldn't find an rmap format inode that isn't associated with
-        * an rtgroup and has ondisk blocks allocated to it.
-        */
-       if (ip->i_nblocks) {
+       switch (ip->i_metatype) {
+       case XFS_METAFILE_RTRMAP:
+               type = XFS_RTGI_RMAP;
+               break;
+       case XFS_METAFILE_RTREFCOUNT:
+               type = XFS_RTGI_REFCOUNT;
+               break;
+       default:
                ASSERT(0);
                return -EFSCORRUPTED;
        }
 
-       return 0;
-}
 
-static int
-xrep_rmap_scan_rtrefcountbt(
-       struct xrep_rmap_ifork  *rf,
-       struct xfs_inode        *ip)
-{
-       struct xfs_scrub        *sc = rf->rr->sc;
-       struct xfs_rtgroup      *rtg = NULL;
-       struct xfs_btree_cur    *cur;
-       int                     error;
-
-       if (rf->whichfork != XFS_DATA_FORK)
-               return -EFSCORRUPTED;
-
-       while ((rtg = xfs_rtgroup_next(sc->mp, rtg))) {
-               if (ip == rtg->rtg_inodes[XFS_RTGI_REFCOUNT]) {
-                       cur = xfs_rtrefcountbt_init_cursor(sc->tp, rtg);
-                       error = xrep_rmap_scan_iroot_btree(rf, cur);
-                       xfs_btree_del_cursor(cur, error);
-                       xfs_rtgroup_rele(rtg);
-                       return error;
-               }
-       }
+       while ((rtg = xfs_rtgroup_next(sc->mp, rtg)))
+               if (ip == rtg->rtg_inodes[type])
+                       goto found;
 
        /*
         * We shouldn't find a refcount format inode that isn't associated with
@@ -570,6 +543,16 @@ xrep_rmap_scan_rtrefcountbt(
        }
 
        return 0;
+
+found:
+       if (ip->i_metatype == XFS_METAFILE_RTRMAP)
+               cur = xfs_rtrmapbt_init_cursor(sc->tp, rtg);
+       else
+               cur = xfs_rtrefcountbt_init_cursor(sc->tp, rtg);
+       error = xrep_rmap_scan_iroot_btree(rf, cur);
+       xfs_btree_del_cursor(cur, error);
+       xfs_rtgroup_rele(rtg);
+       return error;
 }
 
 /* Find all the extents from a given AG in an inode fork. */
@@ -585,14 +568,14 @@ xrep_rmap_scan_ifork(
                .whichfork      = whichfork,
        };
        struct xfs_ifork        *ifp = xfs_ifork_ptr(ip, whichfork);
+       bool                    mappings_done;
        int                     error = 0;
 
        if (!ifp)
                return 0;
 
-       if (ifp->if_format == XFS_DINODE_FMT_BTREE) {
-               bool            mappings_done;
-
+       switch (ifp->if_format) {
+       case XFS_DINODE_FMT_BTREE:
                /*
                 * Scan the bmap btree for data device mappings.  This includes
                 * the btree blocks themselves, even if this is a realtime
@@ -601,19 +584,17 @@ xrep_rmap_scan_ifork(
                error = xrep_rmap_scan_bmbt(&rf, ip, &mappings_done);
                if (error || mappings_done)
                        return error;
-       } else if (ifp->if_format == XFS_DINODE_FMT_RMAP) {
-               return xrep_rmap_scan_rtrmapbt(&rf, ip);
-       } else if (ifp->if_format == XFS_DINODE_FMT_REFCOUNT) {
-               return xrep_rmap_scan_rtrefcountbt(&rf, ip);
-       } else if (ifp->if_format != XFS_DINODE_FMT_EXTENTS) {
+               fallthrough;
+       case XFS_DINODE_FMT_EXTENTS:
+               /* Scan incore extent cache if this isn't a realtime file. */
+               if (xfs_ifork_is_realtime(ip, whichfork))
+                       return 0;
+               return xrep_rmap_scan_iext(&rf, ifp);
+       case XFS_DINODE_FMT_META_BTREE:
+               return xrep_rmap_scan_meta_btree(&rf, ip);
+       default:
                return 0;
        }
-
-       /* Scan incore extent cache if this isn't a realtime file. */
-       if (xfs_ifork_is_realtime(ip, whichfork))
-               return 0;
-
-       return xrep_rmap_scan_iext(&rf, ifp);
 }
 
 /*
index 179ce923944540c551372e352fc4f4133a68e84a..ab9315c5d69d02bced56c259cb8aed8158771f84 100644 (file)
@@ -671,7 +671,7 @@ xrep_rtrefc_build_new_tree(
                goto err_cur;
 
        /* Add all observed refcount records. */
-       rr->new_btree.ifake.if_fork->if_format = XFS_DINODE_FMT_REFCOUNT;
+       rr->new_btree.ifake.if_fork->if_format = XFS_DINODE_FMT_META_BTREE;
        rr->array_cur = XFARRAY_CURSOR_INIT;
        error = xfs_btree_bload(refc_cur, &rr->new_btree.bload, rr);
        if (error)
index 4de2a5335af5d9bd4aff0ddadc6beaa44a025e68..e70f6f9918e8443915f1b94db944dc9a1d22280e 100644 (file)
@@ -772,7 +772,7 @@ xrep_rtrmap_build_new_tree(
                goto err_mcur;
 
        /* Add all observed rmap records. */
-       rr->new_btree.ifake.if_fork->if_format = XFS_DINODE_FMT_RMAP;
+       rr->new_btree.ifake.if_fork->if_format = XFS_DINODE_FMT_META_BTREE;
        error = xfs_btree_bload(rmap_cur, &rr->new_btree.bload, rr);
        if (error)
                goto err_mcur;
index f39db43f5bf030d41478e87573ef2a5b3d61bbaf..71ec46991e8446699c037902e76b38c1f468c9c6 100644 (file)
@@ -2382,19 +2382,11 @@ xfs_iflush(
                        __func__, ip->i_ino, be16_to_cpu(dip->di_magic), dip);
                goto flush_out;
        }
-       if (ip->i_df.if_format == XFS_DINODE_FMT_RMAP) {
+       if (ip->i_df.if_format == XFS_DINODE_FMT_META_BTREE) {
                if (!S_ISREG(VFS_I(ip)->i_mode) ||
                    !(ip->i_diflags2 & XFS_DIFLAG2_METADATA)) {
                        xfs_alert_tag(mp, XFS_PTAG_IFLUSH,
-                               "%s: Bad rt rmapbt inode %Lu, ptr "PTR_FMT,
-                               __func__, ip->i_ino, ip);
-                       goto flush_out;
-               }
-       } else if (ip->i_df.if_format == XFS_DINODE_FMT_REFCOUNT) {
-               if (!S_ISREG(VFS_I(ip)->i_mode) ||
-                   !(ip->i_diflags2 & XFS_DIFLAG2_METADATA)) {
-                       xfs_alert_tag(mp, XFS_PTAG_IFLUSH,
-                               "%s: Bad rt refcountbt inode %Lu, ptr "PTR_FMT,
+                               "%s: Bad meta btree inode %Lu, ptr "PTR_FMT,
                                __func__, ip->i_ino, ip);
                        goto flush_out;
                }
@@ -2438,18 +2430,12 @@ xfs_iflush(
                goto flush_out;
        }
 
-       if (xfs_inode_has_attr_fork(ip)) {
-               if (ip->i_af.if_format == XFS_DINODE_FMT_RMAP) {
-                       xfs_alert_tag(mp, XFS_PTAG_IFLUSH,
-                               "%s: rt rmapbt in inode %Lu attr fork, ptr "PTR_FMT,
-                               __func__, ip->i_ino, ip);
-                       goto flush_out;
-               } else if (ip->i_af.if_format == XFS_DINODE_FMT_REFCOUNT) {
-                       xfs_alert_tag(mp, XFS_PTAG_IFLUSH,
-                               "%s: rt refcountbt in inode %Lu attr fork, ptr "PTR_FMT,
-                               __func__, ip->i_ino, ip);
-                       goto flush_out;
-               }
+       if (xfs_inode_has_attr_fork(ip) &&
+           ip->i_af.if_format == XFS_DINODE_FMT_META_BTREE) {
+               xfs_alert_tag(mp, XFS_PTAG_IFLUSH,
+                       "%s: meta btree in inode %Lu attr fork, ptr "PTR_FMT,
+                       __func__, ip->i_ino, ip);
+               goto flush_out;
        }
 
        /*
index 5338c7fa12c972e6ca0c859678315534e5c7a0f4..70283c6419fd30e63d81468c8a6c8b3ee410f1de 100644 (file)
@@ -256,8 +256,7 @@ xfs_inode_item_data_fork_size(
                }
                break;
        case XFS_DINODE_FMT_BTREE:
-       case XFS_DINODE_FMT_RMAP:
-       case XFS_DINODE_FMT_REFCOUNT:
+       case XFS_DINODE_FMT_META_BTREE:
                if ((iip->ili_fields & XFS_ILOG_DBROOT) &&
                    ip->i_df.if_broot_bytes > 0) {
                        *nbytes += ip->i_df.if_broot_bytes;
@@ -378,8 +377,7 @@ xfs_inode_item_format_data_fork(
                }
                break;
        case XFS_DINODE_FMT_BTREE:
-       case XFS_DINODE_FMT_RMAP:
-       case XFS_DINODE_FMT_REFCOUNT:
+       case XFS_DINODE_FMT_META_BTREE:
                iip->ili_fields &=
                        ~(XFS_ILOG_DDATA | XFS_ILOG_DEXT | XFS_ILOG_DEV);
 
index ee8ea8cfa3fef7abe7f260973cdc8f0f7416da5f..5c77fcad4342d68fea4af1ce3015b8a74a06eaae 100644 (file)
@@ -281,19 +281,23 @@ xlog_recover_inode_dbroot(
        switch (dip->di_format) {
        case XFS_DINODE_FMT_BTREE:
                xfs_bmbt_to_bmdr(mp, src, len, dfork, dsize);
-               break;
-       case XFS_DINODE_FMT_RMAP:
-               xfs_rtrmapbt_to_disk(mp, src, len, dfork, dsize);
-               break;
-       case XFS_DINODE_FMT_REFCOUNT:
-               xfs_rtrefcountbt_to_disk(mp, src, len, dfork, dsize);
-               break;
+               return 0;
+       case XFS_DINODE_FMT_META_BTREE:
+               switch (be16_to_cpu(dip->di_metatype)) {
+               case XFS_METAFILE_RTRMAP:
+                       xfs_rtrmapbt_to_disk(mp, src, len, dfork, dsize);
+                       return 0;
+               case XFS_METAFILE_RTREFCOUNT:
+                       xfs_rtrefcountbt_to_disk(mp, src, len, dfork, dsize);
+                       return 0;
+               default:
+                       ASSERT(0);
+                       return -EFSCORRUPTED;
+               }
        default:
                ASSERT(0);
                return -EFSCORRUPTED;
        }
-
-       return 0;
 }
 
 STATIC int
@@ -424,8 +428,7 @@ xlog_recover_inode_commit_pass2(
 
        if (unlikely(S_ISREG(ldip->di_mode))) {
                if ((ldip->di_format != XFS_DINODE_FMT_EXTENTS) &&
-                   (ldip->di_format != XFS_DINODE_FMT_RMAP) &&
-                   (ldip->di_format != XFS_DINODE_FMT_REFCOUNT) &&
+                   (ldip->di_format != XFS_DINODE_FMT_META_BTREE) &&
                    (ldip->di_format != XFS_DINODE_FMT_BTREE)) {
                        XFS_CORRUPTION_ERROR(
                                "Bad log dinode data fork format for regular file",
index 64fa36806dca5b8d3aff1f61cc46488ef9844357..c92129ebd1025a631ae7a949986a816128404995 100644 (file)
@@ -2295,8 +2295,7 @@ TRACE_DEFINE_ENUM(XFS_DINODE_FMT_LOCAL);
 TRACE_DEFINE_ENUM(XFS_DINODE_FMT_EXTENTS);
 TRACE_DEFINE_ENUM(XFS_DINODE_FMT_BTREE);
 TRACE_DEFINE_ENUM(XFS_DINODE_FMT_UUID);
-TRACE_DEFINE_ENUM(XFS_DINODE_FMT_RMAP);
-TRACE_DEFINE_ENUM(XFS_DINODE_FMT_REFCOUNT);
+TRACE_DEFINE_ENUM(XFS_DINODE_FMT_META_BTREE);
 
 DECLARE_EVENT_CLASS(xfs_swap_extent_class,
        TP_PROTO(struct xfs_inode *ip, int which),