From 5cf3ff2b61a1aa62afd6603928feee97b395a8d6 Mon Sep 17 00:00:00 2001 From: "Darrick J. Wong" Date: Mon, 12 Aug 2024 10:41:56 +0200 Subject: [PATCH] xfs: add realtime reverse map inode to metadata directory Source kernel commit: 7dbfdba02ee58377503d271a9dac7f9b761b6d7f 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 Signed-off-by: Christoph Hellwig --- libxfs/xfs_format.h | 10 +++++++--- libxfs/xfs_inode_buf.c | 10 ++++++++++ libxfs/xfs_inode_fork.c | 9 +++++++++ libxfs/xfs_rtgroup.c | 23 ++++++++++++++++++++++- libxfs/xfs_rtgroup.h | 3 +++ libxfs/xfs_rtrmap_btree.c | 2 ++ 6 files changed, 53 insertions(+), 4 deletions(-) diff --git a/libxfs/xfs_format.h b/libxfs/xfs_format.h index 58aef1e39..ab0336ffb 100644 --- a/libxfs/xfs_format.h +++ b/libxfs/xfs_format.h @@ -867,6 +867,7 @@ enum xfs_metafile_type { XFS_METAFILE_PRJQUOTA, /* project quota */ XFS_METAFILE_RTBITMAP, /* rt bitmap */ XFS_METAFILE_RTSUMMARY, /* rt summary */ + XFS_METAFILE_RTRMAP, /* rt rmap */ XFS_METAFILE_MAX }; @@ -878,7 +879,8 @@ enum xfs_metafile_type { { XFS_METAFILE_GRPQUOTA, "grpquota" }, \ { XFS_METAFILE_PRJQUOTA, "prjquota" }, \ { XFS_METAFILE_RTBITMAP, "rtbitmap" }, \ - { XFS_METAFILE_RTSUMMARY, "rtsummary" } + { XFS_METAFILE_RTSUMMARY, "rtsummary" }, \ + { XFS_METAFILE_RTRMAP, "rtrmap" } /* * On-disk inode structure. @@ -1010,7 +1012,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 \ @@ -1018,7 +1021,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 d10bbdd7d..3732636fd 100644 --- a/libxfs/xfs_inode_buf.c +++ b/libxfs/xfs_inode_buf.c @@ -436,6 +436,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; } @@ -455,6 +461,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 6a78dc66b..983b8a490 100644 --- a/libxfs/xfs_rtgroup.c +++ b/libxfs/xfs_rtgroup.c @@ -308,7 +308,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; + } } /* @@ -339,6 +346,7 @@ struct xfs_rtginode_ops { enum xfs_metafile_type metafile_type; unsigned int sick; /* rtgroup sickness flag */ + int8_t format; /* data fork format */ /* Does the fs have this feature? */ bool (*enabled)(struct xfs_mount *mp); @@ -363,6 +371,12 @@ static const struct xfs_rtginode_ops xfs_rtginode_ops[XFS_RTG_MAX] = { .sick = XFS_SICK_RG_SUMMARY, .create = xfs_rtsummary_create, }, + [XFS_RTG_RMAP] = { + .name = "rmap", + .metafile_type = XFS_METAFILE_RTRMAP, + .format = XFS_DINODE_FMT_RMAP, + .enabled = xfs_has_rtrmapbt, + }, }; /* Return the shortname of this rtgroup inode. */ @@ -456,6 +470,13 @@ xfs_rtginode_load( return error; } + if (ops->format && + XFS_IS_CORRUPT(mp, ip->i_df.if_format != ops->format)) { + xfs_irele(ip); + xfs_rtgroup_mark_sick(rtg, ops->sick); + return -EFSCORRUPTED; + } + if (XFS_IS_CORRUPT(mp, ip->i_projid != rtg->rtg_rgno)) { xfs_irele(ip); xfs_rtginode_mark_sick(rtg, type); diff --git a/libxfs/xfs_rtgroup.h b/libxfs/xfs_rtgroup.h index e45e2b94d..b64039929 100644 --- a/libxfs/xfs_rtgroup.h +++ b/libxfs/xfs_rtgroup.h @@ -12,6 +12,7 @@ struct xfs_trans; enum xfs_rtg_inodes { XFS_RTG_BITMAP, /* allocation bitmap */ XFS_RTG_SUMMARY, /* allocation summary */ + XFS_RTG_RMAP, /* rmap btree inode */ XFS_RTG_MAX, }; @@ -316,6 +317,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..e421635af 100644 --- a/libxfs/xfs_rtrmap_btree.c +++ b/libxfs/xfs_rtrmap_btree.c @@ -18,6 +18,7 @@ #include "xfs_alloc.h" #include "xfs_btree.h" #include "xfs_btree_staging.h" +#include "xfs_metafile.h" #include "xfs_rmap.h" #include "xfs_rtrmap_btree.h" #include "xfs_trace.h" @@ -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