]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
xfs: add realtime refcount btree inode to metadata directory
authorDarrick J. Wong <djwong@kernel.org>
Thu, 21 Nov 2024 00:20:52 +0000 (16:20 -0800)
committerDarrick J. Wong <djwong@kernel.org>
Mon, 23 Dec 2024 21:06:11 +0000 (13:06 -0800)
Add a metadir path to select the realtime refcount btree inode and load
it at mount time.  The rtrefcountbt 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" <djwong@kernel.org>
Reviewed-by: Christoph Hellwig <hch@lst.de>
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_rtgroup.h
fs/xfs/libxfs/xfs_rtrefcount_btree.c

index 17f7c0d1aaa45208a877712547d4108b5d0e34ab..b6828f92c131fb1dd7d9a35ecce0a6bd10e7afbf 100644 (file)
@@ -858,6 +858,7 @@ enum xfs_metafile_type {
        XFS_METAFILE_RTBITMAP,          /* rt bitmap */
        XFS_METAFILE_RTSUMMARY,         /* rt summary */
        XFS_METAFILE_RTRMAP,            /* rt rmap */
+       XFS_METAFILE_RTREFCOUNT,        /* rt refcount */
 
        XFS_METAFILE_MAX
 } __packed;
@@ -870,7 +871,8 @@ enum xfs_metafile_type {
        { XFS_METAFILE_PRJQUOTA,        "prjquota" }, \
        { XFS_METAFILE_RTBITMAP,        "rtbitmap" }, \
        { XFS_METAFILE_RTSUMMARY,       "rtsummary" }, \
-       { XFS_METAFILE_RTRMAP,          "rtrmap" }
+       { XFS_METAFILE_RTRMAP,          "rtrmap" }, \
+       { XFS_METAFILE_RTREFCOUNT,      "rtrefcount" }
 
 /*
  * On-disk inode structure.
index 17cb91b89fcaa19bd49eca3b46d4e14576533b65..65eec8f60376d3d41d98f95fa159adcf34b84f51 100644 (file)
@@ -456,6 +456,11 @@ xfs_dinode_verify_fork(
                        if (!xfs_has_rmapbt(mp))
                                return __this_address;
                        break;
+               case XFS_METAFILE_RTREFCOUNT:
+                       /* same comment about growfs and rmap inodes applies */
+                       if (!xfs_has_reflink(mp))
+                               return __this_address;
+                       break;
                default:
                        return __this_address;
                }
index d9b3c182cb400bd95894e99ae4905d8fa8f78f35..0c4bc12401a151ffd5efde2c78dee9374a6d5772 100644 (file)
@@ -272,6 +272,9 @@ xfs_iformat_data_fork(
                        switch (ip->i_metatype) {
                        case XFS_METAFILE_RTRMAP:
                                return xfs_iformat_rtrmap(ip, dip);
+                       case XFS_METAFILE_RTREFCOUNT:
+                               ASSERT(0); /* to be implemented later */
+                               return -EFSCORRUPTED;
                        default:
                                break;
                        }
@@ -620,6 +623,9 @@ xfs_iflush_fork(
                case XFS_METAFILE_RTRMAP:
                        xfs_iflush_rtrmap(ip, dip);
                        break;
+               case XFS_METAFILE_RTREFCOUNT:
+                       ASSERT(0); /* to be implemented later */
+                       break;
                default:
                        ASSERT(0);
                        break;
index b7ed2d27d5455392d3b8670155799fed1958be49..6aebe9f484901f7b5a8b02f964b790ea5148217d 100644 (file)
@@ -367,6 +367,13 @@ static const struct xfs_rtginode_ops xfs_rtginode_ops[XFS_RTGI_MAX] = {
                .enabled        = xfs_has_rmapbt,
                .create         = xfs_rtrmapbt_create,
        },
+       [XFS_RTGI_REFCOUNT] = {
+               .name           = "refcount",
+               .metafile_type  = XFS_METAFILE_RTREFCOUNT,
+               .fmt_mask       = 1U << XFS_DINODE_FMT_META_BTREE,
+               /* same comment about growfs and rmap inodes applies here */
+               .enabled        = xfs_has_reflink,
+       },
 };
 
 /* Return the shortname of this rtgroup inode. */
index 733da7417c9cd79daf3b15c6facc92a65f47bfbc..385ea8e2f28b671dca0940c8000fa82a29c744a3 100644 (file)
@@ -15,6 +15,7 @@ enum xfs_rtg_inodes {
        XFS_RTGI_BITMAP,        /* allocation bitmap */
        XFS_RTGI_SUMMARY,       /* allocation summary */
        XFS_RTGI_RMAP,          /* rmap btree inode */
+       XFS_RTGI_REFCOUNT,      /* refcount btree inode */
 
        XFS_RTGI_MAX,
 };
@@ -80,6 +81,11 @@ static inline struct xfs_inode *rtg_rmap(const struct xfs_rtgroup *rtg)
        return rtg->rtg_inodes[XFS_RTGI_RMAP];
 }
 
+static inline struct xfs_inode *rtg_refcount(const struct xfs_rtgroup *rtg)
+{
+       return rtg->rtg_inodes[XFS_RTGI_REFCOUNT];
+}
+
 /* Passive rtgroup references */
 static inline struct xfs_rtgroup *
 xfs_rtgroup_get(
index e30af941581651e0bf3db62538504633d061bb97..ebbeab112d141255f05b41118dab0697419cec00 100644 (file)
@@ -26,6 +26,7 @@
 #include "xfs_extent_busy.h"
 #include "xfs_rtgroup.h"
 #include "xfs_rtbitmap.h"
+#include "xfs_metafile.h"
 
 static struct kmem_cache       *xfs_rtrefcountbt_cur_cache;
 
@@ -281,12 +282,10 @@ xfs_rtrefcountbt_init_cursor(
        struct xfs_trans        *tp,
        struct xfs_rtgroup      *rtg)
 {
-       struct xfs_inode        *ip = NULL;
+       struct xfs_inode        *ip = rtg_refcount(rtg);
        struct xfs_mount        *mp = rtg_mount(rtg);
        struct xfs_btree_cur    *cur;
 
-       return NULL; /* XXX */
-
        xfs_assert_ilocked(ip, XFS_ILOCK_SHARED | XFS_ILOCK_EXCL);
 
        cur = xfs_btree_alloc_cursor(mp, tp, &xfs_rtrefcountbt_ops,
@@ -316,6 +315,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_META_BTREE);
 
        /*
         * Free any resources hanging off the real fork, then shallow-copy the