summaryrefslogtreecommitdiff
path: root/fs/xfs
diff options
context:
space:
mode:
authorDarrick J. Wong <djwong@kernel.org>2021-01-05 17:46:58 -0800
committerDarrick J. Wong <djwong@kernel.org>2021-03-25 17:08:48 -0700
commitd8ec53d054e733efc55c407a19a7be657acb0314 (patch)
treea95dfec4db960be9652eec9da5c77ddcec1bae8b /fs/xfs
parent59a2bf78fe9da0ac349d1cebe8f668e16fc7b8d1 (diff)
xfs: define the on-disk realtime refcount btree format
Start filling out the rtrefcount btree implementation. Start with the on-disk btree format; add everything needed to read, write and manipulate refcount btree blocks. This prepares the way for connecting the btree operations implementation. Signed-off-by: Darrick J. Wong <djwong@kernel.org>
Diffstat (limited to 'fs/xfs')
-rw-r--r--fs/xfs/Makefile1
-rw-r--r--fs/xfs/libxfs/xfs_btree.c4
-rw-r--r--fs/xfs/libxfs/xfs_btree.h13
-rw-r--r--fs/xfs/libxfs/xfs_format.h28
-rw-r--r--fs/xfs/libxfs/xfs_rtrefcount_btree.c253
-rw-r--r--fs/xfs/libxfs/xfs_rtrefcount_btree.h65
-rw-r--r--fs/xfs/libxfs/xfs_sb.c8
-rw-r--r--fs/xfs/libxfs/xfs_shared.h1
-rw-r--r--fs/xfs/xfs_mount.c3
-rw-r--r--fs/xfs/xfs_mount.h3
-rw-r--r--fs/xfs/xfs_ondisk.h2
11 files changed, 377 insertions, 4 deletions
diff --git a/fs/xfs/Makefile b/fs/xfs/Makefile
index df27b6ae0d6c..7cf622753b6d 100644
--- a/fs/xfs/Makefile
+++ b/fs/xfs/Makefile
@@ -48,6 +48,7 @@ xfs-y += $(addprefix libxfs/, \
xfs_rtrmap_btree.o \
xfs_refcount.o \
xfs_refcount_btree.o \
+ xfs_rtrefcount_btree.o \
xfs_sb.o \
xfs_swapext.o \
xfs_symlink_remote.o \
diff --git a/fs/xfs/libxfs/xfs_btree.c b/fs/xfs/libxfs/xfs_btree.c
index 90ad8dbfec38..0197cdbcaa3d 100644
--- a/fs/xfs/libxfs/xfs_btree.c
+++ b/fs/xfs/libxfs/xfs_btree.c
@@ -1227,6 +1227,7 @@ xfs_btree_set_refs(
xfs_buf_set_ref(bp, XFS_RMAP_BTREE_REF);
break;
case XFS_BTNUM_REFC:
+ case XFS_BTNUM_RTREFC:
xfs_buf_set_ref(bp, XFS_REFC_BTREE_REF);
break;
default:
@@ -5289,6 +5290,8 @@ xfs_btree_maxlevels(
return mp->m_refc_maxlevels;
case XFS_BTNUM_RTRMAP:
return mp->m_rtrmap_maxlevels;
+ case XFS_BTNUM_RTREFC:
+ return mp->m_rtrefc_maxlevels;
default:
break;
}
@@ -5299,6 +5302,7 @@ xfs_btree_maxlevels(
ret = max(ret, M_IGEO(mp)->inobt_maxlevels);
ret = max(ret, mp->m_rmap_maxlevels);
ret = max(ret, mp->m_rtrmap_maxlevels);
+ ret = max(ret, mp->m_rtrefc_maxlevels);
return max(ret, mp->m_refc_maxlevels);
}
diff --git a/fs/xfs/libxfs/xfs_btree.h b/fs/xfs/libxfs/xfs_btree.h
index e6f9509b20a6..e0011e9fcfbe 100644
--- a/fs/xfs/libxfs/xfs_btree.h
+++ b/fs/xfs/libxfs/xfs_btree.h
@@ -38,6 +38,7 @@ union xfs_btree_key {
struct xfs_refcount_key refc;
struct xfs_rtrmap_key rtrmap;
struct xfs_rtrmap_key __rtrmap_bigkey[2];
+ struct xfs_rtrefcount_key rtrefc;
};
union xfs_btree_rec {
@@ -48,6 +49,7 @@ union xfs_btree_rec {
struct xfs_rmap_rec rmap;
struct xfs_refcount_rec refc;
struct xfs_rtrmap_rec rtrmap;
+ struct xfs_rtrefcount_rec rtrefc;
};
/*
@@ -182,6 +184,11 @@ union xfs_btree_irec {
struct xfs_refcount_irec rc;
};
+struct xbtree_refc {
+ unsigned long nr_ops; /* # record updates */
+ int shape_changes; /* # of extent splits */
+};
+
/* Per-AG btree information. */
struct xfs_btree_cur_ag {
union {
@@ -190,10 +197,7 @@ struct xfs_btree_cur_ag {
};
xfs_agnumber_t agno;
union {
- struct {
- unsigned long nr_ops; /* # record updates */
- int shape_changes; /* # of extent splits */
- } refc;
+ struct xbtree_refc refc;
struct {
bool active; /* allocation cursor state */
} abt;
@@ -213,6 +217,7 @@ struct xfs_btree_cur_ino {
/* For extent swap, ignore owner check in verifier */
#define XFS_BTCUR_BMBT_INVALID_OWNER (1 << 1)
+ struct xbtree_refc refc;
};
struct xfs_btree_level {
diff --git a/fs/xfs/libxfs/xfs_format.h b/fs/xfs/libxfs/xfs_format.h
index 8a6d2e25fe1d..e26fe754097b 100644
--- a/fs/xfs/libxfs/xfs_format.h
+++ b/fs/xfs/libxfs/xfs_format.h
@@ -1898,6 +1898,7 @@ struct xfs_refcount_irec {
#define MAXREFCOUNT ((xfs_nlink_t)~0U)
#define MAXREFCEXTLEN ((xfs_extlen_t)~0U)
+#define MAXRTREFCEXTLEN ((xfs_filblks_t)~0U)
/* btree pointer type */
typedef __be32 xfs_refcount_ptr_t;
@@ -1910,6 +1911,33 @@ typedef __be32 xfs_refcount_ptr_t;
#define XFS_RTREFC_CRC_MAGIC 0x52434e54 /* 'RCNT' */
/*
+ * Extents that are being used to stage a copy on write are stored
+ * in the refcount btree with a refcount of 1 and the upper bit set
+ * on the startblock. This speeds up mount time deletion of stale
+ * staging extents because they're all at the right side of the tree.
+ */
+#define XFS_RTREFC_COW_START ((xfs_fsblock_t)(1ULL << 63))
+#define RTREFCNTBT_COWFLAG_BITLEN 1
+#define RTREFCNTBT_RTBLOCK_BITLEN 63
+
+/*
+ * Reference count record for realtime volumes. Note that the units here are
+ * blocks, even though allocations are done in units of rt extents.
+ */
+struct xfs_rtrefcount_rec {
+ __be64 rc_startblock; /* starting block number */
+ __be64 rc_blockcount; /* count of blocks */
+ __be32 rc_refcount; /* number of inodes linked here */
+} __attribute__((packed));
+
+struct xfs_rtrefcount_key {
+ __be64 rc_startblock; /* starting block number */
+};
+
+/* btree pointer type */
+typedef __be64 xfs_rtrefcount_ptr_t;
+
+/*
* BMAP Btree format definitions
*
* This includes both the root block definition that sits inside an inode fork
diff --git a/fs/xfs/libxfs/xfs_rtrefcount_btree.c b/fs/xfs/libxfs/xfs_rtrefcount_btree.c
new file mode 100644
index 000000000000..20319aa49b49
--- /dev/null
+++ b/fs/xfs/libxfs/xfs_rtrefcount_btree.c
@@ -0,0 +1,253 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Copyright (C) 2021 Oracle. All Rights Reserved.
+ * Author: Darrick J. Wong <djwong@kernel.org>
+ */
+#include "xfs.h"
+#include "xfs_fs.h"
+#include "xfs_shared.h"
+#include "xfs_format.h"
+#include "xfs_log_format.h"
+#include "xfs_trans_resv.h"
+#include "xfs_bit.h"
+#include "xfs_sb.h"
+#include "xfs_mount.h"
+#include "xfs_defer.h"
+#include "xfs_inode.h"
+#include "xfs_trans.h"
+#include "xfs_alloc.h"
+#include "xfs_btree.h"
+#include "xfs_btree_staging.h"
+#include "xfs_rtrefcount_btree.h"
+#include "xfs_trace.h"
+#include "xfs_cksum.h"
+#include "xfs_error.h"
+#include "xfs_extent_busy.h"
+#include "xfs_ag_resv.h"
+
+/*
+ * Realtime Reference Count btree.
+ *
+ * This is a btree used to track the owner(s) of a given extent in the realtime
+ * device. See the comments in xfs_refcount_btree.c for more information.
+ *
+ * This tree is basically the same as the regular refcount btree except that it
+ * doesn't live in free space, and the startblock and blockcount fields have
+ * been widened to 64 bits.
+ */
+
+static struct xfs_btree_cur *
+xfs_rtrefcountbt_dup_cursor(
+ struct xfs_btree_cur *cur)
+{
+ struct xfs_btree_cur *new;
+
+ new = xfs_rtrefcountbt_init_cursor(cur->bc_mp, cur->bc_tp,
+ cur->bc_ino.ip);
+
+ /* Copy the flags values since init cursor doesn't get them. */
+ new->bc_ino.flags = cur->bc_ino.flags;
+
+ return new;
+}
+
+static xfs_failaddr_t
+xfs_rtrefcountbt_verify(
+ struct xfs_buf *bp)
+{
+ struct xfs_mount *mp = bp->b_target->bt_mount;
+ struct xfs_btree_block *block = XFS_BUF_TO_BLOCK(bp);
+ xfs_failaddr_t fa;
+ int level;
+
+ if (block->bb_magic != cpu_to_be32(XFS_RTREFC_CRC_MAGIC))
+ return __this_address;
+
+ if (!xfs_sb_version_hasreflink(&mp->m_sb))
+ return __this_address;
+ fa = xfs_btree_lblock_v5hdr_verify(bp, XFS_RMAP_OWN_UNKNOWN);
+ if (fa)
+ return fa;
+ level = be16_to_cpu(block->bb_level);
+ if (level > mp->m_rtrefc_maxlevels)
+ return __this_address;
+
+ return xfs_btree_lblock_verify(bp, mp->m_rtrefc_mxr[level != 0]);
+}
+
+static void
+xfs_rtrefcountbt_read_verify(
+ struct xfs_buf *bp)
+{
+ xfs_failaddr_t fa;
+
+ if (!xfs_btree_lblock_verify_crc(bp))
+ xfs_verifier_error(bp, -EFSBADCRC, __this_address);
+ else {
+ fa = xfs_rtrefcountbt_verify(bp);
+ if (fa)
+ xfs_verifier_error(bp, -EFSCORRUPTED, fa);
+ }
+
+ if (bp->b_error)
+ trace_xfs_btree_corrupt(bp, _RET_IP_);
+}
+
+static void
+xfs_rtrefcountbt_write_verify(
+ struct xfs_buf *bp)
+{
+ xfs_failaddr_t fa;
+
+ fa = xfs_rtrefcountbt_verify(bp);
+ if (fa) {
+ trace_xfs_btree_corrupt(bp, _RET_IP_);
+ xfs_verifier_error(bp, -EFSCORRUPTED, fa);
+ return;
+ }
+ xfs_btree_lblock_calc_crc(bp);
+
+}
+
+const struct xfs_buf_ops xfs_rtrefcountbt_buf_ops = {
+ .name = "xfs_rtrefcountbt",
+ .verify_read = xfs_rtrefcountbt_read_verify,
+ .verify_write = xfs_rtrefcountbt_write_verify,
+ .verify_struct = xfs_rtrefcountbt_verify,
+};
+
+static const struct xfs_btree_ops xfs_rtrefcountbt_ops = {
+ .rec_len = sizeof(struct xfs_rtrefcount_rec),
+ .key_len = sizeof(struct xfs_rtrefcount_key),
+
+ .dup_cursor = xfs_rtrefcountbt_dup_cursor,
+ .buf_ops = &xfs_rtrefcountbt_buf_ops,
+};
+
+/* Initialize a new rt refcount btree cursor. */
+static struct xfs_btree_cur *
+xfs_rtrefcountbt_init_common(
+ struct xfs_mount *mp,
+ struct xfs_trans *tp,
+ struct xfs_inode *ip)
+{
+ struct xfs_btree_cur *cur;
+
+ cur = xfs_btree_alloc_cursor(mp, tp, XFS_BTNUM_RTREFC);
+ cur->bc_flags = XFS_BTREE_LONG_PTRS | XFS_BTREE_ROOT_IN_INODE |
+ XFS_BTREE_CRC_BLOCKS | XFS_BTREE_IROOT_RECORDS;
+ cur->bc_statoff = XFS_STATS_CALC_INDEX(xs_refcbt_2);
+
+ cur->bc_ino.ip = ip;
+ cur->bc_ino.allocated = 0;
+ cur->bc_ino.flags = 0;
+ cur->bc_ino.refc.nr_ops = 0;
+ cur->bc_ino.refc.shape_changes = 0;
+ cur->bc_ops = &xfs_rtrefcountbt_ops;
+
+ return cur;
+}
+
+/* Allocate a new rt refcount btree cursor. */
+struct xfs_btree_cur *
+xfs_rtrefcountbt_init_cursor(
+ struct xfs_mount *mp,
+ struct xfs_trans *tp,
+ struct xfs_inode *ip)
+{
+ struct xfs_btree_cur *cur;
+ struct xfs_ifork *ifp = XFS_IFORK_PTR(ip, XFS_DATA_FORK);
+
+ cur = xfs_rtrefcountbt_init_common(mp, tp, ip);
+ cur->bc_nlevels = be16_to_cpu(ifp->if_broot->bb_level) + 1;
+ cur->bc_ino.forksize = XFS_IFORK_SIZE(ip, XFS_DATA_FORK);
+ cur->bc_ino.whichfork = XFS_DATA_FORK;
+ return cur;
+}
+
+/* Create a new rt reverse mapping btree cursor with a fake root for staging. */
+struct xfs_btree_cur *
+xfs_rtrefcountbt_stage_cursor(
+ struct xfs_mount *mp,
+ struct xfs_inode *ip,
+ struct xbtree_ifakeroot *ifake)
+{
+ struct xfs_btree_cur *cur;
+
+ cur = xfs_rtrefcountbt_init_common(mp, NULL, ip);
+ cur->bc_nlevels = ifake->if_levels;
+ cur->bc_ino.forksize = ifake->if_fork_size;
+ cur->bc_ino.whichfork = -1;
+ xfs_btree_stage_ifakeroot(cur, ifake, NULL);
+ return cur;
+}
+
+/*
+ * Install a new rt reverse mapping btree root. Caller is responsible for
+ * invalidating and freeing the old btree blocks.
+ */
+void
+xfs_rtrefcountbt_commit_staged_btree(
+ struct xfs_btree_cur *cur,
+ struct xfs_trans *tp)
+{
+ struct xbtree_ifakeroot *ifake = cur->bc_ino.ifake;
+ struct xfs_ifork *ifp;
+ int flags = XFS_ILOG_CORE | XFS_ILOG_DBROOT;
+
+ ASSERT(cur->bc_flags & XFS_BTREE_STAGING);
+
+ /*
+ * Free any resources hanging off the real fork, then shallow-copy the
+ * staging fork's contents into the real fork to transfer everything
+ * we just built.
+ */
+ ifp = XFS_IFORK_PTR(cur->bc_ino.ip, XFS_DATA_FORK);
+ xfs_idestroy_fork(ifp);
+ memcpy(ifp, ifake->if_fork, sizeof(struct xfs_ifork));
+
+ xfs_trans_log_inode(tp, cur->bc_ino.ip, flags);
+ xfs_btree_commit_ifakeroot(cur, tp, XFS_DATA_FORK,
+ &xfs_rtrefcountbt_ops);
+}
+
+/*
+ * Calculate number of records in an refcount btree block.
+ */
+unsigned int
+xfs_rtrefcountbt_maxrecs(
+ struct xfs_mount *mp,
+ unsigned int blocklen,
+ bool leaf)
+{
+ blocklen -= XFS_RTREFCOUNT_BLOCK_LEN;
+
+ if (leaf)
+ return blocklen / sizeof(struct xfs_rtrefcount_rec);
+ return blocklen / (sizeof(struct xfs_rtrefcount_key) +
+ sizeof(xfs_rtrefcount_ptr_t));
+}
+
+/* Compute the maximum height of an refcount btree. */
+unsigned int
+xfs_rtrefcountbt_compute_maxlevels(
+ struct xfs_mount *mp,
+ xfs_rfsblock_t dblocks,
+ xfs_rfsblock_t rblocks)
+{
+ xfs_rtblock_t rexts;
+ unsigned int d_maxlevels, r_maxlevels;
+
+ /*
+ * The realtime refcountbt lives on the data device, which means that
+ * its maximum height is constrained by the size of the data device and
+ * the height required to store one refcount record for each rt extent.
+ */
+ rexts = div_u64(rblocks, mp->m_sb.sb_rextsize);
+ d_maxlevels = xfs_btree_compute_maxlevels_size(dblocks,
+ mp->m_rtrefc_mnr[1]);
+ r_maxlevels = xfs_btree_compute_maxlevels(mp->m_rtrefc_mnr, rexts);
+
+ /* Add one level to handle the inode root level. */
+ return min(d_maxlevels, r_maxlevels) + 1;
+}
diff --git a/fs/xfs/libxfs/xfs_rtrefcount_btree.h b/fs/xfs/libxfs/xfs_rtrefcount_btree.h
new file mode 100644
index 000000000000..65094c38fe78
--- /dev/null
+++ b/fs/xfs/libxfs/xfs_rtrefcount_btree.h
@@ -0,0 +1,65 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+/*
+ * Copyright (C) 2021 Oracle. All Rights Reserved.
+ * Author: Darrick J. Wong <djwong@kernel.org>
+ */
+#ifndef __XFS_RTREFCOUNT_BTREE_H__
+#define __XFS_RTREFCOUNT_BTREE_H__
+
+struct xfs_buf;
+struct xfs_btree_cur;
+struct xfs_mount;
+struct xbtree_ifakeroot;
+
+/* refcounts only exist on crc enabled filesystems */
+#define XFS_RTREFCOUNT_BLOCK_LEN XFS_BTREE_LBLOCK_CRC_LEN
+
+struct xfs_btree_cur *xfs_rtrefcountbt_init_cursor(struct xfs_mount *mp,
+ struct xfs_trans *tp, struct xfs_inode *ip);
+struct xfs_btree_cur *xfs_rtrefcountbt_stage_cursor(struct xfs_mount *mp,
+ struct xfs_inode *ip, struct xbtree_ifakeroot *ifake);
+void xfs_rtrefcountbt_commit_staged_btree(struct xfs_btree_cur *cur,
+ struct xfs_trans *tp);
+unsigned int xfs_rtrefcountbt_maxrecs(struct xfs_mount *mp,
+ unsigned int blocklen, bool leaf);
+unsigned int xfs_rtrefcountbt_compute_maxlevels(struct xfs_mount *mp,
+ xfs_rfsblock_t dblocks, xfs_rfsblock_t rblocks);
+
+/*
+ * Addresses of records, keys, and pointers within an incore rtrefcountbt block.
+ *
+ * (note that some of these may appear unused, but they are used in userspace)
+ */
+static inline struct xfs_rtrefcount_rec *
+xfs_rtrefcount_rec_addr(
+ struct xfs_btree_block *block,
+ unsigned int index)
+{
+ return (struct xfs_rtrefcount_rec *)
+ ((char *)block + XFS_RTREFCOUNT_BLOCK_LEN +
+ (index - 1) * sizeof(struct xfs_rtrefcount_rec));
+}
+
+static inline struct xfs_rtrefcount_key *
+xfs_rtrefcount_key_addr(
+ struct xfs_btree_block *block,
+ unsigned int index)
+{
+ return (struct xfs_rtrefcount_key *)
+ ((char *)block + XFS_RTREFCOUNT_BLOCK_LEN +
+ (index - 1) * sizeof(struct xfs_rtrefcount_key));
+}
+
+static inline xfs_rtrefcount_ptr_t *
+xfs_rtrefcount_ptr_addr(
+ struct xfs_btree_block *block,
+ unsigned int index,
+ unsigned int maxrecs)
+{
+ return (xfs_rtrefcount_ptr_t *)
+ ((char *)block + XFS_RTREFCOUNT_BLOCK_LEN +
+ maxrecs * sizeof(struct xfs_rtrefcount_key) +
+ (index - 1) * sizeof(xfs_rtrefcount_ptr_t));
+}
+
+#endif /* __XFS_RTREFCOUNT_BTREE_H__ */
diff --git a/fs/xfs/libxfs/xfs_sb.c b/fs/xfs/libxfs/xfs_sb.c
index 098f16786e96..bd9ccaa73396 100644
--- a/fs/xfs/libxfs/xfs_sb.c
+++ b/fs/xfs/libxfs/xfs_sb.c
@@ -26,6 +26,7 @@
#include "xfs_da_format.h"
#include "xfs_health.h"
#include "xfs_rtrmap_btree.h"
+#include "xfs_rtrefcount_btree.h"
/*
* Physical superblock buffer manipulations. Shared with libxfs in userspace.
@@ -873,6 +874,13 @@ xfs_sb_mount_common(
mp->m_refc_mnr[0] = mp->m_refc_mxr[0] / 2;
mp->m_refc_mnr[1] = mp->m_refc_mxr[1] / 2;
+ mp->m_rtrefc_mxr[0] = xfs_rtrefcountbt_maxrecs(mp, sbp->sb_blocksize,
+ true);
+ mp->m_rtrefc_mxr[1] = xfs_rtrefcountbt_maxrecs(mp, sbp->sb_blocksize,
+ false);
+ mp->m_rtrefc_mnr[0] = mp->m_rtrefc_mxr[0] / 2;
+ mp->m_rtrefc_mnr[1] = mp->m_rtrefc_mxr[1] / 2;
+
mp->m_bsize = XFS_FSB_TO_BB(mp, 1);
mp->m_alloc_set_aside = xfs_alloc_set_aside(mp);
mp->m_ag_max_usable = xfs_alloc_ag_max_usable(mp);
diff --git a/fs/xfs/libxfs/xfs_shared.h b/fs/xfs/libxfs/xfs_shared.h
index 775c45b4561d..4232299519a7 100644
--- a/fs/xfs/libxfs/xfs_shared.h
+++ b/fs/xfs/libxfs/xfs_shared.h
@@ -30,6 +30,7 @@ extern const struct xfs_buf_ops xfs_cntbt_buf_ops;
extern const struct xfs_buf_ops xfs_rmapbt_buf_ops;
extern const struct xfs_buf_ops xfs_rtrmapbt_buf_ops;
extern const struct xfs_buf_ops xfs_refcountbt_buf_ops;
+extern const struct xfs_buf_ops xfs_rtrefcountbt_buf_ops;
extern const struct xfs_buf_ops xfs_attr3_leaf_buf_ops;
extern const struct xfs_buf_ops xfs_attr3_rmt_buf_ops;
extern const struct xfs_buf_ops xfs_bmbt_buf_ops;
diff --git a/fs/xfs/xfs_mount.c b/fs/xfs/xfs_mount.c
index 15069200af12..b2838f2ad8c8 100644
--- a/fs/xfs/xfs_mount.c
+++ b/fs/xfs/xfs_mount.c
@@ -34,6 +34,7 @@
#include "xfs_trace.h"
#include "xfs_imeta.h"
#include "xfs_rtrmap_btree.h"
+#include "xfs_rtrefcount_btree.h"
static DEFINE_MUTEX(xfs_uuid_table_mutex);
static int xfs_uuid_table_size;
@@ -801,6 +802,8 @@ xfs_mountfs(
mp->m_rtrmap_maxlevels = xfs_rtrmapbt_compute_maxlevels(mp,
mp->m_sb.sb_dblocks, mp->m_sb.sb_rblocks);
xfs_refcountbt_compute_maxlevels(mp);
+ mp->m_rtrefc_maxlevels = xfs_rtrefcountbt_compute_maxlevels(mp,
+ mp->m_sb.sb_dblocks, mp->m_sb.sb_rblocks);
/*
* Check if sb_agblocks is aligned at stripe boundary. If sb_agblocks
diff --git a/fs/xfs/xfs_mount.h b/fs/xfs/xfs_mount.h
index c83eb1401b65..ba73740a3687 100644
--- a/fs/xfs/xfs_mount.h
+++ b/fs/xfs/xfs_mount.h
@@ -130,11 +130,14 @@ typedef struct xfs_mount {
uint m_rtrmap_mnr[2]; /* min rtrmap btree records */
uint m_refc_mxr[2]; /* max refc btree records */
uint m_refc_mnr[2]; /* min refc btree records */
+ uint m_rtrefc_mxr[2]; /* max rtrefc btree records */
+ uint m_rtrefc_mnr[2]; /* min rtrefc btree records */
uint m_ag_maxlevels; /* XFS_AG_MAXLEVELS */
uint m_bm_maxlevels[2]; /* XFS_BM_MAXLEVELS */
uint m_rmap_maxlevels; /* max rmap btree levels */
uint m_rtrmap_maxlevels; /* max rtrmap btree level */
uint m_refc_maxlevels; /* max refcount btree level */
+ uint m_rtrefc_maxlevels; /* max rtrefc btree level */
xfs_extlen_t m_ag_prealloc_blocks; /* reserved ag blocks */
uint m_alloc_set_aside; /* space we can't use */
uint m_ag_max_usable; /* max space per AG */
diff --git a/fs/xfs/xfs_ondisk.h b/fs/xfs/xfs_ondisk.h
index b261c614a958..2723133e4d83 100644
--- a/fs/xfs/xfs_ondisk.h
+++ b/fs/xfs/xfs_ondisk.h
@@ -43,6 +43,8 @@ xfs_check_ondisk_structs(void)
XFS_CHECK_STRUCT_SIZE(struct xfs_inobt_rec, 16);
XFS_CHECK_STRUCT_SIZE(struct xfs_refcount_key, 4);
XFS_CHECK_STRUCT_SIZE(struct xfs_refcount_rec, 12);
+ XFS_CHECK_STRUCT_SIZE(struct xfs_rtrefcount_key, 8);
+ XFS_CHECK_STRUCT_SIZE(struct xfs_rtrefcount_rec, 20);
XFS_CHECK_STRUCT_SIZE(struct xfs_rmap_key, 20);
XFS_CHECK_STRUCT_SIZE(struct xfs_rmap_rec, 24);
XFS_CHECK_STRUCT_SIZE(xfs_timestamp_t, 8);