From 1e1ffb6ff7de7cee87c7da817fd838fd2c2f9eca Mon Sep 17 00:00:00 2001 From: "Darrick J. Wong" Date: Tue, 28 May 2024 21:11:52 -0700 Subject: [PATCH] xfs: add realtime reverse map inode to metadata directory Add a metadir path to select the realtime rmap btree inode and load it at mount time. The rtrmapbt inode will have a unique extent format code, which means that we also have to update the inode validation and flush routines to look for it. Signed-off-by: Darrick J. Wong --- libxfs/xfs_format.h | 6 ++++-- libxfs/xfs_inode_buf.c | 10 ++++++++++ libxfs/xfs_inode_fork.c | 9 +++++++++ libxfs/xfs_rtgroup.c | 15 ++++++++++++++- libxfs/xfs_rtgroup.h | 4 +++- libxfs/xfs_rtrmap_btree.c | 2 ++ 6 files changed, 42 insertions(+), 4 deletions(-) diff --git a/libxfs/xfs_format.h b/libxfs/xfs_format.h index ef2232171..28501fae2 100644 --- a/libxfs/xfs_format.h +++ b/libxfs/xfs_format.h @@ -986,7 +986,8 @@ enum xfs_dinode_fmt { XFS_DINODE_FMT_LOCAL, /* bulk data */ 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_UUID, /* added long ago, but never used */ + XFS_DINODE_FMT_RMAP, /* reverse mapping btree */ }; #define XFS_INODE_FORMAT_STR \ @@ -994,7 +995,8 @@ enum xfs_dinode_fmt { { XFS_DINODE_FMT_LOCAL, "local" }, \ { XFS_DINODE_FMT_EXTENTS, "extent" }, \ { XFS_DINODE_FMT_BTREE, "btree" }, \ - { XFS_DINODE_FMT_UUID, "uuid" } + { XFS_DINODE_FMT_UUID, "uuid" }, \ + { XFS_DINODE_FMT_RMAP, "rmap" } /* * Max values for extnum and aextnum. diff --git a/libxfs/xfs_inode_buf.c b/libxfs/xfs_inode_buf.c index 98a39e071..192d3202d 100644 --- a/libxfs/xfs_inode_buf.c +++ b/libxfs/xfs_inode_buf.c @@ -431,6 +431,12 @@ xfs_dinode_verify_fork( if (di_nextents > max_extents) return __this_address; break; + case XFS_DINODE_FMT_RMAP: + if (!xfs_has_rtrmapbt(mp)) + return __this_address; + if (!(dip->di_flags2 & cpu_to_be64(XFS_DIFLAG2_METADATA))) + return __this_address; + break; default: return __this_address; } @@ -450,6 +456,10 @@ xfs_dinode_verify_forkoff( if (dip->di_forkoff != (roundup(sizeof(xfs_dev_t), 8) >> 3)) return __this_address; break; + case XFS_DINODE_FMT_RMAP: + if (!(xfs_has_metadir(mp) && xfs_has_parent(mp))) + return __this_address; + fallthrough; case XFS_DINODE_FMT_LOCAL: /* fall through ... */ case XFS_DINODE_FMT_EXTENTS: /* fall through ... */ case XFS_DINODE_FMT_BTREE: diff --git a/libxfs/xfs_inode_fork.c b/libxfs/xfs_inode_fork.c index 98f788901..1e7f81eea 100644 --- a/libxfs/xfs_inode_fork.c +++ b/libxfs/xfs_inode_fork.c @@ -266,6 +266,11 @@ 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: + if (!xfs_has_rtrmapbt(ip->i_mount)) + return -EFSCORRUPTED; + ASSERT(0); /* to be implemented later */ + return -EFSCORRUPTED; default: xfs_inode_verifier_error(ip, -EFSCORRUPTED, __func__, dip, sizeof(*dip), __this_address); @@ -652,6 +657,10 @@ xfs_iflush_fork( } break; + case XFS_DINODE_FMT_RMAP: + ASSERT(0); /* to be implemented later */ + break; + default: ASSERT(0); break; diff --git a/libxfs/xfs_rtgroup.c b/libxfs/xfs_rtgroup.c index da2a4d498..208886ccf 100644 --- a/libxfs/xfs_rtgroup.c +++ b/libxfs/xfs_rtgroup.c @@ -26,6 +26,7 @@ #include "xfs_trans.h" #include "xfs_trace.h" #include "xfs_inode.h" +#include "xfs_metafile.h" #include "xfs_rtgroup.h" #include "xfs_rtbitmap.h" #include "xfs_metafile.h" @@ -500,7 +501,14 @@ xfs_rtginode_ilock_print_fn( const struct xfs_inode *ip = container_of(m, struct xfs_inode, i_lock.dep_map); - printk(KERN_CONT " rgno=%u", ip->i_projid); + switch (ip->i_df.if_format) { + case XFS_DINODE_FMT_RMAP: + printk(KERN_CONT " rgno=%u rmapbt", ip->i_projid); + break; + default: + printk(KERN_CONT " rgno=%u", ip->i_projid); + break; + } } /* @@ -540,6 +548,11 @@ struct xfs_rtginode_ops { }; static const struct xfs_rtginode_ops xfs_rtginode_ops[XFS_RTG_MAX] = { + [XFS_RTG_RMAP] = { + .name = "rmap", + .format = XFS_DINODE_FMT_RMAP, + .enabled = xfs_has_rtrmapbt, + }, }; /* Return the shortname of this rtgroup inode. */ diff --git a/libxfs/xfs_rtgroup.h b/libxfs/xfs_rtgroup.h index 88a10091f..004b19fd9 100644 --- a/libxfs/xfs_rtgroup.h +++ b/libxfs/xfs_rtgroup.h @@ -10,7 +10,7 @@ struct xfs_mount; struct xfs_trans; enum xfs_rtg_inodes { - XFS_RTG_NOTHING, /* shut up gcc */ + XFS_RTG_RMAP, /* rmap btree inode */ XFS_RTG_MAX, }; @@ -245,6 +245,8 @@ int xfs_rtginode_create(struct xfs_rtgroup *rtg, enum xfs_rtg_inodes type, bool init); void xfs_rtginode_irele(struct xfs_inode **ipp); +void xfs_rtginode_irele(struct xfs_inode **ipp); + static inline const char *xfs_rtginode_path(xfs_rgnumber_t rgno, enum xfs_rtg_inodes type) { diff --git a/libxfs/xfs_rtrmap_btree.c b/libxfs/xfs_rtrmap_btree.c index 2e1232155..2c5f37dc9 100644 --- a/libxfs/xfs_rtrmap_btree.c +++ b/libxfs/xfs_rtrmap_btree.c @@ -24,6 +24,7 @@ #include "xfs_cksum.h" #include "xfs_rtgroup.h" #include "xfs_bmap.h" +#include "xfs_metafile.h" static struct kmem_cache *xfs_rtrmapbt_cur_cache; @@ -441,6 +442,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); /* * Free any resources hanging off the real fork, then shallow-copy the -- 2.50.1