diff options
author | Darrick J. Wong <djwong@kernel.org> | 2021-01-05 17:46:58 -0800 |
---|---|---|
committer | Darrick J. Wong <djwong@kernel.org> | 2021-03-25 17:08:48 -0700 |
commit | d8ec53d054e733efc55c407a19a7be657acb0314 (patch) | |
tree | a95dfec4db960be9652eec9da5c77ddcec1bae8b /fs/xfs | |
parent | 59a2bf78fe9da0ac349d1cebe8f668e16fc7b8d1 (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/Makefile | 1 | ||||
-rw-r--r-- | fs/xfs/libxfs/xfs_btree.c | 4 | ||||
-rw-r--r-- | fs/xfs/libxfs/xfs_btree.h | 13 | ||||
-rw-r--r-- | fs/xfs/libxfs/xfs_format.h | 28 | ||||
-rw-r--r-- | fs/xfs/libxfs/xfs_rtrefcount_btree.c | 253 | ||||
-rw-r--r-- | fs/xfs/libxfs/xfs_rtrefcount_btree.h | 65 | ||||
-rw-r--r-- | fs/xfs/libxfs/xfs_sb.c | 8 | ||||
-rw-r--r-- | fs/xfs/libxfs/xfs_shared.h | 1 | ||||
-rw-r--r-- | fs/xfs/xfs_mount.c | 3 | ||||
-rw-r--r-- | fs/xfs/xfs_mount.h | 3 | ||||
-rw-r--r-- | fs/xfs/xfs_ondisk.h | 2 |
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); |