From 9488062805943c2d63350d3ef9e4dc093799789a Mon Sep 17 00:00:00 2001 From: "Darrick J. Wong" Date: Mon, 16 Oct 2023 09:16:06 -0700 Subject: xfs: bump max fsgeom struct version The latest version of the fs geometry structure is v5. Bump this constant so that xfs_db and mkfs calls to libxfs_fs_geometry will fill out all the fields. IOWs, this commit is a no-op for the kernel, but will be useful for userspace reporting in later changes. Signed-off-by: Darrick J. Wong Reviewed-by: Christoph Hellwig --- fs/xfs/libxfs/xfs_sb.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'fs/xfs') diff --git a/fs/xfs/libxfs/xfs_sb.h b/fs/xfs/libxfs/xfs_sb.h index a5e14740ec9a..19134b23c10b 100644 --- a/fs/xfs/libxfs/xfs_sb.h +++ b/fs/xfs/libxfs/xfs_sb.h @@ -25,7 +25,7 @@ extern uint64_t xfs_sb_version_to_features(struct xfs_sb *sbp); extern int xfs_update_secondary_sbs(struct xfs_mount *mp); -#define XFS_FS_GEOM_MAX_STRUCT_VER (4) +#define XFS_FS_GEOM_MAX_STRUCT_VER (5) extern void xfs_fs_geometry(struct xfs_mount *mp, struct xfs_fsop_geom *geo, int struct_version); extern int xfs_sb_read_secondary(struct xfs_mount *mp, -- cgit v1.2.3 From 6c664484337b37fa0cf6e958f4019623e30d40f7 Mon Sep 17 00:00:00 2001 From: "Darrick J. Wong" Date: Mon, 16 Oct 2023 09:16:22 -0700 Subject: xfs: hoist freeing of rt data fork extent mappings Currently, xfs_bmap_del_extent_real contains a bunch of code to convert the physical extent of a data fork mapping for a realtime file into rt extents and pass that to the rt extent freeing function. Since the details of this aren't needed when CONFIG_XFS_REALTIME=n, move it to xfs_rtbitmap.c to reduce code size when realtime isn't enabled. This will (one day) enable realtime EFIs to reuse the same unit-converting call with less code duplication. Signed-off-by: Darrick J. Wong Reviewed-by: Christoph Hellwig --- fs/xfs/libxfs/xfs_bmap.c | 19 +++---------------- fs/xfs/libxfs/xfs_rtbitmap.c | 33 +++++++++++++++++++++++++++++++++ fs/xfs/xfs_rtalloc.h | 5 +++++ 3 files changed, 41 insertions(+), 16 deletions(-) (limited to 'fs/xfs') diff --git a/fs/xfs/libxfs/xfs_bmap.c b/fs/xfs/libxfs/xfs_bmap.c index 30c931b38853..26bfa34b4bbf 100644 --- a/fs/xfs/libxfs/xfs_bmap.c +++ b/fs/xfs/libxfs/xfs_bmap.c @@ -5057,33 +5057,20 @@ xfs_bmap_del_extent_real( flags = XFS_ILOG_CORE; if (whichfork == XFS_DATA_FORK && XFS_IS_REALTIME_INODE(ip)) { - xfs_filblks_t len; - xfs_extlen_t mod; - - len = div_u64_rem(del->br_blockcount, mp->m_sb.sb_rextsize, - &mod); - ASSERT(mod == 0); - if (!(bflags & XFS_BMAPI_REMAP)) { - xfs_fsblock_t bno; - - bno = div_u64_rem(del->br_startblock, - mp->m_sb.sb_rextsize, &mod); - ASSERT(mod == 0); - - error = xfs_rtfree_extent(tp, bno, (xfs_extlen_t)len); + error = xfs_rtfree_blocks(tp, del->br_startblock, + del->br_blockcount); if (error) goto done; } do_fx = 0; - nblks = len * mp->m_sb.sb_rextsize; qfield = XFS_TRANS_DQ_RTBCOUNT; } else { do_fx = 1; - nblks = del->br_blockcount; qfield = XFS_TRANS_DQ_BCOUNT; } + nblks = del->br_blockcount; del_endblock = del->br_startblock + del->br_blockcount; if (cur) { diff --git a/fs/xfs/libxfs/xfs_rtbitmap.c b/fs/xfs/libxfs/xfs_rtbitmap.c index fa180ab66b73..655108a4cd05 100644 --- a/fs/xfs/libxfs/xfs_rtbitmap.c +++ b/fs/xfs/libxfs/xfs_rtbitmap.c @@ -1005,6 +1005,39 @@ xfs_rtfree_extent( return 0; } +/* + * Free some blocks in the realtime subvolume. rtbno and rtlen are in units of + * rt blocks, not rt extents; must be aligned to the rt extent size; and rtlen + * cannot exceed XFS_MAX_BMBT_EXTLEN. + */ +int +xfs_rtfree_blocks( + struct xfs_trans *tp, + xfs_fsblock_t rtbno, + xfs_filblks_t rtlen) +{ + struct xfs_mount *mp = tp->t_mountp; + xfs_rtblock_t bno; + xfs_filblks_t len; + xfs_extlen_t mod; + + ASSERT(rtlen <= XFS_MAX_BMBT_EXTLEN); + + len = div_u64_rem(rtlen, mp->m_sb.sb_rextsize, &mod); + if (mod) { + ASSERT(mod == 0); + return -EIO; + } + + bno = div_u64_rem(rtbno, mp->m_sb.sb_rextsize, &mod); + if (mod) { + ASSERT(mod == 0); + return -EIO; + } + + return xfs_rtfree_extent(tp, bno, len); +} + /* Find all the free records within a given range. */ int xfs_rtalloc_query_range( diff --git a/fs/xfs/xfs_rtalloc.h b/fs/xfs/xfs_rtalloc.h index 62c7ad79cbb6..3b2f1b499a11 100644 --- a/fs/xfs/xfs_rtalloc.h +++ b/fs/xfs/xfs_rtalloc.h @@ -58,6 +58,10 @@ xfs_rtfree_extent( xfs_rtblock_t bno, /* starting block number to free */ xfs_extlen_t len); /* length of extent freed */ +/* Same as above, but in units of rt blocks. */ +int xfs_rtfree_blocks(struct xfs_trans *tp, xfs_fsblock_t rtbno, + xfs_filblks_t rtlen); + /* * Initialize realtime fields in the mount structure. */ @@ -139,6 +143,7 @@ int xfs_rtalloc_reinit_frextents(struct xfs_mount *mp); #else # define xfs_rtallocate_extent(t,b,min,max,l,f,p,rb) (ENOSYS) # define xfs_rtfree_extent(t,b,l) (ENOSYS) +# define xfs_rtfree_blocks(t,rb,rl) (ENOSYS) # define xfs_rtpick_extent(m,t,l,rb) (ENOSYS) # define xfs_growfs_rt(mp,in) (ENOSYS) # define xfs_rtalloc_query_range(t,l,h,f,p) (ENOSYS) -- cgit v1.2.3 From b73494fa9a304ab95b59f07845e8d7d36e4d23e0 Mon Sep 17 00:00:00 2001 From: "Darrick J. Wong" Date: Mon, 16 Oct 2023 09:21:05 -0700 Subject: xfs: prevent rt growfs when quota is enabled Quotas aren't (yet) supported with realtime, so we shouldn't allow userspace to set up a realtime section when quotas are enabled, even if they attached one via mount options. IOWS, you shouldn't be able to do: # mkfs.xfs -f /dev/sda # mount /dev/sda /mnt -o rtdev=/dev/sdb,usrquota # xfs_growfs -r /mnt Signed-off-by: Darrick J. Wong Reviewed-by: Christoph Hellwig --- fs/xfs/xfs_rtalloc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'fs/xfs') diff --git a/fs/xfs/xfs_rtalloc.c b/fs/xfs/xfs_rtalloc.c index 16534e9873f6..31fd65b3aaa9 100644 --- a/fs/xfs/xfs_rtalloc.c +++ b/fs/xfs/xfs_rtalloc.c @@ -954,7 +954,7 @@ xfs_growfs_rt( return -EINVAL; /* Unsupported realtime features. */ - if (xfs_has_rmapbt(mp) || xfs_has_reflink(mp)) + if (xfs_has_rmapbt(mp) || xfs_has_reflink(mp) || xfs_has_quota(mp)) return -EOPNOTSUPP; nrblocks = in->newblocks; -- cgit v1.2.3 From c2988eb5cff75c02bc57e02c323154aa08f55b78 Mon Sep 17 00:00:00 2001 From: "Darrick J. Wong" Date: Mon, 16 Oct 2023 09:21:21 -0700 Subject: xfs: rt stubs should return negative errnos when rt disabled When realtime support is not compiled into the kernel, these functions should return negative errnos, not positive errnos. While we're at it, fix a broken macro declaration. Signed-off-by: Darrick J. Wong Reviewed-by: Christoph Hellwig --- fs/xfs/xfs_rtalloc.h | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) (limited to 'fs/xfs') diff --git a/fs/xfs/xfs_rtalloc.h b/fs/xfs/xfs_rtalloc.h index 3b2f1b499a11..65c284e9d33e 100644 --- a/fs/xfs/xfs_rtalloc.h +++ b/fs/xfs/xfs_rtalloc.h @@ -141,17 +141,17 @@ int xfs_rtalloc_extent_is_free(struct xfs_mount *mp, struct xfs_trans *tp, bool *is_free); int xfs_rtalloc_reinit_frextents(struct xfs_mount *mp); #else -# define xfs_rtallocate_extent(t,b,min,max,l,f,p,rb) (ENOSYS) -# define xfs_rtfree_extent(t,b,l) (ENOSYS) -# define xfs_rtfree_blocks(t,rb,rl) (ENOSYS) -# define xfs_rtpick_extent(m,t,l,rb) (ENOSYS) -# define xfs_growfs_rt(mp,in) (ENOSYS) -# define xfs_rtalloc_query_range(t,l,h,f,p) (ENOSYS) -# define xfs_rtalloc_query_all(m,t,f,p) (ENOSYS) -# define xfs_rtbuf_get(m,t,b,i,p) (ENOSYS) -# define xfs_verify_rtbno(m, r) (false) -# define xfs_rtalloc_extent_is_free(m,t,s,l,i) (ENOSYS) -# define xfs_rtalloc_reinit_frextents(m) (0) +# define xfs_rtallocate_extent(t,b,min,max,l,f,p,rb) (-ENOSYS) +# define xfs_rtfree_extent(t,b,l) (-ENOSYS) +# define xfs_rtfree_blocks(t,rb,rl) (-ENOSYS) +# define xfs_rtpick_extent(m,t,l,rb) (-ENOSYS) +# define xfs_growfs_rt(mp,in) (-ENOSYS) +# define xfs_rtalloc_query_range(m,t,l,h,f,p) (-ENOSYS) +# define xfs_rtalloc_query_all(m,t,f,p) (-ENOSYS) +# define xfs_rtbuf_get(m,t,b,i,p) (-ENOSYS) +# define xfs_verify_rtbno(m, r) (false) +# define xfs_rtalloc_extent_is_free(m,t,s,l,i) (-ENOSYS) +# define xfs_rtalloc_reinit_frextents(m) (0) static inline int /* error */ xfs_rtmount_init( xfs_mount_t *mp) /* file system mount structure */ @@ -162,7 +162,7 @@ xfs_rtmount_init( xfs_warn(mp, "Not built with CONFIG_XFS_RT"); return -ENOSYS; } -# define xfs_rtmount_inodes(m) (((mp)->m_sb.sb_rblocks == 0)? 0 : (ENOSYS)) +# define xfs_rtmount_inodes(m) (((mp)->m_sb.sb_rblocks == 0)? 0 : (-ENOSYS)) # define xfs_rtunmount_inodes(m) #endif /* CONFIG_XFS_RT */ -- cgit v1.2.3 From ddd98076d5c075c8a6c49d9e6e8ee12844137f23 Mon Sep 17 00:00:00 2001 From: "Darrick J. Wong" Date: Mon, 16 Oct 2023 09:21:37 -0700 Subject: xfs: fix units conversion error in xfs_bmap_del_extent_delay The unit conversions in this function do not make sense. First we convert a block count to bytes, then divide that bytes value by rextsize, which is in blocks, to get an rt extent count. You can't divide bytes by blocks to get a (possibly multiblock) extent value. Fortunately nobody uses delalloc on the rt volume so this hasn't mattered. Fixes: fa5c836ca8eb5 ("xfs: refactor xfs_bunmapi_cow") Signed-off-by: Darrick J. Wong Reviewed-by: Christoph Hellwig --- fs/xfs/libxfs/xfs_bmap.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'fs/xfs') diff --git a/fs/xfs/libxfs/xfs_bmap.c b/fs/xfs/libxfs/xfs_bmap.c index 26bfa34b4bbf..617cc7e78e38 100644 --- a/fs/xfs/libxfs/xfs_bmap.c +++ b/fs/xfs/libxfs/xfs_bmap.c @@ -4827,7 +4827,7 @@ xfs_bmap_del_extent_delay( ASSERT(got_endoff >= del_endoff); if (isrt) { - uint64_t rtexts = XFS_FSB_TO_B(mp, del->br_blockcount); + uint64_t rtexts = del->br_blockcount; do_div(rtexts, mp->m_sb.sb_rextsize); xfs_mod_frextents(mp, rtexts); -- cgit v1.2.3 From f6a2dae2a1f52ea23f649c02615d073beba4cc35 Mon Sep 17 00:00:00 2001 From: "Darrick J. Wong" Date: Mon, 16 Oct 2023 09:21:38 -0700 Subject: xfs: make sure maxlen is still congruent with prod when rounding down In commit 2a6ca4baed62, we tried to fix an overflow problem in the realtime allocator that was caused by an overly large maxlen value causing xfs_rtcheck_range to run off the end of the realtime bitmap. Unfortunately, there is a subtle bug here -- maxlen (and minlen) both have to be aligned with @prod, but @prod can be larger than 1 if the user has set an extent size hint on the file, and that extent size hint is larger than the realtime extent size. If the rt free space extents are not aligned to this file's extszhint because other files without extent size hints allocated space (or the number of rt extents is similarly not aligned), then it's possible that maxlen after clamping to sb_rextents will no longer be aligned to prod. The allocation will succeed just fine, but we still trip the assertion. Fix the problem by reducing maxlen by any misalignment with prod. While we're at it, split the assertions into two so that we can tell which value had the bad alignment. Fixes: 2a6ca4baed62 ("xfs: make sure the rt allocator doesn't run off the end") Signed-off-by: Darrick J. Wong Reviewed-by: Christoph Hellwig --- fs/xfs/xfs_rtalloc.c | 31 ++++++++++++++++++++++++++----- 1 file changed, 26 insertions(+), 5 deletions(-) (limited to 'fs/xfs') diff --git a/fs/xfs/xfs_rtalloc.c b/fs/xfs/xfs_rtalloc.c index 31fd65b3aaa9..0e4e2df08aed 100644 --- a/fs/xfs/xfs_rtalloc.c +++ b/fs/xfs/xfs_rtalloc.c @@ -211,6 +211,23 @@ xfs_rtallocate_range( return error; } +/* + * Make sure we don't run off the end of the rt volume. Be careful that + * adjusting maxlen downwards doesn't cause us to fail the alignment checks. + */ +static inline xfs_extlen_t +xfs_rtallocate_clamp_len( + struct xfs_mount *mp, + xfs_rtblock_t startrtx, + xfs_extlen_t rtxlen, + xfs_extlen_t prod) +{ + xfs_extlen_t ret; + + ret = min(mp->m_sb.sb_rextents, startrtx + rtxlen) - startrtx; + return rounddown(ret, prod); +} + /* * Attempt to allocate an extent minlen<=len<=maxlen starting from * bitmap block bbno. If we don't get maxlen then use prod to trim @@ -248,7 +265,7 @@ xfs_rtallocate_extent_block( i <= end; i++) { /* Make sure we don't scan off the end of the rt volume. */ - maxlen = min(mp->m_sb.sb_rextents, i + maxlen) - i; + maxlen = xfs_rtallocate_clamp_len(mp, i, maxlen, prod); /* * See if there's a free extent of maxlen starting at i. @@ -355,7 +372,8 @@ xfs_rtallocate_extent_exact( int isfree; /* extent is free */ xfs_rtblock_t next; /* next block to try (dummy) */ - ASSERT(minlen % prod == 0 && maxlen % prod == 0); + ASSERT(minlen % prod == 0); + ASSERT(maxlen % prod == 0); /* * Check if the range in question (for maxlen) is free. */ @@ -438,7 +456,9 @@ xfs_rtallocate_extent_near( xfs_rtblock_t n; /* next block to try */ xfs_rtblock_t r; /* result block */ - ASSERT(minlen % prod == 0 && maxlen % prod == 0); + ASSERT(minlen % prod == 0); + ASSERT(maxlen % prod == 0); + /* * If the block number given is off the end, silently set it to * the last block. @@ -447,7 +467,7 @@ xfs_rtallocate_extent_near( bno = mp->m_sb.sb_rextents - 1; /* Make sure we don't run off the end of the rt volume. */ - maxlen = min(mp->m_sb.sb_rextents, bno + maxlen) - bno; + maxlen = xfs_rtallocate_clamp_len(mp, bno, maxlen, prod); if (maxlen < minlen) { *rtblock = NULLRTBLOCK; return 0; @@ -638,7 +658,8 @@ xfs_rtallocate_extent_size( xfs_rtblock_t r; /* result block number */ xfs_suminfo_t sum; /* summary information for extents */ - ASSERT(minlen % prod == 0 && maxlen % prod == 0); + ASSERT(minlen % prod == 0); + ASSERT(maxlen % prod == 0); ASSERT(maxlen != 0); /* -- cgit v1.2.3 From 13928113fc5b5e79c91796290a99ed991ac0efe2 Mon Sep 17 00:00:00 2001 From: "Darrick J. Wong" Date: Mon, 16 Oct 2023 09:21:47 -0700 Subject: xfs: move the xfs_rtbitmap.c declarations to xfs_rtbitmap.h Move all the declarations for functionality in xfs_rtbitmap.c into a separate xfs_rtbitmap.h header file. Signed-off-by: Darrick J. Wong Reviewed-by: Christoph Hellwig --- fs/xfs/libxfs/xfs_bmap.c | 2 +- fs/xfs/libxfs/xfs_rtbitmap.c | 1 + fs/xfs/libxfs/xfs_rtbitmap.h | 82 ++++++++++++++++++++++++++++++++++++++++++++ fs/xfs/scrub/fscounters.c | 2 +- fs/xfs/scrub/rtbitmap.c | 2 +- fs/xfs/scrub/rtsummary.c | 2 +- fs/xfs/xfs_fsmap.c | 2 +- fs/xfs/xfs_rtalloc.c | 1 + fs/xfs/xfs_rtalloc.h | 73 --------------------------------------- 9 files changed, 89 insertions(+), 78 deletions(-) create mode 100644 fs/xfs/libxfs/xfs_rtbitmap.h (limited to 'fs/xfs') diff --git a/fs/xfs/libxfs/xfs_bmap.c b/fs/xfs/libxfs/xfs_bmap.c index 617cc7e78e38..a47da8d3d1bc 100644 --- a/fs/xfs/libxfs/xfs_bmap.c +++ b/fs/xfs/libxfs/xfs_bmap.c @@ -21,7 +21,7 @@ #include "xfs_bmap.h" #include "xfs_bmap_util.h" #include "xfs_bmap_btree.h" -#include "xfs_rtalloc.h" +#include "xfs_rtbitmap.h" #include "xfs_errortag.h" #include "xfs_error.h" #include "xfs_quota.h" diff --git a/fs/xfs/libxfs/xfs_rtbitmap.c b/fs/xfs/libxfs/xfs_rtbitmap.c index 655108a4cd05..9eb1b5aa7e35 100644 --- a/fs/xfs/libxfs/xfs_rtbitmap.c +++ b/fs/xfs/libxfs/xfs_rtbitmap.c @@ -16,6 +16,7 @@ #include "xfs_trans.h" #include "xfs_rtalloc.h" #include "xfs_error.h" +#include "xfs_rtbitmap.h" /* * Realtime allocator bitmap functions shared with userspace. diff --git a/fs/xfs/libxfs/xfs_rtbitmap.h b/fs/xfs/libxfs/xfs_rtbitmap.h new file mode 100644 index 000000000000..546dea34bb37 --- /dev/null +++ b/fs/xfs/libxfs/xfs_rtbitmap.h @@ -0,0 +1,82 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (c) 2000-2003,2005 Silicon Graphics, Inc. + * All Rights Reserved. + */ +#ifndef __XFS_RTBITMAP_H__ +#define __XFS_RTBITMAP_H__ + +/* + * XXX: Most of the realtime allocation functions deal in units of realtime + * extents, not realtime blocks. This looks funny when paired with the type + * name and screams for a larger cleanup. + */ +struct xfs_rtalloc_rec { + xfs_rtblock_t ar_startext; + xfs_rtblock_t ar_extcount; +}; + +typedef int (*xfs_rtalloc_query_range_fn)( + struct xfs_mount *mp, + struct xfs_trans *tp, + const struct xfs_rtalloc_rec *rec, + void *priv); + +#ifdef CONFIG_XFS_RT +int xfs_rtbuf_get(struct xfs_mount *mp, struct xfs_trans *tp, + xfs_rtblock_t block, int issum, struct xfs_buf **bpp); +int xfs_rtcheck_range(struct xfs_mount *mp, struct xfs_trans *tp, + xfs_rtblock_t start, xfs_extlen_t len, int val, + xfs_rtblock_t *new, int *stat); +int xfs_rtfind_back(struct xfs_mount *mp, struct xfs_trans *tp, + xfs_rtblock_t start, xfs_rtblock_t limit, + xfs_rtblock_t *rtblock); +int xfs_rtfind_forw(struct xfs_mount *mp, struct xfs_trans *tp, + xfs_rtblock_t start, xfs_rtblock_t limit, + xfs_rtblock_t *rtblock); +int xfs_rtmodify_range(struct xfs_mount *mp, struct xfs_trans *tp, + xfs_rtblock_t start, xfs_extlen_t len, int val); +int xfs_rtmodify_summary_int(struct xfs_mount *mp, struct xfs_trans *tp, + int log, xfs_rtblock_t bbno, int delta, + struct xfs_buf **rbpp, xfs_fsblock_t *rsb, + xfs_suminfo_t *sum); +int xfs_rtmodify_summary(struct xfs_mount *mp, struct xfs_trans *tp, int log, + xfs_rtblock_t bbno, int delta, struct xfs_buf **rbpp, + xfs_fsblock_t *rsb); +int xfs_rtfree_range(struct xfs_mount *mp, struct xfs_trans *tp, + xfs_rtblock_t start, xfs_extlen_t len, + struct xfs_buf **rbpp, xfs_fsblock_t *rsb); +int xfs_rtalloc_query_range(struct xfs_mount *mp, struct xfs_trans *tp, + const struct xfs_rtalloc_rec *low_rec, + const struct xfs_rtalloc_rec *high_rec, + xfs_rtalloc_query_range_fn fn, void *priv); +int xfs_rtalloc_query_all(struct xfs_mount *mp, struct xfs_trans *tp, + xfs_rtalloc_query_range_fn fn, + void *priv); +bool xfs_verify_rtbno(struct xfs_mount *mp, xfs_rtblock_t rtbno); +int xfs_rtalloc_extent_is_free(struct xfs_mount *mp, struct xfs_trans *tp, + xfs_rtblock_t start, xfs_extlen_t len, + bool *is_free); +/* + * Free an extent in the realtime subvolume. Length is expressed in + * realtime extents, as is the block number. + */ +int /* error */ +xfs_rtfree_extent( + struct xfs_trans *tp, /* transaction pointer */ + xfs_rtblock_t bno, /* starting block number to free */ + xfs_extlen_t len); /* length of extent freed */ + +/* Same as above, but in units of rt blocks. */ +int xfs_rtfree_blocks(struct xfs_trans *tp, xfs_fsblock_t rtbno, + xfs_filblks_t rtlen); +#else /* CONFIG_XFS_RT */ +# define xfs_rtfree_extent(t,b,l) (-ENOSYS) +# define xfs_rtfree_blocks(t,rb,rl) (-ENOSYS) +# define xfs_rtalloc_query_range(m,t,l,h,f,p) (-ENOSYS) +# define xfs_rtalloc_query_all(m,t,f,p) (-ENOSYS) +# define xfs_rtbuf_get(m,t,b,i,p) (-ENOSYS) +# define xfs_rtalloc_extent_is_free(m,t,s,l,i) (-ENOSYS) +#endif /* CONFIG_XFS_RT */ + +#endif /* __XFS_RTBITMAP_H__ */ diff --git a/fs/xfs/scrub/fscounters.c b/fs/xfs/scrub/fscounters.c index 05be757668bb..5799e9a94f1f 100644 --- a/fs/xfs/scrub/fscounters.c +++ b/fs/xfs/scrub/fscounters.c @@ -16,7 +16,7 @@ #include "xfs_health.h" #include "xfs_btree.h" #include "xfs_ag.h" -#include "xfs_rtalloc.h" +#include "xfs_rtbitmap.h" #include "xfs_inode.h" #include "xfs_icache.h" #include "scrub/scrub.h" diff --git a/fs/xfs/scrub/rtbitmap.c b/fs/xfs/scrub/rtbitmap.c index 008ddb599e13..2e5fd52f7af3 100644 --- a/fs/xfs/scrub/rtbitmap.c +++ b/fs/xfs/scrub/rtbitmap.c @@ -11,7 +11,7 @@ #include "xfs_mount.h" #include "xfs_log_format.h" #include "xfs_trans.h" -#include "xfs_rtalloc.h" +#include "xfs_rtbitmap.h" #include "xfs_inode.h" #include "xfs_bmap.h" #include "scrub/scrub.h" diff --git a/fs/xfs/scrub/rtsummary.c b/fs/xfs/scrub/rtsummary.c index 437ed9acbb27..f4635a920470 100644 --- a/fs/xfs/scrub/rtsummary.c +++ b/fs/xfs/scrub/rtsummary.c @@ -13,7 +13,7 @@ #include "xfs_inode.h" #include "xfs_log_format.h" #include "xfs_trans.h" -#include "xfs_rtalloc.h" +#include "xfs_rtbitmap.h" #include "xfs_bit.h" #include "xfs_bmap.h" #include "scrub/scrub.h" diff --git a/fs/xfs/xfs_fsmap.c b/fs/xfs/xfs_fsmap.c index 736e5545f584..8982c5d6cbd0 100644 --- a/fs/xfs/xfs_fsmap.c +++ b/fs/xfs/xfs_fsmap.c @@ -23,7 +23,7 @@ #include "xfs_refcount.h" #include "xfs_refcount_btree.h" #include "xfs_alloc_btree.h" -#include "xfs_rtalloc.h" +#include "xfs_rtbitmap.h" #include "xfs_ag.h" /* Convert an xfs_fsmap to an fsmap. */ diff --git a/fs/xfs/xfs_rtalloc.c b/fs/xfs/xfs_rtalloc.c index 0e4e2df08aed..f2eb0c8b595d 100644 --- a/fs/xfs/xfs_rtalloc.c +++ b/fs/xfs/xfs_rtalloc.c @@ -19,6 +19,7 @@ #include "xfs_icache.h" #include "xfs_rtalloc.h" #include "xfs_sb.h" +#include "xfs_rtbitmap.h" /* * Read and return the summary information for a given extent size, diff --git a/fs/xfs/xfs_rtalloc.h b/fs/xfs/xfs_rtalloc.h index 65c284e9d33e..11859c259a1c 100644 --- a/fs/xfs/xfs_rtalloc.h +++ b/fs/xfs/xfs_rtalloc.h @@ -11,22 +11,6 @@ struct xfs_mount; struct xfs_trans; -/* - * XXX: Most of the realtime allocation functions deal in units of realtime - * extents, not realtime blocks. This looks funny when paired with the type - * name and screams for a larger cleanup. - */ -struct xfs_rtalloc_rec { - xfs_rtblock_t ar_startext; - xfs_rtblock_t ar_extcount; -}; - -typedef int (*xfs_rtalloc_query_range_fn)( - struct xfs_mount *mp, - struct xfs_trans *tp, - const struct xfs_rtalloc_rec *rec, - void *priv); - #ifdef CONFIG_XFS_RT /* * Function prototypes for exported functions. @@ -48,19 +32,6 @@ xfs_rtallocate_extent( xfs_extlen_t prod, /* extent product factor */ xfs_rtblock_t *rtblock); /* out: start block allocated */ -/* - * Free an extent in the realtime subvolume. Length is expressed in - * realtime extents, as is the block number. - */ -int /* error */ -xfs_rtfree_extent( - struct xfs_trans *tp, /* transaction pointer */ - xfs_rtblock_t bno, /* starting block number to free */ - xfs_extlen_t len); /* length of extent freed */ - -/* Same as above, but in units of rt blocks. */ -int xfs_rtfree_blocks(struct xfs_trans *tp, xfs_fsblock_t rtbno, - xfs_filblks_t rtlen); /* * Initialize realtime fields in the mount structure. @@ -102,55 +73,11 @@ xfs_growfs_rt( struct xfs_mount *mp, /* file system mount structure */ xfs_growfs_rt_t *in); /* user supplied growfs struct */ -/* - * From xfs_rtbitmap.c - */ -int xfs_rtbuf_get(struct xfs_mount *mp, struct xfs_trans *tp, - xfs_rtblock_t block, int issum, struct xfs_buf **bpp); -int xfs_rtcheck_range(struct xfs_mount *mp, struct xfs_trans *tp, - xfs_rtblock_t start, xfs_extlen_t len, int val, - xfs_rtblock_t *new, int *stat); -int xfs_rtfind_back(struct xfs_mount *mp, struct xfs_trans *tp, - xfs_rtblock_t start, xfs_rtblock_t limit, - xfs_rtblock_t *rtblock); -int xfs_rtfind_forw(struct xfs_mount *mp, struct xfs_trans *tp, - xfs_rtblock_t start, xfs_rtblock_t limit, - xfs_rtblock_t *rtblock); -int xfs_rtmodify_range(struct xfs_mount *mp, struct xfs_trans *tp, - xfs_rtblock_t start, xfs_extlen_t len, int val); -int xfs_rtmodify_summary_int(struct xfs_mount *mp, struct xfs_trans *tp, - int log, xfs_rtblock_t bbno, int delta, - struct xfs_buf **rbpp, xfs_fsblock_t *rsb, - xfs_suminfo_t *sum); -int xfs_rtmodify_summary(struct xfs_mount *mp, struct xfs_trans *tp, int log, - xfs_rtblock_t bbno, int delta, struct xfs_buf **rbpp, - xfs_fsblock_t *rsb); -int xfs_rtfree_range(struct xfs_mount *mp, struct xfs_trans *tp, - xfs_rtblock_t start, xfs_extlen_t len, - struct xfs_buf **rbpp, xfs_fsblock_t *rsb); -int xfs_rtalloc_query_range(struct xfs_mount *mp, struct xfs_trans *tp, - const struct xfs_rtalloc_rec *low_rec, - const struct xfs_rtalloc_rec *high_rec, - xfs_rtalloc_query_range_fn fn, void *priv); -int xfs_rtalloc_query_all(struct xfs_mount *mp, struct xfs_trans *tp, - xfs_rtalloc_query_range_fn fn, - void *priv); -bool xfs_verify_rtbno(struct xfs_mount *mp, xfs_rtblock_t rtbno); -int xfs_rtalloc_extent_is_free(struct xfs_mount *mp, struct xfs_trans *tp, - xfs_rtblock_t start, xfs_extlen_t len, - bool *is_free); int xfs_rtalloc_reinit_frextents(struct xfs_mount *mp); #else # define xfs_rtallocate_extent(t,b,min,max,l,f,p,rb) (-ENOSYS) -# define xfs_rtfree_extent(t,b,l) (-ENOSYS) -# define xfs_rtfree_blocks(t,rb,rl) (-ENOSYS) # define xfs_rtpick_extent(m,t,l,rb) (-ENOSYS) # define xfs_growfs_rt(mp,in) (-ENOSYS) -# define xfs_rtalloc_query_range(m,t,l,h,f,p) (-ENOSYS) -# define xfs_rtalloc_query_all(m,t,f,p) (-ENOSYS) -# define xfs_rtbuf_get(m,t,b,i,p) (-ENOSYS) -# define xfs_verify_rtbno(m, r) (false) -# define xfs_rtalloc_extent_is_free(m,t,s,l,i) (-ENOSYS) # define xfs_rtalloc_reinit_frextents(m) (0) static inline int /* error */ xfs_rtmount_init( -- cgit v1.2.3 From a684c538bc14410565e8939393089670fa1e19dd Mon Sep 17 00:00:00 2001 From: "Darrick J. Wong" Date: Mon, 16 Oct 2023 09:31:11 -0700 Subject: xfs: convert xfs_extlen_t to xfs_rtxlen_t in the rt allocator In most of the filesystem, we use xfs_extlen_t to store the length of a file (or AG) space mapping in units of fs blocks. Unfortunately, the realtime allocator also uses it to store the length of a rt space mapping in units of rt extents. This is confusing, since one rt extent can consist of many fs blocks. Separate the two by introducing a new type (xfs_rtxlen_t) to store the length of a space mapping (in units of realtime extents) that would be found in a file. Signed-off-by: Darrick J. Wong Reviewed-by: Christoph Hellwig --- fs/xfs/libxfs/xfs_rtbitmap.c | 12 ++++----- fs/xfs/libxfs/xfs_rtbitmap.h | 11 ++++----- fs/xfs/libxfs/xfs_types.h | 1 + fs/xfs/scrub/rtbitmap.c | 2 +- fs/xfs/xfs_bmap_util.c | 6 ++--- fs/xfs/xfs_rtalloc.c | 58 ++++++++++++++++++++++---------------------- fs/xfs/xfs_rtalloc.h | 10 ++++---- 7 files changed, 50 insertions(+), 50 deletions(-) (limited to 'fs/xfs') diff --git a/fs/xfs/libxfs/xfs_rtbitmap.c b/fs/xfs/libxfs/xfs_rtbitmap.c index 9eb1b5aa7e35..d33c3e561077 100644 --- a/fs/xfs/libxfs/xfs_rtbitmap.c +++ b/fs/xfs/libxfs/xfs_rtbitmap.c @@ -534,7 +534,7 @@ xfs_rtmodify_range( xfs_mount_t *mp, /* file system mount point */ xfs_trans_t *tp, /* transaction pointer */ xfs_rtblock_t start, /* starting block to modify */ - xfs_extlen_t len, /* length of extent to modify */ + xfs_rtxlen_t len, /* length of extent to modify */ int val) /* 1 for free, 0 for allocated */ { xfs_rtword_t *b; /* current word in buffer */ @@ -690,7 +690,7 @@ xfs_rtfree_range( xfs_mount_t *mp, /* file system mount point */ xfs_trans_t *tp, /* transaction pointer */ xfs_rtblock_t start, /* starting block to free */ - xfs_extlen_t len, /* length to free */ + xfs_rtxlen_t len, /* length to free */ struct xfs_buf **rbpp, /* in/out: summary block buffer */ xfs_fsblock_t *rsb) /* in/out: summary block number */ { @@ -766,7 +766,7 @@ xfs_rtcheck_range( xfs_mount_t *mp, /* file system mount point */ xfs_trans_t *tp, /* transaction pointer */ xfs_rtblock_t start, /* starting block number of extent */ - xfs_extlen_t len, /* length of extent */ + xfs_rtxlen_t len, /* length of extent */ int val, /* 1 for free, 0 for allocated */ xfs_rtblock_t *new, /* out: first block not matching */ int *stat) /* out: 1 for matches, 0 for not */ @@ -942,7 +942,7 @@ xfs_rtcheck_alloc_range( xfs_mount_t *mp, /* file system mount point */ xfs_trans_t *tp, /* transaction pointer */ xfs_rtblock_t bno, /* starting block number of extent */ - xfs_extlen_t len) /* length of extent */ + xfs_rtxlen_t len) /* length of extent */ { xfs_rtblock_t new; /* dummy for xfs_rtcheck_range */ int stat; @@ -965,7 +965,7 @@ int /* error */ xfs_rtfree_extent( xfs_trans_t *tp, /* transaction pointer */ xfs_rtblock_t bno, /* starting block number to free */ - xfs_extlen_t len) /* length of extent freed */ + xfs_rtxlen_t len) /* length of extent freed */ { int error; /* error value */ xfs_mount_t *mp; /* file system mount structure */ @@ -1116,7 +1116,7 @@ xfs_rtalloc_extent_is_free( struct xfs_mount *mp, struct xfs_trans *tp, xfs_rtblock_t start, - xfs_extlen_t len, + xfs_rtxlen_t len, bool *is_free) { xfs_rtblock_t end; diff --git a/fs/xfs/libxfs/xfs_rtbitmap.h b/fs/xfs/libxfs/xfs_rtbitmap.h index 546dea34bb37..d4449610154a 100644 --- a/fs/xfs/libxfs/xfs_rtbitmap.h +++ b/fs/xfs/libxfs/xfs_rtbitmap.h @@ -26,7 +26,7 @@ typedef int (*xfs_rtalloc_query_range_fn)( int xfs_rtbuf_get(struct xfs_mount *mp, struct xfs_trans *tp, xfs_rtblock_t block, int issum, struct xfs_buf **bpp); int xfs_rtcheck_range(struct xfs_mount *mp, struct xfs_trans *tp, - xfs_rtblock_t start, xfs_extlen_t len, int val, + xfs_rtblock_t start, xfs_rtxlen_t len, int val, xfs_rtblock_t *new, int *stat); int xfs_rtfind_back(struct xfs_mount *mp, struct xfs_trans *tp, xfs_rtblock_t start, xfs_rtblock_t limit, @@ -35,7 +35,7 @@ int xfs_rtfind_forw(struct xfs_mount *mp, struct xfs_trans *tp, xfs_rtblock_t start, xfs_rtblock_t limit, xfs_rtblock_t *rtblock); int xfs_rtmodify_range(struct xfs_mount *mp, struct xfs_trans *tp, - xfs_rtblock_t start, xfs_extlen_t len, int val); + xfs_rtblock_t start, xfs_rtxlen_t len, int val); int xfs_rtmodify_summary_int(struct xfs_mount *mp, struct xfs_trans *tp, int log, xfs_rtblock_t bbno, int delta, struct xfs_buf **rbpp, xfs_fsblock_t *rsb, @@ -44,7 +44,7 @@ int xfs_rtmodify_summary(struct xfs_mount *mp, struct xfs_trans *tp, int log, xfs_rtblock_t bbno, int delta, struct xfs_buf **rbpp, xfs_fsblock_t *rsb); int xfs_rtfree_range(struct xfs_mount *mp, struct xfs_trans *tp, - xfs_rtblock_t start, xfs_extlen_t len, + xfs_rtblock_t start, xfs_rtxlen_t len, struct xfs_buf **rbpp, xfs_fsblock_t *rsb); int xfs_rtalloc_query_range(struct xfs_mount *mp, struct xfs_trans *tp, const struct xfs_rtalloc_rec *low_rec, @@ -53,9 +53,8 @@ int xfs_rtalloc_query_range(struct xfs_mount *mp, struct xfs_trans *tp, int xfs_rtalloc_query_all(struct xfs_mount *mp, struct xfs_trans *tp, xfs_rtalloc_query_range_fn fn, void *priv); -bool xfs_verify_rtbno(struct xfs_mount *mp, xfs_rtblock_t rtbno); int xfs_rtalloc_extent_is_free(struct xfs_mount *mp, struct xfs_trans *tp, - xfs_rtblock_t start, xfs_extlen_t len, + xfs_rtblock_t start, xfs_rtxlen_t len, bool *is_free); /* * Free an extent in the realtime subvolume. Length is expressed in @@ -65,7 +64,7 @@ int /* error */ xfs_rtfree_extent( struct xfs_trans *tp, /* transaction pointer */ xfs_rtblock_t bno, /* starting block number to free */ - xfs_extlen_t len); /* length of extent freed */ + xfs_rtxlen_t len); /* length of extent freed */ /* Same as above, but in units of rt blocks. */ int xfs_rtfree_blocks(struct xfs_trans *tp, xfs_fsblock_t rtbno, diff --git a/fs/xfs/libxfs/xfs_types.h b/fs/xfs/libxfs/xfs_types.h index 851220021484..713cb70311ef 100644 --- a/fs/xfs/libxfs/xfs_types.h +++ b/fs/xfs/libxfs/xfs_types.h @@ -11,6 +11,7 @@ typedef uint32_t prid_t; /* project ID */ typedef uint32_t xfs_agblock_t; /* blockno in alloc. group */ typedef uint32_t xfs_agino_t; /* inode # within allocation grp */ typedef uint32_t xfs_extlen_t; /* extent length in blocks */ +typedef uint32_t xfs_rtxlen_t; /* file extent length in rtextents */ typedef uint32_t xfs_agnumber_t; /* allocation group number */ typedef uint64_t xfs_extnum_t; /* # of extents in a file */ typedef uint32_t xfs_aextnum_t; /* # extents in an attribute fork */ diff --git a/fs/xfs/scrub/rtbitmap.c b/fs/xfs/scrub/rtbitmap.c index 2e5fd52f7af3..71d3e8b85844 100644 --- a/fs/xfs/scrub/rtbitmap.c +++ b/fs/xfs/scrub/rtbitmap.c @@ -133,7 +133,7 @@ xchk_xref_is_used_rt_space( { xfs_rtblock_t startext; xfs_rtblock_t endext; - xfs_rtblock_t extcount; + xfs_rtxlen_t extcount; bool is_free; int error; diff --git a/fs/xfs/xfs_bmap_util.c b/fs/xfs/xfs_bmap_util.c index fcefab687285..574665ca8fea 100644 --- a/fs/xfs/xfs_bmap_util.c +++ b/fs/xfs/xfs_bmap_util.c @@ -76,13 +76,13 @@ xfs_bmap_rtalloc( struct xfs_mount *mp = ap->ip->i_mount; xfs_fileoff_t orig_offset = ap->offset; xfs_rtblock_t rtb; - xfs_extlen_t prod = 0; /* product factor for allocators */ + xfs_rtxlen_t prod = 0; /* product factor for allocators */ xfs_extlen_t mod = 0; /* product factor for allocators */ - xfs_extlen_t ralen = 0; /* realtime allocation length */ + xfs_rtxlen_t ralen = 0; /* realtime allocation length */ xfs_extlen_t align; /* minimum allocation alignment */ xfs_extlen_t orig_length = ap->length; xfs_extlen_t minlen = mp->m_sb.sb_rextsize; - xfs_extlen_t raminlen; + xfs_rtxlen_t raminlen; bool rtlocked = false; bool ignore_locality = false; int error; diff --git a/fs/xfs/xfs_rtalloc.c b/fs/xfs/xfs_rtalloc.c index f2eb0c8b595d..1789ae818662 100644 --- a/fs/xfs/xfs_rtalloc.c +++ b/fs/xfs/xfs_rtalloc.c @@ -144,7 +144,7 @@ xfs_rtallocate_range( xfs_mount_t *mp, /* file system mount point */ xfs_trans_t *tp, /* transaction pointer */ xfs_rtblock_t start, /* start block to allocate */ - xfs_extlen_t len, /* length to allocate */ + xfs_rtxlen_t len, /* length to allocate */ struct xfs_buf **rbpp, /* in/out: summary block buffer */ xfs_fsblock_t *rsb) /* in/out: summary block number */ { @@ -216,14 +216,14 @@ xfs_rtallocate_range( * Make sure we don't run off the end of the rt volume. Be careful that * adjusting maxlen downwards doesn't cause us to fail the alignment checks. */ -static inline xfs_extlen_t +static inline xfs_rtxlen_t xfs_rtallocate_clamp_len( struct xfs_mount *mp, xfs_rtblock_t startrtx, - xfs_extlen_t rtxlen, - xfs_extlen_t prod) + xfs_rtxlen_t rtxlen, + xfs_rtxlen_t prod) { - xfs_extlen_t ret; + xfs_rtxlen_t ret; ret = min(mp->m_sb.sb_rextents, startrtx + rtxlen) - startrtx; return rounddown(ret, prod); @@ -240,13 +240,13 @@ xfs_rtallocate_extent_block( xfs_mount_t *mp, /* file system mount point */ xfs_trans_t *tp, /* transaction pointer */ xfs_rtblock_t bbno, /* bitmap block number */ - xfs_extlen_t minlen, /* minimum length to allocate */ - xfs_extlen_t maxlen, /* maximum length to allocate */ - xfs_extlen_t *len, /* out: actual length allocated */ + xfs_rtxlen_t minlen, /* minimum length to allocate */ + xfs_rtxlen_t maxlen, /* maximum length to allocate */ + xfs_rtxlen_t *len, /* out: actual length allocated */ xfs_rtblock_t *nextp, /* out: next block to try */ struct xfs_buf **rbpp, /* in/out: summary block buffer */ xfs_fsblock_t *rsb, /* in/out: summary block number */ - xfs_extlen_t prod, /* extent product factor */ + xfs_rtxlen_t prod, /* extent product factor */ xfs_rtblock_t *rtblock) /* out: start block allocated */ { xfs_rtblock_t besti; /* best rtblock found so far */ @@ -319,7 +319,7 @@ xfs_rtallocate_extent_block( * Searched the whole thing & didn't find a maxlen free extent. */ if (minlen < maxlen && besti != -1) { - xfs_extlen_t p; /* amount to trim length by */ + xfs_rtxlen_t p; /* amount to trim length by */ /* * If size should be a multiple of prod, make that so. @@ -360,16 +360,16 @@ xfs_rtallocate_extent_exact( xfs_mount_t *mp, /* file system mount point */ xfs_trans_t *tp, /* transaction pointer */ xfs_rtblock_t bno, /* starting block number to allocate */ - xfs_extlen_t minlen, /* minimum length to allocate */ - xfs_extlen_t maxlen, /* maximum length to allocate */ - xfs_extlen_t *len, /* out: actual length allocated */ + xfs_rtxlen_t minlen, /* minimum length to allocate */ + xfs_rtxlen_t maxlen, /* maximum length to allocate */ + xfs_rtxlen_t *len, /* out: actual length allocated */ struct xfs_buf **rbpp, /* in/out: summary block buffer */ xfs_fsblock_t *rsb, /* in/out: summary block number */ - xfs_extlen_t prod, /* extent product factor */ + xfs_rtxlen_t prod, /* extent product factor */ xfs_rtblock_t *rtblock) /* out: start block allocated */ { int error; /* error value */ - xfs_extlen_t i; /* extent length trimmed due to prod */ + xfs_rtxlen_t i; /* extent length trimmed due to prod */ int isfree; /* extent is free */ xfs_rtblock_t next; /* next block to try (dummy) */ @@ -440,12 +440,12 @@ xfs_rtallocate_extent_near( xfs_mount_t *mp, /* file system mount point */ xfs_trans_t *tp, /* transaction pointer */ xfs_rtblock_t bno, /* starting block number to allocate */ - xfs_extlen_t minlen, /* minimum length to allocate */ - xfs_extlen_t maxlen, /* maximum length to allocate */ - xfs_extlen_t *len, /* out: actual length allocated */ + xfs_rtxlen_t minlen, /* minimum length to allocate */ + xfs_rtxlen_t maxlen, /* maximum length to allocate */ + xfs_rtxlen_t *len, /* out: actual length allocated */ struct xfs_buf **rbpp, /* in/out: summary block buffer */ xfs_fsblock_t *rsb, /* in/out: summary block number */ - xfs_extlen_t prod, /* extent product factor */ + xfs_rtxlen_t prod, /* extent product factor */ xfs_rtblock_t *rtblock) /* out: start block allocated */ { int any; /* any useful extents from summary */ @@ -644,12 +644,12 @@ STATIC int /* error */ xfs_rtallocate_extent_size( xfs_mount_t *mp, /* file system mount point */ xfs_trans_t *tp, /* transaction pointer */ - xfs_extlen_t minlen, /* minimum length to allocate */ - xfs_extlen_t maxlen, /* maximum length to allocate */ - xfs_extlen_t *len, /* out: actual length allocated */ + xfs_rtxlen_t minlen, /* minimum length to allocate */ + xfs_rtxlen_t maxlen, /* maximum length to allocate */ + xfs_rtxlen_t *len, /* out: actual length allocated */ struct xfs_buf **rbpp, /* in/out: summary block buffer */ xfs_fsblock_t *rsb, /* in/out: summary block number */ - xfs_extlen_t prod, /* extent product factor */ + xfs_rtxlen_t prod, /* extent product factor */ xfs_rtblock_t *rtblock) /* out: start block allocated */ { int error; /* error value */ @@ -1197,11 +1197,11 @@ int /* error */ xfs_rtallocate_extent( xfs_trans_t *tp, /* transaction pointer */ xfs_rtblock_t bno, /* starting block number to allocate */ - xfs_extlen_t minlen, /* minimum length to allocate */ - xfs_extlen_t maxlen, /* maximum length to allocate */ - xfs_extlen_t *len, /* out: actual length allocated */ + xfs_rtxlen_t minlen, /* minimum length to allocate */ + xfs_rtxlen_t maxlen, /* maximum length to allocate */ + xfs_rtxlen_t *len, /* out: actual length allocated */ int wasdel, /* was a delayed allocation extent */ - xfs_extlen_t prod, /* extent product factor */ + xfs_rtxlen_t prod, /* extent product factor */ xfs_rtblock_t *rtblock) /* out: start block allocated */ { xfs_mount_t *mp = tp->t_mountp; @@ -1217,7 +1217,7 @@ xfs_rtallocate_extent( * If prod is set then figure out what to do to minlen and maxlen. */ if (prod > 1) { - xfs_extlen_t i; + xfs_rtxlen_t i; if ((i = maxlen % prod)) maxlen -= i; @@ -1444,7 +1444,7 @@ int /* error */ xfs_rtpick_extent( xfs_mount_t *mp, /* file system mount point */ xfs_trans_t *tp, /* transaction pointer */ - xfs_extlen_t len, /* allocation length (rtextents) */ + xfs_rtxlen_t len, /* allocation length (rtextents) */ xfs_rtblock_t *pick) /* result rt extent */ { xfs_rtblock_t b; /* result block */ diff --git a/fs/xfs/xfs_rtalloc.h b/fs/xfs/xfs_rtalloc.h index 11859c259a1c..24a4a1321de0 100644 --- a/fs/xfs/xfs_rtalloc.h +++ b/fs/xfs/xfs_rtalloc.h @@ -25,11 +25,11 @@ int /* error */ xfs_rtallocate_extent( struct xfs_trans *tp, /* transaction pointer */ xfs_rtblock_t bno, /* starting block number to allocate */ - xfs_extlen_t minlen, /* minimum length to allocate */ - xfs_extlen_t maxlen, /* maximum length to allocate */ - xfs_extlen_t *len, /* out: actual length allocated */ + xfs_rtxlen_t minlen, /* minimum length to allocate */ + xfs_rtxlen_t maxlen, /* maximum length to allocate */ + xfs_rtxlen_t *len, /* out: actual length allocated */ int wasdel, /* was a delayed allocation extent */ - xfs_extlen_t prod, /* extent product factor */ + xfs_rtxlen_t prod, /* extent product factor */ xfs_rtblock_t *rtblock); /* out: start block allocated */ @@ -62,7 +62,7 @@ int /* error */ xfs_rtpick_extent( struct xfs_mount *mp, /* file system mount point */ struct xfs_trans *tp, /* transaction pointer */ - xfs_extlen_t len, /* allocation length (rtextents) */ + xfs_rtxlen_t len, /* allocation length (rtextents) */ xfs_rtblock_t *pick); /* result rt extent */ /* -- cgit v1.2.3 From 03f4de332e2e79db36ed2156fb2350480f142bec Mon Sep 17 00:00:00 2001 From: "Darrick J. Wong" Date: Mon, 16 Oct 2023 09:31:11 -0700 Subject: xfs: convert rt bitmap/summary block numbers to xfs_fileoff_t We should use xfs_fileoff_t to store the file block offset of any location within the realtime bitmap or summary files. Signed-off-by: Darrick J. Wong Reviewed-by: Christoph Hellwig --- fs/xfs/libxfs/xfs_rtbitmap.c | 22 +++++++++++----------- fs/xfs/libxfs/xfs_rtbitmap.h | 12 ++++++------ fs/xfs/xfs_rtalloc.c | 34 +++++++++++++++++----------------- 3 files changed, 34 insertions(+), 34 deletions(-) (limited to 'fs/xfs') diff --git a/fs/xfs/libxfs/xfs_rtbitmap.c b/fs/xfs/libxfs/xfs_rtbitmap.c index d33c3e561077..de9730a34f7b 100644 --- a/fs/xfs/libxfs/xfs_rtbitmap.c +++ b/fs/xfs/libxfs/xfs_rtbitmap.c @@ -55,7 +55,7 @@ int xfs_rtbuf_get( xfs_mount_t *mp, /* file system mount structure */ xfs_trans_t *tp, /* transaction pointer */ - xfs_rtblock_t block, /* block number in bitmap or summary */ + xfs_fileoff_t block, /* block number in bitmap or summary */ int issum, /* is summary not bitmap */ struct xfs_buf **bpp) /* output: buffer for the block */ { @@ -101,7 +101,7 @@ xfs_rtfind_back( { xfs_rtword_t *b; /* current word in buffer */ int bit; /* bit number in the word */ - xfs_rtblock_t block; /* bitmap block number */ + xfs_fileoff_t block; /* bitmap block number */ struct xfs_buf *bp; /* buf for the block */ xfs_rtword_t *bufp; /* starting word in buffer */ int error; /* error value */ @@ -276,7 +276,7 @@ xfs_rtfind_forw( { xfs_rtword_t *b; /* current word in buffer */ int bit; /* bit number in the word */ - xfs_rtblock_t block; /* bitmap block number */ + xfs_fileoff_t block; /* bitmap block number */ struct xfs_buf *bp; /* buf for the block */ xfs_rtword_t *bufp; /* starting word in buffer */ int error; /* error value */ @@ -446,15 +446,15 @@ xfs_rtmodify_summary_int( xfs_mount_t *mp, /* file system mount structure */ xfs_trans_t *tp, /* transaction pointer */ int log, /* log2 of extent size */ - xfs_rtblock_t bbno, /* bitmap block number */ + xfs_fileoff_t bbno, /* bitmap block number */ int delta, /* change to make to summary info */ struct xfs_buf **rbpp, /* in/out: summary block buffer */ - xfs_fsblock_t *rsb, /* in/out: summary block number */ + xfs_fileoff_t *rsb, /* in/out: summary block number */ xfs_suminfo_t *sum) /* out: summary info for this block */ { struct xfs_buf *bp; /* buffer for the summary block */ int error; /* error value */ - xfs_fsblock_t sb; /* summary fsblock */ + xfs_fileoff_t sb; /* summary fsblock */ int so; /* index into the summary file */ xfs_suminfo_t *sp; /* pointer to returned data */ @@ -516,10 +516,10 @@ xfs_rtmodify_summary( xfs_mount_t *mp, /* file system mount structure */ xfs_trans_t *tp, /* transaction pointer */ int log, /* log2 of extent size */ - xfs_rtblock_t bbno, /* bitmap block number */ + xfs_fileoff_t bbno, /* bitmap block number */ int delta, /* change to make to summary info */ struct xfs_buf **rbpp, /* in/out: summary block buffer */ - xfs_fsblock_t *rsb) /* in/out: summary block number */ + xfs_fileoff_t *rsb) /* in/out: summary block number */ { return xfs_rtmodify_summary_int(mp, tp, log, bbno, delta, rbpp, rsb, NULL); @@ -539,7 +539,7 @@ xfs_rtmodify_range( { xfs_rtword_t *b; /* current word in buffer */ int bit; /* bit number in the word */ - xfs_rtblock_t block; /* bitmap block number */ + xfs_fileoff_t block; /* bitmap block number */ struct xfs_buf *bp; /* buf for the block */ xfs_rtword_t *bufp; /* starting word in buffer */ int error; /* error value */ @@ -692,7 +692,7 @@ xfs_rtfree_range( xfs_rtblock_t start, /* starting block to free */ xfs_rtxlen_t len, /* length to free */ struct xfs_buf **rbpp, /* in/out: summary block buffer */ - xfs_fsblock_t *rsb) /* in/out: summary block number */ + xfs_fileoff_t *rsb) /* in/out: summary block number */ { xfs_rtblock_t end; /* end of the freed extent */ int error; /* error value */ @@ -773,7 +773,7 @@ xfs_rtcheck_range( { xfs_rtword_t *b; /* current word in buffer */ int bit; /* bit number in the word */ - xfs_rtblock_t block; /* bitmap block number */ + xfs_fileoff_t block; /* bitmap block number */ struct xfs_buf *bp; /* buf for the block */ xfs_rtword_t *bufp; /* starting word in buffer */ int error; /* error value */ diff --git a/fs/xfs/libxfs/xfs_rtbitmap.h b/fs/xfs/libxfs/xfs_rtbitmap.h index d4449610154a..e2ea6d31c38b 100644 --- a/fs/xfs/libxfs/xfs_rtbitmap.h +++ b/fs/xfs/libxfs/xfs_rtbitmap.h @@ -24,7 +24,7 @@ typedef int (*xfs_rtalloc_query_range_fn)( #ifdef CONFIG_XFS_RT int xfs_rtbuf_get(struct xfs_mount *mp, struct xfs_trans *tp, - xfs_rtblock_t block, int issum, struct xfs_buf **bpp); + xfs_fileoff_t block, int issum, struct xfs_buf **bpp); int xfs_rtcheck_range(struct xfs_mount *mp, struct xfs_trans *tp, xfs_rtblock_t start, xfs_rtxlen_t len, int val, xfs_rtblock_t *new, int *stat); @@ -37,15 +37,15 @@ int xfs_rtfind_forw(struct xfs_mount *mp, struct xfs_trans *tp, int xfs_rtmodify_range(struct xfs_mount *mp, struct xfs_trans *tp, xfs_rtblock_t start, xfs_rtxlen_t len, int val); int xfs_rtmodify_summary_int(struct xfs_mount *mp, struct xfs_trans *tp, - int log, xfs_rtblock_t bbno, int delta, - struct xfs_buf **rbpp, xfs_fsblock_t *rsb, + int log, xfs_fileoff_t bbno, int delta, + struct xfs_buf **rbpp, xfs_fileoff_t *rsb, xfs_suminfo_t *sum); int xfs_rtmodify_summary(struct xfs_mount *mp, struct xfs_trans *tp, int log, - xfs_rtblock_t bbno, int delta, struct xfs_buf **rbpp, - xfs_fsblock_t *rsb); + xfs_fileoff_t bbno, int delta, struct xfs_buf **rbpp, + xfs_fileoff_t *rsb); int xfs_rtfree_range(struct xfs_mount *mp, struct xfs_trans *tp, xfs_rtblock_t start, xfs_rtxlen_t len, - struct xfs_buf **rbpp, xfs_fsblock_t *rsb); + struct xfs_buf **rbpp, xfs_fileoff_t *rsb); int xfs_rtalloc_query_range(struct xfs_mount *mp, struct xfs_trans *tp, const struct xfs_rtalloc_rec *low_rec, const struct xfs_rtalloc_rec *high_rec, diff --git a/fs/xfs/xfs_rtalloc.c b/fs/xfs/xfs_rtalloc.c index 1789ae818662..a109dd06f87a 100644 --- a/fs/xfs/xfs_rtalloc.c +++ b/fs/xfs/xfs_rtalloc.c @@ -32,9 +32,9 @@ xfs_rtget_summary( xfs_mount_t *mp, /* file system mount structure */ xfs_trans_t *tp, /* transaction pointer */ int log, /* log2 of extent size */ - xfs_rtblock_t bbno, /* bitmap block number */ + xfs_fileoff_t bbno, /* bitmap block number */ struct xfs_buf **rbpp, /* in/out: summary block buffer */ - xfs_fsblock_t *rsb, /* in/out: summary block number */ + xfs_fileoff_t *rsb, /* in/out: summary block number */ xfs_suminfo_t *sum) /* out: summary info for this block */ { return xfs_rtmodify_summary_int(mp, tp, log, bbno, 0, rbpp, rsb, sum); @@ -50,9 +50,9 @@ xfs_rtany_summary( xfs_trans_t *tp, /* transaction pointer */ int low, /* low log2 extent size */ int high, /* high log2 extent size */ - xfs_rtblock_t bbno, /* bitmap block number */ + xfs_fileoff_t bbno, /* bitmap block number */ struct xfs_buf **rbpp, /* in/out: summary block buffer */ - xfs_fsblock_t *rsb, /* in/out: summary block number */ + xfs_fileoff_t *rsb, /* in/out: summary block number */ int *stat) /* out: any good extents here? */ { int error; /* error value */ @@ -104,12 +104,12 @@ xfs_rtcopy_summary( xfs_mount_t *nmp, /* new file system mount point */ xfs_trans_t *tp) /* transaction pointer */ { - xfs_rtblock_t bbno; /* bitmap block number */ + xfs_fileoff_t bbno; /* bitmap block number */ struct xfs_buf *bp; /* summary buffer */ int error; /* error return value */ int log; /* summary level number (log length) */ xfs_suminfo_t sum; /* summary data */ - xfs_fsblock_t sumbno; /* summary block number */ + xfs_fileoff_t sumbno; /* summary block number */ bp = NULL; for (log = omp->m_rsumlevels - 1; log >= 0; log--) { @@ -146,7 +146,7 @@ xfs_rtallocate_range( xfs_rtblock_t start, /* start block to allocate */ xfs_rtxlen_t len, /* length to allocate */ struct xfs_buf **rbpp, /* in/out: summary block buffer */ - xfs_fsblock_t *rsb) /* in/out: summary block number */ + xfs_fileoff_t *rsb) /* in/out: summary block number */ { xfs_rtblock_t end; /* end of the allocated extent */ int error; /* error value */ @@ -239,13 +239,13 @@ STATIC int /* error */ xfs_rtallocate_extent_block( xfs_mount_t *mp, /* file system mount point */ xfs_trans_t *tp, /* transaction pointer */ - xfs_rtblock_t bbno, /* bitmap block number */ + xfs_fileoff_t bbno, /* bitmap block number */ xfs_rtxlen_t minlen, /* minimum length to allocate */ xfs_rtxlen_t maxlen, /* maximum length to allocate */ xfs_rtxlen_t *len, /* out: actual length allocated */ xfs_rtblock_t *nextp, /* out: next block to try */ struct xfs_buf **rbpp, /* in/out: summary block buffer */ - xfs_fsblock_t *rsb, /* in/out: summary block number */ + xfs_fileoff_t *rsb, /* in/out: summary block number */ xfs_rtxlen_t prod, /* extent product factor */ xfs_rtblock_t *rtblock) /* out: start block allocated */ { @@ -364,7 +364,7 @@ xfs_rtallocate_extent_exact( xfs_rtxlen_t maxlen, /* maximum length to allocate */ xfs_rtxlen_t *len, /* out: actual length allocated */ struct xfs_buf **rbpp, /* in/out: summary block buffer */ - xfs_fsblock_t *rsb, /* in/out: summary block number */ + xfs_fileoff_t *rsb, /* in/out: summary block number */ xfs_rtxlen_t prod, /* extent product factor */ xfs_rtblock_t *rtblock) /* out: start block allocated */ { @@ -444,12 +444,12 @@ xfs_rtallocate_extent_near( xfs_rtxlen_t maxlen, /* maximum length to allocate */ xfs_rtxlen_t *len, /* out: actual length allocated */ struct xfs_buf **rbpp, /* in/out: summary block buffer */ - xfs_fsblock_t *rsb, /* in/out: summary block number */ + xfs_fileoff_t *rsb, /* in/out: summary block number */ xfs_rtxlen_t prod, /* extent product factor */ xfs_rtblock_t *rtblock) /* out: start block allocated */ { int any; /* any useful extents from summary */ - xfs_rtblock_t bbno; /* bitmap block number */ + xfs_fileoff_t bbno; /* bitmap block number */ int error; /* error value */ int i; /* bitmap block offset (loop control) */ int j; /* secondary loop control */ @@ -648,12 +648,12 @@ xfs_rtallocate_extent_size( xfs_rtxlen_t maxlen, /* maximum length to allocate */ xfs_rtxlen_t *len, /* out: actual length allocated */ struct xfs_buf **rbpp, /* in/out: summary block buffer */ - xfs_fsblock_t *rsb, /* in/out: summary block number */ + xfs_fileoff_t *rsb, /* in/out: summary block number */ xfs_rtxlen_t prod, /* extent product factor */ xfs_rtblock_t *rtblock) /* out: start block allocated */ { int error; /* error value */ - int i; /* bitmap block number */ + xfs_fileoff_t i; /* bitmap block number */ int l; /* level number (loop control) */ xfs_rtblock_t n; /* next block to be tried */ xfs_rtblock_t r; /* result block number */ @@ -929,7 +929,7 @@ xfs_growfs_rt( xfs_mount_t *mp, /* mount point for filesystem */ xfs_growfs_rt_t *in) /* growfs rt input struct */ { - xfs_rtblock_t bmbno; /* bitmap block number */ + xfs_fileoff_t bmbno; /* bitmap block number */ struct xfs_buf *bp; /* temporary buffer */ int error; /* error return value */ xfs_mount_t *nmp; /* new (fake) mount structure */ @@ -944,7 +944,7 @@ xfs_growfs_rt( xfs_extlen_t rbmblocks; /* current number of rt bitmap blocks */ xfs_extlen_t rsumblocks; /* current number of rt summary blks */ xfs_sb_t *sbp; /* old superblock */ - xfs_fsblock_t sumbno; /* summary block number */ + xfs_fileoff_t sumbno; /* summary block number */ uint8_t *rsum_cache; /* old summary cache */ sbp = &mp->m_sb; @@ -1207,7 +1207,7 @@ xfs_rtallocate_extent( xfs_mount_t *mp = tp->t_mountp; int error; /* error value */ xfs_rtblock_t r; /* result allocated block */ - xfs_fsblock_t sb; /* summary file block number */ + xfs_fileoff_t sb; /* summary file block number */ struct xfs_buf *sumbp; /* summary file block buffer */ ASSERT(xfs_isilocked(mp->m_rbmip, XFS_ILOCK_EXCL)); -- cgit v1.2.3 From f29c3e745dc253bf9d9d06ddc36af1a534ba1dd0 Mon Sep 17 00:00:00 2001 From: "Darrick J. Wong" Date: Mon, 16 Oct 2023 09:31:12 -0700 Subject: xfs: convert rt bitmap extent lengths to xfs_rtbxlen_t XFS uses xfs_rtblock_t for many different uses, which makes it much more difficult to perform a unit analysis on the codebase. One of these (ab)uses is when we need to store the length of a free space extent as stored in the realtime bitmap. Because there can be up to 2^64 realtime extents in a filesystem, we need a new type that is larger than xfs_rtxlen_t for callers that are querying the bitmap directly. This means scrub and growfs. Create this type as "xfs_rtbxlen_t" and use it to store 64-bit rtx lengths. 'b' stands for 'bitmap' or 'big'; reader's choice. Signed-off-by: Darrick J. Wong Reviewed-by: Christoph Hellwig --- fs/xfs/libxfs/xfs_format.h | 2 +- fs/xfs/libxfs/xfs_rtbitmap.h | 2 +- fs/xfs/libxfs/xfs_types.h | 1 + fs/xfs/scrub/trace.h | 3 ++- 4 files changed, 5 insertions(+), 3 deletions(-) (limited to 'fs/xfs') diff --git a/fs/xfs/libxfs/xfs_format.h b/fs/xfs/libxfs/xfs_format.h index 371dc07233e0..20acb8573d7a 100644 --- a/fs/xfs/libxfs/xfs_format.h +++ b/fs/xfs/libxfs/xfs_format.h @@ -98,7 +98,7 @@ typedef struct xfs_sb { uint32_t sb_blocksize; /* logical block size, bytes */ xfs_rfsblock_t sb_dblocks; /* number of data blocks */ xfs_rfsblock_t sb_rblocks; /* number of realtime blocks */ - xfs_rtblock_t sb_rextents; /* number of realtime extents */ + xfs_rtbxlen_t sb_rextents; /* number of realtime extents */ uuid_t sb_uuid; /* user-visible file system unique id */ xfs_fsblock_t sb_logstart; /* starting block of log if internal */ xfs_ino_t sb_rootino; /* root inode number */ diff --git a/fs/xfs/libxfs/xfs_rtbitmap.h b/fs/xfs/libxfs/xfs_rtbitmap.h index e2ea6d31c38b..b0a81fb8dbda 100644 --- a/fs/xfs/libxfs/xfs_rtbitmap.h +++ b/fs/xfs/libxfs/xfs_rtbitmap.h @@ -13,7 +13,7 @@ */ struct xfs_rtalloc_rec { xfs_rtblock_t ar_startext; - xfs_rtblock_t ar_extcount; + xfs_rtbxlen_t ar_extcount; }; typedef int (*xfs_rtalloc_query_range_fn)( diff --git a/fs/xfs/libxfs/xfs_types.h b/fs/xfs/libxfs/xfs_types.h index 713cb70311ef..9af98a975239 100644 --- a/fs/xfs/libxfs/xfs_types.h +++ b/fs/xfs/libxfs/xfs_types.h @@ -32,6 +32,7 @@ typedef uint64_t xfs_rfsblock_t; /* blockno in filesystem (raw) */ typedef uint64_t xfs_rtblock_t; /* extent (block) in realtime area */ typedef uint64_t xfs_fileoff_t; /* block number in a file */ typedef uint64_t xfs_filblks_t; /* number of blocks in a file */ +typedef uint64_t xfs_rtbxlen_t; /* rtbitmap extent length in rtextents */ typedef int64_t xfs_srtblock_t; /* signed version of xfs_rtblock_t */ diff --git a/fs/xfs/scrub/trace.h b/fs/xfs/scrub/trace.h index cbd4d01e253c..df49ca2e8c23 100644 --- a/fs/xfs/scrub/trace.h +++ b/fs/xfs/scrub/trace.h @@ -1037,7 +1037,8 @@ TRACE_EVENT(xfarray_sort_stats, #ifdef CONFIG_XFS_RT TRACE_EVENT(xchk_rtsum_record_free, TP_PROTO(struct xfs_mount *mp, xfs_rtblock_t start, - uint64_t len, unsigned int log, loff_t pos, xfs_suminfo_t v), + xfs_rtbxlen_t len, unsigned int log, loff_t pos, + xfs_suminfo_t v), TP_ARGS(mp, start, len, log, pos, v), TP_STRUCT__entry( __field(dev_t, dev) -- cgit v1.2.3 From 3d2b6d034f0feb7741b313f978a2fe45e917e1be Mon Sep 17 00:00:00 2001 From: "Darrick J. Wong" Date: Mon, 16 Oct 2023 09:31:22 -0700 Subject: xfs: rename xfs_verify_rtext to xfs_verify_rtbext This helper function validates that a range of *blocks* in the realtime section is completely contained within the realtime section. It does /not/ validate ranges of *rtextents*. Rename the function to avoid suggesting that it does, and change the type of the @len parameter since xfs_rtblock_t is a position unit, not a length unit. Signed-off-by: Darrick J. Wong Reviewed-by: Christoph Hellwig --- fs/xfs/libxfs/xfs_bmap.c | 4 ++-- fs/xfs/libxfs/xfs_types.c | 4 ++-- fs/xfs/libxfs/xfs_types.h | 4 ++-- fs/xfs/scrub/bmap.c | 2 +- fs/xfs/scrub/rtbitmap.c | 4 ++-- fs/xfs/scrub/rtsummary.c | 2 +- 6 files changed, 10 insertions(+), 10 deletions(-) (limited to 'fs/xfs') diff --git a/fs/xfs/libxfs/xfs_bmap.c b/fs/xfs/libxfs/xfs_bmap.c index a47da8d3d1bc..4e7de4f2fd7a 100644 --- a/fs/xfs/libxfs/xfs_bmap.c +++ b/fs/xfs/libxfs/xfs_bmap.c @@ -6196,8 +6196,8 @@ xfs_bmap_validate_extent( return __this_address; if (XFS_IS_REALTIME_INODE(ip) && whichfork == XFS_DATA_FORK) { - if (!xfs_verify_rtext(mp, irec->br_startblock, - irec->br_blockcount)) + if (!xfs_verify_rtbext(mp, irec->br_startblock, + irec->br_blockcount)) return __this_address; } else { if (!xfs_verify_fsbext(mp, irec->br_startblock, diff --git a/fs/xfs/libxfs/xfs_types.c b/fs/xfs/libxfs/xfs_types.c index 5c2765934732..c299b16c9365 100644 --- a/fs/xfs/libxfs/xfs_types.c +++ b/fs/xfs/libxfs/xfs_types.c @@ -148,10 +148,10 @@ xfs_verify_rtbno( /* Verify that a realtime device extent is fully contained inside the volume. */ bool -xfs_verify_rtext( +xfs_verify_rtbext( struct xfs_mount *mp, xfs_rtblock_t rtbno, - xfs_rtblock_t len) + xfs_filblks_t len) { if (rtbno + len <= rtbno) return false; diff --git a/fs/xfs/libxfs/xfs_types.h b/fs/xfs/libxfs/xfs_types.h index 9af98a975239..9e45f13f6d70 100644 --- a/fs/xfs/libxfs/xfs_types.h +++ b/fs/xfs/libxfs/xfs_types.h @@ -231,8 +231,8 @@ bool xfs_verify_ino(struct xfs_mount *mp, xfs_ino_t ino); bool xfs_internal_inum(struct xfs_mount *mp, xfs_ino_t ino); bool xfs_verify_dir_ino(struct xfs_mount *mp, xfs_ino_t ino); bool xfs_verify_rtbno(struct xfs_mount *mp, xfs_rtblock_t rtbno); -bool xfs_verify_rtext(struct xfs_mount *mp, xfs_rtblock_t rtbno, - xfs_rtblock_t len); +bool xfs_verify_rtbext(struct xfs_mount *mp, xfs_rtblock_t rtbno, + xfs_filblks_t len); bool xfs_verify_icount(struct xfs_mount *mp, unsigned long long icount); bool xfs_verify_dablk(struct xfs_mount *mp, xfs_fileoff_t off); void xfs_icount_range(struct xfs_mount *mp, unsigned long long *min, diff --git a/fs/xfs/scrub/bmap.c b/fs/xfs/scrub/bmap.c index 75588915572e..06d8c1996a33 100644 --- a/fs/xfs/scrub/bmap.c +++ b/fs/xfs/scrub/bmap.c @@ -410,7 +410,7 @@ xchk_bmap_iextent( /* Make sure the extent points to a valid place. */ if (info->is_rt && - !xfs_verify_rtext(mp, irec->br_startblock, irec->br_blockcount)) + !xfs_verify_rtbext(mp, irec->br_startblock, irec->br_blockcount)) xchk_fblock_set_corrupt(info->sc, info->whichfork, irec->br_startoff); if (!info->is_rt && diff --git a/fs/xfs/scrub/rtbitmap.c b/fs/xfs/scrub/rtbitmap.c index 71d3e8b85844..8c8a611cc6d4 100644 --- a/fs/xfs/scrub/rtbitmap.c +++ b/fs/xfs/scrub/rtbitmap.c @@ -48,12 +48,12 @@ xchk_rtbitmap_rec( { struct xfs_scrub *sc = priv; xfs_rtblock_t startblock; - xfs_rtblock_t blockcount; + xfs_filblks_t blockcount; startblock = rec->ar_startext * mp->m_sb.sb_rextsize; blockcount = rec->ar_extcount * mp->m_sb.sb_rextsize; - if (!xfs_verify_rtext(mp, startblock, blockcount)) + if (!xfs_verify_rtbext(mp, startblock, blockcount)) xchk_fblock_set_corrupt(sc, XFS_DATA_FORK, 0); return 0; } diff --git a/fs/xfs/scrub/rtsummary.c b/fs/xfs/scrub/rtsummary.c index f4635a920470..d998f0c378a4 100644 --- a/fs/xfs/scrub/rtsummary.c +++ b/fs/xfs/scrub/rtsummary.c @@ -137,7 +137,7 @@ xchk_rtsum_record_free( rtbno = rec->ar_startext * mp->m_sb.sb_rextsize; rtlen = rec->ar_extcount * mp->m_sb.sb_rextsize; - if (!xfs_verify_rtext(mp, rtbno, rtlen)) { + if (!xfs_verify_rtbext(mp, rtbno, rtlen)) { xchk_ino_xref_set_corrupt(sc, mp->m_rbmip->i_ino); return -EFSCORRUPTED; } -- cgit v1.2.3 From 2d5f216b77e33f9b503bd42998271da35d4b7055 Mon Sep 17 00:00:00 2001 From: "Darrick J. Wong" Date: Mon, 16 Oct 2023 09:32:45 -0700 Subject: xfs: convert rt extent numbers to xfs_rtxnum_t Further disambiguate the xfs_rtblock_t uses by creating a new type, xfs_rtxnum_t, to store the position of an extent within the realtime section, in units of rtextents. Signed-off-by: Darrick J. Wong Reviewed-by: Christoph Hellwig --- fs/xfs/libxfs/xfs_rtbitmap.c | 86 +++++++++++++-------------- fs/xfs/libxfs/xfs_rtbitmap.h | 26 ++++----- fs/xfs/libxfs/xfs_types.h | 2 + fs/xfs/scrub/rtbitmap.c | 4 +- fs/xfs/scrub/trace.h | 4 +- fs/xfs/xfs_bmap_util.c | 12 ++-- fs/xfs/xfs_rtalloc.c | 136 +++++++++++++++++++++---------------------- fs/xfs/xfs_rtalloc.h | 6 +- 8 files changed, 137 insertions(+), 139 deletions(-) (limited to 'fs/xfs') diff --git a/fs/xfs/libxfs/xfs_rtbitmap.c b/fs/xfs/libxfs/xfs_rtbitmap.c index de9730a34f7b..f64e4aeb393b 100644 --- a/fs/xfs/libxfs/xfs_rtbitmap.c +++ b/fs/xfs/libxfs/xfs_rtbitmap.c @@ -95,9 +95,9 @@ int xfs_rtfind_back( xfs_mount_t *mp, /* file system mount point */ xfs_trans_t *tp, /* transaction pointer */ - xfs_rtblock_t start, /* starting block to look at */ - xfs_rtblock_t limit, /* last block to look at */ - xfs_rtblock_t *rtblock) /* out: start block found */ + xfs_rtxnum_t start, /* starting rtext to look at */ + xfs_rtxnum_t limit, /* last rtext to look at */ + xfs_rtxnum_t *rtx) /* out: start rtext found */ { xfs_rtword_t *b; /* current word in buffer */ int bit; /* bit number in the word */ @@ -105,9 +105,9 @@ xfs_rtfind_back( struct xfs_buf *bp; /* buf for the block */ xfs_rtword_t *bufp; /* starting word in buffer */ int error; /* error value */ - xfs_rtblock_t firstbit; /* first useful bit in the word */ - xfs_rtblock_t i; /* current bit number rel. to start */ - xfs_rtblock_t len; /* length of inspected area */ + xfs_rtxnum_t firstbit; /* first useful bit in the word */ + xfs_rtxnum_t i; /* current bit number rel. to start */ + xfs_rtxnum_t len; /* length of inspected area */ xfs_rtword_t mask; /* mask of relevant bits for value */ xfs_rtword_t want; /* mask for "good" values */ xfs_rtword_t wdiff; /* difference from wanted value */ @@ -156,7 +156,7 @@ xfs_rtfind_back( */ xfs_trans_brelse(tp, bp); i = bit - XFS_RTHIBIT(wdiff); - *rtblock = start - i + 1; + *rtx = start - i + 1; return 0; } i = bit - firstbit + 1; @@ -202,7 +202,7 @@ xfs_rtfind_back( */ xfs_trans_brelse(tp, bp); i += XFS_NBWORD - 1 - XFS_RTHIBIT(wdiff); - *rtblock = start - i + 1; + *rtx = start - i + 1; return 0; } i += XFS_NBWORD; @@ -249,7 +249,7 @@ xfs_rtfind_back( */ xfs_trans_brelse(tp, bp); i += XFS_NBWORD - 1 - XFS_RTHIBIT(wdiff); - *rtblock = start - i + 1; + *rtx = start - i + 1; return 0; } else i = len; @@ -258,7 +258,7 @@ xfs_rtfind_back( * No match, return that we scanned the whole area. */ xfs_trans_brelse(tp, bp); - *rtblock = start - i + 1; + *rtx = start - i + 1; return 0; } @@ -270,9 +270,9 @@ int xfs_rtfind_forw( xfs_mount_t *mp, /* file system mount point */ xfs_trans_t *tp, /* transaction pointer */ - xfs_rtblock_t start, /* starting block to look at */ - xfs_rtblock_t limit, /* last block to look at */ - xfs_rtblock_t *rtblock) /* out: start block found */ + xfs_rtxnum_t start, /* starting rtext to look at */ + xfs_rtxnum_t limit, /* last rtext to look at */ + xfs_rtxnum_t *rtx) /* out: start rtext found */ { xfs_rtword_t *b; /* current word in buffer */ int bit; /* bit number in the word */ @@ -280,9 +280,9 @@ xfs_rtfind_forw( struct xfs_buf *bp; /* buf for the block */ xfs_rtword_t *bufp; /* starting word in buffer */ int error; /* error value */ - xfs_rtblock_t i; /* current bit number rel. to start */ - xfs_rtblock_t lastbit; /* last useful bit in the word */ - xfs_rtblock_t len; /* length of inspected area */ + xfs_rtxnum_t i; /* current bit number rel. to start */ + xfs_rtxnum_t lastbit; /* last useful bit in the word */ + xfs_rtxnum_t len; /* length of inspected area */ xfs_rtword_t mask; /* mask of relevant bits for value */ xfs_rtword_t want; /* mask for "good" values */ xfs_rtword_t wdiff; /* difference from wanted value */ @@ -330,7 +330,7 @@ xfs_rtfind_forw( */ xfs_trans_brelse(tp, bp); i = XFS_RTLOBIT(wdiff) - bit; - *rtblock = start + i - 1; + *rtx = start + i - 1; return 0; } i = lastbit - bit; @@ -375,7 +375,7 @@ xfs_rtfind_forw( */ xfs_trans_brelse(tp, bp); i += XFS_RTLOBIT(wdiff); - *rtblock = start + i - 1; + *rtx = start + i - 1; return 0; } i += XFS_NBWORD; @@ -419,7 +419,7 @@ xfs_rtfind_forw( */ xfs_trans_brelse(tp, bp); i += XFS_RTLOBIT(wdiff); - *rtblock = start + i - 1; + *rtx = start + i - 1; return 0; } else i = len; @@ -428,7 +428,7 @@ xfs_rtfind_forw( * No match, return that we scanned the whole area. */ xfs_trans_brelse(tp, bp); - *rtblock = start + i - 1; + *rtx = start + i - 1; return 0; } @@ -533,7 +533,7 @@ int xfs_rtmodify_range( xfs_mount_t *mp, /* file system mount point */ xfs_trans_t *tp, /* transaction pointer */ - xfs_rtblock_t start, /* starting block to modify */ + xfs_rtxnum_t start, /* starting rtext to modify */ xfs_rtxlen_t len, /* length of extent to modify */ int val) /* 1 for free, 0 for allocated */ { @@ -689,15 +689,15 @@ int xfs_rtfree_range( xfs_mount_t *mp, /* file system mount point */ xfs_trans_t *tp, /* transaction pointer */ - xfs_rtblock_t start, /* starting block to free */ + xfs_rtxnum_t start, /* starting rtext to free */ xfs_rtxlen_t len, /* length to free */ struct xfs_buf **rbpp, /* in/out: summary block buffer */ xfs_fileoff_t *rsb) /* in/out: summary block number */ { - xfs_rtblock_t end; /* end of the freed extent */ + xfs_rtxnum_t end; /* end of the freed extent */ int error; /* error value */ - xfs_rtblock_t postblock; /* first block freed > end */ - xfs_rtblock_t preblock; /* first block freed < start */ + xfs_rtxnum_t postblock; /* first rtext freed > end */ + xfs_rtxnum_t preblock; /* first rtext freed < start */ end = start + len - 1; /* @@ -765,10 +765,10 @@ int xfs_rtcheck_range( xfs_mount_t *mp, /* file system mount point */ xfs_trans_t *tp, /* transaction pointer */ - xfs_rtblock_t start, /* starting block number of extent */ + xfs_rtxnum_t start, /* starting rtext number of extent */ xfs_rtxlen_t len, /* length of extent */ int val, /* 1 for free, 0 for allocated */ - xfs_rtblock_t *new, /* out: first block not matching */ + xfs_rtxnum_t *new, /* out: first rtext not matching */ int *stat) /* out: 1 for matches, 0 for not */ { xfs_rtword_t *b; /* current word in buffer */ @@ -777,8 +777,8 @@ xfs_rtcheck_range( struct xfs_buf *bp; /* buf for the block */ xfs_rtword_t *bufp; /* starting word in buffer */ int error; /* error value */ - xfs_rtblock_t i; /* current bit number rel. to start */ - xfs_rtblock_t lastbit; /* last useful bit in word */ + xfs_rtxnum_t i; /* current bit number rel. to start */ + xfs_rtxnum_t lastbit; /* last useful bit in word */ xfs_rtword_t mask; /* mask of relevant bits for value */ xfs_rtword_t wdiff; /* difference from wanted value */ int word; /* word number in the buffer */ @@ -941,14 +941,14 @@ STATIC int /* error */ xfs_rtcheck_alloc_range( xfs_mount_t *mp, /* file system mount point */ xfs_trans_t *tp, /* transaction pointer */ - xfs_rtblock_t bno, /* starting block number of extent */ + xfs_rtxnum_t start, /* starting rtext number of extent */ xfs_rtxlen_t len) /* length of extent */ { - xfs_rtblock_t new; /* dummy for xfs_rtcheck_range */ + xfs_rtxnum_t new; /* dummy for xfs_rtcheck_range */ int stat; int error; - error = xfs_rtcheck_range(mp, tp, bno, len, 0, &new, &stat); + error = xfs_rtcheck_range(mp, tp, start, len, 0, &new, &stat); if (error) return error; ASSERT(stat); @@ -964,7 +964,7 @@ xfs_rtcheck_alloc_range( int /* error */ xfs_rtfree_extent( xfs_trans_t *tp, /* transaction pointer */ - xfs_rtblock_t bno, /* starting block number to free */ + xfs_rtxnum_t start, /* starting rtext number to free */ xfs_rtxlen_t len) /* length of extent freed */ { int error; /* error value */ @@ -977,14 +977,14 @@ xfs_rtfree_extent( ASSERT(mp->m_rbmip->i_itemp != NULL); ASSERT(xfs_isilocked(mp->m_rbmip, XFS_ILOCK_EXCL)); - error = xfs_rtcheck_alloc_range(mp, tp, bno, len); + error = xfs_rtcheck_alloc_range(mp, tp, start, len); if (error) return error; /* * Free the range of realtime blocks. */ - error = xfs_rtfree_range(mp, tp, bno, len, &sumbp, &sb); + error = xfs_rtfree_range(mp, tp, start, len, &sumbp, &sb); if (error) { return error; } @@ -1018,7 +1018,7 @@ xfs_rtfree_blocks( xfs_filblks_t rtlen) { struct xfs_mount *mp = tp->t_mountp; - xfs_rtblock_t bno; + xfs_rtxnum_t start; xfs_filblks_t len; xfs_extlen_t mod; @@ -1030,13 +1030,13 @@ xfs_rtfree_blocks( return -EIO; } - bno = div_u64_rem(rtbno, mp->m_sb.sb_rextsize, &mod); + start = div_u64_rem(rtbno, mp->m_sb.sb_rextsize, &mod); if (mod) { ASSERT(mod == 0); return -EIO; } - return xfs_rtfree_extent(tp, bno, len); + return xfs_rtfree_extent(tp, start, len); } /* Find all the free records within a given range. */ @@ -1050,9 +1050,9 @@ xfs_rtalloc_query_range( void *priv) { struct xfs_rtalloc_rec rec; - xfs_rtblock_t rtstart; - xfs_rtblock_t rtend; - xfs_rtblock_t high_key; + xfs_rtxnum_t rtstart; + xfs_rtxnum_t rtend; + xfs_rtxnum_t high_key; int is_free; int error = 0; @@ -1115,11 +1115,11 @@ int xfs_rtalloc_extent_is_free( struct xfs_mount *mp, struct xfs_trans *tp, - xfs_rtblock_t start, + xfs_rtxnum_t start, xfs_rtxlen_t len, bool *is_free) { - xfs_rtblock_t end; + xfs_rtxnum_t end; int matches; int error; diff --git a/fs/xfs/libxfs/xfs_rtbitmap.h b/fs/xfs/libxfs/xfs_rtbitmap.h index b0a81fb8dbda..5e2afb7fea0e 100644 --- a/fs/xfs/libxfs/xfs_rtbitmap.h +++ b/fs/xfs/libxfs/xfs_rtbitmap.h @@ -7,12 +7,10 @@ #define __XFS_RTBITMAP_H__ /* - * XXX: Most of the realtime allocation functions deal in units of realtime - * extents, not realtime blocks. This looks funny when paired with the type - * name and screams for a larger cleanup. + * Functions for walking free space rtextents in the realtime bitmap. */ struct xfs_rtalloc_rec { - xfs_rtblock_t ar_startext; + xfs_rtxnum_t ar_startext; xfs_rtbxlen_t ar_extcount; }; @@ -26,16 +24,16 @@ typedef int (*xfs_rtalloc_query_range_fn)( int xfs_rtbuf_get(struct xfs_mount *mp, struct xfs_trans *tp, xfs_fileoff_t block, int issum, struct xfs_buf **bpp); int xfs_rtcheck_range(struct xfs_mount *mp, struct xfs_trans *tp, - xfs_rtblock_t start, xfs_rtxlen_t len, int val, - xfs_rtblock_t *new, int *stat); + xfs_rtxnum_t start, xfs_rtxlen_t len, int val, + xfs_rtxnum_t *new, int *stat); int xfs_rtfind_back(struct xfs_mount *mp, struct xfs_trans *tp, - xfs_rtblock_t start, xfs_rtblock_t limit, - xfs_rtblock_t *rtblock); + xfs_rtxnum_t start, xfs_rtxnum_t limit, + xfs_rtxnum_t *rtblock); int xfs_rtfind_forw(struct xfs_mount *mp, struct xfs_trans *tp, - xfs_rtblock_t start, xfs_rtblock_t limit, - xfs_rtblock_t *rtblock); + xfs_rtxnum_t start, xfs_rtxnum_t limit, + xfs_rtxnum_t *rtblock); int xfs_rtmodify_range(struct xfs_mount *mp, struct xfs_trans *tp, - xfs_rtblock_t start, xfs_rtxlen_t len, int val); + xfs_rtxnum_t start, xfs_rtxlen_t len, int val); int xfs_rtmodify_summary_int(struct xfs_mount *mp, struct xfs_trans *tp, int log, xfs_fileoff_t bbno, int delta, struct xfs_buf **rbpp, xfs_fileoff_t *rsb, @@ -44,7 +42,7 @@ int xfs_rtmodify_summary(struct xfs_mount *mp, struct xfs_trans *tp, int log, xfs_fileoff_t bbno, int delta, struct xfs_buf **rbpp, xfs_fileoff_t *rsb); int xfs_rtfree_range(struct xfs_mount *mp, struct xfs_trans *tp, - xfs_rtblock_t start, xfs_rtxlen_t len, + xfs_rtxnum_t start, xfs_rtxlen_t len, struct xfs_buf **rbpp, xfs_fileoff_t *rsb); int xfs_rtalloc_query_range(struct xfs_mount *mp, struct xfs_trans *tp, const struct xfs_rtalloc_rec *low_rec, @@ -54,7 +52,7 @@ int xfs_rtalloc_query_all(struct xfs_mount *mp, struct xfs_trans *tp, xfs_rtalloc_query_range_fn fn, void *priv); int xfs_rtalloc_extent_is_free(struct xfs_mount *mp, struct xfs_trans *tp, - xfs_rtblock_t start, xfs_rtxlen_t len, + xfs_rtxnum_t start, xfs_rtxlen_t len, bool *is_free); /* * Free an extent in the realtime subvolume. Length is expressed in @@ -63,7 +61,7 @@ int xfs_rtalloc_extent_is_free(struct xfs_mount *mp, struct xfs_trans *tp, int /* error */ xfs_rtfree_extent( struct xfs_trans *tp, /* transaction pointer */ - xfs_rtblock_t bno, /* starting block number to free */ + xfs_rtxnum_t start, /* starting rtext number to free */ xfs_rtxlen_t len); /* length of extent freed */ /* Same as above, but in units of rt blocks. */ diff --git a/fs/xfs/libxfs/xfs_types.h b/fs/xfs/libxfs/xfs_types.h index 9e45f13f6d70..c78237852e27 100644 --- a/fs/xfs/libxfs/xfs_types.h +++ b/fs/xfs/libxfs/xfs_types.h @@ -32,6 +32,7 @@ typedef uint64_t xfs_rfsblock_t; /* blockno in filesystem (raw) */ typedef uint64_t xfs_rtblock_t; /* extent (block) in realtime area */ typedef uint64_t xfs_fileoff_t; /* block number in a file */ typedef uint64_t xfs_filblks_t; /* number of blocks in a file */ +typedef uint64_t xfs_rtxnum_t; /* rtextent number */ typedef uint64_t xfs_rtbxlen_t; /* rtbitmap extent length in rtextents */ typedef int64_t xfs_srtblock_t; /* signed version of xfs_rtblock_t */ @@ -49,6 +50,7 @@ typedef void * xfs_failaddr_t; #define NULLRFSBLOCK ((xfs_rfsblock_t)-1) #define NULLRTBLOCK ((xfs_rtblock_t)-1) #define NULLFILEOFF ((xfs_fileoff_t)-1) +#define NULLRTEXTNO ((xfs_rtxnum_t)-1) #define NULLAGBLOCK ((xfs_agblock_t)-1) #define NULLAGNUMBER ((xfs_agnumber_t)-1) diff --git a/fs/xfs/scrub/rtbitmap.c b/fs/xfs/scrub/rtbitmap.c index 8c8a611cc6d4..bea5a2b75a06 100644 --- a/fs/xfs/scrub/rtbitmap.c +++ b/fs/xfs/scrub/rtbitmap.c @@ -131,8 +131,8 @@ xchk_xref_is_used_rt_space( xfs_rtblock_t fsbno, xfs_extlen_t len) { - xfs_rtblock_t startext; - xfs_rtblock_t endext; + xfs_rtxnum_t startext; + xfs_rtxnum_t endext; xfs_rtxlen_t extcount; bool is_free; int error; diff --git a/fs/xfs/scrub/trace.h b/fs/xfs/scrub/trace.h index df49ca2e8c23..b0cf6757444f 100644 --- a/fs/xfs/scrub/trace.h +++ b/fs/xfs/scrub/trace.h @@ -1036,14 +1036,14 @@ TRACE_EVENT(xfarray_sort_stats, #ifdef CONFIG_XFS_RT TRACE_EVENT(xchk_rtsum_record_free, - TP_PROTO(struct xfs_mount *mp, xfs_rtblock_t start, + TP_PROTO(struct xfs_mount *mp, xfs_rtxnum_t start, xfs_rtbxlen_t len, unsigned int log, loff_t pos, xfs_suminfo_t v), TP_ARGS(mp, start, len, log, pos, v), TP_STRUCT__entry( __field(dev_t, dev) __field(dev_t, rtdev) - __field(xfs_rtblock_t, start) + __field(xfs_rtxnum_t, start) __field(unsigned long long, len) __field(unsigned int, log) __field(loff_t, pos) diff --git a/fs/xfs/xfs_bmap_util.c b/fs/xfs/xfs_bmap_util.c index 574665ca8fea..557330281ae3 100644 --- a/fs/xfs/xfs_bmap_util.c +++ b/fs/xfs/xfs_bmap_util.c @@ -75,7 +75,7 @@ xfs_bmap_rtalloc( { struct xfs_mount *mp = ap->ip->i_mount; xfs_fileoff_t orig_offset = ap->offset; - xfs_rtblock_t rtb; + xfs_rtxnum_t rtx; xfs_rtxlen_t prod = 0; /* product factor for allocators */ xfs_extlen_t mod = 0; /* product factor for allocators */ xfs_rtxlen_t ralen = 0; /* realtime allocation length */ @@ -144,8 +144,6 @@ retry: * pick an extent that will space things out in the rt area. */ if (ap->eof && ap->offset == 0) { - xfs_rtblock_t rtx; /* realtime extent no */ - error = xfs_rtpick_extent(mp, ap->tp, ralen, &rtx); if (error) return error; @@ -163,16 +161,16 @@ retry: ap->blkno = 0; else do_div(ap->blkno, mp->m_sb.sb_rextsize); - rtb = ap->blkno; + rtx = ap->blkno; ap->length = ralen; raminlen = max_t(xfs_extlen_t, 1, minlen / mp->m_sb.sb_rextsize); error = xfs_rtallocate_extent(ap->tp, ap->blkno, raminlen, ap->length, - &ralen, ap->wasdel, prod, &rtb); + &ralen, ap->wasdel, prod, &rtx); if (error) return error; - if (rtb != NULLRTBLOCK) { - ap->blkno = rtb * mp->m_sb.sb_rextsize; + if (rtx != NULLRTEXTNO) { + ap->blkno = rtx * mp->m_sb.sb_rextsize; ap->length = ralen * mp->m_sb.sb_rextsize; ap->ip->i_nblocks += ap->length; xfs_trans_log_inode(ap->tp, ap->ip, XFS_ILOG_CORE); diff --git a/fs/xfs/xfs_rtalloc.c b/fs/xfs/xfs_rtalloc.c index a109dd06f87a..62faec195040 100644 --- a/fs/xfs/xfs_rtalloc.c +++ b/fs/xfs/xfs_rtalloc.c @@ -143,15 +143,15 @@ STATIC int /* error */ xfs_rtallocate_range( xfs_mount_t *mp, /* file system mount point */ xfs_trans_t *tp, /* transaction pointer */ - xfs_rtblock_t start, /* start block to allocate */ + xfs_rtxnum_t start, /* start rtext to allocate */ xfs_rtxlen_t len, /* length to allocate */ struct xfs_buf **rbpp, /* in/out: summary block buffer */ xfs_fileoff_t *rsb) /* in/out: summary block number */ { - xfs_rtblock_t end; /* end of the allocated extent */ + xfs_rtxnum_t end; /* end of the allocated rtext */ int error; /* error value */ - xfs_rtblock_t postblock = 0; /* first block allocated > end */ - xfs_rtblock_t preblock = 0; /* first block allocated < start */ + xfs_rtxnum_t postblock = 0; /* first rtext allocated > end */ + xfs_rtxnum_t preblock = 0; /* first rtext allocated < start */ end = start + len - 1; /* @@ -219,7 +219,7 @@ xfs_rtallocate_range( static inline xfs_rtxlen_t xfs_rtallocate_clamp_len( struct xfs_mount *mp, - xfs_rtblock_t startrtx, + xfs_rtxnum_t startrtx, xfs_rtxlen_t rtxlen, xfs_rtxlen_t prod) { @@ -232,7 +232,7 @@ xfs_rtallocate_clamp_len( /* * Attempt to allocate an extent minlen<=len<=maxlen starting from * bitmap block bbno. If we don't get maxlen then use prod to trim - * the length, if given. Returns error; returns starting block in *rtblock. + * the length, if given. Returns error; returns starting block in *rtx. * The lengths are all in rtextents. */ STATIC int /* error */ @@ -243,18 +243,18 @@ xfs_rtallocate_extent_block( xfs_rtxlen_t minlen, /* minimum length to allocate */ xfs_rtxlen_t maxlen, /* maximum length to allocate */ xfs_rtxlen_t *len, /* out: actual length allocated */ - xfs_rtblock_t *nextp, /* out: next block to try */ + xfs_rtxnum_t *nextp, /* out: next rtext to try */ struct xfs_buf **rbpp, /* in/out: summary block buffer */ xfs_fileoff_t *rsb, /* in/out: summary block number */ xfs_rtxlen_t prod, /* extent product factor */ - xfs_rtblock_t *rtblock) /* out: start block allocated */ + xfs_rtxnum_t *rtx) /* out: start rtext allocated */ { - xfs_rtblock_t besti; /* best rtblock found so far */ - xfs_rtblock_t bestlen; /* best length found so far */ - xfs_rtblock_t end; /* last rtblock in chunk */ + xfs_rtxnum_t besti; /* best rtext found so far */ + xfs_rtxnum_t bestlen; /* best length found so far */ + xfs_rtxnum_t end; /* last rtext in chunk */ int error; /* error value */ - xfs_rtblock_t i; /* current rtblock trying */ - xfs_rtblock_t next; /* next rtblock to try */ + xfs_rtxnum_t i; /* current rtext trying */ + xfs_rtxnum_t next; /* next rtext to try */ int stat; /* status from internal calls */ /* @@ -286,7 +286,7 @@ xfs_rtallocate_extent_block( return error; } *len = maxlen; - *rtblock = i; + *rtx = i; return 0; } /* @@ -296,7 +296,7 @@ xfs_rtallocate_extent_block( * so far, remember it. */ if (minlen < maxlen) { - xfs_rtblock_t thislen; /* this extent size */ + xfs_rtxnum_t thislen; /* this extent size */ thislen = next - i; if (thislen >= minlen && thislen > bestlen) { @@ -338,47 +338,47 @@ xfs_rtallocate_extent_block( return error; } *len = bestlen; - *rtblock = besti; + *rtx = besti; return 0; } /* * Allocation failed. Set *nextp to the next block to try. */ *nextp = next; - *rtblock = NULLRTBLOCK; + *rtx = NULLRTEXTNO; return 0; } /* * Allocate an extent of length minlen<=len<=maxlen, starting at block * bno. If we don't get maxlen then use prod to trim the length, if given. - * Returns error; returns starting block in *rtblock. + * Returns error; returns starting block in *rtx. * The lengths are all in rtextents. */ STATIC int /* error */ xfs_rtallocate_extent_exact( xfs_mount_t *mp, /* file system mount point */ xfs_trans_t *tp, /* transaction pointer */ - xfs_rtblock_t bno, /* starting block number to allocate */ + xfs_rtxnum_t start, /* starting rtext number to allocate */ xfs_rtxlen_t minlen, /* minimum length to allocate */ xfs_rtxlen_t maxlen, /* maximum length to allocate */ xfs_rtxlen_t *len, /* out: actual length allocated */ struct xfs_buf **rbpp, /* in/out: summary block buffer */ xfs_fileoff_t *rsb, /* in/out: summary block number */ xfs_rtxlen_t prod, /* extent product factor */ - xfs_rtblock_t *rtblock) /* out: start block allocated */ + xfs_rtxnum_t *rtx) /* out: start rtext allocated */ { int error; /* error value */ xfs_rtxlen_t i; /* extent length trimmed due to prod */ int isfree; /* extent is free */ - xfs_rtblock_t next; /* next block to try (dummy) */ + xfs_rtxnum_t next; /* next rtext to try (dummy) */ ASSERT(minlen % prod == 0); ASSERT(maxlen % prod == 0); /* * Check if the range in question (for maxlen) is free. */ - error = xfs_rtcheck_range(mp, tp, bno, maxlen, 1, &next, &isfree); + error = xfs_rtcheck_range(mp, tp, start, maxlen, 1, &next, &isfree); if (error) { return error; } @@ -386,23 +386,23 @@ xfs_rtallocate_extent_exact( /* * If it is, allocate it and return success. */ - error = xfs_rtallocate_range(mp, tp, bno, maxlen, rbpp, rsb); + error = xfs_rtallocate_range(mp, tp, start, maxlen, rbpp, rsb); if (error) { return error; } *len = maxlen; - *rtblock = bno; + *rtx = start; return 0; } /* * If not, allocate what there is, if it's at least minlen. */ - maxlen = next - bno; + maxlen = next - start; if (maxlen < minlen) { /* * Failed, return failure status. */ - *rtblock = NULLRTBLOCK; + *rtx = NULLRTEXTNO; return 0; } /* @@ -414,39 +414,39 @@ xfs_rtallocate_extent_exact( /* * Now we can't do it, return failure status. */ - *rtblock = NULLRTBLOCK; + *rtx = NULLRTEXTNO; return 0; } } /* * Allocate what we can and return it. */ - error = xfs_rtallocate_range(mp, tp, bno, maxlen, rbpp, rsb); + error = xfs_rtallocate_range(mp, tp, start, maxlen, rbpp, rsb); if (error) { return error; } *len = maxlen; - *rtblock = bno; + *rtx = start; return 0; } /* * Allocate an extent of length minlen<=len<=maxlen, starting as near - * to bno as possible. If we don't get maxlen then use prod to trim + * to start as possible. If we don't get maxlen then use prod to trim * the length, if given. The lengths are all in rtextents. */ STATIC int /* error */ xfs_rtallocate_extent_near( xfs_mount_t *mp, /* file system mount point */ xfs_trans_t *tp, /* transaction pointer */ - xfs_rtblock_t bno, /* starting block number to allocate */ + xfs_rtxnum_t start, /* starting rtext number to allocate */ xfs_rtxlen_t minlen, /* minimum length to allocate */ xfs_rtxlen_t maxlen, /* maximum length to allocate */ xfs_rtxlen_t *len, /* out: actual length allocated */ struct xfs_buf **rbpp, /* in/out: summary block buffer */ xfs_fileoff_t *rsb, /* in/out: summary block number */ xfs_rtxlen_t prod, /* extent product factor */ - xfs_rtblock_t *rtblock) /* out: start block allocated */ + xfs_rtxnum_t *rtx) /* out: start rtext allocated */ { int any; /* any useful extents from summary */ xfs_fileoff_t bbno; /* bitmap block number */ @@ -454,8 +454,8 @@ xfs_rtallocate_extent_near( int i; /* bitmap block offset (loop control) */ int j; /* secondary loop control */ int log2len; /* log2 of minlen */ - xfs_rtblock_t n; /* next block to try */ - xfs_rtblock_t r; /* result block */ + xfs_rtxnum_t n; /* next rtext to try */ + xfs_rtxnum_t r; /* result rtext */ ASSERT(minlen % prod == 0); ASSERT(maxlen % prod == 0); @@ -464,20 +464,20 @@ xfs_rtallocate_extent_near( * If the block number given is off the end, silently set it to * the last block. */ - if (bno >= mp->m_sb.sb_rextents) - bno = mp->m_sb.sb_rextents - 1; + if (start >= mp->m_sb.sb_rextents) + start = mp->m_sb.sb_rextents - 1; /* Make sure we don't run off the end of the rt volume. */ - maxlen = xfs_rtallocate_clamp_len(mp, bno, maxlen, prod); + maxlen = xfs_rtallocate_clamp_len(mp, start, maxlen, prod); if (maxlen < minlen) { - *rtblock = NULLRTBLOCK; + *rtx = NULLRTEXTNO; return 0; } /* * Try the exact allocation first. */ - error = xfs_rtallocate_extent_exact(mp, tp, bno, minlen, maxlen, len, + error = xfs_rtallocate_extent_exact(mp, tp, start, minlen, maxlen, len, rbpp, rsb, prod, &r); if (error) { return error; @@ -485,11 +485,11 @@ xfs_rtallocate_extent_near( /* * If the exact allocation worked, return that. */ - if (r != NULLRTBLOCK) { - *rtblock = r; + if (r != NULLRTEXTNO) { + *rtx = r; return 0; } - bbno = XFS_BITTOBLOCK(mp, bno); + bbno = XFS_BITTOBLOCK(mp, start); i = 0; ASSERT(minlen != 0); log2len = xfs_highbit32(minlen); @@ -528,8 +528,8 @@ xfs_rtallocate_extent_near( /* * If it worked, return it. */ - if (r != NULLRTBLOCK) { - *rtblock = r; + if (r != NULLRTEXTNO) { + *rtx = r; return 0; } } @@ -573,8 +573,8 @@ xfs_rtallocate_extent_near( /* * If it works, return the extent. */ - if (r != NULLRTBLOCK) { - *rtblock = r; + if (r != NULLRTEXTNO) { + *rtx = r; return 0; } } @@ -595,8 +595,8 @@ xfs_rtallocate_extent_near( /* * If it works, return the extent. */ - if (r != NULLRTBLOCK) { - *rtblock = r; + if (r != NULLRTEXTNO) { + *rtx = r; return 0; } } @@ -631,7 +631,7 @@ xfs_rtallocate_extent_near( else break; } - *rtblock = NULLRTBLOCK; + *rtx = NULLRTEXTNO; return 0; } @@ -650,13 +650,13 @@ xfs_rtallocate_extent_size( struct xfs_buf **rbpp, /* in/out: summary block buffer */ xfs_fileoff_t *rsb, /* in/out: summary block number */ xfs_rtxlen_t prod, /* extent product factor */ - xfs_rtblock_t *rtblock) /* out: start block allocated */ + xfs_rtxnum_t *rtx) /* out: start rtext allocated */ { int error; /* error value */ xfs_fileoff_t i; /* bitmap block number */ int l; /* level number (loop control) */ - xfs_rtblock_t n; /* next block to be tried */ - xfs_rtblock_t r; /* result block number */ + xfs_rtxnum_t n; /* next rtext to be tried */ + xfs_rtxnum_t r; /* result rtext number */ xfs_suminfo_t sum; /* summary information for extents */ ASSERT(minlen % prod == 0); @@ -699,8 +699,8 @@ xfs_rtallocate_extent_size( /* * If it worked, return that. */ - if (r != NULLRTBLOCK) { - *rtblock = r; + if (r != NULLRTEXTNO) { + *rtx = r; return 0; } /* @@ -717,7 +717,7 @@ xfs_rtallocate_extent_size( * we're asking for a fixed size extent. */ if (minlen > --maxlen) { - *rtblock = NULLRTBLOCK; + *rtx = NULLRTEXTNO; return 0; } ASSERT(minlen != 0); @@ -762,8 +762,8 @@ xfs_rtallocate_extent_size( /* * If it worked, return that extent. */ - if (r != NULLRTBLOCK) { - *rtblock = r; + if (r != NULLRTEXTNO) { + *rtx = r; return 0; } /* @@ -778,7 +778,7 @@ xfs_rtallocate_extent_size( /* * Got nothing, return failure. */ - *rtblock = NULLRTBLOCK; + *rtx = NULLRTEXTNO; return 0; } @@ -935,7 +935,7 @@ xfs_growfs_rt( xfs_mount_t *nmp; /* new (fake) mount structure */ xfs_rfsblock_t nrblocks; /* new number of realtime blocks */ xfs_extlen_t nrbmblocks; /* new number of rt bitmap blocks */ - xfs_rtblock_t nrextents; /* new number of realtime extents */ + xfs_rtxnum_t nrextents; /* new number of realtime extents */ uint8_t nrextslog; /* new log2 of sb_rextents */ xfs_extlen_t nrsumblocks; /* new number of summary blocks */ uint nrsumlevels; /* new rt summary levels */ @@ -1196,17 +1196,17 @@ out_free: int /* error */ xfs_rtallocate_extent( xfs_trans_t *tp, /* transaction pointer */ - xfs_rtblock_t bno, /* starting block number to allocate */ + xfs_rtxnum_t start, /* starting rtext number to allocate */ xfs_rtxlen_t minlen, /* minimum length to allocate */ xfs_rtxlen_t maxlen, /* maximum length to allocate */ xfs_rtxlen_t *len, /* out: actual length allocated */ int wasdel, /* was a delayed allocation extent */ xfs_rtxlen_t prod, /* extent product factor */ - xfs_rtblock_t *rtblock) /* out: start block allocated */ + xfs_rtxnum_t *rtblock) /* out: start rtext allocated */ { xfs_mount_t *mp = tp->t_mountp; int error; /* error value */ - xfs_rtblock_t r; /* result allocated block */ + xfs_rtxnum_t r; /* result allocated rtext */ xfs_fileoff_t sb; /* summary file block number */ struct xfs_buf *sumbp; /* summary file block buffer */ @@ -1224,18 +1224,18 @@ xfs_rtallocate_extent( if ((i = minlen % prod)) minlen += prod - i; if (maxlen < minlen) { - *rtblock = NULLRTBLOCK; + *rtblock = NULLRTEXTNO; return 0; } } retry: sumbp = NULL; - if (bno == 0) { + if (start == 0) { error = xfs_rtallocate_extent_size(mp, tp, minlen, maxlen, len, &sumbp, &sb, prod, &r); } else { - error = xfs_rtallocate_extent_near(mp, tp, bno, minlen, maxlen, + error = xfs_rtallocate_extent_near(mp, tp, start, minlen, maxlen, len, &sumbp, &sb, prod, &r); } @@ -1245,7 +1245,7 @@ retry: /* * If it worked, update the superblock. */ - if (r != NULLRTBLOCK) { + if (r != NULLRTEXTNO) { long slen = (long)*len; ASSERT(*len >= minlen && *len <= maxlen); @@ -1445,9 +1445,9 @@ xfs_rtpick_extent( xfs_mount_t *mp, /* file system mount point */ xfs_trans_t *tp, /* transaction pointer */ xfs_rtxlen_t len, /* allocation length (rtextents) */ - xfs_rtblock_t *pick) /* result rt extent */ + xfs_rtxnum_t *pick) /* result rt extent */ { - xfs_rtblock_t b; /* result block */ + xfs_rtxnum_t b; /* result rtext */ int log2; /* log of sequence number */ uint64_t resid; /* residual after log removed */ uint64_t seq; /* sequence number of file creation */ diff --git a/fs/xfs/xfs_rtalloc.h b/fs/xfs/xfs_rtalloc.h index 24a4a1321de0..f7cb9ffe51ca 100644 --- a/fs/xfs/xfs_rtalloc.h +++ b/fs/xfs/xfs_rtalloc.h @@ -24,13 +24,13 @@ struct xfs_trans; int /* error */ xfs_rtallocate_extent( struct xfs_trans *tp, /* transaction pointer */ - xfs_rtblock_t bno, /* starting block number to allocate */ + xfs_rtxnum_t start, /* starting rtext number to allocate */ xfs_rtxlen_t minlen, /* minimum length to allocate */ xfs_rtxlen_t maxlen, /* maximum length to allocate */ xfs_rtxlen_t *len, /* out: actual length allocated */ int wasdel, /* was a delayed allocation extent */ xfs_rtxlen_t prod, /* extent product factor */ - xfs_rtblock_t *rtblock); /* out: start block allocated */ + xfs_rtxnum_t *rtblock); /* out: start rtext allocated */ /* @@ -63,7 +63,7 @@ xfs_rtpick_extent( struct xfs_mount *mp, /* file system mount point */ struct xfs_trans *tp, /* transaction pointer */ xfs_rtxlen_t len, /* allocation length (rtextents) */ - xfs_rtblock_t *pick); /* result rt extent */ + xfs_rtxnum_t *pick); /* result rt extent */ /* * Grow the realtime area of the filesystem. -- cgit v1.2.3 From fa5a387230861116c2434c20d29fc4b3fd077d24 Mon Sep 17 00:00:00 2001 From: "Darrick J. Wong" Date: Mon, 16 Oct 2023 09:32:54 -0700 Subject: xfs: create a helper to convert rtextents to rtblocks Create a helper to convert a realtime extent to a realtime block. Later on we'll change the helper to use bit shifts when possible. Signed-off-by: Darrick J. Wong Reviewed-by: Christoph Hellwig --- fs/xfs/libxfs/xfs_rtbitmap.h | 16 ++++++++++++++++ fs/xfs/scrub/rtbitmap.c | 4 ++-- fs/xfs/scrub/rtsummary.c | 4 ++-- fs/xfs/xfs_bmap_util.c | 9 +++++---- fs/xfs/xfs_fsmap.c | 6 +++--- fs/xfs/xfs_super.c | 3 ++- 6 files changed, 30 insertions(+), 12 deletions(-) (limited to 'fs/xfs') diff --git a/fs/xfs/libxfs/xfs_rtbitmap.h b/fs/xfs/libxfs/xfs_rtbitmap.h index 5e2afb7fea0e..099ea8902aaa 100644 --- a/fs/xfs/libxfs/xfs_rtbitmap.h +++ b/fs/xfs/libxfs/xfs_rtbitmap.h @@ -6,6 +6,22 @@ #ifndef __XFS_RTBITMAP_H__ #define __XFS_RTBITMAP_H__ +static inline xfs_rtblock_t +xfs_rtx_to_rtb( + struct xfs_mount *mp, + xfs_rtxnum_t rtx) +{ + return rtx * mp->m_sb.sb_rextsize; +} + +static inline xfs_extlen_t +xfs_rtxlen_to_extlen( + struct xfs_mount *mp, + xfs_rtxlen_t rtxlen) +{ + return rtxlen * mp->m_sb.sb_rextsize; +} + /* * Functions for walking free space rtextents in the realtime bitmap. */ diff --git a/fs/xfs/scrub/rtbitmap.c b/fs/xfs/scrub/rtbitmap.c index bea5a2b75a06..584a2b8badac 100644 --- a/fs/xfs/scrub/rtbitmap.c +++ b/fs/xfs/scrub/rtbitmap.c @@ -50,8 +50,8 @@ xchk_rtbitmap_rec( xfs_rtblock_t startblock; xfs_filblks_t blockcount; - startblock = rec->ar_startext * mp->m_sb.sb_rextsize; - blockcount = rec->ar_extcount * mp->m_sb.sb_rextsize; + startblock = xfs_rtx_to_rtb(mp, rec->ar_startext); + blockcount = xfs_rtx_to_rtb(mp, rec->ar_extcount); if (!xfs_verify_rtbext(mp, startblock, blockcount)) xchk_fblock_set_corrupt(sc, XFS_DATA_FORK, 0); diff --git a/fs/xfs/scrub/rtsummary.c b/fs/xfs/scrub/rtsummary.c index d998f0c378a4..d363286e8b72 100644 --- a/fs/xfs/scrub/rtsummary.c +++ b/fs/xfs/scrub/rtsummary.c @@ -134,8 +134,8 @@ xchk_rtsum_record_free( lenlog = XFS_RTBLOCKLOG(rec->ar_extcount); offs = XFS_SUMOFFS(mp, lenlog, rbmoff); - rtbno = rec->ar_startext * mp->m_sb.sb_rextsize; - rtlen = rec->ar_extcount * mp->m_sb.sb_rextsize; + rtbno = xfs_rtx_to_rtb(mp, rec->ar_startext); + rtlen = xfs_rtx_to_rtb(mp, rec->ar_extcount); if (!xfs_verify_rtbext(mp, rtbno, rtlen)) { xchk_ino_xref_set_corrupt(sc, mp->m_rbmip->i_ino); diff --git a/fs/xfs/xfs_bmap_util.c b/fs/xfs/xfs_bmap_util.c index 557330281ae3..2d747084c199 100644 --- a/fs/xfs/xfs_bmap_util.c +++ b/fs/xfs/xfs_bmap_util.c @@ -28,6 +28,7 @@ #include "xfs_icache.h" #include "xfs_iomap.h" #include "xfs_reflink.h" +#include "xfs_rtbitmap.h" /* Kernel only BMAP related definitions and functions */ @@ -125,7 +126,7 @@ retry: * XFS_BMBT_MAX_EXTLEN), we don't hear about that number, and can't * adjust the starting point to match it. */ - if (ralen * mp->m_sb.sb_rextsize >= XFS_MAX_BMBT_EXTLEN) + if (xfs_rtxlen_to_extlen(mp, ralen) >= XFS_MAX_BMBT_EXTLEN) ralen = XFS_MAX_BMBT_EXTLEN / mp->m_sb.sb_rextsize; /* @@ -147,7 +148,7 @@ retry: error = xfs_rtpick_extent(mp, ap->tp, ralen, &rtx); if (error) return error; - ap->blkno = rtx * mp->m_sb.sb_rextsize; + ap->blkno = xfs_rtx_to_rtb(mp, rtx); } else { ap->blkno = 0; } @@ -170,8 +171,8 @@ retry: return error; if (rtx != NULLRTEXTNO) { - ap->blkno = rtx * mp->m_sb.sb_rextsize; - ap->length = ralen * mp->m_sb.sb_rextsize; + ap->blkno = xfs_rtx_to_rtb(mp, rtx); + ap->length = xfs_rtxlen_to_extlen(mp, ralen); ap->ip->i_nblocks += ap->length; xfs_trans_log_inode(ap->tp, ap->ip, XFS_ILOG_CORE); if (ap->wasdel) diff --git a/fs/xfs/xfs_fsmap.c b/fs/xfs/xfs_fsmap.c index 8982c5d6cbd0..1a187bc9da3d 100644 --- a/fs/xfs/xfs_fsmap.c +++ b/fs/xfs/xfs_fsmap.c @@ -483,11 +483,11 @@ xfs_getfsmap_rtdev_rtbitmap_helper( xfs_rtblock_t rtbno; xfs_daddr_t rec_daddr, len_daddr; - rtbno = rec->ar_startext * mp->m_sb.sb_rextsize; + rtbno = xfs_rtx_to_rtb(mp, rec->ar_startext); rec_daddr = XFS_FSB_TO_BB(mp, rtbno); irec.rm_startblock = rtbno; - rtbno = rec->ar_extcount * mp->m_sb.sb_rextsize; + rtbno = xfs_rtx_to_rtb(mp, rec->ar_extcount); len_daddr = XFS_FSB_TO_BB(mp, rtbno); irec.rm_blockcount = rtbno; @@ -514,7 +514,7 @@ xfs_getfsmap_rtdev_rtbitmap( uint64_t eofs; int error; - eofs = XFS_FSB_TO_BB(mp, mp->m_sb.sb_rextents * mp->m_sb.sb_rextsize); + eofs = XFS_FSB_TO_BB(mp, xfs_rtx_to_rtb(mp, mp->m_sb.sb_rextents)); if (keys[0].fmr_physical >= eofs) return 0; start_rtb = XFS_BB_TO_FSBT(mp, diff --git a/fs/xfs/xfs_super.c b/fs/xfs/xfs_super.c index 819a3568b28f..991a31089dc7 100644 --- a/fs/xfs/xfs_super.c +++ b/fs/xfs/xfs_super.c @@ -42,6 +42,7 @@ #include "xfs_xattr.h" #include "xfs_iunlink_item.h" #include "xfs_dahash_test.h" +#include "xfs_rtbitmap.h" #include "scrub/stats.h" #include @@ -890,7 +891,7 @@ xfs_fs_statfs( statp->f_blocks = sbp->sb_rblocks; freertx = percpu_counter_sum_positive(&mp->m_frextents); - statp->f_bavail = statp->f_bfree = freertx * sbp->sb_rextsize; + statp->f_bavail = statp->f_bfree = xfs_rtx_to_rtb(mp, freertx); } return 0; -- cgit v1.2.3 From 68db60bf01c131c09bbe35adf43bd957a4c124bc Mon Sep 17 00:00:00 2001 From: "Darrick J. Wong" Date: Mon, 16 Oct 2023 09:34:39 -0700 Subject: xfs: create a helper to compute leftovers of realtime extents Create a helper to compute the misalignment between a file extent (xfs_extlen_t) and a realtime extent. Signed-off-by: Darrick J. Wong Reviewed-by: Christoph Hellwig --- fs/xfs/libxfs/xfs_bmap.c | 4 ++-- fs/xfs/libxfs/xfs_rtbitmap.h | 9 +++++++++ fs/xfs/scrub/inode.c | 3 ++- fs/xfs/xfs_bmap_util.c | 2 +- fs/xfs/xfs_inode_item.c | 3 ++- fs/xfs/xfs_ioctl.c | 5 +++-- 6 files changed, 19 insertions(+), 7 deletions(-) (limited to 'fs/xfs') diff --git a/fs/xfs/libxfs/xfs_bmap.c b/fs/xfs/libxfs/xfs_bmap.c index 4e7de4f2fd7a..19203699b992 100644 --- a/fs/xfs/libxfs/xfs_bmap.c +++ b/fs/xfs/libxfs/xfs_bmap.c @@ -2989,7 +2989,7 @@ xfs_bmap_extsize_align( * If realtime, and the result isn't a multiple of the realtime * extent size we need to remove blocks until it is. */ - if (rt && (temp = (align_alen % mp->m_sb.sb_rextsize))) { + if (rt && (temp = xfs_extlen_to_rtxmod(mp, align_alen))) { /* * We're not covering the original request, or * we won't be able to once we fix the length. @@ -3016,7 +3016,7 @@ xfs_bmap_extsize_align( else { align_alen -= orig_off - align_off; align_off = orig_off; - align_alen -= align_alen % mp->m_sb.sb_rextsize; + align_alen -= xfs_extlen_to_rtxmod(mp, align_alen); } /* * Result doesn't cover the request, fail it. diff --git a/fs/xfs/libxfs/xfs_rtbitmap.h b/fs/xfs/libxfs/xfs_rtbitmap.h index 099ea8902aaa..b6a4c46bddc0 100644 --- a/fs/xfs/libxfs/xfs_rtbitmap.h +++ b/fs/xfs/libxfs/xfs_rtbitmap.h @@ -22,6 +22,15 @@ xfs_rtxlen_to_extlen( return rtxlen * mp->m_sb.sb_rextsize; } +/* Compute the misalignment between an extent length and a realtime extent .*/ +static inline unsigned int +xfs_extlen_to_rtxmod( + struct xfs_mount *mp, + xfs_extlen_t len) +{ + return len % mp->m_sb.sb_rextsize; +} + /* * Functions for walking free space rtextents in the realtime bitmap. */ diff --git a/fs/xfs/scrub/inode.c b/fs/xfs/scrub/inode.c index 59d7912fb75f..889f556bc98f 100644 --- a/fs/xfs/scrub/inode.c +++ b/fs/xfs/scrub/inode.c @@ -20,6 +20,7 @@ #include "xfs_reflink.h" #include "xfs_rmap.h" #include "xfs_bmap_util.h" +#include "xfs_rtbitmap.h" #include "scrub/scrub.h" #include "scrub/common.h" #include "scrub/btree.h" @@ -225,7 +226,7 @@ xchk_inode_extsize( */ if ((flags & XFS_DIFLAG_RTINHERIT) && (flags & XFS_DIFLAG_EXTSZINHERIT) && - value % sc->mp->m_sb.sb_rextsize > 0) + xfs_extlen_to_rtxmod(sc->mp, value) > 0) xchk_ino_set_warning(sc, ino); } diff --git a/fs/xfs/xfs_bmap_util.c b/fs/xfs/xfs_bmap_util.c index 2d747084c199..8895184ff90a 100644 --- a/fs/xfs/xfs_bmap_util.c +++ b/fs/xfs/xfs_bmap_util.c @@ -97,7 +97,7 @@ retry: if (error) return error; ASSERT(ap->length); - ASSERT(ap->length % mp->m_sb.sb_rextsize == 0); + ASSERT(xfs_extlen_to_rtxmod(mp, ap->length) == 0); /* * If we shifted the file offset downward to satisfy an extent size diff --git a/fs/xfs/xfs_inode_item.c b/fs/xfs/xfs_inode_item.c index 127b2410eb20..3183d0b03e0b 100644 --- a/fs/xfs/xfs_inode_item.c +++ b/fs/xfs/xfs_inode_item.c @@ -19,6 +19,7 @@ #include "xfs_log.h" #include "xfs_log_priv.h" #include "xfs_error.h" +#include "xfs_rtbitmap.h" #include @@ -107,7 +108,7 @@ xfs_inode_item_precommit( */ if ((ip->i_diflags & XFS_DIFLAG_RTINHERIT) && (ip->i_diflags & XFS_DIFLAG_EXTSZINHERIT) && - (ip->i_extsize % ip->i_mount->m_sb.sb_rextsize) > 0) { + xfs_extlen_to_rtxmod(ip->i_mount, ip->i_extsize) > 0) { ip->i_diflags &= ~(XFS_DIFLAG_EXTSIZE | XFS_DIFLAG_EXTSZINHERIT); ip->i_extsize = 0; diff --git a/fs/xfs/xfs_ioctl.c b/fs/xfs/xfs_ioctl.c index 55bb01173cde..a82470e027f7 100644 --- a/fs/xfs/xfs_ioctl.c +++ b/fs/xfs/xfs_ioctl.c @@ -38,6 +38,7 @@ #include "xfs_reflink.h" #include "xfs_ioctl.h" #include "xfs_xattr.h" +#include "xfs_rtbitmap.h" #include #include @@ -1004,7 +1005,7 @@ xfs_fill_fsxattr( * later. */ if ((ip->i_diflags & XFS_DIFLAG_RTINHERIT) && - ip->i_extsize % mp->m_sb.sb_rextsize > 0) { + xfs_extlen_to_rtxmod(mp, ip->i_extsize) > 0) { fa->fsx_xflags &= ~(FS_XFLAG_EXTSIZE | FS_XFLAG_EXTSZINHERIT); fa->fsx_extsize = 0; @@ -1130,7 +1131,7 @@ xfs_ioctl_setattr_xflags( /* If realtime flag is set then must have realtime device */ if (fa->fsx_xflags & FS_XFLAG_REALTIME) { if (mp->m_sb.sb_rblocks == 0 || mp->m_sb.sb_rextsize == 0 || - (ip->i_extsize % mp->m_sb.sb_rextsize)) + xfs_extlen_to_rtxmod(mp, ip->i_extsize)) return -EINVAL; } -- cgit v1.2.3 From 2c2b981b737a519907429f62148bbd9e40e01132 Mon Sep 17 00:00:00 2001 From: "Darrick J. Wong" Date: Mon, 16 Oct 2023 09:35:23 -0700 Subject: xfs: create a helper to convert extlen to rtextlen Create a helper to compute the realtime extent (xfs_rtxlen_t) from an extent length (xfs_extlen_t) value. Signed-off-by: Darrick J. Wong Reviewed-by: Christoph Hellwig --- fs/xfs/libxfs/xfs_rtbitmap.h | 8 ++++++++ fs/xfs/libxfs/xfs_trans_resv.c | 3 ++- fs/xfs/xfs_bmap_util.c | 11 ++++------- fs/xfs/xfs_trans.c | 3 ++- 4 files changed, 16 insertions(+), 9 deletions(-) (limited to 'fs/xfs') diff --git a/fs/xfs/libxfs/xfs_rtbitmap.h b/fs/xfs/libxfs/xfs_rtbitmap.h index b6a4c46bddc0..e2a36fc157c4 100644 --- a/fs/xfs/libxfs/xfs_rtbitmap.h +++ b/fs/xfs/libxfs/xfs_rtbitmap.h @@ -31,6 +31,14 @@ xfs_extlen_to_rtxmod( return len % mp->m_sb.sb_rextsize; } +static inline xfs_rtxlen_t +xfs_extlen_to_rtxlen( + struct xfs_mount *mp, + xfs_extlen_t len) +{ + return len / mp->m_sb.sb_rextsize; +} + /* * Functions for walking free space rtextents in the realtime bitmap. */ diff --git a/fs/xfs/libxfs/xfs_trans_resv.c b/fs/xfs/libxfs/xfs_trans_resv.c index 5b2f27cbdb80..4629f10d2f67 100644 --- a/fs/xfs/libxfs/xfs_trans_resv.c +++ b/fs/xfs/libxfs/xfs_trans_resv.c @@ -19,6 +19,7 @@ #include "xfs_trans.h" #include "xfs_qm.h" #include "xfs_trans_space.h" +#include "xfs_rtbitmap.h" #define _ALLOC true #define _FREE false @@ -220,7 +221,7 @@ xfs_rtalloc_block_count( unsigned int blksz = XFS_FSB_TO_B(mp, 1); unsigned int rtbmp_bytes; - rtbmp_bytes = (XFS_MAX_BMBT_EXTLEN / mp->m_sb.sb_rextsize) / NBBY; + rtbmp_bytes = xfs_extlen_to_rtxlen(mp, XFS_MAX_BMBT_EXTLEN) / NBBY; return (howmany(rtbmp_bytes, blksz) + 1) * num_ops; } diff --git a/fs/xfs/xfs_bmap_util.c b/fs/xfs/xfs_bmap_util.c index 8895184ff90a..4f53f784f06d 100644 --- a/fs/xfs/xfs_bmap_util.c +++ b/fs/xfs/xfs_bmap_util.c @@ -90,7 +90,7 @@ xfs_bmap_rtalloc( align = xfs_get_extsz_hint(ap->ip); retry: - prod = align / mp->m_sb.sb_rextsize; + prod = xfs_extlen_to_rtxlen(mp, align); error = xfs_bmap_extsize_align(mp, &ap->got, &ap->prev, align, 1, ap->eof, 0, ap->conv, &ap->offset, &ap->length); @@ -117,17 +117,14 @@ retry: prod = 1; /* * Set ralen to be the actual requested length in rtextents. - */ - ralen = ap->length / mp->m_sb.sb_rextsize; - /* + * * If the old value was close enough to XFS_BMBT_MAX_EXTLEN that * we rounded up to it, cut it back so it's valid again. * Note that if it's a really large request (bigger than * XFS_BMBT_MAX_EXTLEN), we don't hear about that number, and can't * adjust the starting point to match it. */ - if (xfs_rtxlen_to_extlen(mp, ralen) >= XFS_MAX_BMBT_EXTLEN) - ralen = XFS_MAX_BMBT_EXTLEN / mp->m_sb.sb_rextsize; + ralen = xfs_extlen_to_rtxlen(mp, min(ap->length, XFS_MAX_BMBT_EXTLEN)); /* * Lock out modifications to both the RT bitmap and summary inodes @@ -164,7 +161,7 @@ retry: do_div(ap->blkno, mp->m_sb.sb_rextsize); rtx = ap->blkno; ap->length = ralen; - raminlen = max_t(xfs_extlen_t, 1, minlen / mp->m_sb.sb_rextsize); + raminlen = max_t(xfs_rtxlen_t, 1, xfs_extlen_to_rtxlen(mp, minlen)); error = xfs_rtallocate_extent(ap->tp, ap->blkno, raminlen, ap->length, &ralen, ap->wasdel, prod, &rtx); if (error) diff --git a/fs/xfs/xfs_trans.c b/fs/xfs/xfs_trans.c index 8c0bfc9a33b1..338dd3774507 100644 --- a/fs/xfs/xfs_trans.c +++ b/fs/xfs/xfs_trans.c @@ -24,6 +24,7 @@ #include "xfs_dquot_item.h" #include "xfs_dquot.h" #include "xfs_icache.h" +#include "xfs_rtbitmap.h" struct kmem_cache *xfs_trans_cache; @@ -1196,7 +1197,7 @@ xfs_trans_alloc_inode( retry: error = xfs_trans_alloc(mp, resv, dblocks, - rblocks / mp->m_sb.sb_rextsize, + xfs_extlen_to_rtxlen(mp, rblocks), force ? XFS_TRANS_RESERVE : 0, &tp); if (error) return error; -- cgit v1.2.3 From 5dc3a80d46a450481df7f7e9fe673ba3eb4514c3 Mon Sep 17 00:00:00 2001 From: "Darrick J. Wong" Date: Mon, 16 Oct 2023 09:37:07 -0700 Subject: xfs: create helpers to convert rt block numbers to rt extent numbers Create helpers to do unit conversions of rt block numbers to rt extent numbers. There are three variations -- one to compute the rt extent number from an rt block number; one to compute the offset of an rt block within an rt extent; and one to extract both. Signed-off-by: Darrick J. Wong Reviewed-by: Christoph Hellwig --- fs/xfs/libxfs/xfs_bmap.c | 8 ++++---- fs/xfs/libxfs/xfs_rtbitmap.c | 4 ++-- fs/xfs/libxfs/xfs_rtbitmap.h | 31 +++++++++++++++++++++++++++++++ 3 files changed, 37 insertions(+), 6 deletions(-) (limited to 'fs/xfs') diff --git a/fs/xfs/libxfs/xfs_bmap.c b/fs/xfs/libxfs/xfs_bmap.c index 19203699b992..fc96aa59a691 100644 --- a/fs/xfs/libxfs/xfs_bmap.c +++ b/fs/xfs/libxfs/xfs_bmap.c @@ -5276,7 +5276,6 @@ __xfs_bunmapi( int tmp_logflags; /* partial logging flags */ int wasdel; /* was a delayed alloc extent */ int whichfork; /* data or attribute fork */ - xfs_fsblock_t sum; xfs_filblks_t len = *rlen; /* length to unmap in file */ xfs_fileoff_t end; struct xfs_iext_cursor icur; @@ -5371,8 +5370,8 @@ __xfs_bunmapi( if (!isrt) goto delete; - sum = del.br_startblock + del.br_blockcount; - div_u64_rem(sum, mp->m_sb.sb_rextsize, &mod); + mod = xfs_rtb_to_rtxoff(mp, + del.br_startblock + del.br_blockcount); if (mod) { /* * Realtime extent not lined up at the end. @@ -5419,7 +5418,8 @@ __xfs_bunmapi( goto error0; goto nodelete; } - div_u64_rem(del.br_startblock, mp->m_sb.sb_rextsize, &mod); + + mod = xfs_rtb_to_rtxoff(mp, del.br_startblock); if (mod) { xfs_extlen_t off = mp->m_sb.sb_rextsize - mod; diff --git a/fs/xfs/libxfs/xfs_rtbitmap.c b/fs/xfs/libxfs/xfs_rtbitmap.c index f64e4aeb393b..383c6437e042 100644 --- a/fs/xfs/libxfs/xfs_rtbitmap.c +++ b/fs/xfs/libxfs/xfs_rtbitmap.c @@ -1024,13 +1024,13 @@ xfs_rtfree_blocks( ASSERT(rtlen <= XFS_MAX_BMBT_EXTLEN); - len = div_u64_rem(rtlen, mp->m_sb.sb_rextsize, &mod); + len = xfs_rtb_to_rtxrem(mp, rtlen, &mod); if (mod) { ASSERT(mod == 0); return -EIO; } - start = div_u64_rem(rtbno, mp->m_sb.sb_rextsize, &mod); + start = xfs_rtb_to_rtxrem(mp, rtbno, &mod); if (mod) { ASSERT(mod == 0); return -EIO; diff --git a/fs/xfs/libxfs/xfs_rtbitmap.h b/fs/xfs/libxfs/xfs_rtbitmap.h index e2a36fc157c4..9df583083407 100644 --- a/fs/xfs/libxfs/xfs_rtbitmap.h +++ b/fs/xfs/libxfs/xfs_rtbitmap.h @@ -39,6 +39,37 @@ xfs_extlen_to_rtxlen( return len / mp->m_sb.sb_rextsize; } +/* Convert an rt block number into an rt extent number. */ +static inline xfs_rtxnum_t +xfs_rtb_to_rtx( + struct xfs_mount *mp, + xfs_rtblock_t rtbno) +{ + return div_u64(rtbno, mp->m_sb.sb_rextsize); +} + +/* Return the offset of an rt block number within an rt extent. */ +static inline xfs_extlen_t +xfs_rtb_to_rtxoff( + struct xfs_mount *mp, + xfs_rtblock_t rtbno) +{ + return do_div(rtbno, mp->m_sb.sb_rextsize); +} + +/* + * Crack an rt block number into an rt extent number and an offset within that + * rt extent. Returns the rt extent number directly and the offset in @off. + */ +static inline xfs_rtxnum_t +xfs_rtb_to_rtxrem( + struct xfs_mount *mp, + xfs_rtblock_t rtbno, + xfs_extlen_t *off) +{ + return div_u64_rem(rtbno, mp->m_sb.sb_rextsize, off); +} + /* * Functions for walking free space rtextents in the realtime bitmap. */ -- cgit v1.2.3 From 055641248f649b52620a5fe8774bea253690e057 Mon Sep 17 00:00:00 2001 From: "Darrick J. Wong" Date: Mon, 16 Oct 2023 09:37:47 -0700 Subject: xfs: convert do_div calls to xfs_rtb_to_rtx helper calls Convert these calls to use the helpers, and clean up all these places where the same variable can have different units depending on where it is in the function. Signed-off-by: Darrick J. Wong Reviewed-by: Christoph Hellwig --- fs/xfs/libxfs/xfs_bmap.c | 8 ++------ fs/xfs/libxfs/xfs_rtbitmap.h | 14 ++++++++++++++ fs/xfs/scrub/rtbitmap.c | 14 +++++--------- fs/xfs/xfs_bmap_util.c | 10 ++++------ fs/xfs/xfs_fsmap.c | 7 ++----- fs/xfs/xfs_rtalloc.c | 3 +-- 6 files changed, 28 insertions(+), 28 deletions(-) (limited to 'fs/xfs') diff --git a/fs/xfs/libxfs/xfs_bmap.c b/fs/xfs/libxfs/xfs_bmap.c index fc96aa59a691..be62acffad6c 100644 --- a/fs/xfs/libxfs/xfs_bmap.c +++ b/fs/xfs/libxfs/xfs_bmap.c @@ -4826,12 +4826,8 @@ xfs_bmap_del_extent_delay( ASSERT(got->br_startoff <= del->br_startoff); ASSERT(got_endoff >= del_endoff); - if (isrt) { - uint64_t rtexts = del->br_blockcount; - - do_div(rtexts, mp->m_sb.sb_rextsize); - xfs_mod_frextents(mp, rtexts); - } + if (isrt) + xfs_mod_frextents(mp, xfs_rtb_to_rtx(mp, del->br_blockcount)); /* * Update the inode delalloc counter now and wait to update the diff --git a/fs/xfs/libxfs/xfs_rtbitmap.h b/fs/xfs/libxfs/xfs_rtbitmap.h index 9df583083407..ff901bf3d1ee 100644 --- a/fs/xfs/libxfs/xfs_rtbitmap.h +++ b/fs/xfs/libxfs/xfs_rtbitmap.h @@ -70,6 +70,20 @@ xfs_rtb_to_rtxrem( return div_u64_rem(rtbno, mp->m_sb.sb_rextsize, off); } +/* + * Convert an rt block number into an rt extent number, rounding up to the next + * rt extent if the rt block is not aligned to an rt extent boundary. + */ +static inline xfs_rtxnum_t +xfs_rtb_to_rtxup( + struct xfs_mount *mp, + xfs_rtblock_t rtbno) +{ + if (do_div(rtbno, mp->m_sb.sb_rextsize)) + rtbno++; + return rtbno; +} + /* * Functions for walking free space rtextents in the realtime bitmap. */ diff --git a/fs/xfs/scrub/rtbitmap.c b/fs/xfs/scrub/rtbitmap.c index 584a2b8badac..41a1d89ae8e6 100644 --- a/fs/xfs/scrub/rtbitmap.c +++ b/fs/xfs/scrub/rtbitmap.c @@ -128,26 +128,22 @@ out: void xchk_xref_is_used_rt_space( struct xfs_scrub *sc, - xfs_rtblock_t fsbno, + xfs_rtblock_t rtbno, xfs_extlen_t len) { xfs_rtxnum_t startext; xfs_rtxnum_t endext; - xfs_rtxlen_t extcount; bool is_free; int error; if (xchk_skip_xref(sc->sm)) return; - startext = fsbno; - endext = fsbno + len - 1; - do_div(startext, sc->mp->m_sb.sb_rextsize); - do_div(endext, sc->mp->m_sb.sb_rextsize); - extcount = endext - startext + 1; + startext = xfs_rtb_to_rtx(sc->mp, rtbno); + endext = xfs_rtb_to_rtx(sc->mp, rtbno + len - 1); xfs_ilock(sc->mp->m_rbmip, XFS_ILOCK_SHARED | XFS_ILOCK_RTBITMAP); - error = xfs_rtalloc_extent_is_free(sc->mp, sc->tp, startext, extcount, - &is_free); + error = xfs_rtalloc_extent_is_free(sc->mp, sc->tp, startext, + endext - startext + 1, &is_free); if (!xchk_should_check_xref(sc, &error, NULL)) goto out_unlock; if (is_free) diff --git a/fs/xfs/xfs_bmap_util.c b/fs/xfs/xfs_bmap_util.c index 4f53f784f06d..25a03c1276e3 100644 --- a/fs/xfs/xfs_bmap_util.c +++ b/fs/xfs/xfs_bmap_util.c @@ -156,14 +156,12 @@ retry: * Realtime allocation, done through xfs_rtallocate_extent. */ if (ignore_locality) - ap->blkno = 0; + rtx = 0; else - do_div(ap->blkno, mp->m_sb.sb_rextsize); - rtx = ap->blkno; - ap->length = ralen; + rtx = xfs_rtb_to_rtx(mp, ap->blkno); raminlen = max_t(xfs_rtxlen_t, 1, xfs_extlen_to_rtxlen(mp, minlen)); - error = xfs_rtallocate_extent(ap->tp, ap->blkno, raminlen, ap->length, - &ralen, ap->wasdel, prod, &rtx); + error = xfs_rtallocate_extent(ap->tp, rtx, raminlen, ralen, &ralen, + ap->wasdel, prod, &rtx); if (error) return error; diff --git a/fs/xfs/xfs_fsmap.c b/fs/xfs/xfs_fsmap.c index 1a187bc9da3d..5a72217f5feb 100644 --- a/fs/xfs/xfs_fsmap.c +++ b/fs/xfs/xfs_fsmap.c @@ -539,11 +539,8 @@ xfs_getfsmap_rtdev_rtbitmap( * Set up query parameters to return free rtextents covering the range * we want. */ - alow.ar_startext = start_rtb; - ahigh.ar_startext = end_rtb; - do_div(alow.ar_startext, mp->m_sb.sb_rextsize); - if (do_div(ahigh.ar_startext, mp->m_sb.sb_rextsize)) - ahigh.ar_startext++; + alow.ar_startext = xfs_rtb_to_rtx(mp, start_rtb); + ahigh.ar_startext = xfs_rtb_to_rtxup(mp, end_rtb); error = xfs_rtalloc_query_range(mp, tp, &alow, &ahigh, xfs_getfsmap_rtdev_rtbitmap_helper, info); if (error) diff --git a/fs/xfs/xfs_rtalloc.c b/fs/xfs/xfs_rtalloc.c index 62faec195040..ac7c269ad547 100644 --- a/fs/xfs/xfs_rtalloc.c +++ b/fs/xfs/xfs_rtalloc.c @@ -1058,8 +1058,7 @@ xfs_growfs_rt( nrblocks_step = (bmbno + 1) * NBBY * nsbp->sb_blocksize * nsbp->sb_rextsize; nsbp->sb_rblocks = min(nrblocks, nrblocks_step); - nsbp->sb_rextents = nsbp->sb_rblocks; - do_div(nsbp->sb_rextents, nsbp->sb_rextsize); + nsbp->sb_rextents = xfs_rtb_to_rtx(nmp, nsbp->sb_rblocks); ASSERT(nsbp->sb_rextents != 0); nsbp->sb_rextslog = xfs_highbit32(nsbp->sb_rextents); nrsumlevels = nmp->m_rsumlevels = nsbp->sb_rextslog + 1; -- cgit v1.2.3 From 5f57f7309d9ab9d24d50c5707472b1ed8af4eabc Mon Sep 17 00:00:00 2001 From: "Darrick J. Wong" Date: Mon, 16 Oct 2023 09:38:28 -0700 Subject: xfs: create rt extent rounding helpers for realtime extent blocks Create a pair of functions to round rtblock numbers up or down to the nearest rt extent. Signed-off-by: Darrick J. Wong Reviewed-by: Christoph Hellwig --- fs/xfs/libxfs/xfs_rtbitmap.h | 18 ++++++++++++++++++ fs/xfs/xfs_bmap_util.c | 8 +++----- 2 files changed, 21 insertions(+), 5 deletions(-) (limited to 'fs/xfs') diff --git a/fs/xfs/libxfs/xfs_rtbitmap.h b/fs/xfs/libxfs/xfs_rtbitmap.h index ff901bf3d1ee..ecf5645dd670 100644 --- a/fs/xfs/libxfs/xfs_rtbitmap.h +++ b/fs/xfs/libxfs/xfs_rtbitmap.h @@ -84,6 +84,24 @@ xfs_rtb_to_rtxup( return rtbno; } +/* Round this rtblock up to the nearest rt extent size. */ +static inline xfs_rtblock_t +xfs_rtb_roundup_rtx( + struct xfs_mount *mp, + xfs_rtblock_t rtbno) +{ + return roundup_64(rtbno, mp->m_sb.sb_rextsize); +} + +/* Round this rtblock down to the nearest rt extent size. */ +static inline xfs_rtblock_t +xfs_rtb_rounddown_rtx( + struct xfs_mount *mp, + xfs_rtblock_t rtbno) +{ + return rounddown_64(rtbno, mp->m_sb.sb_rextsize); +} + /* * Functions for walking free space rtextents in the realtime bitmap. */ diff --git a/fs/xfs/xfs_bmap_util.c b/fs/xfs/xfs_bmap_util.c index 25a03c1276e3..c640dfc2d00f 100644 --- a/fs/xfs/xfs_bmap_util.c +++ b/fs/xfs/xfs_bmap_util.c @@ -684,7 +684,7 @@ xfs_can_free_eofblocks( */ end_fsb = XFS_B_TO_FSB(mp, (xfs_ufsize_t)XFS_ISIZE(ip)); if (XFS_IS_REALTIME_INODE(ip) && mp->m_sb.sb_rextsize > 1) - end_fsb = roundup_64(end_fsb, mp->m_sb.sb_rextsize); + end_fsb = xfs_rtb_roundup_rtx(mp, end_fsb); last_fsb = XFS_B_TO_FSB(mp, mp->m_super->s_maxbytes); if (last_fsb <= end_fsb) return false; @@ -983,10 +983,8 @@ xfs_free_file_space( /* We can only free complete realtime extents. */ if (XFS_IS_REALTIME_INODE(ip) && mp->m_sb.sb_rextsize > 1) { - startoffset_fsb = roundup_64(startoffset_fsb, - mp->m_sb.sb_rextsize); - endoffset_fsb = rounddown_64(endoffset_fsb, - mp->m_sb.sb_rextsize); + startoffset_fsb = xfs_rtb_roundup_rtx(mp, startoffset_fsb); + endoffset_fsb = xfs_rtb_rounddown_rtx(mp, endoffset_fsb); } /* -- cgit v1.2.3 From ef5a83b7e597038d1c734ddb4bc00638082c2bf1 Mon Sep 17 00:00:00 2001 From: "Darrick J. Wong" Date: Mon, 16 Oct 2023 09:40:11 -0700 Subject: xfs: use shifting and masking when converting rt extents, if possible Avoid the costs of integer division (32-bit and 64-bit) if the realtime extent size is a power of two. Signed-off-by: Darrick J. Wong Reviewed-by: Christoph Hellwig --- fs/xfs/libxfs/xfs_rtbitmap.h | 29 +++++++++++++++++++++++++++++ fs/xfs/libxfs/xfs_sb.c | 2 ++ fs/xfs/xfs_linux.h | 12 ++++++++++++ fs/xfs/xfs_mount.h | 2 ++ fs/xfs/xfs_rtalloc.c | 1 + fs/xfs/xfs_trans.c | 4 ++++ 6 files changed, 50 insertions(+) (limited to 'fs/xfs') diff --git a/fs/xfs/libxfs/xfs_rtbitmap.h b/fs/xfs/libxfs/xfs_rtbitmap.h index ecf5645dd670..3686a53e0aed 100644 --- a/fs/xfs/libxfs/xfs_rtbitmap.h +++ b/fs/xfs/libxfs/xfs_rtbitmap.h @@ -11,6 +11,9 @@ xfs_rtx_to_rtb( struct xfs_mount *mp, xfs_rtxnum_t rtx) { + if (mp->m_rtxblklog >= 0) + return rtx << mp->m_rtxblklog; + return rtx * mp->m_sb.sb_rextsize; } @@ -19,6 +22,9 @@ xfs_rtxlen_to_extlen( struct xfs_mount *mp, xfs_rtxlen_t rtxlen) { + if (mp->m_rtxblklog >= 0) + return rtxlen << mp->m_rtxblklog; + return rtxlen * mp->m_sb.sb_rextsize; } @@ -28,6 +34,9 @@ xfs_extlen_to_rtxmod( struct xfs_mount *mp, xfs_extlen_t len) { + if (mp->m_rtxblklog >= 0) + return len & mp->m_rtxblkmask; + return len % mp->m_sb.sb_rextsize; } @@ -36,6 +45,9 @@ xfs_extlen_to_rtxlen( struct xfs_mount *mp, xfs_extlen_t len) { + if (mp->m_rtxblklog >= 0) + return len >> mp->m_rtxblklog; + return len / mp->m_sb.sb_rextsize; } @@ -45,6 +57,9 @@ xfs_rtb_to_rtx( struct xfs_mount *mp, xfs_rtblock_t rtbno) { + if (likely(mp->m_rtxblklog >= 0)) + return rtbno >> mp->m_rtxblklog; + return div_u64(rtbno, mp->m_sb.sb_rextsize); } @@ -54,6 +69,9 @@ xfs_rtb_to_rtxoff( struct xfs_mount *mp, xfs_rtblock_t rtbno) { + if (likely(mp->m_rtxblklog >= 0)) + return rtbno & mp->m_rtxblkmask; + return do_div(rtbno, mp->m_sb.sb_rextsize); } @@ -67,6 +85,11 @@ xfs_rtb_to_rtxrem( xfs_rtblock_t rtbno, xfs_extlen_t *off) { + if (likely(mp->m_rtxblklog >= 0)) { + *off = rtbno & mp->m_rtxblkmask; + return rtbno >> mp->m_rtxblklog; + } + return div_u64_rem(rtbno, mp->m_sb.sb_rextsize, off); } @@ -79,6 +102,12 @@ xfs_rtb_to_rtxup( struct xfs_mount *mp, xfs_rtblock_t rtbno) { + if (likely(mp->m_rtxblklog >= 0)) { + if (rtbno & mp->m_rtxblkmask) + return (rtbno >> mp->m_rtxblklog) + 1; + return rtbno >> mp->m_rtxblklog; + } + if (do_div(rtbno, mp->m_sb.sb_rextsize)) rtbno++; return rtbno; diff --git a/fs/xfs/libxfs/xfs_sb.c b/fs/xfs/libxfs/xfs_sb.c index 6264daaab37b..1f74d0cd1618 100644 --- a/fs/xfs/libxfs/xfs_sb.c +++ b/fs/xfs/libxfs/xfs_sb.c @@ -975,6 +975,8 @@ xfs_sb_mount_common( mp->m_blockmask = sbp->sb_blocksize - 1; mp->m_blockwsize = sbp->sb_blocksize >> XFS_WORDLOG; mp->m_blockwmask = mp->m_blockwsize - 1; + mp->m_rtxblklog = log2_if_power2(sbp->sb_rextsize); + mp->m_rtxblkmask = mask64_if_power2(sbp->sb_rextsize); mp->m_alloc_mxr[0] = xfs_allocbt_maxrecs(mp, sbp->sb_blocksize, 1); mp->m_alloc_mxr[1] = xfs_allocbt_maxrecs(mp, sbp->sb_blocksize, 0); diff --git a/fs/xfs/xfs_linux.h b/fs/xfs/xfs_linux.h index e9d317a3dafe..d7873e0360f0 100644 --- a/fs/xfs/xfs_linux.h +++ b/fs/xfs/xfs_linux.h @@ -198,6 +198,18 @@ static inline uint64_t howmany_64(uint64_t x, uint32_t y) return x; } +/* If @b is a power of 2, return log2(b). Else return -1. */ +static inline int8_t log2_if_power2(unsigned long b) +{ + return is_power_of_2(b) ? ilog2(b) : -1; +} + +/* If @b is a power of 2, return a mask of the lower bits, else return zero. */ +static inline unsigned long long mask64_if_power2(unsigned long b) +{ + return is_power_of_2(b) ? b - 1 : 0; +} + int xfs_rw_bdev(struct block_device *bdev, sector_t sector, unsigned int count, char *data, enum req_op op); diff --git a/fs/xfs/xfs_mount.h b/fs/xfs/xfs_mount.h index d19cca099bc3..d8769dc5f6dd 100644 --- a/fs/xfs/xfs_mount.h +++ b/fs/xfs/xfs_mount.h @@ -119,6 +119,7 @@ typedef struct xfs_mount { uint8_t m_blkbb_log; /* blocklog - BBSHIFT */ uint8_t m_agno_log; /* log #ag's */ uint8_t m_sectbb_log; /* sectlog - BBSHIFT */ + int8_t m_rtxblklog; /* log2 of rextsize, if possible */ uint m_blockmask; /* sb_blocksize-1 */ uint m_blockwsize; /* sb_blocksize in words */ uint m_blockwmask; /* blockwsize-1 */ @@ -152,6 +153,7 @@ typedef struct xfs_mount { uint64_t m_features; /* active filesystem features */ uint64_t m_low_space[XFS_LOWSP_MAX]; uint64_t m_low_rtexts[XFS_LOWSP_MAX]; + uint64_t m_rtxblkmask; /* rt extent block mask */ struct xfs_ino_geometry m_ino_geo; /* inode geometry */ struct xfs_trans_resv m_resv; /* precomputed res values */ /* low free space thresholds */ diff --git a/fs/xfs/xfs_rtalloc.c b/fs/xfs/xfs_rtalloc.c index ac7c269ad547..e5a3200cea72 100644 --- a/fs/xfs/xfs_rtalloc.c +++ b/fs/xfs/xfs_rtalloc.c @@ -1054,6 +1054,7 @@ xfs_growfs_rt( * Calculate new sb and mount fields for this round. */ nsbp->sb_rextsize = in->extsize; + nmp->m_rtxblklog = -1; /* don't use shift or masking */ nsbp->sb_rbmblocks = bmbno + 1; nrblocks_step = (bmbno + 1) * NBBY * nsbp->sb_blocksize * nsbp->sb_rextsize; diff --git a/fs/xfs/xfs_trans.c b/fs/xfs/xfs_trans.c index 338dd3774507..305c9d07bf1b 100644 --- a/fs/xfs/xfs_trans.c +++ b/fs/xfs/xfs_trans.c @@ -656,6 +656,10 @@ xfs_trans_unreserve_and_mod_sb( mp->m_sb.sb_agcount += tp->t_agcount_delta; mp->m_sb.sb_imax_pct += tp->t_imaxpct_delta; mp->m_sb.sb_rextsize += tp->t_rextsize_delta; + if (tp->t_rextsize_delta) { + mp->m_rtxblklog = log2_if_power2(mp->m_sb.sb_rextsize); + mp->m_rtxblkmask = mask64_if_power2(mp->m_sb.sb_rextsize); + } mp->m_sb.sb_rbmblocks += tp->t_rbmblocks_delta; mp->m_sb.sb_rblocks += tp->t_rblocks_delta; mp->m_sb.sb_rextents += tp->t_rextents_delta; -- cgit v1.2.3 From 90d98a6ada1da0f8797ff3f5adafd175dd8c0a81 Mon Sep 17 00:00:00 2001 From: "Darrick J. Wong" Date: Mon, 16 Oct 2023 09:44:13 -0700 Subject: xfs: convert the rtbitmap block and bit macros to static inline functions Replace these macros with typechecked helper functions. Eventually we're going to add more logic to the helpers and it'll be easier if we don't have to macro it up. Signed-off-by: Darrick J. Wong Reviewed-by: Christoph Hellwig --- fs/xfs/libxfs/xfs_format.h | 5 ----- fs/xfs/libxfs/xfs_rtbitmap.c | 30 +++++++++++++++--------------- fs/xfs/libxfs/xfs_rtbitmap.h | 27 +++++++++++++++++++++++++++ fs/xfs/scrub/rtsummary.c | 2 +- fs/xfs/xfs_rtalloc.c | 20 ++++++++++---------- 5 files changed, 53 insertions(+), 31 deletions(-) (limited to 'fs/xfs') diff --git a/fs/xfs/libxfs/xfs_format.h b/fs/xfs/libxfs/xfs_format.h index 20acb8573d7a..0e2ee8202402 100644 --- a/fs/xfs/libxfs/xfs_format.h +++ b/fs/xfs/libxfs/xfs_format.h @@ -1155,11 +1155,6 @@ static inline bool xfs_dinode_has_large_extent_counts( ((xfs_suminfo_t *)((bp)->b_addr + \ (((so) * (uint)sizeof(xfs_suminfo_t)) & XFS_BLOCKMASK(mp)))) -#define XFS_BITTOBLOCK(mp,bi) ((bi) >> (mp)->m_blkbit_log) -#define XFS_BLOCKTOBIT(mp,bb) ((bb) << (mp)->m_blkbit_log) -#define XFS_BITTOWORD(mp,bi) \ - ((int)(((bi) >> XFS_NBWORDLOG) & XFS_BLOCKWMASK(mp))) - #define XFS_RTMIN(a,b) ((a) < (b) ? (a) : (b)) #define XFS_RTMAX(a,b) ((a) > (b) ? (a) : (b)) diff --git a/fs/xfs/libxfs/xfs_rtbitmap.c b/fs/xfs/libxfs/xfs_rtbitmap.c index 383c6437e042..9ef336d22861 100644 --- a/fs/xfs/libxfs/xfs_rtbitmap.c +++ b/fs/xfs/libxfs/xfs_rtbitmap.c @@ -111,12 +111,12 @@ xfs_rtfind_back( xfs_rtword_t mask; /* mask of relevant bits for value */ xfs_rtword_t want; /* mask for "good" values */ xfs_rtword_t wdiff; /* difference from wanted value */ - int word; /* word number in the buffer */ + unsigned int word; /* word number in the buffer */ /* * Compute and read in starting bitmap block for starting block. */ - block = XFS_BITTOBLOCK(mp, start); + block = xfs_rtx_to_rbmblock(mp, start); error = xfs_rtbuf_get(mp, tp, block, 0, &bp); if (error) { return error; @@ -125,7 +125,7 @@ xfs_rtfind_back( /* * Get the first word's index & point to it. */ - word = XFS_BITTOWORD(mp, start); + word = xfs_rtx_to_rbmword(mp, start); b = &bufp[word]; bit = (int)(start & (XFS_NBWORD - 1)); len = start - limit + 1; @@ -286,12 +286,12 @@ xfs_rtfind_forw( xfs_rtword_t mask; /* mask of relevant bits for value */ xfs_rtword_t want; /* mask for "good" values */ xfs_rtword_t wdiff; /* difference from wanted value */ - int word; /* word number in the buffer */ + unsigned int word; /* word number in the buffer */ /* * Compute and read in starting bitmap block for starting block. */ - block = XFS_BITTOBLOCK(mp, start); + block = xfs_rtx_to_rbmblock(mp, start); error = xfs_rtbuf_get(mp, tp, block, 0, &bp); if (error) { return error; @@ -300,7 +300,7 @@ xfs_rtfind_forw( /* * Get the first word's index & point to it. */ - word = XFS_BITTOWORD(mp, start); + word = xfs_rtx_to_rbmword(mp, start); b = &bufp[word]; bit = (int)(start & (XFS_NBWORD - 1)); len = limit - start + 1; @@ -547,12 +547,12 @@ xfs_rtmodify_range( int i; /* current bit number rel. to start */ int lastbit; /* last useful bit in word */ xfs_rtword_t mask; /* mask o frelevant bits for value */ - int word; /* word number in the buffer */ + unsigned int word; /* word number in the buffer */ /* * Compute starting bitmap block number. */ - block = XFS_BITTOBLOCK(mp, start); + block = xfs_rtx_to_rbmblock(mp, start); /* * Read the bitmap block, and point to its data. */ @@ -564,7 +564,7 @@ xfs_rtmodify_range( /* * Compute the starting word's address, and starting bit. */ - word = XFS_BITTOWORD(mp, start); + word = xfs_rtx_to_rbmword(mp, start); first = b = &bufp[word]; bit = (int)(start & (XFS_NBWORD - 1)); /* @@ -730,7 +730,7 @@ xfs_rtfree_range( if (preblock < start) { error = xfs_rtmodify_summary(mp, tp, XFS_RTBLOCKLOG(start - preblock), - XFS_BITTOBLOCK(mp, preblock), -1, rbpp, rsb); + xfs_rtx_to_rbmblock(mp, preblock), -1, rbpp, rsb); if (error) { return error; } @@ -742,7 +742,7 @@ xfs_rtfree_range( if (postblock > end) { error = xfs_rtmodify_summary(mp, tp, XFS_RTBLOCKLOG(postblock - end), - XFS_BITTOBLOCK(mp, end + 1), -1, rbpp, rsb); + xfs_rtx_to_rbmblock(mp, end + 1), -1, rbpp, rsb); if (error) { return error; } @@ -753,7 +753,7 @@ xfs_rtfree_range( */ error = xfs_rtmodify_summary(mp, tp, XFS_RTBLOCKLOG(postblock + 1 - preblock), - XFS_BITTOBLOCK(mp, preblock), 1, rbpp, rsb); + xfs_rtx_to_rbmblock(mp, preblock), 1, rbpp, rsb); return error; } @@ -781,12 +781,12 @@ xfs_rtcheck_range( xfs_rtxnum_t lastbit; /* last useful bit in word */ xfs_rtword_t mask; /* mask of relevant bits for value */ xfs_rtword_t wdiff; /* difference from wanted value */ - int word; /* word number in the buffer */ + unsigned int word; /* word number in the buffer */ /* * Compute starting bitmap block number */ - block = XFS_BITTOBLOCK(mp, start); + block = xfs_rtx_to_rbmblock(mp, start); /* * Read the bitmap block. */ @@ -798,7 +798,7 @@ xfs_rtcheck_range( /* * Compute the starting word's address, and starting bit. */ - word = XFS_BITTOWORD(mp, start); + word = xfs_rtx_to_rbmword(mp, start); b = &bufp[word]; bit = (int)(start & (XFS_NBWORD - 1)); /* diff --git a/fs/xfs/libxfs/xfs_rtbitmap.h b/fs/xfs/libxfs/xfs_rtbitmap.h index 3686a53e0aed..5c4325702cb1 100644 --- a/fs/xfs/libxfs/xfs_rtbitmap.h +++ b/fs/xfs/libxfs/xfs_rtbitmap.h @@ -131,6 +131,33 @@ xfs_rtb_rounddown_rtx( return rounddown_64(rtbno, mp->m_sb.sb_rextsize); } +/* Convert an rt extent number to a file block offset in the rt bitmap file. */ +static inline xfs_fileoff_t +xfs_rtx_to_rbmblock( + struct xfs_mount *mp, + xfs_rtxnum_t rtx) +{ + return rtx >> mp->m_blkbit_log; +} + +/* Convert an rt extent number to a word offset within an rt bitmap block. */ +static inline unsigned int +xfs_rtx_to_rbmword( + struct xfs_mount *mp, + xfs_rtxnum_t rtx) +{ + return (rtx >> XFS_NBWORDLOG) & XFS_BLOCKWMASK(mp); +} + +/* Convert a file block offset in the rt bitmap file to an rt extent number. */ +static inline xfs_rtxnum_t +xfs_rbmblock_to_rtx( + struct xfs_mount *mp, + xfs_fileoff_t rbmoff) +{ + return rbmoff << mp->m_blkbit_log; +} + /* * Functions for walking free space rtextents in the realtime bitmap. */ diff --git a/fs/xfs/scrub/rtsummary.c b/fs/xfs/scrub/rtsummary.c index d363286e8b72..169b7b0dcaa5 100644 --- a/fs/xfs/scrub/rtsummary.c +++ b/fs/xfs/scrub/rtsummary.c @@ -130,7 +130,7 @@ xchk_rtsum_record_free( return error; /* Compute the relevant location in the rtsum file. */ - rbmoff = XFS_BITTOBLOCK(mp, rec->ar_startext); + rbmoff = xfs_rtx_to_rbmblock(mp, rec->ar_startext); lenlog = XFS_RTBLOCKLOG(rec->ar_extcount); offs = XFS_SUMOFFS(mp, lenlog, rbmoff); diff --git a/fs/xfs/xfs_rtalloc.c b/fs/xfs/xfs_rtalloc.c index e5a3200cea72..fdfb22baa6da 100644 --- a/fs/xfs/xfs_rtalloc.c +++ b/fs/xfs/xfs_rtalloc.c @@ -177,7 +177,7 @@ xfs_rtallocate_range( */ error = xfs_rtmodify_summary(mp, tp, XFS_RTBLOCKLOG(postblock + 1 - preblock), - XFS_BITTOBLOCK(mp, preblock), -1, rbpp, rsb); + xfs_rtx_to_rbmblock(mp, preblock), -1, rbpp, rsb); if (error) { return error; } @@ -188,7 +188,7 @@ xfs_rtallocate_range( if (preblock < start) { error = xfs_rtmodify_summary(mp, tp, XFS_RTBLOCKLOG(start - preblock), - XFS_BITTOBLOCK(mp, preblock), 1, rbpp, rsb); + xfs_rtx_to_rbmblock(mp, preblock), 1, rbpp, rsb); if (error) { return error; } @@ -200,7 +200,7 @@ xfs_rtallocate_range( if (postblock > end) { error = xfs_rtmodify_summary(mp, tp, XFS_RTBLOCKLOG(postblock - end), - XFS_BITTOBLOCK(mp, end + 1), 1, rbpp, rsb); + xfs_rtx_to_rbmblock(mp, end + 1), 1, rbpp, rsb); if (error) { return error; } @@ -261,8 +261,8 @@ xfs_rtallocate_extent_block( * Loop over all the extents starting in this bitmap block, * looking for one that's long enough. */ - for (i = XFS_BLOCKTOBIT(mp, bbno), besti = -1, bestlen = 0, - end = XFS_BLOCKTOBIT(mp, bbno + 1) - 1; + for (i = xfs_rbmblock_to_rtx(mp, bbno), besti = -1, bestlen = 0, + end = xfs_rbmblock_to_rtx(mp, bbno + 1) - 1; i <= end; i++) { /* Make sure we don't scan off the end of the rt volume. */ @@ -489,7 +489,7 @@ xfs_rtallocate_extent_near( *rtx = r; return 0; } - bbno = XFS_BITTOBLOCK(mp, start); + bbno = xfs_rtx_to_rbmblock(mp, start); i = 0; ASSERT(minlen != 0); log2len = xfs_highbit32(minlen); @@ -708,8 +708,8 @@ xfs_rtallocate_extent_size( * allocator is beyond the next bitmap block, * skip to that bitmap block. */ - if (XFS_BITTOBLOCK(mp, n) > i + 1) - i = XFS_BITTOBLOCK(mp, n) - 1; + if (xfs_rtx_to_rbmblock(mp, n) > i + 1) + i = xfs_rtx_to_rbmblock(mp, n) - 1; } } /* @@ -771,8 +771,8 @@ xfs_rtallocate_extent_size( * allocator is beyond the next bitmap block, * skip to that bitmap block. */ - if (XFS_BITTOBLOCK(mp, n) > i + 1) - i = XFS_BITTOBLOCK(mp, n) - 1; + if (xfs_rtx_to_rbmblock(mp, n) > i + 1) + i = xfs_rtx_to_rbmblock(mp, n) - 1; } } /* -- cgit v1.2.3 From add3cddaea509071d01bf1d34df0d05db1a93a07 Mon Sep 17 00:00:00 2001 From: "Darrick J. Wong" Date: Mon, 16 Oct 2023 09:46:08 -0700 Subject: xfs: remove XFS_BLOCKWSIZE and XFS_BLOCKWMASK macros Remove these trivial macros since they're not even part of the ondisk format. Signed-off-by: Darrick J. Wong Reviewed-by: Christoph Hellwig --- fs/xfs/libxfs/xfs_format.h | 2 -- fs/xfs/libxfs/xfs_rtbitmap.c | 16 ++++++++-------- fs/xfs/libxfs/xfs_rtbitmap.h | 2 +- 3 files changed, 9 insertions(+), 11 deletions(-) (limited to 'fs/xfs') diff --git a/fs/xfs/libxfs/xfs_format.h b/fs/xfs/libxfs/xfs_format.h index 0e2ee8202402..ac6dd102342d 100644 --- a/fs/xfs/libxfs/xfs_format.h +++ b/fs/xfs/libxfs/xfs_format.h @@ -1142,8 +1142,6 @@ static inline bool xfs_dinode_has_large_extent_counts( #define XFS_BLOCKSIZE(mp) ((mp)->m_sb.sb_blocksize) #define XFS_BLOCKMASK(mp) ((mp)->m_blockmask) -#define XFS_BLOCKWSIZE(mp) ((mp)->m_blockwsize) -#define XFS_BLOCKWMASK(mp) ((mp)->m_blockwmask) /* * RT Summary and bit manipulation macros. diff --git a/fs/xfs/libxfs/xfs_rtbitmap.c b/fs/xfs/libxfs/xfs_rtbitmap.c index 9ef336d22861..63caad17dd88 100644 --- a/fs/xfs/libxfs/xfs_rtbitmap.c +++ b/fs/xfs/libxfs/xfs_rtbitmap.c @@ -174,7 +174,7 @@ xfs_rtfind_back( return error; } bufp = bp->b_addr; - word = XFS_BLOCKWMASK(mp); + word = mp->m_blockwsize - 1; b = &bufp[word]; } else { /* @@ -220,7 +220,7 @@ xfs_rtfind_back( return error; } bufp = bp->b_addr; - word = XFS_BLOCKWMASK(mp); + word = mp->m_blockwsize - 1; b = &bufp[word]; } else { /* @@ -338,7 +338,7 @@ xfs_rtfind_forw( * Go on to next block if that's where the next word is * and we need the next word. */ - if (++word == XFS_BLOCKWSIZE(mp) && i < len) { + if (++word == mp->m_blockwsize && i < len) { /* * If done with this block, get the previous one. */ @@ -383,7 +383,7 @@ xfs_rtfind_forw( * Go on to next block if that's where the next word is * and we need the next word. */ - if (++word == XFS_BLOCKWSIZE(mp) && i < len) { + if (++word == mp->m_blockwsize && i < len) { /* * If done with this block, get the next one. */ @@ -593,7 +593,7 @@ xfs_rtmodify_range( * Go on to the next block if that's where the next word is * and we need the next word. */ - if (++word == XFS_BLOCKWSIZE(mp) && i < len) { + if (++word == mp->m_blockwsize && i < len) { /* * Log the changed part of this block. * Get the next one. @@ -633,7 +633,7 @@ xfs_rtmodify_range( * Go on to the next block if that's where the next word is * and we need the next word. */ - if (++word == XFS_BLOCKWSIZE(mp) && i < len) { + if (++word == mp->m_blockwsize && i < len) { /* * Log the changed part of this block. * Get the next one. @@ -836,7 +836,7 @@ xfs_rtcheck_range( * Go on to next block if that's where the next word is * and we need the next word. */ - if (++word == XFS_BLOCKWSIZE(mp) && i < len) { + if (++word == mp->m_blockwsize && i < len) { /* * If done with this block, get the next one. */ @@ -882,7 +882,7 @@ xfs_rtcheck_range( * Go on to next block if that's where the next word is * and we need the next word. */ - if (++word == XFS_BLOCKWSIZE(mp) && i < len) { + if (++word == mp->m_blockwsize && i < len) { /* * If done with this block, get the next one. */ diff --git a/fs/xfs/libxfs/xfs_rtbitmap.h b/fs/xfs/libxfs/xfs_rtbitmap.h index 5c4325702cb1..a382b38c6c30 100644 --- a/fs/xfs/libxfs/xfs_rtbitmap.h +++ b/fs/xfs/libxfs/xfs_rtbitmap.h @@ -146,7 +146,7 @@ xfs_rtx_to_rbmword( struct xfs_mount *mp, xfs_rtxnum_t rtx) { - return (rtx >> XFS_NBWORDLOG) & XFS_BLOCKWMASK(mp); + return (rtx >> XFS_NBWORDLOG) & (mp->m_blockwsize - 1); } /* Convert a file block offset in the rt bitmap file to an rt extent number. */ -- cgit v1.2.3 From a9948626849c2c65dfd201b5e9d855e62937de61 Mon Sep 17 00:00:00 2001 From: "Darrick J. Wong" Date: Mon, 16 Oct 2023 09:46:53 -0700 Subject: xfs: convert open-coded xfs_rtword_t pointer accesses to helper There are a bunch of places where we use open-coded logic to find a pointer to an xfs_rtword_t within a rt bitmap buffer. Convert all that to helper functions for better type safety. Signed-off-by: Darrick J. Wong Reviewed-by: Christoph Hellwig --- fs/xfs/libxfs/xfs_rtbitmap.c | 59 +++++++++++++++++++++++--------------------- fs/xfs/libxfs/xfs_rtbitmap.h | 11 +++++++++ 2 files changed, 42 insertions(+), 28 deletions(-) (limited to 'fs/xfs') diff --git a/fs/xfs/libxfs/xfs_rtbitmap.c b/fs/xfs/libxfs/xfs_rtbitmap.c index 63caad17dd88..cc3e70b7fbe5 100644 --- a/fs/xfs/libxfs/xfs_rtbitmap.c +++ b/fs/xfs/libxfs/xfs_rtbitmap.c @@ -103,7 +103,6 @@ xfs_rtfind_back( int bit; /* bit number in the word */ xfs_fileoff_t block; /* bitmap block number */ struct xfs_buf *bp; /* buf for the block */ - xfs_rtword_t *bufp; /* starting word in buffer */ int error; /* error value */ xfs_rtxnum_t firstbit; /* first useful bit in the word */ xfs_rtxnum_t i; /* current bit number rel. to start */ @@ -121,12 +120,12 @@ xfs_rtfind_back( if (error) { return error; } - bufp = bp->b_addr; + /* * Get the first word's index & point to it. */ word = xfs_rtx_to_rbmword(mp, start); - b = &bufp[word]; + b = xfs_rbmblock_wordptr(bp, word); bit = (int)(start & (XFS_NBWORD - 1)); len = start - limit + 1; /* @@ -173,9 +172,9 @@ xfs_rtfind_back( if (error) { return error; } - bufp = bp->b_addr; + word = mp->m_blockwsize - 1; - b = &bufp[word]; + b = xfs_rbmblock_wordptr(bp, word); } else { /* * Go on to the previous word in the buffer. @@ -219,9 +218,9 @@ xfs_rtfind_back( if (error) { return error; } - bufp = bp->b_addr; + word = mp->m_blockwsize - 1; - b = &bufp[word]; + b = xfs_rbmblock_wordptr(bp, word); } else { /* * Go on to the previous word in the buffer. @@ -278,7 +277,6 @@ xfs_rtfind_forw( int bit; /* bit number in the word */ xfs_fileoff_t block; /* bitmap block number */ struct xfs_buf *bp; /* buf for the block */ - xfs_rtword_t *bufp; /* starting word in buffer */ int error; /* error value */ xfs_rtxnum_t i; /* current bit number rel. to start */ xfs_rtxnum_t lastbit; /* last useful bit in the word */ @@ -296,12 +294,12 @@ xfs_rtfind_forw( if (error) { return error; } - bufp = bp->b_addr; + /* * Get the first word's index & point to it. */ word = xfs_rtx_to_rbmword(mp, start); - b = &bufp[word]; + b = xfs_rbmblock_wordptr(bp, word); bit = (int)(start & (XFS_NBWORD - 1)); len = limit - start + 1; /* @@ -347,8 +345,9 @@ xfs_rtfind_forw( if (error) { return error; } - b = bufp = bp->b_addr; + word = 0; + b = xfs_rbmblock_wordptr(bp, word); } else { /* * Go on to the previous word in the buffer. @@ -392,8 +391,9 @@ xfs_rtfind_forw( if (error) { return error; } - b = bufp = bp->b_addr; + word = 0; + b = xfs_rbmblock_wordptr(bp, word); } else { /* * Go on to the next word in the buffer. @@ -541,7 +541,6 @@ xfs_rtmodify_range( int bit; /* bit number in the word */ xfs_fileoff_t block; /* bitmap block number */ struct xfs_buf *bp; /* buf for the block */ - xfs_rtword_t *bufp; /* starting word in buffer */ int error; /* error value */ xfs_rtword_t *first; /* first used word in the buffer */ int i; /* current bit number rel. to start */ @@ -560,12 +559,12 @@ xfs_rtmodify_range( if (error) { return error; } - bufp = bp->b_addr; + /* * Compute the starting word's address, and starting bit. */ word = xfs_rtx_to_rbmword(mp, start); - first = b = &bufp[word]; + first = b = xfs_rbmblock_wordptr(bp, word); bit = (int)(start & (XFS_NBWORD - 1)); /* * 0 (allocated) => all zeroes; 1 (free) => all ones. @@ -599,14 +598,15 @@ xfs_rtmodify_range( * Get the next one. */ xfs_trans_log_buf(tp, bp, - (uint)((char *)first - (char *)bufp), - (uint)((char *)b - (char *)bufp)); + (uint)((char *)first - (char *)bp->b_addr), + (uint)((char *)b - (char *)bp->b_addr)); error = xfs_rtbuf_get(mp, tp, ++block, 0, &bp); if (error) { return error; } - first = b = bufp = bp->b_addr; + word = 0; + first = b = xfs_rbmblock_wordptr(bp, word); } else { /* * Go on to the next word in the buffer @@ -639,14 +639,15 @@ xfs_rtmodify_range( * Get the next one. */ xfs_trans_log_buf(tp, bp, - (uint)((char *)first - (char *)bufp), - (uint)((char *)b - (char *)bufp)); + (uint)((char *)first - (char *)bp->b_addr), + (uint)((char *)b - (char *)bp->b_addr)); error = xfs_rtbuf_get(mp, tp, ++block, 0, &bp); if (error) { return error; } - first = b = bufp = bp->b_addr; + word = 0; + first = b = xfs_rbmblock_wordptr(bp, word); } else { /* * Go on to the next word in the buffer @@ -676,8 +677,9 @@ xfs_rtmodify_range( * Log any remaining changed bytes. */ if (b > first) - xfs_trans_log_buf(tp, bp, (uint)((char *)first - (char *)bufp), - (uint)((char *)b - (char *)bufp - 1)); + xfs_trans_log_buf(tp, bp, + (uint)((char *)first - (char *)bp->b_addr), + (uint)((char *)b - (char *)bp->b_addr - 1)); return 0; } @@ -775,7 +777,6 @@ xfs_rtcheck_range( int bit; /* bit number in the word */ xfs_fileoff_t block; /* bitmap block number */ struct xfs_buf *bp; /* buf for the block */ - xfs_rtword_t *bufp; /* starting word in buffer */ int error; /* error value */ xfs_rtxnum_t i; /* current bit number rel. to start */ xfs_rtxnum_t lastbit; /* last useful bit in word */ @@ -794,12 +795,12 @@ xfs_rtcheck_range( if (error) { return error; } - bufp = bp->b_addr; + /* * Compute the starting word's address, and starting bit. */ word = xfs_rtx_to_rbmword(mp, start); - b = &bufp[word]; + b = xfs_rbmblock_wordptr(bp, word); bit = (int)(start & (XFS_NBWORD - 1)); /* * 0 (allocated) => all zero's; 1 (free) => all one's. @@ -845,8 +846,9 @@ xfs_rtcheck_range( if (error) { return error; } - b = bufp = bp->b_addr; + word = 0; + b = xfs_rbmblock_wordptr(bp, word); } else { /* * Go on to the next word in the buffer. @@ -891,8 +893,9 @@ xfs_rtcheck_range( if (error) { return error; } - b = bufp = bp->b_addr; + word = 0; + b = xfs_rbmblock_wordptr(bp, word); } else { /* * Go on to the next word in the buffer. diff --git a/fs/xfs/libxfs/xfs_rtbitmap.h b/fs/xfs/libxfs/xfs_rtbitmap.h index a382b38c6c30..3252ed217a6a 100644 --- a/fs/xfs/libxfs/xfs_rtbitmap.h +++ b/fs/xfs/libxfs/xfs_rtbitmap.h @@ -158,6 +158,17 @@ xfs_rbmblock_to_rtx( return rbmoff << mp->m_blkbit_log; } +/* Return a pointer to a bitmap word within a rt bitmap block. */ +static inline xfs_rtword_t * +xfs_rbmblock_wordptr( + struct xfs_buf *bp, + unsigned int index) +{ + xfs_rtword_t *words = bp->b_addr; + + return words + index; +} + /* * Functions for walking free space rtextents in the realtime bitmap. */ -- cgit v1.2.3 From 097b4b7b64ef67a4703b89fd4064480b61557fd5 Mon Sep 17 00:00:00 2001 From: "Darrick J. Wong" Date: Mon, 16 Oct 2023 09:47:34 -0700 Subject: xfs: convert rt summary macros to helpers Convert the realtime summary file macros to helper functions so that we can improve type checking. Signed-off-by: Darrick J. Wong Reviewed-by: Christoph Hellwig --- fs/xfs/libxfs/xfs_format.h | 9 +------- fs/xfs/libxfs/xfs_rtbitmap.c | 10 +++++---- fs/xfs/libxfs/xfs_rtbitmap.h | 50 ++++++++++++++++++++++++++++++++++++++++++++ fs/xfs/libxfs/xfs_types.h | 2 ++ fs/xfs/scrub/rtsummary.c | 14 +++++++------ 5 files changed, 67 insertions(+), 18 deletions(-) (limited to 'fs/xfs') diff --git a/fs/xfs/libxfs/xfs_format.h b/fs/xfs/libxfs/xfs_format.h index ac6dd102342d..d48e3a395bd9 100644 --- a/fs/xfs/libxfs/xfs_format.h +++ b/fs/xfs/libxfs/xfs_format.h @@ -1144,15 +1144,8 @@ static inline bool xfs_dinode_has_large_extent_counts( #define XFS_BLOCKMASK(mp) ((mp)->m_blockmask) /* - * RT Summary and bit manipulation macros. + * RT bit manipulation macros. */ -#define XFS_SUMOFFS(mp,ls,bb) ((int)((ls) * (mp)->m_sb.sb_rbmblocks + (bb))) -#define XFS_SUMOFFSTOBLOCK(mp,s) \ - (((s) * (uint)sizeof(xfs_suminfo_t)) >> (mp)->m_sb.sb_blocklog) -#define XFS_SUMPTR(mp,bp,so) \ - ((xfs_suminfo_t *)((bp)->b_addr + \ - (((so) * (uint)sizeof(xfs_suminfo_t)) & XFS_BLOCKMASK(mp)))) - #define XFS_RTMIN(a,b) ((a) < (b) ? (a) : (b)) #define XFS_RTMAX(a,b) ((a) > (b) ? (a) : (b)) diff --git a/fs/xfs/libxfs/xfs_rtbitmap.c b/fs/xfs/libxfs/xfs_rtbitmap.c index cc3e70b7fbe5..efa084de58c2 100644 --- a/fs/xfs/libxfs/xfs_rtbitmap.c +++ b/fs/xfs/libxfs/xfs_rtbitmap.c @@ -455,17 +455,18 @@ xfs_rtmodify_summary_int( struct xfs_buf *bp; /* buffer for the summary block */ int error; /* error value */ xfs_fileoff_t sb; /* summary fsblock */ - int so; /* index into the summary file */ + xfs_rtsumoff_t so; /* index into the summary file */ xfs_suminfo_t *sp; /* pointer to returned data */ + unsigned int infoword; /* * Compute entry number in the summary file. */ - so = XFS_SUMOFFS(mp, log, bbno); + so = xfs_rtsumoffs(mp, log, bbno); /* * Compute the block number in the summary file. */ - sb = XFS_SUMOFFSTOBLOCK(mp, so); + sb = xfs_rtsumoffs_to_block(mp, so); /* * If we have an old buffer, and the block number matches, use that. */ @@ -493,7 +494,8 @@ xfs_rtmodify_summary_int( /* * Point to the summary information, modify/log it, and/or copy it out. */ - sp = XFS_SUMPTR(mp, bp, so); + infoword = xfs_rtsumoffs_to_infoword(mp, so); + sp = xfs_rsumblock_infoptr(bp, infoword); if (delta) { uint first = (uint)((char *)sp - (char *)bp->b_addr); diff --git a/fs/xfs/libxfs/xfs_rtbitmap.h b/fs/xfs/libxfs/xfs_rtbitmap.h index 3252ed217a6a..79ade6d2361b 100644 --- a/fs/xfs/libxfs/xfs_rtbitmap.h +++ b/fs/xfs/libxfs/xfs_rtbitmap.h @@ -169,6 +169,56 @@ xfs_rbmblock_wordptr( return words + index; } +/* + * Convert a rt extent length and rt bitmap block number to a xfs_suminfo_t + * offset within the rt summary file. + */ +static inline xfs_rtsumoff_t +xfs_rtsumoffs( + struct xfs_mount *mp, + int log2_len, + xfs_fileoff_t rbmoff) +{ + return log2_len * mp->m_sb.sb_rbmblocks + rbmoff; +} + +/* + * Convert an xfs_suminfo_t offset to a file block offset within the rt summary + * file. + */ +static inline xfs_fileoff_t +xfs_rtsumoffs_to_block( + struct xfs_mount *mp, + xfs_rtsumoff_t rsumoff) +{ + return XFS_B_TO_FSBT(mp, rsumoff * sizeof(xfs_suminfo_t)); +} + +/* + * Convert an xfs_suminfo_t offset to an info word offset within an rt summary + * block. + */ +static inline unsigned int +xfs_rtsumoffs_to_infoword( + struct xfs_mount *mp, + xfs_rtsumoff_t rsumoff) +{ + unsigned int mask = mp->m_blockmask >> XFS_SUMINFOLOG; + + return rsumoff & mask; +} + +/* Return a pointer to a summary info word within a rt summary block. */ +static inline xfs_suminfo_t * +xfs_rsumblock_infoptr( + struct xfs_buf *bp, + unsigned int index) +{ + xfs_suminfo_t *info = bp->b_addr; + + return info + index; +} + /* * Functions for walking free space rtextents in the realtime bitmap. */ diff --git a/fs/xfs/libxfs/xfs_types.h b/fs/xfs/libxfs/xfs_types.h index c78237852e27..533200c4ccc2 100644 --- a/fs/xfs/libxfs/xfs_types.h +++ b/fs/xfs/libxfs/xfs_types.h @@ -19,6 +19,7 @@ typedef int64_t xfs_fsize_t; /* bytes in a file */ typedef uint64_t xfs_ufsize_t; /* unsigned bytes in a file */ typedef int32_t xfs_suminfo_t; /* type of bitmap summary info */ +typedef uint32_t xfs_rtsumoff_t; /* offset of an rtsummary info word */ typedef uint32_t xfs_rtword_t; /* word type for bitmap manipulations */ typedef int64_t xfs_lsn_t; /* log sequence number */ @@ -149,6 +150,7 @@ typedef uint32_t xfs_dqid_t; */ #define XFS_NBBYLOG 3 /* log2(NBBY) */ #define XFS_WORDLOG 2 /* log2(sizeof(xfs_rtword_t)) */ +#define XFS_SUMINFOLOG 2 /* log2(sizeof(xfs_suminfo_t)) */ #define XFS_NBWORDLOG (XFS_NBBYLOG + XFS_WORDLOG) #define XFS_NBWORD (1 << XFS_NBWORDLOG) #define XFS_WORDMASK ((1 << XFS_WORDLOG) - 1) diff --git a/fs/xfs/scrub/rtsummary.c b/fs/xfs/scrub/rtsummary.c index 169b7b0dcaa5..3c8a6cc33800 100644 --- a/fs/xfs/scrub/rtsummary.c +++ b/fs/xfs/scrub/rtsummary.c @@ -81,7 +81,7 @@ typedef unsigned int xchk_rtsumoff_t; static inline int xfsum_load( struct xfs_scrub *sc, - xchk_rtsumoff_t sumoff, + xfs_rtsumoff_t sumoff, xfs_suminfo_t *info) { return xfile_obj_load(sc->xfile, info, sizeof(xfs_suminfo_t), @@ -91,7 +91,7 @@ xfsum_load( static inline int xfsum_store( struct xfs_scrub *sc, - xchk_rtsumoff_t sumoff, + xfs_rtsumoff_t sumoff, const xfs_suminfo_t info) { return xfile_obj_store(sc->xfile, &info, sizeof(xfs_suminfo_t), @@ -101,7 +101,7 @@ xfsum_store( static inline int xfsum_copyout( struct xfs_scrub *sc, - xchk_rtsumoff_t sumoff, + xfs_rtsumoff_t sumoff, xfs_suminfo_t *info, unsigned int nr_words) { @@ -121,7 +121,7 @@ xchk_rtsum_record_free( xfs_fileoff_t rbmoff; xfs_rtblock_t rtbno; xfs_filblks_t rtlen; - xchk_rtsumoff_t offs; + xfs_rtsumoff_t offs; unsigned int lenlog; xfs_suminfo_t v = 0; int error = 0; @@ -132,7 +132,7 @@ xchk_rtsum_record_free( /* Compute the relevant location in the rtsum file. */ rbmoff = xfs_rtx_to_rbmblock(mp, rec->ar_startext); lenlog = XFS_RTBLOCKLOG(rec->ar_extcount); - offs = XFS_SUMOFFS(mp, lenlog, rbmoff); + offs = xfs_rtsumoffs(mp, lenlog, rbmoff); rtbno = xfs_rtx_to_rtb(mp, rec->ar_startext); rtlen = xfs_rtx_to_rtb(mp, rec->ar_extcount); @@ -185,6 +185,7 @@ xchk_rtsum_compare( int nmap; for (off = 0; off < XFS_B_TO_FSB(mp, mp->m_rsumsize); off++) { + xfs_suminfo_t *ondisk_info; int error = 0; if (xchk_should_terminate(sc, &error)) @@ -216,7 +217,8 @@ xchk_rtsum_compare( return error; } - if (memcmp(bp->b_addr, sc->buf, + ondisk_info = xfs_rsumblock_infoptr(bp, 0); + if (memcmp(ondisk_info, sc->buf, mp->m_blockwsize << XFS_WORDLOG) != 0) xchk_fblock_set_corrupt(sc, XFS_DATA_FORK, off); -- cgit v1.2.3 From d0448fe76ac1a9ccbce574577a4c82246d17eec4 Mon Sep 17 00:00:00 2001 From: "Darrick J. Wong" Date: Mon, 16 Oct 2023 09:48:20 -0700 Subject: xfs: create helpers for rtbitmap block/wordcount computations Create helper functions that compute the number of blocks or words necessary to store the rt bitmap. Signed-off-by: Darrick J. Wong Reviewed-by: Christoph Hellwig --- fs/xfs/libxfs/xfs_rtbitmap.c | 27 +++++++++++++++++++++++++++ fs/xfs/libxfs/xfs_rtbitmap.h | 12 ++++++++++++ fs/xfs/libxfs/xfs_trans_resv.c | 9 +++++---- fs/xfs/scrub/rtsummary.c | 7 +++---- fs/xfs/xfs_rtalloc.c | 2 +- 5 files changed, 48 insertions(+), 9 deletions(-) (limited to 'fs/xfs') diff --git a/fs/xfs/libxfs/xfs_rtbitmap.c b/fs/xfs/libxfs/xfs_rtbitmap.c index efa084de58c2..aefa2b0747a5 100644 --- a/fs/xfs/libxfs/xfs_rtbitmap.c +++ b/fs/xfs/libxfs/xfs_rtbitmap.c @@ -1135,3 +1135,30 @@ xfs_rtalloc_extent_is_free( *is_free = matches; return 0; } + +/* + * Compute the number of rtbitmap blocks needed to track the given number of rt + * extents. + */ +xfs_filblks_t +xfs_rtbitmap_blockcount( + struct xfs_mount *mp, + xfs_rtbxlen_t rtextents) +{ + return howmany_64(rtextents, NBBY * mp->m_sb.sb_blocksize); +} + +/* + * Compute the number of rtbitmap words needed to populate every block of a + * bitmap that is large enough to track the given number of rt extents. + */ +unsigned long long +xfs_rtbitmap_wordcount( + struct xfs_mount *mp, + xfs_rtbxlen_t rtextents) +{ + xfs_filblks_t blocks; + + blocks = xfs_rtbitmap_blockcount(mp, rtextents); + return XFS_FSB_TO_B(mp, blocks) >> XFS_WORDLOG; +} diff --git a/fs/xfs/libxfs/xfs_rtbitmap.h b/fs/xfs/libxfs/xfs_rtbitmap.h index 79ade6d2361b..01eabb9b5516 100644 --- a/fs/xfs/libxfs/xfs_rtbitmap.h +++ b/fs/xfs/libxfs/xfs_rtbitmap.h @@ -280,6 +280,11 @@ xfs_rtfree_extent( /* Same as above, but in units of rt blocks. */ int xfs_rtfree_blocks(struct xfs_trans *tp, xfs_fsblock_t rtbno, xfs_filblks_t rtlen); + +xfs_filblks_t xfs_rtbitmap_blockcount(struct xfs_mount *mp, xfs_rtbxlen_t + rtextents); +unsigned long long xfs_rtbitmap_wordcount(struct xfs_mount *mp, + xfs_rtbxlen_t rtextents); #else /* CONFIG_XFS_RT */ # define xfs_rtfree_extent(t,b,l) (-ENOSYS) # define xfs_rtfree_blocks(t,rb,rl) (-ENOSYS) @@ -287,6 +292,13 @@ int xfs_rtfree_blocks(struct xfs_trans *tp, xfs_fsblock_t rtbno, # define xfs_rtalloc_query_all(m,t,f,p) (-ENOSYS) # define xfs_rtbuf_get(m,t,b,i,p) (-ENOSYS) # define xfs_rtalloc_extent_is_free(m,t,s,l,i) (-ENOSYS) +static inline xfs_filblks_t +xfs_rtbitmap_blockcount(struct xfs_mount *mp, xfs_rtbxlen_t rtextents) +{ + /* shut up gcc */ + return 0; +} +# define xfs_rtbitmap_wordcount(mp, r) (0) #endif /* CONFIG_XFS_RT */ #endif /* __XFS_RTBITMAP_H__ */ diff --git a/fs/xfs/libxfs/xfs_trans_resv.c b/fs/xfs/libxfs/xfs_trans_resv.c index 4629f10d2f67..6cd45e8c118d 100644 --- a/fs/xfs/libxfs/xfs_trans_resv.c +++ b/fs/xfs/libxfs/xfs_trans_resv.c @@ -218,11 +218,12 @@ xfs_rtalloc_block_count( struct xfs_mount *mp, unsigned int num_ops) { - unsigned int blksz = XFS_FSB_TO_B(mp, 1); - unsigned int rtbmp_bytes; + unsigned int rtbmp_blocks; + xfs_rtxlen_t rtxlen; - rtbmp_bytes = xfs_extlen_to_rtxlen(mp, XFS_MAX_BMBT_EXTLEN) / NBBY; - return (howmany(rtbmp_bytes, blksz) + 1) * num_ops; + rtxlen = xfs_extlen_to_rtxlen(mp, XFS_MAX_BMBT_EXTLEN); + rtbmp_blocks = xfs_rtbitmap_blockcount(mp, rtxlen); + return (rtbmp_blocks + 1) * num_ops; } /* diff --git a/fs/xfs/scrub/rtsummary.c b/fs/xfs/scrub/rtsummary.c index 3c8a6cc33800..0971d002d906 100644 --- a/fs/xfs/scrub/rtsummary.c +++ b/fs/xfs/scrub/rtsummary.c @@ -160,12 +160,11 @@ xchk_rtsum_compute( struct xfs_scrub *sc) { struct xfs_mount *mp = sc->mp; - unsigned long long rtbmp_bytes; + unsigned long long rtbmp_blocks; /* If the bitmap size doesn't match the computed size, bail. */ - rtbmp_bytes = howmany_64(mp->m_sb.sb_rextents, NBBY); - if (roundup_64(rtbmp_bytes, mp->m_sb.sb_blocksize) != - mp->m_rbmip->i_disk_size) + rtbmp_blocks = xfs_rtbitmap_blockcount(mp, mp->m_sb.sb_rextents); + if (XFS_FSB_TO_B(mp, rtbmp_blocks) != mp->m_rbmip->i_disk_size) return -EFSCORRUPTED; return xfs_rtalloc_query_all(sc->mp, sc->tp, xchk_rtsum_record_free, diff --git a/fs/xfs/xfs_rtalloc.c b/fs/xfs/xfs_rtalloc.c index fdfb22baa6da..8e041df12640 100644 --- a/fs/xfs/xfs_rtalloc.c +++ b/fs/xfs/xfs_rtalloc.c @@ -998,7 +998,7 @@ xfs_growfs_rt( */ nrextents = nrblocks; do_div(nrextents, in->extsize); - nrbmblocks = howmany_64(nrextents, NBBY * sbp->sb_blocksize); + nrbmblocks = xfs_rtbitmap_blockcount(mp, nrextents); nrextslog = xfs_highbit32(nrextents); nrsumlevels = nrextslog + 1; nrsumsize = (uint)sizeof(xfs_suminfo_t) * nrsumlevels * nrbmblocks; -- cgit v1.2.3 From 312d61021b8947446aa9ec80b78b9230e8cb3691 Mon Sep 17 00:00:00 2001 From: "Darrick J. Wong" Date: Tue, 17 Oct 2023 16:43:10 -0700 Subject: xfs: create a helper to handle logging parts of rt bitmap/summary blocks Create an explicit helper function to log parts of rt bitmap and summary blocks. While we're at it, fix an off-by-one error in two of the rtbitmap logging calls that led to unnecessarily large log items but was otherwise benign. Note that the upcoming rtgroups patchset will add block headers to the rtbitmap and rtsummary files. The helpers in this and the next few patches take a less than direct route through xfs_rbmblock_wordptr and xfs_rsumblock_infoptr to avoid helper churn in that patchset. Suggested-by: Christoph Hellwig Signed-off-by: Darrick J. Wong Reviewed-by: Christoph Hellwig --- fs/xfs/libxfs/xfs_rtbitmap.c | 55 ++++++++++++++++++++++++++++++++------------ 1 file changed, 40 insertions(+), 15 deletions(-) (limited to 'fs/xfs') diff --git a/fs/xfs/libxfs/xfs_rtbitmap.c b/fs/xfs/libxfs/xfs_rtbitmap.c index aefa2b0747a5..4f096348d4b2 100644 --- a/fs/xfs/libxfs/xfs_rtbitmap.c +++ b/fs/xfs/libxfs/xfs_rtbitmap.c @@ -432,6 +432,21 @@ xfs_rtfind_forw( return 0; } +/* Log rtsummary counter at @infoword. */ +static inline void +xfs_trans_log_rtsummary( + struct xfs_trans *tp, + struct xfs_buf *bp, + unsigned int infoword) +{ + size_t first, last; + + first = (void *)xfs_rsumblock_infoptr(bp, infoword) - bp->b_addr; + last = first + sizeof(xfs_suminfo_t) - 1; + + xfs_trans_log_buf(tp, bp, first, last); +} + /* * Read and/or modify the summary information for a given extent size, * bitmap block combination. @@ -497,8 +512,6 @@ xfs_rtmodify_summary_int( infoword = xfs_rtsumoffs_to_infoword(mp, so); sp = xfs_rsumblock_infoptr(bp, infoword); if (delta) { - uint first = (uint)((char *)sp - (char *)bp->b_addr); - *sp += delta; if (mp->m_rsum_cache) { if (*sp == 0 && log == mp->m_rsum_cache[bbno]) @@ -506,7 +519,7 @@ xfs_rtmodify_summary_int( if (*sp != 0 && log < mp->m_rsum_cache[bbno]) mp->m_rsum_cache[bbno] = log; } - xfs_trans_log_buf(tp, bp, first, first + sizeof(*sp) - 1); + xfs_trans_log_rtsummary(tp, bp, infoword); } if (sum) *sum = *sp; @@ -527,6 +540,22 @@ xfs_rtmodify_summary( delta, rbpp, rsb, NULL); } +/* Log rtbitmap block from the word @from to the byte before @next. */ +static inline void +xfs_trans_log_rtbitmap( + struct xfs_trans *tp, + struct xfs_buf *bp, + unsigned int from, + unsigned int next) +{ + size_t first, last; + + first = (void *)xfs_rbmblock_wordptr(bp, from) - bp->b_addr; + last = ((void *)xfs_rbmblock_wordptr(bp, next) - 1) - bp->b_addr; + + xfs_trans_log_buf(tp, bp, first, last); +} + /* * Set the given range of bitmap bits to the given value. * Do whatever I/O and logging is required. @@ -548,6 +577,7 @@ xfs_rtmodify_range( int i; /* current bit number rel. to start */ int lastbit; /* last useful bit in word */ xfs_rtword_t mask; /* mask o frelevant bits for value */ + unsigned int firstword; /* first word used in the buffer */ unsigned int word; /* word number in the buffer */ /* @@ -565,7 +595,7 @@ xfs_rtmodify_range( /* * Compute the starting word's address, and starting bit. */ - word = xfs_rtx_to_rbmword(mp, start); + firstword = word = xfs_rtx_to_rbmword(mp, start); first = b = xfs_rbmblock_wordptr(bp, word); bit = (int)(start & (XFS_NBWORD - 1)); /* @@ -599,15 +629,13 @@ xfs_rtmodify_range( * Log the changed part of this block. * Get the next one. */ - xfs_trans_log_buf(tp, bp, - (uint)((char *)first - (char *)bp->b_addr), - (uint)((char *)b - (char *)bp->b_addr)); + xfs_trans_log_rtbitmap(tp, bp, firstword, word); error = xfs_rtbuf_get(mp, tp, ++block, 0, &bp); if (error) { return error; } - word = 0; + firstword = word = 0; first = b = xfs_rbmblock_wordptr(bp, word); } else { /* @@ -640,15 +668,13 @@ xfs_rtmodify_range( * Log the changed part of this block. * Get the next one. */ - xfs_trans_log_buf(tp, bp, - (uint)((char *)first - (char *)bp->b_addr), - (uint)((char *)b - (char *)bp->b_addr)); + xfs_trans_log_rtbitmap(tp, bp, firstword, word); error = xfs_rtbuf_get(mp, tp, ++block, 0, &bp); if (error) { return error; } - word = 0; + firstword = word = 0; first = b = xfs_rbmblock_wordptr(bp, word); } else { /* @@ -673,15 +699,14 @@ xfs_rtmodify_range( *b |= mask; else *b &= ~mask; + word++; b++; } /* * Log any remaining changed bytes. */ if (b > first) - xfs_trans_log_buf(tp, bp, - (uint)((char *)first - (char *)bp->b_addr), - (uint)((char *)b - (char *)bp->b_addr - 1)); + xfs_trans_log_rtbitmap(tp, bp, firstword, word); return 0; } -- cgit v1.2.3 From 97e993830a1cdd86ad7d207308b9f55a00660edd Mon Sep 17 00:00:00 2001 From: "Darrick J. Wong" Date: Mon, 16 Oct 2023 09:49:01 -0700 Subject: xfs: use accessor functions for bitmap words Create get and set functions for rtbitmap words so that we can redefine the ondisk format with a specific endianness. Note that this requires the definition of a distinct type for ondisk rtbitmap words so that the compiler can perform proper typechecking as we go back and forth. In the upcoming rtgroups feature, we're going to fix the problem that rtwords are written in host endian order, which means we'll need the distinct rtword/rtword_raw types. Suggested-by: Christoph Hellwig Signed-off-by: Darrick J. Wong Reviewed-by: Christoph Hellwig --- fs/xfs/libxfs/xfs_format.h | 8 ++++ fs/xfs/libxfs/xfs_rtbitmap.c | 109 ++++++++++++++----------------------------- fs/xfs/libxfs/xfs_rtbitmap.h | 27 ++++++++++- fs/xfs/xfs_ondisk.h | 3 ++ 4 files changed, 70 insertions(+), 77 deletions(-) (limited to 'fs/xfs') diff --git a/fs/xfs/libxfs/xfs_format.h b/fs/xfs/libxfs/xfs_format.h index d48e3a395bd9..2af891d5d171 100644 --- a/fs/xfs/libxfs/xfs_format.h +++ b/fs/xfs/libxfs/xfs_format.h @@ -690,6 +690,14 @@ struct xfs_agfl { ASSERT(xfs_daddr_to_agno(mp, d) == \ xfs_daddr_to_agno(mp, (d) + (len) - 1))) +/* + * Realtime bitmap information is accessed by the word, which is currently + * stored in host-endian format. + */ +union xfs_rtword_raw { + __u32 old; +}; + /* * XFS Timestamps * ============== diff --git a/fs/xfs/libxfs/xfs_rtbitmap.c b/fs/xfs/libxfs/xfs_rtbitmap.c index 4f096348d4b2..b81e4ffa1f44 100644 --- a/fs/xfs/libxfs/xfs_rtbitmap.c +++ b/fs/xfs/libxfs/xfs_rtbitmap.c @@ -99,7 +99,6 @@ xfs_rtfind_back( xfs_rtxnum_t limit, /* last rtext to look at */ xfs_rtxnum_t *rtx) /* out: start rtext found */ { - xfs_rtword_t *b; /* current word in buffer */ int bit; /* bit number in the word */ xfs_fileoff_t block; /* bitmap block number */ struct xfs_buf *bp; /* buf for the block */ @@ -110,6 +109,7 @@ xfs_rtfind_back( xfs_rtword_t mask; /* mask of relevant bits for value */ xfs_rtword_t want; /* mask for "good" values */ xfs_rtword_t wdiff; /* difference from wanted value */ + xfs_rtword_t incore; unsigned int word; /* word number in the buffer */ /* @@ -125,14 +125,14 @@ xfs_rtfind_back( * Get the first word's index & point to it. */ word = xfs_rtx_to_rbmword(mp, start); - b = xfs_rbmblock_wordptr(bp, word); bit = (int)(start & (XFS_NBWORD - 1)); len = start - limit + 1; /* * Compute match value, based on the bit at start: if 1 (free) * then all-ones, else all-zeroes. */ - want = (*b & ((xfs_rtword_t)1 << bit)) ? -1 : 0; + incore = xfs_rtbitmap_getword(bp, word); + want = (incore & ((xfs_rtword_t)1 << bit)) ? -1 : 0; /* * If the starting position is not word-aligned, deal with the * partial word. @@ -149,7 +149,7 @@ xfs_rtfind_back( * Calculate the difference between the value there * and what we're looking for. */ - if ((wdiff = (*b ^ want) & mask)) { + if ((wdiff = (incore ^ want) & mask)) { /* * Different. Mark where we are and return. */ @@ -174,12 +174,6 @@ xfs_rtfind_back( } word = mp->m_blockwsize - 1; - b = xfs_rbmblock_wordptr(bp, word); - } else { - /* - * Go on to the previous word in the buffer. - */ - b--; } } else { /* @@ -195,7 +189,8 @@ xfs_rtfind_back( /* * Compute difference between actual and desired value. */ - if ((wdiff = *b ^ want)) { + incore = xfs_rtbitmap_getword(bp, word); + if ((wdiff = incore ^ want)) { /* * Different, mark where we are and return. */ @@ -220,12 +215,6 @@ xfs_rtfind_back( } word = mp->m_blockwsize - 1; - b = xfs_rbmblock_wordptr(bp, word); - } else { - /* - * Go on to the previous word in the buffer. - */ - b--; } } /* @@ -242,7 +231,8 @@ xfs_rtfind_back( /* * Compute difference between actual and desired value. */ - if ((wdiff = (*b ^ want) & mask)) { + incore = xfs_rtbitmap_getword(bp, word); + if ((wdiff = (incore ^ want) & mask)) { /* * Different, mark where we are and return. */ @@ -273,7 +263,6 @@ xfs_rtfind_forw( xfs_rtxnum_t limit, /* last rtext to look at */ xfs_rtxnum_t *rtx) /* out: start rtext found */ { - xfs_rtword_t *b; /* current word in buffer */ int bit; /* bit number in the word */ xfs_fileoff_t block; /* bitmap block number */ struct xfs_buf *bp; /* buf for the block */ @@ -284,6 +273,7 @@ xfs_rtfind_forw( xfs_rtword_t mask; /* mask of relevant bits for value */ xfs_rtword_t want; /* mask for "good" values */ xfs_rtword_t wdiff; /* difference from wanted value */ + xfs_rtword_t incore; unsigned int word; /* word number in the buffer */ /* @@ -299,14 +289,14 @@ xfs_rtfind_forw( * Get the first word's index & point to it. */ word = xfs_rtx_to_rbmword(mp, start); - b = xfs_rbmblock_wordptr(bp, word); bit = (int)(start & (XFS_NBWORD - 1)); len = limit - start + 1; /* * Compute match value, based on the bit at start: if 1 (free) * then all-ones, else all-zeroes. */ - want = (*b & ((xfs_rtword_t)1 << bit)) ? -1 : 0; + incore = xfs_rtbitmap_getword(bp, word); + want = (incore & ((xfs_rtword_t)1 << bit)) ? -1 : 0; /* * If the starting position is not word-aligned, deal with the * partial word. @@ -322,7 +312,7 @@ xfs_rtfind_forw( * Calculate the difference between the value there * and what we're looking for. */ - if ((wdiff = (*b ^ want) & mask)) { + if ((wdiff = (incore ^ want) & mask)) { /* * Different. Mark where we are and return. */ @@ -347,12 +337,6 @@ xfs_rtfind_forw( } word = 0; - b = xfs_rbmblock_wordptr(bp, word); - } else { - /* - * Go on to the previous word in the buffer. - */ - b++; } } else { /* @@ -368,7 +352,8 @@ xfs_rtfind_forw( /* * Compute difference between actual and desired value. */ - if ((wdiff = *b ^ want)) { + incore = xfs_rtbitmap_getword(bp, word); + if ((wdiff = incore ^ want)) { /* * Different, mark where we are and return. */ @@ -393,12 +378,6 @@ xfs_rtfind_forw( } word = 0; - b = xfs_rbmblock_wordptr(bp, word); - } else { - /* - * Go on to the next word in the buffer. - */ - b++; } } /* @@ -413,7 +392,8 @@ xfs_rtfind_forw( /* * Compute difference between actual and desired value. */ - if ((wdiff = (*b ^ want) & mask)) { + incore = xfs_rtbitmap_getword(bp, word); + if ((wdiff = (incore ^ want) & mask)) { /* * Different, mark where we are and return. */ @@ -568,15 +548,14 @@ xfs_rtmodify_range( xfs_rtxlen_t len, /* length of extent to modify */ int val) /* 1 for free, 0 for allocated */ { - xfs_rtword_t *b; /* current word in buffer */ int bit; /* bit number in the word */ xfs_fileoff_t block; /* bitmap block number */ struct xfs_buf *bp; /* buf for the block */ int error; /* error value */ - xfs_rtword_t *first; /* first used word in the buffer */ int i; /* current bit number rel. to start */ int lastbit; /* last useful bit in word */ xfs_rtword_t mask; /* mask o frelevant bits for value */ + xfs_rtword_t incore; unsigned int firstword; /* first word used in the buffer */ unsigned int word; /* word number in the buffer */ @@ -596,7 +575,6 @@ xfs_rtmodify_range( * Compute the starting word's address, and starting bit. */ firstword = word = xfs_rtx_to_rbmword(mp, start); - first = b = xfs_rbmblock_wordptr(bp, word); bit = (int)(start & (XFS_NBWORD - 1)); /* * 0 (allocated) => all zeroes; 1 (free) => all ones. @@ -615,10 +593,12 @@ xfs_rtmodify_range( /* * Set/clear the active bits. */ + incore = xfs_rtbitmap_getword(bp, word); if (val) - *b |= mask; + incore |= mask; else - *b &= ~mask; + incore &= ~mask; + xfs_rtbitmap_setword(bp, word, incore); i = lastbit - bit; /* * Go on to the next block if that's where the next word is @@ -636,12 +616,6 @@ xfs_rtmodify_range( } firstword = word = 0; - first = b = xfs_rbmblock_wordptr(bp, word); - } else { - /* - * Go on to the next word in the buffer - */ - b++; } } else { /* @@ -657,7 +631,7 @@ xfs_rtmodify_range( /* * Set the word value correctly. */ - *b = val; + xfs_rtbitmap_setword(bp, word, val); i += XFS_NBWORD; /* * Go on to the next block if that's where the next word is @@ -675,12 +649,6 @@ xfs_rtmodify_range( } firstword = word = 0; - first = b = xfs_rbmblock_wordptr(bp, word); - } else { - /* - * Go on to the next word in the buffer - */ - b++; } } /* @@ -695,17 +663,18 @@ xfs_rtmodify_range( /* * Set/clear the active bits. */ + incore = xfs_rtbitmap_getword(bp, word); if (val) - *b |= mask; + incore |= mask; else - *b &= ~mask; + incore &= ~mask; + xfs_rtbitmap_setword(bp, word, incore); word++; - b++; } /* * Log any remaining changed bytes. */ - if (b > first) + if (word > firstword) xfs_trans_log_rtbitmap(tp, bp, firstword, word); return 0; } @@ -800,7 +769,6 @@ xfs_rtcheck_range( xfs_rtxnum_t *new, /* out: first rtext not matching */ int *stat) /* out: 1 for matches, 0 for not */ { - xfs_rtword_t *b; /* current word in buffer */ int bit; /* bit number in the word */ xfs_fileoff_t block; /* bitmap block number */ struct xfs_buf *bp; /* buf for the block */ @@ -809,6 +777,7 @@ xfs_rtcheck_range( xfs_rtxnum_t lastbit; /* last useful bit in word */ xfs_rtword_t mask; /* mask of relevant bits for value */ xfs_rtword_t wdiff; /* difference from wanted value */ + xfs_rtword_t incore; unsigned int word; /* word number in the buffer */ /* @@ -827,7 +796,6 @@ xfs_rtcheck_range( * Compute the starting word's address, and starting bit. */ word = xfs_rtx_to_rbmword(mp, start); - b = xfs_rbmblock_wordptr(bp, word); bit = (int)(start & (XFS_NBWORD - 1)); /* * 0 (allocated) => all zero's; 1 (free) => all one's. @@ -849,7 +817,8 @@ xfs_rtcheck_range( /* * Compute difference between actual and desired value. */ - if ((wdiff = (*b ^ val) & mask)) { + incore = xfs_rtbitmap_getword(bp, word); + if ((wdiff = (incore ^ val) & mask)) { /* * Different, compute first wrong bit and return. */ @@ -875,12 +844,6 @@ xfs_rtcheck_range( } word = 0; - b = xfs_rbmblock_wordptr(bp, word); - } else { - /* - * Go on to the next word in the buffer. - */ - b++; } } else { /* @@ -896,7 +859,8 @@ xfs_rtcheck_range( /* * Compute difference between actual and desired value. */ - if ((wdiff = *b ^ val)) { + incore = xfs_rtbitmap_getword(bp, word); + if ((wdiff = incore ^ val)) { /* * Different, compute first wrong bit and return. */ @@ -922,12 +886,6 @@ xfs_rtcheck_range( } word = 0; - b = xfs_rbmblock_wordptr(bp, word); - } else { - /* - * Go on to the next word in the buffer. - */ - b++; } } /* @@ -942,7 +900,8 @@ xfs_rtcheck_range( /* * Compute difference between actual and desired value. */ - if ((wdiff = (*b ^ val) & mask)) { + incore = xfs_rtbitmap_getword(bp, word); + if ((wdiff = (incore ^ val) & mask)) { /* * Different, compute first wrong bit and return. */ diff --git a/fs/xfs/libxfs/xfs_rtbitmap.h b/fs/xfs/libxfs/xfs_rtbitmap.h index 01eabb9b5516..ede24de74620 100644 --- a/fs/xfs/libxfs/xfs_rtbitmap.h +++ b/fs/xfs/libxfs/xfs_rtbitmap.h @@ -159,16 +159,39 @@ xfs_rbmblock_to_rtx( } /* Return a pointer to a bitmap word within a rt bitmap block. */ -static inline xfs_rtword_t * +static inline union xfs_rtword_raw * xfs_rbmblock_wordptr( struct xfs_buf *bp, unsigned int index) { - xfs_rtword_t *words = bp->b_addr; + union xfs_rtword_raw *words = bp->b_addr; return words + index; } +/* Convert an ondisk bitmap word to its incore representation. */ +static inline xfs_rtword_t +xfs_rtbitmap_getword( + struct xfs_buf *bp, + unsigned int index) +{ + union xfs_rtword_raw *word = xfs_rbmblock_wordptr(bp, index); + + return word->old; +} + +/* Set an ondisk bitmap word from an incore representation. */ +static inline void +xfs_rtbitmap_setword( + struct xfs_buf *bp, + unsigned int index, + xfs_rtword_t value) +{ + union xfs_rtword_raw *word = xfs_rbmblock_wordptr(bp, index); + + word->old = value; +} + /* * Convert a rt extent length and rt bitmap block number to a xfs_suminfo_t * offset within the rt summary file. diff --git a/fs/xfs/xfs_ondisk.h b/fs/xfs/xfs_ondisk.h index c4cc99b70dd3..14d455f768d3 100644 --- a/fs/xfs/xfs_ondisk.h +++ b/fs/xfs/xfs_ondisk.h @@ -72,6 +72,9 @@ xfs_check_ondisk_structs(void) XFS_CHECK_STRUCT_SIZE(xfs_attr_leaf_map_t, 4); XFS_CHECK_STRUCT_SIZE(xfs_attr_leaf_name_local_t, 4); + /* realtime structures */ + XFS_CHECK_STRUCT_SIZE(union xfs_rtword_raw, 4); + /* * m68k has problems with xfs_attr_leaf_name_remote_t, but we pad it to * 4 bytes anyway so it's not obviously a problem. Hence for the moment -- cgit v1.2.3 From bd85af280de66a946022775a876edf0c553e3f35 Mon Sep 17 00:00:00 2001 From: "Darrick J. Wong" Date: Mon, 16 Oct 2023 09:50:34 -0700 Subject: xfs: create helpers for rtsummary block/wordcount computations Create helper functions that compute the number of blocks or words necessary to store the rt summary file. Signed-off-by: Darrick J. Wong Reviewed-by: Christoph Hellwig --- fs/xfs/libxfs/xfs_rtbitmap.c | 29 +++++++++++++++++++++++++++++ fs/xfs/libxfs/xfs_rtbitmap.h | 7 +++++++ fs/xfs/xfs_rtalloc.c | 17 +++++++---------- 3 files changed, 43 insertions(+), 10 deletions(-) (limited to 'fs/xfs') diff --git a/fs/xfs/libxfs/xfs_rtbitmap.c b/fs/xfs/libxfs/xfs_rtbitmap.c index b81e4ffa1f44..fb05ea0177ec 100644 --- a/fs/xfs/libxfs/xfs_rtbitmap.c +++ b/fs/xfs/libxfs/xfs_rtbitmap.c @@ -1146,3 +1146,32 @@ xfs_rtbitmap_wordcount( blocks = xfs_rtbitmap_blockcount(mp, rtextents); return XFS_FSB_TO_B(mp, blocks) >> XFS_WORDLOG; } + +/* Compute the number of rtsummary blocks needed to track the given rt space. */ +xfs_filblks_t +xfs_rtsummary_blockcount( + struct xfs_mount *mp, + unsigned int rsumlevels, + xfs_extlen_t rbmblocks) +{ + unsigned long long rsumwords; + + rsumwords = (unsigned long long)rsumlevels * rbmblocks; + return XFS_B_TO_FSB(mp, rsumwords << XFS_WORDLOG); +} + +/* + * Compute the number of rtsummary info words needed to populate every block of + * a summary file that is large enough to track the given rt space. + */ +unsigned long long +xfs_rtsummary_wordcount( + struct xfs_mount *mp, + unsigned int rsumlevels, + xfs_extlen_t rbmblocks) +{ + xfs_filblks_t blocks; + + blocks = xfs_rtsummary_blockcount(mp, rsumlevels, rbmblocks); + return XFS_FSB_TO_B(mp, blocks) >> XFS_WORDLOG; +} diff --git a/fs/xfs/libxfs/xfs_rtbitmap.h b/fs/xfs/libxfs/xfs_rtbitmap.h index ede24de74620..a3e8288bedea 100644 --- a/fs/xfs/libxfs/xfs_rtbitmap.h +++ b/fs/xfs/libxfs/xfs_rtbitmap.h @@ -308,6 +308,11 @@ xfs_filblks_t xfs_rtbitmap_blockcount(struct xfs_mount *mp, xfs_rtbxlen_t rtextents); unsigned long long xfs_rtbitmap_wordcount(struct xfs_mount *mp, xfs_rtbxlen_t rtextents); + +xfs_filblks_t xfs_rtsummary_blockcount(struct xfs_mount *mp, + unsigned int rsumlevels, xfs_extlen_t rbmblocks); +unsigned long long xfs_rtsummary_wordcount(struct xfs_mount *mp, + unsigned int rsumlevels, xfs_extlen_t rbmblocks); #else /* CONFIG_XFS_RT */ # define xfs_rtfree_extent(t,b,l) (-ENOSYS) # define xfs_rtfree_blocks(t,rb,rl) (-ENOSYS) @@ -322,6 +327,8 @@ xfs_rtbitmap_blockcount(struct xfs_mount *mp, xfs_rtbxlen_t rtextents) return 0; } # define xfs_rtbitmap_wordcount(mp, r) (0) +# define xfs_rtsummary_blockcount(mp, l, b) (0) +# define xfs_rtsummary_wordcount(mp, l, b) (0) #endif /* CONFIG_XFS_RT */ #endif /* __XFS_RTBITMAP_H__ */ diff --git a/fs/xfs/xfs_rtalloc.c b/fs/xfs/xfs_rtalloc.c index 8e041df12640..3be6bda2fd92 100644 --- a/fs/xfs/xfs_rtalloc.c +++ b/fs/xfs/xfs_rtalloc.c @@ -1001,8 +1001,7 @@ xfs_growfs_rt( nrbmblocks = xfs_rtbitmap_blockcount(mp, nrextents); nrextslog = xfs_highbit32(nrextents); nrsumlevels = nrextslog + 1; - nrsumsize = (uint)sizeof(xfs_suminfo_t) * nrsumlevels * nrbmblocks; - nrsumblocks = XFS_B_TO_FSB(mp, nrsumsize); + nrsumblocks = xfs_rtsummary_blockcount(mp, nrsumlevels, nrbmblocks); nrsumsize = XFS_FSB_TO_B(mp, nrsumblocks); /* * New summary size can't be more than half the size of @@ -1063,10 +1062,8 @@ xfs_growfs_rt( ASSERT(nsbp->sb_rextents != 0); nsbp->sb_rextslog = xfs_highbit32(nsbp->sb_rextents); nrsumlevels = nmp->m_rsumlevels = nsbp->sb_rextslog + 1; - nrsumsize = - (uint)sizeof(xfs_suminfo_t) * nrsumlevels * - nsbp->sb_rbmblocks; - nrsumblocks = XFS_B_TO_FSB(mp, nrsumsize); + nrsumblocks = xfs_rtsummary_blockcount(mp, nrsumlevels, + nsbp->sb_rbmblocks); nmp->m_rsumsize = nrsumsize = XFS_FSB_TO_B(mp, nrsumblocks); /* * Start a transaction, get the log reservation. @@ -1272,6 +1269,7 @@ xfs_rtmount_init( struct xfs_buf *bp; /* buffer for last block of subvolume */ struct xfs_sb *sbp; /* filesystem superblock copy in mount */ xfs_daddr_t d; /* address of last block of subvolume */ + unsigned int rsumblocks; int error; sbp = &mp->m_sb; @@ -1283,10 +1281,9 @@ xfs_rtmount_init( return -ENODEV; } mp->m_rsumlevels = sbp->sb_rextslog + 1; - mp->m_rsumsize = - (uint)sizeof(xfs_suminfo_t) * mp->m_rsumlevels * - sbp->sb_rbmblocks; - mp->m_rsumsize = roundup(mp->m_rsumsize, sbp->sb_blocksize); + rsumblocks = xfs_rtsummary_blockcount(mp, mp->m_rsumlevels, + mp->m_sb.sb_rbmblocks); + mp->m_rsumsize = XFS_FSB_TO_B(mp, rsumblocks); mp->m_rbmip = mp->m_rsumip = NULL; /* * Check that the realtime section is an ok size. -- cgit v1.2.3 From 663b8db7b0256b81152b2f786e45ecf12bdf265f Mon Sep 17 00:00:00 2001 From: "Darrick J. Wong" Date: Mon, 16 Oct 2023 09:51:16 -0700 Subject: xfs: use accessor functions for summary info words Create get and set functions for rtsummary words so that we can redefine the ondisk format with a specific endianness. Note that this requires the definition of a distinct type for ondisk summary info words so that the compiler can perform proper typechecking. Signed-off-by: Darrick J. Wong Reviewed-by: Christoph Hellwig --- fs/xfs/libxfs/xfs_format.h | 8 ++++++++ fs/xfs/libxfs/xfs_rtbitmap.c | 15 ++++++++------- fs/xfs/libxfs/xfs_rtbitmap.h | 28 ++++++++++++++++++++++++++-- fs/xfs/scrub/rtsummary.c | 32 ++++++++++++++++++++++---------- fs/xfs/scrub/trace.c | 1 + fs/xfs/scrub/trace.h | 10 +++++----- fs/xfs/xfs_ondisk.h | 1 + 7 files changed, 71 insertions(+), 24 deletions(-) (limited to 'fs/xfs') diff --git a/fs/xfs/libxfs/xfs_format.h b/fs/xfs/libxfs/xfs_format.h index 2af891d5d171..9a88aba1589f 100644 --- a/fs/xfs/libxfs/xfs_format.h +++ b/fs/xfs/libxfs/xfs_format.h @@ -698,6 +698,14 @@ union xfs_rtword_raw { __u32 old; }; +/* + * Realtime summary counts are accessed by the word, which is currently + * stored in host-endian format. + */ +union xfs_suminfo_raw { + __u32 old; +}; + /* * XFS Timestamps * ============== diff --git a/fs/xfs/libxfs/xfs_rtbitmap.c b/fs/xfs/libxfs/xfs_rtbitmap.c index fb05ea0177ec..4221f539615f 100644 --- a/fs/xfs/libxfs/xfs_rtbitmap.c +++ b/fs/xfs/libxfs/xfs_rtbitmap.c @@ -451,7 +451,6 @@ xfs_rtmodify_summary_int( int error; /* error value */ xfs_fileoff_t sb; /* summary fsblock */ xfs_rtsumoff_t so; /* index into the summary file */ - xfs_suminfo_t *sp; /* pointer to returned data */ unsigned int infoword; /* @@ -490,19 +489,21 @@ xfs_rtmodify_summary_int( * Point to the summary information, modify/log it, and/or copy it out. */ infoword = xfs_rtsumoffs_to_infoword(mp, so); - sp = xfs_rsumblock_infoptr(bp, infoword); if (delta) { - *sp += delta; + xfs_suminfo_t val = xfs_suminfo_add(bp, infoword, delta); + if (mp->m_rsum_cache) { - if (*sp == 0 && log == mp->m_rsum_cache[bbno]) + if (val == 0 && log == mp->m_rsum_cache[bbno]) mp->m_rsum_cache[bbno]++; - if (*sp != 0 && log < mp->m_rsum_cache[bbno]) + if (val != 0 && log < mp->m_rsum_cache[bbno]) mp->m_rsum_cache[bbno] = log; } xfs_trans_log_rtsummary(tp, bp, infoword); + if (sum) + *sum = val; + } else if (sum) { + *sum = xfs_suminfo_get(bp, infoword); } - if (sum) - *sum = *sp; return 0; } diff --git a/fs/xfs/libxfs/xfs_rtbitmap.h b/fs/xfs/libxfs/xfs_rtbitmap.h index a3e8288bedea..fdfa98e0ee52 100644 --- a/fs/xfs/libxfs/xfs_rtbitmap.h +++ b/fs/xfs/libxfs/xfs_rtbitmap.h @@ -232,16 +232,40 @@ xfs_rtsumoffs_to_infoword( } /* Return a pointer to a summary info word within a rt summary block. */ -static inline xfs_suminfo_t * +static inline union xfs_suminfo_raw * xfs_rsumblock_infoptr( struct xfs_buf *bp, unsigned int index) { - xfs_suminfo_t *info = bp->b_addr; + union xfs_suminfo_raw *info = bp->b_addr; return info + index; } +/* Get the current value of a summary counter. */ +static inline xfs_suminfo_t +xfs_suminfo_get( + struct xfs_buf *bp, + unsigned int index) +{ + union xfs_suminfo_raw *info = xfs_rsumblock_infoptr(bp, index); + + return info->old; +} + +/* Add to the current value of a summary counter and return the new value. */ +static inline xfs_suminfo_t +xfs_suminfo_add( + struct xfs_buf *bp, + unsigned int index, + int delta) +{ + union xfs_suminfo_raw *info = xfs_rsumblock_infoptr(bp, index); + + info->old += delta; + return info->old; +} + /* * Functions for walking free space rtextents in the realtime bitmap. */ diff --git a/fs/xfs/scrub/rtsummary.c b/fs/xfs/scrub/rtsummary.c index 0971d002d906..e9eac5354f19 100644 --- a/fs/xfs/scrub/rtsummary.c +++ b/fs/xfs/scrub/rtsummary.c @@ -82,9 +82,10 @@ static inline int xfsum_load( struct xfs_scrub *sc, xfs_rtsumoff_t sumoff, - xfs_suminfo_t *info) + union xfs_suminfo_raw *rawinfo) { - return xfile_obj_load(sc->xfile, info, sizeof(xfs_suminfo_t), + return xfile_obj_load(sc->xfile, rawinfo, + sizeof(union xfs_suminfo_raw), sumoff << XFS_WORDLOG); } @@ -92,9 +93,10 @@ static inline int xfsum_store( struct xfs_scrub *sc, xfs_rtsumoff_t sumoff, - const xfs_suminfo_t info) + const union xfs_suminfo_raw rawinfo) { - return xfile_obj_store(sc->xfile, &info, sizeof(xfs_suminfo_t), + return xfile_obj_store(sc->xfile, &rawinfo, + sizeof(union xfs_suminfo_raw), sumoff << XFS_WORDLOG); } @@ -102,13 +104,22 @@ static inline int xfsum_copyout( struct xfs_scrub *sc, xfs_rtsumoff_t sumoff, - xfs_suminfo_t *info, + union xfs_suminfo_raw *rawinfo, unsigned int nr_words) { - return xfile_obj_load(sc->xfile, info, nr_words << XFS_WORDLOG, + return xfile_obj_load(sc->xfile, rawinfo, nr_words << XFS_WORDLOG, sumoff << XFS_WORDLOG); } +static inline xfs_suminfo_t +xchk_rtsum_inc( + struct xfs_mount *mp, + union xfs_suminfo_raw *v) +{ + v->old += 1; + return v->old; +} + /* Update the summary file to reflect the free extent that we've accumulated. */ STATIC int xchk_rtsum_record_free( @@ -123,7 +134,8 @@ xchk_rtsum_record_free( xfs_filblks_t rtlen; xfs_rtsumoff_t offs; unsigned int lenlog; - xfs_suminfo_t v = 0; + union xfs_suminfo_raw v; + xfs_suminfo_t value; int error = 0; if (xchk_should_terminate(sc, &error)) @@ -147,9 +159,9 @@ xchk_rtsum_record_free( if (error) return error; - v++; + value = xchk_rtsum_inc(sc->mp, &v); trace_xchk_rtsum_record_free(mp, rec->ar_startext, rec->ar_extcount, - lenlog, offs, v); + lenlog, offs, value); return xfsum_store(sc, offs, v); } @@ -184,7 +196,7 @@ xchk_rtsum_compare( int nmap; for (off = 0; off < XFS_B_TO_FSB(mp, mp->m_rsumsize); off++) { - xfs_suminfo_t *ondisk_info; + union xfs_suminfo_raw *ondisk_info; int error = 0; if (xchk_should_terminate(sc, &error)) diff --git a/fs/xfs/scrub/trace.c b/fs/xfs/scrub/trace.c index 46249e7b17e0..29afa4851235 100644 --- a/fs/xfs/scrub/trace.c +++ b/fs/xfs/scrub/trace.c @@ -13,6 +13,7 @@ #include "xfs_inode.h" #include "xfs_btree.h" #include "xfs_ag.h" +#include "xfs_rtbitmap.h" #include "scrub/scrub.h" #include "scrub/xfile.h" #include "scrub/xfarray.h" diff --git a/fs/xfs/scrub/trace.h b/fs/xfs/scrub/trace.h index b0cf6757444f..4a8bc6f3c8f2 100644 --- a/fs/xfs/scrub/trace.h +++ b/fs/xfs/scrub/trace.h @@ -1038,8 +1038,8 @@ TRACE_EVENT(xfarray_sort_stats, TRACE_EVENT(xchk_rtsum_record_free, TP_PROTO(struct xfs_mount *mp, xfs_rtxnum_t start, xfs_rtbxlen_t len, unsigned int log, loff_t pos, - xfs_suminfo_t v), - TP_ARGS(mp, start, len, log, pos, v), + xfs_suminfo_t value), + TP_ARGS(mp, start, len, log, pos, value), TP_STRUCT__entry( __field(dev_t, dev) __field(dev_t, rtdev) @@ -1047,7 +1047,7 @@ TRACE_EVENT(xchk_rtsum_record_free, __field(unsigned long long, len) __field(unsigned int, log) __field(loff_t, pos) - __field(xfs_suminfo_t, v) + __field(xfs_suminfo_t, value) ), TP_fast_assign( __entry->dev = mp->m_super->s_dev; @@ -1056,7 +1056,7 @@ TRACE_EVENT(xchk_rtsum_record_free, __entry->len = len; __entry->log = log; __entry->pos = pos; - __entry->v = v; + __entry->value = value; ), TP_printk("dev %d:%d rtdev %d:%d rtx 0x%llx rtxcount 0x%llx log %u rsumpos 0x%llx sumcount %u", MAJOR(__entry->dev), MINOR(__entry->dev), @@ -1065,7 +1065,7 @@ TRACE_EVENT(xchk_rtsum_record_free, __entry->len, __entry->log, __entry->pos, - __entry->v) + __entry->value) ); #endif /* CONFIG_XFS_RT */ diff --git a/fs/xfs/xfs_ondisk.h b/fs/xfs/xfs_ondisk.h index 14d455f768d3..21a7e350b4c5 100644 --- a/fs/xfs/xfs_ondisk.h +++ b/fs/xfs/xfs_ondisk.h @@ -74,6 +74,7 @@ xfs_check_ondisk_structs(void) /* realtime structures */ XFS_CHECK_STRUCT_SIZE(union xfs_rtword_raw, 4); + XFS_CHECK_STRUCT_SIZE(union xfs_suminfo_raw, 4); /* * m68k has problems with xfs_attr_leaf_name_remote_t, but we pad it to -- cgit v1.2.3 From 41f33d82cfd310e344fc9183f02cc9e0d2d27663 Mon Sep 17 00:00:00 2001 From: Dave Chinner Date: Mon, 16 Oct 2023 09:54:19 -0700 Subject: xfs: consolidate realtime allocation arguments Consolidate the arguments passed around the rt allocator into a struct xfs_rtalloc_arg similar to how the btree allocator arguments are consolidated in a struct xfs_alloc_arg.... Signed-off-by: Dave Chinner Reviewed-by: Darrick J. Wong Signed-off-by: Darrick J. Wong Reviewed-by: Christoph Hellwig --- fs/xfs/libxfs/xfs_rtbitmap.c | 366 ++++++++++++++++++++++--------------------- fs/xfs/libxfs/xfs_rtbitmap.h | 46 +++--- fs/xfs/scrub/rtsummary.c | 6 +- fs/xfs/xfs_rtalloc.c | 333 ++++++++++++++++++++------------------- 4 files changed, 386 insertions(+), 365 deletions(-) (limited to 'fs/xfs') diff --git a/fs/xfs/libxfs/xfs_rtbitmap.c b/fs/xfs/libxfs/xfs_rtbitmap.c index 4221f539615f..07841969ada9 100644 --- a/fs/xfs/libxfs/xfs_rtbitmap.c +++ b/fs/xfs/libxfs/xfs_rtbitmap.c @@ -53,17 +53,17 @@ const struct xfs_buf_ops xfs_rtbuf_ops = { */ int xfs_rtbuf_get( - xfs_mount_t *mp, /* file system mount structure */ - xfs_trans_t *tp, /* transaction pointer */ - xfs_fileoff_t block, /* block number in bitmap or summary */ - int issum, /* is summary not bitmap */ - struct xfs_buf **bpp) /* output: buffer for the block */ + struct xfs_rtalloc_args *args, + xfs_fileoff_t block, /* block number in bitmap or summary */ + int issum, /* is summary not bitmap */ + struct xfs_buf **bpp) /* output: buffer for the block */ { - struct xfs_buf *bp; /* block buffer, result */ - xfs_inode_t *ip; /* bitmap or summary inode */ - xfs_bmbt_irec_t map; - int nmap = 1; - int error; /* error value */ + struct xfs_mount *mp = args->mp; + struct xfs_buf *bp; /* block buffer, result */ + struct xfs_inode *ip; /* bitmap or summary inode */ + struct xfs_bmbt_irec map; + int nmap = 1; + int error; ip = issum ? mp->m_rsumip : mp->m_rbmip; @@ -75,13 +75,13 @@ xfs_rtbuf_get( return -EFSCORRUPTED; ASSERT(map.br_startblock != NULLFSBLOCK); - error = xfs_trans_read_buf(mp, tp, mp->m_ddev_targp, + error = xfs_trans_read_buf(mp, args->tp, mp->m_ddev_targp, XFS_FSB_TO_DADDR(mp, map.br_startblock), mp->m_bsize, 0, &bp, &xfs_rtbuf_ops); if (error) return error; - xfs_trans_buf_set_type(tp, bp, issum ? XFS_BLFT_RTSUMMARY_BUF + xfs_trans_buf_set_type(args->tp, bp, issum ? XFS_BLFT_RTSUMMARY_BUF : XFS_BLFT_RTBITMAP_BUF); *bpp = bp; return 0; @@ -93,30 +93,30 @@ xfs_rtbuf_get( */ int xfs_rtfind_back( - xfs_mount_t *mp, /* file system mount point */ - xfs_trans_t *tp, /* transaction pointer */ - xfs_rtxnum_t start, /* starting rtext to look at */ - xfs_rtxnum_t limit, /* last rtext to look at */ - xfs_rtxnum_t *rtx) /* out: start rtext found */ + struct xfs_rtalloc_args *args, + xfs_rtxnum_t start, /* starting rtext to look at */ + xfs_rtxnum_t limit, /* last rtext to look at */ + xfs_rtxnum_t *rtx) /* out: start rtext found */ { - int bit; /* bit number in the word */ - xfs_fileoff_t block; /* bitmap block number */ - struct xfs_buf *bp; /* buf for the block */ - int error; /* error value */ - xfs_rtxnum_t firstbit; /* first useful bit in the word */ - xfs_rtxnum_t i; /* current bit number rel. to start */ - xfs_rtxnum_t len; /* length of inspected area */ - xfs_rtword_t mask; /* mask of relevant bits for value */ - xfs_rtword_t want; /* mask for "good" values */ - xfs_rtword_t wdiff; /* difference from wanted value */ - xfs_rtword_t incore; - unsigned int word; /* word number in the buffer */ + struct xfs_mount *mp = args->mp; + int bit; /* bit number in the word */ + xfs_fileoff_t block; /* bitmap block number */ + struct xfs_buf *bp; /* buf for the block */ + int error; /* error value */ + xfs_rtxnum_t firstbit; /* first useful bit in the word */ + xfs_rtxnum_t i; /* current bit number rel. to start */ + xfs_rtxnum_t len; /* length of inspected area */ + xfs_rtword_t mask; /* mask of relevant bits for value */ + xfs_rtword_t want; /* mask for "good" values */ + xfs_rtword_t wdiff; /* difference from wanted value */ + xfs_rtword_t incore; + unsigned int word; /* word number in the buffer */ /* * Compute and read in starting bitmap block for starting block. */ block = xfs_rtx_to_rbmblock(mp, start); - error = xfs_rtbuf_get(mp, tp, block, 0, &bp); + error = xfs_rtbuf_get(args, block, 0, &bp); if (error) { return error; } @@ -153,7 +153,7 @@ xfs_rtfind_back( /* * Different. Mark where we are and return. */ - xfs_trans_brelse(tp, bp); + xfs_trans_brelse(args->tp, bp); i = bit - XFS_RTHIBIT(wdiff); *rtx = start - i + 1; return 0; @@ -167,8 +167,8 @@ xfs_rtfind_back( /* * If done with this block, get the previous one. */ - xfs_trans_brelse(tp, bp); - error = xfs_rtbuf_get(mp, tp, --block, 0, &bp); + xfs_trans_brelse(args->tp, bp); + error = xfs_rtbuf_get(args, --block, 0, &bp); if (error) { return error; } @@ -194,7 +194,7 @@ xfs_rtfind_back( /* * Different, mark where we are and return. */ - xfs_trans_brelse(tp, bp); + xfs_trans_brelse(args->tp, bp); i += XFS_NBWORD - 1 - XFS_RTHIBIT(wdiff); *rtx = start - i + 1; return 0; @@ -208,8 +208,8 @@ xfs_rtfind_back( /* * If done with this block, get the previous one. */ - xfs_trans_brelse(tp, bp); - error = xfs_rtbuf_get(mp, tp, --block, 0, &bp); + xfs_trans_brelse(args->tp, bp); + error = xfs_rtbuf_get(args, --block, 0, &bp); if (error) { return error; } @@ -236,7 +236,7 @@ xfs_rtfind_back( /* * Different, mark where we are and return. */ - xfs_trans_brelse(tp, bp); + xfs_trans_brelse(args->tp, bp); i += XFS_NBWORD - 1 - XFS_RTHIBIT(wdiff); *rtx = start - i + 1; return 0; @@ -246,7 +246,7 @@ xfs_rtfind_back( /* * No match, return that we scanned the whole area. */ - xfs_trans_brelse(tp, bp); + xfs_trans_brelse(args->tp, bp); *rtx = start - i + 1; return 0; } @@ -257,30 +257,30 @@ xfs_rtfind_back( */ int xfs_rtfind_forw( - xfs_mount_t *mp, /* file system mount point */ - xfs_trans_t *tp, /* transaction pointer */ - xfs_rtxnum_t start, /* starting rtext to look at */ - xfs_rtxnum_t limit, /* last rtext to look at */ - xfs_rtxnum_t *rtx) /* out: start rtext found */ + struct xfs_rtalloc_args *args, + xfs_rtxnum_t start, /* starting rtext to look at */ + xfs_rtxnum_t limit, /* last rtext to look at */ + xfs_rtxnum_t *rtx) /* out: start rtext found */ { - int bit; /* bit number in the word */ - xfs_fileoff_t block; /* bitmap block number */ - struct xfs_buf *bp; /* buf for the block */ - int error; /* error value */ - xfs_rtxnum_t i; /* current bit number rel. to start */ - xfs_rtxnum_t lastbit; /* last useful bit in the word */ - xfs_rtxnum_t len; /* length of inspected area */ - xfs_rtword_t mask; /* mask of relevant bits for value */ - xfs_rtword_t want; /* mask for "good" values */ - xfs_rtword_t wdiff; /* difference from wanted value */ - xfs_rtword_t incore; - unsigned int word; /* word number in the buffer */ + struct xfs_mount *mp = args->mp; + int bit; /* bit number in the word */ + xfs_fileoff_t block; /* bitmap block number */ + struct xfs_buf *bp; /* buf for the block */ + int error; + xfs_rtxnum_t i; /* current bit number rel. to start */ + xfs_rtxnum_t lastbit;/* last useful bit in the word */ + xfs_rtxnum_t len; /* length of inspected area */ + xfs_rtword_t mask; /* mask of relevant bits for value */ + xfs_rtword_t want; /* mask for "good" values */ + xfs_rtword_t wdiff; /* difference from wanted value */ + xfs_rtword_t incore; + unsigned int word; /* word number in the buffer */ /* * Compute and read in starting bitmap block for starting block. */ block = xfs_rtx_to_rbmblock(mp, start); - error = xfs_rtbuf_get(mp, tp, block, 0, &bp); + error = xfs_rtbuf_get(args, block, 0, &bp); if (error) { return error; } @@ -316,7 +316,7 @@ xfs_rtfind_forw( /* * Different. Mark where we are and return. */ - xfs_trans_brelse(tp, bp); + xfs_trans_brelse(args->tp, bp); i = XFS_RTLOBIT(wdiff) - bit; *rtx = start + i - 1; return 0; @@ -330,8 +330,8 @@ xfs_rtfind_forw( /* * If done with this block, get the previous one. */ - xfs_trans_brelse(tp, bp); - error = xfs_rtbuf_get(mp, tp, ++block, 0, &bp); + xfs_trans_brelse(args->tp, bp); + error = xfs_rtbuf_get(args, ++block, 0, &bp); if (error) { return error; } @@ -357,7 +357,7 @@ xfs_rtfind_forw( /* * Different, mark where we are and return. */ - xfs_trans_brelse(tp, bp); + xfs_trans_brelse(args->tp, bp); i += XFS_RTLOBIT(wdiff); *rtx = start + i - 1; return 0; @@ -371,8 +371,8 @@ xfs_rtfind_forw( /* * If done with this block, get the next one. */ - xfs_trans_brelse(tp, bp); - error = xfs_rtbuf_get(mp, tp, ++block, 0, &bp); + xfs_trans_brelse(args->tp, bp); + error = xfs_rtbuf_get(args, ++block, 0, &bp); if (error) { return error; } @@ -397,7 +397,7 @@ xfs_rtfind_forw( /* * Different, mark where we are and return. */ - xfs_trans_brelse(tp, bp); + xfs_trans_brelse(args->tp, bp); i += XFS_RTLOBIT(wdiff); *rtx = start + i - 1; return 0; @@ -407,7 +407,7 @@ xfs_rtfind_forw( /* * No match, return that we scanned the whole area. */ - xfs_trans_brelse(tp, bp); + xfs_trans_brelse(args->tp, bp); *rtx = start + i - 1; return 0; } @@ -438,20 +438,20 @@ xfs_trans_log_rtsummary( */ int xfs_rtmodify_summary_int( - xfs_mount_t *mp, /* file system mount structure */ - xfs_trans_t *tp, /* transaction pointer */ - int log, /* log2 of extent size */ - xfs_fileoff_t bbno, /* bitmap block number */ - int delta, /* change to make to summary info */ - struct xfs_buf **rbpp, /* in/out: summary block buffer */ - xfs_fileoff_t *rsb, /* in/out: summary block number */ - xfs_suminfo_t *sum) /* out: summary info for this block */ + struct xfs_rtalloc_args *args, + int log, /* log2 of extent size */ + xfs_fileoff_t bbno, /* bitmap block number */ + int delta, /* change to make to summary info */ + struct xfs_buf **rbpp, /* in/out: summary block buffer */ + xfs_fileoff_t *rsb, /* in/out: summary block number */ + xfs_suminfo_t *sum) /* out: summary info for this block */ { - struct xfs_buf *bp; /* buffer for the summary block */ - int error; /* error value */ - xfs_fileoff_t sb; /* summary fsblock */ - xfs_rtsumoff_t so; /* index into the summary file */ - unsigned int infoword; + struct xfs_mount *mp = args->mp; + struct xfs_buf *bp; /* buffer for the summary block */ + int error; + xfs_fileoff_t sb; /* summary fsblock */ + xfs_rtsumoff_t so; /* index into the summary file */ + unsigned int infoword; /* * Compute entry number in the summary file. @@ -474,8 +474,8 @@ xfs_rtmodify_summary_int( * If there was an old one, get rid of it first. */ if (*rbpp) - xfs_trans_brelse(tp, *rbpp); - error = xfs_rtbuf_get(mp, tp, sb, 1, &bp); + xfs_trans_brelse(args->tp, *rbpp); + error = xfs_rtbuf_get(args, sb, 1, &bp); if (error) { return error; } @@ -498,7 +498,7 @@ xfs_rtmodify_summary_int( if (val != 0 && log < mp->m_rsum_cache[bbno]) mp->m_rsum_cache[bbno] = log; } - xfs_trans_log_rtsummary(tp, bp, infoword); + xfs_trans_log_rtsummary(args->tp, bp, infoword); if (sum) *sum = val; } else if (sum) { @@ -509,16 +509,14 @@ xfs_rtmodify_summary_int( int xfs_rtmodify_summary( - xfs_mount_t *mp, /* file system mount structure */ - xfs_trans_t *tp, /* transaction pointer */ - int log, /* log2 of extent size */ - xfs_fileoff_t bbno, /* bitmap block number */ - int delta, /* change to make to summary info */ - struct xfs_buf **rbpp, /* in/out: summary block buffer */ - xfs_fileoff_t *rsb) /* in/out: summary block number */ + struct xfs_rtalloc_args *args, + int log, /* log2 of extent size */ + xfs_fileoff_t bbno, /* bitmap block number */ + int delta, /* change to make to summary info */ + struct xfs_buf **rbpp, /* in/out: summary block buffer */ + xfs_fileoff_t *rsb) /* in/out: summary block number */ { - return xfs_rtmodify_summary_int(mp, tp, log, bbno, - delta, rbpp, rsb, NULL); + return xfs_rtmodify_summary_int(args, log, bbno, delta, rbpp, rsb, NULL); } /* Log rtbitmap block from the word @from to the byte before @next. */ @@ -543,22 +541,22 @@ xfs_trans_log_rtbitmap( */ int xfs_rtmodify_range( - xfs_mount_t *mp, /* file system mount point */ - xfs_trans_t *tp, /* transaction pointer */ - xfs_rtxnum_t start, /* starting rtext to modify */ - xfs_rtxlen_t len, /* length of extent to modify */ - int val) /* 1 for free, 0 for allocated */ + struct xfs_rtalloc_args *args, + xfs_rtxnum_t start, /* starting rtext to modify */ + xfs_rtxlen_t len, /* length of extent to modify */ + int val) /* 1 for free, 0 for allocated */ { - int bit; /* bit number in the word */ - xfs_fileoff_t block; /* bitmap block number */ - struct xfs_buf *bp; /* buf for the block */ - int error; /* error value */ - int i; /* current bit number rel. to start */ - int lastbit; /* last useful bit in word */ - xfs_rtword_t mask; /* mask o frelevant bits for value */ - xfs_rtword_t incore; - unsigned int firstword; /* first word used in the buffer */ - unsigned int word; /* word number in the buffer */ + struct xfs_mount *mp = args->mp; + int bit; /* bit number in the word */ + xfs_fileoff_t block; /* bitmap block number */ + struct xfs_buf *bp; /* buf for the block */ + int error; + int i; /* current bit number rel. to start */ + int lastbit; /* last useful bit in word */ + xfs_rtword_t mask; /* mask of relevant bits for value */ + xfs_rtword_t incore; + unsigned int firstword; /* first word used in the buffer */ + unsigned int word; /* word number in the buffer */ /* * Compute starting bitmap block number. @@ -567,7 +565,7 @@ xfs_rtmodify_range( /* * Read the bitmap block, and point to its data. */ - error = xfs_rtbuf_get(mp, tp, block, 0, &bp); + error = xfs_rtbuf_get(args, block, 0, &bp); if (error) { return error; } @@ -610,8 +608,9 @@ xfs_rtmodify_range( * Log the changed part of this block. * Get the next one. */ - xfs_trans_log_rtbitmap(tp, bp, firstword, word); - error = xfs_rtbuf_get(mp, tp, ++block, 0, &bp); + xfs_trans_log_rtbitmap(args->tp, bp, firstword, + word); + error = xfs_rtbuf_get(args, ++block, 0, &bp); if (error) { return error; } @@ -643,11 +642,11 @@ xfs_rtmodify_range( * Log the changed part of this block. * Get the next one. */ - xfs_trans_log_rtbitmap(tp, bp, firstword, word); - error = xfs_rtbuf_get(mp, tp, ++block, 0, &bp); - if (error) { + xfs_trans_log_rtbitmap(args->tp, bp, firstword, + word); + error = xfs_rtbuf_get(args, ++block, 0, &bp); + if (error) return error; - } firstword = word = 0; } @@ -676,7 +675,7 @@ xfs_rtmodify_range( * Log any remaining changed bytes. */ if (word > firstword) - xfs_trans_log_rtbitmap(tp, bp, firstword, word); + xfs_trans_log_rtbitmap(args->tp, bp, firstword, word); return 0; } @@ -686,23 +685,23 @@ xfs_rtmodify_range( */ int xfs_rtfree_range( - xfs_mount_t *mp, /* file system mount point */ - xfs_trans_t *tp, /* transaction pointer */ - xfs_rtxnum_t start, /* starting rtext to free */ - xfs_rtxlen_t len, /* length to free */ - struct xfs_buf **rbpp, /* in/out: summary block buffer */ - xfs_fileoff_t *rsb) /* in/out: summary block number */ + struct xfs_rtalloc_args *args, + xfs_rtxnum_t start, /* starting rtext to free */ + xfs_rtxlen_t len, /* length to free */ + struct xfs_buf **rbpp, /* in/out: summary block buffer */ + xfs_fileoff_t *rsb) /* in/out: summary block number */ { - xfs_rtxnum_t end; /* end of the freed extent */ - int error; /* error value */ - xfs_rtxnum_t postblock; /* first rtext freed > end */ - xfs_rtxnum_t preblock; /* first rtext freed < start */ + struct xfs_mount *mp = args->mp; + xfs_rtxnum_t end; /* end of the freed extent */ + int error; /* error value */ + xfs_rtxnum_t postblock; /* first rtext freed > end */ + xfs_rtxnum_t preblock; /* first rtext freed < start */ end = start + len - 1; /* * Modify the bitmap to mark this extent freed. */ - error = xfs_rtmodify_range(mp, tp, start, len, 1); + error = xfs_rtmodify_range(args, start, len, 1); if (error) { return error; } @@ -711,14 +710,14 @@ xfs_rtfree_range( * We need to find the beginning and end of the extent so we can * properly update the summary. */ - error = xfs_rtfind_back(mp, tp, start, 0, &preblock); + error = xfs_rtfind_back(args, start, 0, &preblock); if (error) { return error; } /* * Find the next allocated block (end of allocated extent). */ - error = xfs_rtfind_forw(mp, tp, end, mp->m_sb.sb_rextents - 1, + error = xfs_rtfind_forw(args, end, mp->m_sb.sb_rextents - 1, &postblock); if (error) return error; @@ -727,7 +726,7 @@ xfs_rtfree_range( * old extent, add summary data for them to be allocated. */ if (preblock < start) { - error = xfs_rtmodify_summary(mp, tp, + error = xfs_rtmodify_summary(args, XFS_RTBLOCKLOG(start - preblock), xfs_rtx_to_rbmblock(mp, preblock), -1, rbpp, rsb); if (error) { @@ -739,7 +738,7 @@ xfs_rtfree_range( * old extent, add summary data for them to be allocated. */ if (postblock > end) { - error = xfs_rtmodify_summary(mp, tp, + error = xfs_rtmodify_summary(args, XFS_RTBLOCKLOG(postblock - end), xfs_rtx_to_rbmblock(mp, end + 1), -1, rbpp, rsb); if (error) { @@ -750,7 +749,7 @@ xfs_rtfree_range( * Increment the summary information corresponding to the entire * (new) free extent. */ - error = xfs_rtmodify_summary(mp, tp, + error = xfs_rtmodify_summary(args, XFS_RTBLOCKLOG(postblock + 1 - preblock), xfs_rtx_to_rbmblock(mp, preblock), 1, rbpp, rsb); return error; @@ -762,24 +761,24 @@ xfs_rtfree_range( */ int xfs_rtcheck_range( - xfs_mount_t *mp, /* file system mount point */ - xfs_trans_t *tp, /* transaction pointer */ - xfs_rtxnum_t start, /* starting rtext number of extent */ - xfs_rtxlen_t len, /* length of extent */ - int val, /* 1 for free, 0 for allocated */ - xfs_rtxnum_t *new, /* out: first rtext not matching */ - int *stat) /* out: 1 for matches, 0 for not */ + struct xfs_rtalloc_args *args, + xfs_rtxnum_t start, /* starting rtext number of extent */ + xfs_rtxlen_t len, /* length of extent */ + int val, /* 1 for free, 0 for allocated */ + xfs_rtxnum_t *new, /* out: first rtext not matching */ + int *stat) /* out: 1 for matches, 0 for not */ { - int bit; /* bit number in the word */ - xfs_fileoff_t block; /* bitmap block number */ - struct xfs_buf *bp; /* buf for the block */ - int error; /* error value */ - xfs_rtxnum_t i; /* current bit number rel. to start */ - xfs_rtxnum_t lastbit; /* last useful bit in word */ - xfs_rtword_t mask; /* mask of relevant bits for value */ - xfs_rtword_t wdiff; /* difference from wanted value */ - xfs_rtword_t incore; - unsigned int word; /* word number in the buffer */ + struct xfs_mount *mp = args->mp; + int bit; /* bit number in the word */ + xfs_fileoff_t block; /* bitmap block number */ + struct xfs_buf *bp; /* buf for the block */ + int error; + xfs_rtxnum_t i; /* current bit number rel. to start */ + xfs_rtxnum_t lastbit; /* last useful bit in word */ + xfs_rtword_t mask; /* mask of relevant bits for value */ + xfs_rtword_t wdiff; /* difference from wanted value */ + xfs_rtword_t incore; + unsigned int word; /* word number in the buffer */ /* * Compute starting bitmap block number @@ -788,7 +787,7 @@ xfs_rtcheck_range( /* * Read the bitmap block. */ - error = xfs_rtbuf_get(mp, tp, block, 0, &bp); + error = xfs_rtbuf_get(args, block, 0, &bp); if (error) { return error; } @@ -823,7 +822,7 @@ xfs_rtcheck_range( /* * Different, compute first wrong bit and return. */ - xfs_trans_brelse(tp, bp); + xfs_trans_brelse(args->tp, bp); i = XFS_RTLOBIT(wdiff) - bit; *new = start + i; *stat = 0; @@ -838,8 +837,8 @@ xfs_rtcheck_range( /* * If done with this block, get the next one. */ - xfs_trans_brelse(tp, bp); - error = xfs_rtbuf_get(mp, tp, ++block, 0, &bp); + xfs_trans_brelse(args->tp, bp); + error = xfs_rtbuf_get(args, ++block, 0, &bp); if (error) { return error; } @@ -865,7 +864,7 @@ xfs_rtcheck_range( /* * Different, compute first wrong bit and return. */ - xfs_trans_brelse(tp, bp); + xfs_trans_brelse(args->tp, bp); i += XFS_RTLOBIT(wdiff); *new = start + i; *stat = 0; @@ -880,8 +879,8 @@ xfs_rtcheck_range( /* * If done with this block, get the next one. */ - xfs_trans_brelse(tp, bp); - error = xfs_rtbuf_get(mp, tp, ++block, 0, &bp); + xfs_trans_brelse(args->tp, bp); + error = xfs_rtbuf_get(args, ++block, 0, &bp); if (error) { return error; } @@ -906,7 +905,7 @@ xfs_rtcheck_range( /* * Different, compute first wrong bit and return. */ - xfs_trans_brelse(tp, bp); + xfs_trans_brelse(args->tp, bp); i += XFS_RTLOBIT(wdiff); *new = start + i; *stat = 0; @@ -917,7 +916,7 @@ xfs_rtcheck_range( /* * Successful, return. */ - xfs_trans_brelse(tp, bp); + xfs_trans_brelse(args->tp, bp); *new = start + i; *stat = 1; return 0; @@ -927,54 +926,55 @@ xfs_rtcheck_range( /* * Check that the given extent (block range) is allocated already. */ -STATIC int /* error */ +STATIC int xfs_rtcheck_alloc_range( - xfs_mount_t *mp, /* file system mount point */ - xfs_trans_t *tp, /* transaction pointer */ - xfs_rtxnum_t start, /* starting rtext number of extent */ - xfs_rtxlen_t len) /* length of extent */ + struct xfs_rtalloc_args *args, + xfs_rtxnum_t start, /* starting rtext number of extent */ + xfs_rtxlen_t len) /* length of extent */ { - xfs_rtxnum_t new; /* dummy for xfs_rtcheck_range */ - int stat; - int error; + xfs_rtxnum_t new; /* dummy for xfs_rtcheck_range */ + int stat; + int error; - error = xfs_rtcheck_range(mp, tp, start, len, 0, &new, &stat); + error = xfs_rtcheck_range(args, start, len, 0, &new, &stat); if (error) return error; ASSERT(stat); return 0; } #else -#define xfs_rtcheck_alloc_range(m,t,b,l) (0) +#define xfs_rtcheck_alloc_range(a,b,l) (0) #endif /* * Free an extent in the realtime subvolume. Length is expressed in * realtime extents, as is the block number. */ -int /* error */ +int xfs_rtfree_extent( - xfs_trans_t *tp, /* transaction pointer */ - xfs_rtxnum_t start, /* starting rtext number to free */ - xfs_rtxlen_t len) /* length of extent freed */ + struct xfs_trans *tp, /* transaction pointer */ + xfs_rtxnum_t start, /* starting rtext number to free */ + xfs_rtxlen_t len) /* length of extent freed */ { - int error; /* error value */ - xfs_mount_t *mp; /* file system mount structure */ - xfs_fsblock_t sb; /* summary file block number */ - struct xfs_buf *sumbp = NULL; /* summary file block buffer */ - - mp = tp->t_mountp; + struct xfs_mount *mp = tp->t_mountp; + struct xfs_rtalloc_args args = { + .mp = mp, + .tp = tp, + }; + int error; + xfs_fsblock_t sb; /* summary file block number */ + struct xfs_buf *sumbp = NULL; /* summary file block buffer */ ASSERT(mp->m_rbmip->i_itemp != NULL); ASSERT(xfs_isilocked(mp->m_rbmip, XFS_ILOCK_EXCL)); - error = xfs_rtcheck_alloc_range(mp, tp, start, len); + error = xfs_rtcheck_alloc_range(&args, start, len); if (error) return error; /* * Free the range of realtime blocks. */ - error = xfs_rtfree_range(mp, tp, start, len, &sumbp, &sb); + error = xfs_rtfree_range(&args, start, len, &sumbp, &sb); if (error) { return error; } @@ -1039,6 +1039,10 @@ xfs_rtalloc_query_range( xfs_rtalloc_query_range_fn fn, void *priv) { + struct xfs_rtalloc_args args = { + .mp = mp, + .tp = tp, + }; struct xfs_rtalloc_rec rec; xfs_rtxnum_t rtstart; xfs_rtxnum_t rtend; @@ -1058,13 +1062,13 @@ xfs_rtalloc_query_range( rtstart = low_rec->ar_startext; while (rtstart <= high_key) { /* Is the first block free? */ - error = xfs_rtcheck_range(mp, tp, rtstart, 1, 1, &rtend, + error = xfs_rtcheck_range(&args, rtstart, 1, 1, &rtend, &is_free); if (error) break; /* How long does the extent go for? */ - error = xfs_rtfind_forw(mp, tp, rtstart, high_key, &rtend); + error = xfs_rtfind_forw(&args, rtstart, high_key, &rtend); if (error) break; @@ -1109,11 +1113,15 @@ xfs_rtalloc_extent_is_free( xfs_rtxlen_t len, bool *is_free) { + struct xfs_rtalloc_args args = { + .mp = mp, + .tp = tp, + }; xfs_rtxnum_t end; int matches; int error; - error = xfs_rtcheck_range(mp, tp, start, len, 1, &end, &matches); + error = xfs_rtcheck_range(&args, start, len, 1, &end, &matches); if (error) return error; diff --git a/fs/xfs/libxfs/xfs_rtbitmap.h b/fs/xfs/libxfs/xfs_rtbitmap.h index fdfa98e0ee52..52aa301aba7b 100644 --- a/fs/xfs/libxfs/xfs_rtbitmap.h +++ b/fs/xfs/libxfs/xfs_rtbitmap.h @@ -6,6 +6,11 @@ #ifndef __XFS_RTBITMAP_H__ #define __XFS_RTBITMAP_H__ +struct xfs_rtalloc_args { + struct xfs_mount *mp; + struct xfs_trans *tp; +}; + static inline xfs_rtblock_t xfs_rtx_to_rtb( struct xfs_mount *mp, @@ -281,29 +286,24 @@ typedef int (*xfs_rtalloc_query_range_fn)( void *priv); #ifdef CONFIG_XFS_RT -int xfs_rtbuf_get(struct xfs_mount *mp, struct xfs_trans *tp, - xfs_fileoff_t block, int issum, struct xfs_buf **bpp); -int xfs_rtcheck_range(struct xfs_mount *mp, struct xfs_trans *tp, - xfs_rtxnum_t start, xfs_rtxlen_t len, int val, - xfs_rtxnum_t *new, int *stat); -int xfs_rtfind_back(struct xfs_mount *mp, struct xfs_trans *tp, - xfs_rtxnum_t start, xfs_rtxnum_t limit, - xfs_rtxnum_t *rtblock); -int xfs_rtfind_forw(struct xfs_mount *mp, struct xfs_trans *tp, - xfs_rtxnum_t start, xfs_rtxnum_t limit, - xfs_rtxnum_t *rtblock); -int xfs_rtmodify_range(struct xfs_mount *mp, struct xfs_trans *tp, - xfs_rtxnum_t start, xfs_rtxlen_t len, int val); -int xfs_rtmodify_summary_int(struct xfs_mount *mp, struct xfs_trans *tp, - int log, xfs_fileoff_t bbno, int delta, - struct xfs_buf **rbpp, xfs_fileoff_t *rsb, - xfs_suminfo_t *sum); -int xfs_rtmodify_summary(struct xfs_mount *mp, struct xfs_trans *tp, int log, - xfs_fileoff_t bbno, int delta, struct xfs_buf **rbpp, - xfs_fileoff_t *rsb); -int xfs_rtfree_range(struct xfs_mount *mp, struct xfs_trans *tp, - xfs_rtxnum_t start, xfs_rtxlen_t len, - struct xfs_buf **rbpp, xfs_fileoff_t *rsb); +int xfs_rtbuf_get(struct xfs_rtalloc_args *args, xfs_fileoff_t block, + int issum, struct xfs_buf **bpp); +int xfs_rtcheck_range(struct xfs_rtalloc_args *args, xfs_rtxnum_t start, + xfs_rtxlen_t len, int val, xfs_rtxnum_t *new, int *stat); +int xfs_rtfind_back(struct xfs_rtalloc_args *args, xfs_rtxnum_t start, + xfs_rtxnum_t limit, xfs_rtxnum_t *rtblock); +int xfs_rtfind_forw(struct xfs_rtalloc_args *args, xfs_rtxnum_t start, + xfs_rtxnum_t limit, xfs_rtxnum_t *rtblock); +int xfs_rtmodify_range(struct xfs_rtalloc_args *args, xfs_rtxnum_t start, + xfs_rtxlen_t len, int val); +int xfs_rtmodify_summary_int(struct xfs_rtalloc_args *args, int log, + xfs_fileoff_t bbno, int delta, struct xfs_buf **rbpp, + xfs_fileoff_t *rsb, xfs_suminfo_t *sum); +int xfs_rtmodify_summary(struct xfs_rtalloc_args *args, int log, + xfs_fileoff_t bbno, int delta, struct xfs_buf **rbpp, + xfs_fileoff_t *rsb); +int xfs_rtfree_range(struct xfs_rtalloc_args *args, xfs_rtxnum_t start, + xfs_rtxlen_t len, struct xfs_buf **rbpp, xfs_fileoff_t *rsb); int xfs_rtalloc_query_range(struct xfs_mount *mp, struct xfs_trans *tp, const struct xfs_rtalloc_rec *low_rec, const struct xfs_rtalloc_rec *high_rec, diff --git a/fs/xfs/scrub/rtsummary.c b/fs/xfs/scrub/rtsummary.c index e9eac5354f19..10e83196301c 100644 --- a/fs/xfs/scrub/rtsummary.c +++ b/fs/xfs/scrub/rtsummary.c @@ -188,6 +188,10 @@ STATIC int xchk_rtsum_compare( struct xfs_scrub *sc) { + struct xfs_rtalloc_args args = { + .mp = sc->mp, + .tp = sc->tp, + }; struct xfs_mount *mp = sc->mp; struct xfs_buf *bp; struct xfs_bmbt_irec map; @@ -217,7 +221,7 @@ xchk_rtsum_compare( } /* Read a block's worth of ondisk rtsummary file. */ - error = xfs_rtbuf_get(mp, sc->tp, off, 1, &bp); + error = xfs_rtbuf_get(&args, off, 1, &bp); if (!xchk_fblock_process_error(sc, XFS_DATA_FORK, off, &error)) return error; diff --git a/fs/xfs/xfs_rtalloc.c b/fs/xfs/xfs_rtalloc.c index 3be6bda2fd92..73d3280fbe36 100644 --- a/fs/xfs/xfs_rtalloc.c +++ b/fs/xfs/xfs_rtalloc.c @@ -29,35 +29,34 @@ */ static int xfs_rtget_summary( - xfs_mount_t *mp, /* file system mount structure */ - xfs_trans_t *tp, /* transaction pointer */ - int log, /* log2 of extent size */ - xfs_fileoff_t bbno, /* bitmap block number */ - struct xfs_buf **rbpp, /* in/out: summary block buffer */ - xfs_fileoff_t *rsb, /* in/out: summary block number */ - xfs_suminfo_t *sum) /* out: summary info for this block */ + struct xfs_rtalloc_args *args, + int log, /* log2 of extent size */ + xfs_fileoff_t bbno, /* bitmap block number */ + struct xfs_buf **rbpp, /* in/out: summary block buffer */ + xfs_fileoff_t *rsb, /* in/out: summary block number */ + xfs_suminfo_t *sum) /* out: summary info for this block */ { - return xfs_rtmodify_summary_int(mp, tp, log, bbno, 0, rbpp, rsb, sum); + return xfs_rtmodify_summary_int(args, log, bbno, 0, rbpp, rsb, sum); } /* * Return whether there are any free extents in the size range given * by low and high, for the bitmap block bbno. */ -STATIC int /* error */ +STATIC int xfs_rtany_summary( - xfs_mount_t *mp, /* file system mount structure */ - xfs_trans_t *tp, /* transaction pointer */ - int low, /* low log2 extent size */ - int high, /* high log2 extent size */ - xfs_fileoff_t bbno, /* bitmap block number */ - struct xfs_buf **rbpp, /* in/out: summary block buffer */ - xfs_fileoff_t *rsb, /* in/out: summary block number */ - int *stat) /* out: any good extents here? */ + struct xfs_rtalloc_args *args, + int low, /* low log2 extent size */ + int high, /* high log2 extent size */ + xfs_fileoff_t bbno, /* bitmap block number */ + struct xfs_buf **rbpp, /* in/out: summary block buffer */ + xfs_fileoff_t *rsb, /* in/out: summary block number */ + int *stat) /* out: any good extents here? */ { - int error; /* error value */ - int log; /* loop counter, log2 of ext. size */ - xfs_suminfo_t sum; /* summary data */ + struct xfs_mount *mp = args->mp; + int error; + int log; /* loop counter, log2 of ext. size */ + xfs_suminfo_t sum; /* summary data */ /* There are no extents at levels < m_rsum_cache[bbno]. */ if (mp->m_rsum_cache && low < mp->m_rsum_cache[bbno]) @@ -70,7 +69,7 @@ xfs_rtany_summary( /* * Get one summary datum. */ - error = xfs_rtget_summary(mp, tp, log, bbno, rbpp, rsb, &sum); + error = xfs_rtget_summary(args, log, bbno, rbpp, rsb, &sum); if (error) { return error; } @@ -98,35 +97,34 @@ out: * Copy and transform the summary file, given the old and new * parameters in the mount structures. */ -STATIC int /* error */ +STATIC int xfs_rtcopy_summary( - xfs_mount_t *omp, /* old file system mount point */ - xfs_mount_t *nmp, /* new file system mount point */ - xfs_trans_t *tp) /* transaction pointer */ + struct xfs_rtalloc_args *oargs, + struct xfs_rtalloc_args *nargs) { - xfs_fileoff_t bbno; /* bitmap block number */ - struct xfs_buf *bp; /* summary buffer */ - int error; /* error return value */ - int log; /* summary level number (log length) */ - xfs_suminfo_t sum; /* summary data */ - xfs_fileoff_t sumbno; /* summary block number */ + xfs_fileoff_t bbno; /* bitmap block number */ + struct xfs_buf *bp; /* summary buffer */ + int error; + int log; /* summary level number (log length) */ + xfs_suminfo_t sum; /* summary data */ + xfs_fileoff_t sumbno; /* summary block number */ bp = NULL; - for (log = omp->m_rsumlevels - 1; log >= 0; log--) { - for (bbno = omp->m_sb.sb_rbmblocks - 1; + for (log = oargs->mp->m_rsumlevels - 1; log >= 0; log--) { + for (bbno = oargs->mp->m_sb.sb_rbmblocks - 1; (xfs_srtblock_t)bbno >= 0; bbno--) { - error = xfs_rtget_summary(omp, tp, log, bbno, &bp, + error = xfs_rtget_summary(oargs, log, bbno, &bp, &sumbno, &sum); if (error) return error; if (sum == 0) continue; - error = xfs_rtmodify_summary(omp, tp, log, bbno, -sum, + error = xfs_rtmodify_summary(oargs, log, bbno, -sum, &bp, &sumbno); if (error) return error; - error = xfs_rtmodify_summary(nmp, tp, log, bbno, sum, + error = xfs_rtmodify_summary(nargs, log, bbno, sum, &bp, &sumbno); if (error) return error; @@ -139,19 +137,19 @@ xfs_rtcopy_summary( * Mark an extent specified by start and len allocated. * Updates all the summary information as well as the bitmap. */ -STATIC int /* error */ +STATIC int xfs_rtallocate_range( - xfs_mount_t *mp, /* file system mount point */ - xfs_trans_t *tp, /* transaction pointer */ - xfs_rtxnum_t start, /* start rtext to allocate */ - xfs_rtxlen_t len, /* length to allocate */ - struct xfs_buf **rbpp, /* in/out: summary block buffer */ - xfs_fileoff_t *rsb) /* in/out: summary block number */ + struct xfs_rtalloc_args *args, + xfs_rtxnum_t start, /* start rtext to allocate */ + xfs_rtxlen_t len, /* length to allocate */ + struct xfs_buf **rbpp, /* in/out: summary block buffer */ + xfs_fileoff_t *rsb) /* in/out: summary block number */ { - xfs_rtxnum_t end; /* end of the allocated rtext */ - int error; /* error value */ - xfs_rtxnum_t postblock = 0; /* first rtext allocated > end */ - xfs_rtxnum_t preblock = 0; /* first rtext allocated < start */ + struct xfs_mount *mp = args->mp; + xfs_rtxnum_t end; /* end of the allocated rtext */ + int error; + xfs_rtxnum_t postblock = 0; /* first rtext allocated > end */ + xfs_rtxnum_t preblock = 0; /* first rtext allocated < start */ end = start + len - 1; /* @@ -159,14 +157,14 @@ xfs_rtallocate_range( * We need to find the beginning and end of the extent so we can * properly update the summary. */ - error = xfs_rtfind_back(mp, tp, start, 0, &preblock); + error = xfs_rtfind_back(args, start, 0, &preblock); if (error) { return error; } /* * Find the next allocated block (end of free extent). */ - error = xfs_rtfind_forw(mp, tp, end, mp->m_sb.sb_rextents - 1, + error = xfs_rtfind_forw(args, end, mp->m_sb.sb_rextents - 1, &postblock); if (error) { return error; @@ -175,7 +173,7 @@ xfs_rtallocate_range( * Decrement the summary information corresponding to the entire * (old) free extent. */ - error = xfs_rtmodify_summary(mp, tp, + error = xfs_rtmodify_summary(args, XFS_RTBLOCKLOG(postblock + 1 - preblock), xfs_rtx_to_rbmblock(mp, preblock), -1, rbpp, rsb); if (error) { @@ -186,7 +184,7 @@ xfs_rtallocate_range( * old extent, add summary data for them to be free. */ if (preblock < start) { - error = xfs_rtmodify_summary(mp, tp, + error = xfs_rtmodify_summary(args, XFS_RTBLOCKLOG(start - preblock), xfs_rtx_to_rbmblock(mp, preblock), 1, rbpp, rsb); if (error) { @@ -198,7 +196,7 @@ xfs_rtallocate_range( * old extent, add summary data for them to be free. */ if (postblock > end) { - error = xfs_rtmodify_summary(mp, tp, + error = xfs_rtmodify_summary(args, XFS_RTBLOCKLOG(postblock - end), xfs_rtx_to_rbmblock(mp, end + 1), 1, rbpp, rsb); if (error) { @@ -208,7 +206,7 @@ xfs_rtallocate_range( /* * Modify the bitmap to mark this extent allocated. */ - error = xfs_rtmodify_range(mp, tp, start, len, 0); + error = xfs_rtmodify_range(args, start, len, 0); return error; } @@ -235,27 +233,27 @@ xfs_rtallocate_clamp_len( * the length, if given. Returns error; returns starting block in *rtx. * The lengths are all in rtextents. */ -STATIC int /* error */ +STATIC int xfs_rtallocate_extent_block( - xfs_mount_t *mp, /* file system mount point */ - xfs_trans_t *tp, /* transaction pointer */ - xfs_fileoff_t bbno, /* bitmap block number */ - xfs_rtxlen_t minlen, /* minimum length to allocate */ - xfs_rtxlen_t maxlen, /* maximum length to allocate */ - xfs_rtxlen_t *len, /* out: actual length allocated */ - xfs_rtxnum_t *nextp, /* out: next rtext to try */ - struct xfs_buf **rbpp, /* in/out: summary block buffer */ - xfs_fileoff_t *rsb, /* in/out: summary block number */ - xfs_rtxlen_t prod, /* extent product factor */ - xfs_rtxnum_t *rtx) /* out: start rtext allocated */ + struct xfs_rtalloc_args *args, + xfs_fileoff_t bbno, /* bitmap block number */ + xfs_rtxlen_t minlen, /* minimum length to allocate */ + xfs_rtxlen_t maxlen, /* maximum length to allocate */ + xfs_rtxlen_t *len, /* out: actual length allocated */ + xfs_rtxnum_t *nextp, /* out: next rtext to try */ + struct xfs_buf **rbpp, /* in/out: summary block buffer */ + xfs_fileoff_t *rsb, /* in/out: summary block number */ + xfs_rtxlen_t prod, /* extent product factor */ + xfs_rtxnum_t *rtx) /* out: start rtext allocated */ { - xfs_rtxnum_t besti; /* best rtext found so far */ - xfs_rtxnum_t bestlen; /* best length found so far */ - xfs_rtxnum_t end; /* last rtext in chunk */ - int error; /* error value */ - xfs_rtxnum_t i; /* current rtext trying */ - xfs_rtxnum_t next; /* next rtext to try */ - int stat; /* status from internal calls */ + struct xfs_mount *mp = args->mp; + xfs_rtxnum_t besti; /* best rtext found so far */ + xfs_rtxnum_t bestlen;/* best length found so far */ + xfs_rtxnum_t end; /* last rtext in chunk */ + int error; + xfs_rtxnum_t i; /* current rtext trying */ + xfs_rtxnum_t next; /* next rtext to try */ + int stat; /* status from internal calls */ /* * Loop over all the extents starting in this bitmap block, @@ -272,7 +270,7 @@ xfs_rtallocate_extent_block( * See if there's a free extent of maxlen starting at i. * If it's not so then next will contain the first non-free. */ - error = xfs_rtcheck_range(mp, tp, i, maxlen, 1, &next, &stat); + error = xfs_rtcheck_range(args, i, maxlen, 1, &next, &stat); if (error) { return error; } @@ -280,7 +278,7 @@ xfs_rtallocate_extent_block( /* * i for maxlen is all free, allocate and return that. */ - error = xfs_rtallocate_range(mp, tp, i, maxlen, rbpp, + error = xfs_rtallocate_range(args, i, maxlen, rbpp, rsb); if (error) { return error; @@ -308,7 +306,7 @@ xfs_rtallocate_extent_block( * If not done yet, find the start of the next free space. */ if (next < end) { - error = xfs_rtfind_forw(mp, tp, next, end, &i); + error = xfs_rtfind_forw(args, next, end, &i); if (error) { return error; } @@ -333,7 +331,7 @@ xfs_rtallocate_extent_block( /* * Allocate besti for bestlen & return that. */ - error = xfs_rtallocate_range(mp, tp, besti, bestlen, rbpp, rsb); + error = xfs_rtallocate_range(args, besti, bestlen, rbpp, rsb); if (error) { return error; } @@ -355,30 +353,29 @@ xfs_rtallocate_extent_block( * Returns error; returns starting block in *rtx. * The lengths are all in rtextents. */ -STATIC int /* error */ +STATIC int xfs_rtallocate_extent_exact( - xfs_mount_t *mp, /* file system mount point */ - xfs_trans_t *tp, /* transaction pointer */ - xfs_rtxnum_t start, /* starting rtext number to allocate */ - xfs_rtxlen_t minlen, /* minimum length to allocate */ - xfs_rtxlen_t maxlen, /* maximum length to allocate */ - xfs_rtxlen_t *len, /* out: actual length allocated */ - struct xfs_buf **rbpp, /* in/out: summary block buffer */ - xfs_fileoff_t *rsb, /* in/out: summary block number */ - xfs_rtxlen_t prod, /* extent product factor */ - xfs_rtxnum_t *rtx) /* out: start rtext allocated */ + struct xfs_rtalloc_args *args, + xfs_rtxnum_t start, /* starting rtext number to allocate */ + xfs_rtxlen_t minlen, /* minimum length to allocate */ + xfs_rtxlen_t maxlen, /* maximum length to allocate */ + xfs_rtxlen_t *len, /* out: actual length allocated */ + struct xfs_buf **rbpp, /* in/out: summary block buffer */ + xfs_fileoff_t *rsb, /* in/out: summary block number */ + xfs_rtxlen_t prod, /* extent product factor */ + xfs_rtxnum_t *rtx) /* out: start rtext allocated */ { - int error; /* error value */ - xfs_rtxlen_t i; /* extent length trimmed due to prod */ - int isfree; /* extent is free */ - xfs_rtxnum_t next; /* next rtext to try (dummy) */ + int error; + xfs_rtxlen_t i; /* extent length trimmed due to prod */ + int isfree; /* extent is free */ + xfs_rtxnum_t next; /* next rtext to try (dummy) */ ASSERT(minlen % prod == 0); ASSERT(maxlen % prod == 0); /* * Check if the range in question (for maxlen) is free. */ - error = xfs_rtcheck_range(mp, tp, start, maxlen, 1, &next, &isfree); + error = xfs_rtcheck_range(args, start, maxlen, 1, &next, &isfree); if (error) { return error; } @@ -386,7 +383,7 @@ xfs_rtallocate_extent_exact( /* * If it is, allocate it and return success. */ - error = xfs_rtallocate_range(mp, tp, start, maxlen, rbpp, rsb); + error = xfs_rtallocate_range(args, start, maxlen, rbpp, rsb); if (error) { return error; } @@ -421,7 +418,7 @@ xfs_rtallocate_extent_exact( /* * Allocate what we can and return it. */ - error = xfs_rtallocate_range(mp, tp, start, maxlen, rbpp, rsb); + error = xfs_rtallocate_range(args, start, maxlen, rbpp, rsb); if (error) { return error; } @@ -435,27 +432,27 @@ xfs_rtallocate_extent_exact( * to start as possible. If we don't get maxlen then use prod to trim * the length, if given. The lengths are all in rtextents. */ -STATIC int /* error */ +STATIC int xfs_rtallocate_extent_near( - xfs_mount_t *mp, /* file system mount point */ - xfs_trans_t *tp, /* transaction pointer */ - xfs_rtxnum_t start, /* starting rtext number to allocate */ - xfs_rtxlen_t minlen, /* minimum length to allocate */ - xfs_rtxlen_t maxlen, /* maximum length to allocate */ - xfs_rtxlen_t *len, /* out: actual length allocated */ - struct xfs_buf **rbpp, /* in/out: summary block buffer */ - xfs_fileoff_t *rsb, /* in/out: summary block number */ - xfs_rtxlen_t prod, /* extent product factor */ - xfs_rtxnum_t *rtx) /* out: start rtext allocated */ + struct xfs_rtalloc_args *args, + xfs_rtxnum_t start, /* starting rtext number to allocate */ + xfs_rtxlen_t minlen, /* minimum length to allocate */ + xfs_rtxlen_t maxlen, /* maximum length to allocate */ + xfs_rtxlen_t *len, /* out: actual length allocated */ + struct xfs_buf **rbpp, /* in/out: summary block buffer */ + xfs_fileoff_t *rsb, /* in/out: summary block number */ + xfs_rtxlen_t prod, /* extent product factor */ + xfs_rtxnum_t *rtx) /* out: start rtext allocated */ { - int any; /* any useful extents from summary */ - xfs_fileoff_t bbno; /* bitmap block number */ - int error; /* error value */ - int i; /* bitmap block offset (loop control) */ - int j; /* secondary loop control */ - int log2len; /* log2 of minlen */ - xfs_rtxnum_t n; /* next rtext to try */ - xfs_rtxnum_t r; /* result rtext */ + struct xfs_mount *mp = args->mp; + int any; /* any useful extents from summary */ + xfs_fileoff_t bbno; /* bitmap block number */ + int error; + int i; /* bitmap block offset (loop control) */ + int j; /* secondary loop control */ + int log2len; /* log2 of minlen */ + xfs_rtxnum_t n; /* next rtext to try */ + xfs_rtxnum_t r; /* result rtext */ ASSERT(minlen % prod == 0); ASSERT(maxlen % prod == 0); @@ -477,8 +474,8 @@ xfs_rtallocate_extent_near( /* * Try the exact allocation first. */ - error = xfs_rtallocate_extent_exact(mp, tp, start, minlen, maxlen, len, - rbpp, rsb, prod, &r); + error = xfs_rtallocate_extent_exact(args, start, minlen, maxlen, len, + rbpp, rsb, prod, &r); if (error) { return error; } @@ -501,7 +498,7 @@ xfs_rtallocate_extent_near( * Get summary information of extents of all useful levels * starting in this bitmap block. */ - error = xfs_rtany_summary(mp, tp, log2len, mp->m_rsumlevels - 1, + error = xfs_rtany_summary(args, log2len, mp->m_rsumlevels - 1, bbno + i, rbpp, rsb, &any); if (error) { return error; @@ -519,7 +516,7 @@ xfs_rtallocate_extent_near( * Try to allocate an extent starting in * this block. */ - error = xfs_rtallocate_extent_block(mp, tp, + error = xfs_rtallocate_extent_block(args, bbno + i, minlen, maxlen, len, &n, rbpp, rsb, prod, &r); if (error) { @@ -548,7 +545,7 @@ xfs_rtallocate_extent_near( * Grab the summary information for * this bitmap block. */ - error = xfs_rtany_summary(mp, tp, + error = xfs_rtany_summary(args, log2len, mp->m_rsumlevels - 1, bbno + j, rbpp, rsb, &any); if (error) { @@ -564,8 +561,8 @@ xfs_rtallocate_extent_near( */ if (any) continue; - error = xfs_rtallocate_extent_block(mp, - tp, bbno + j, minlen, maxlen, + error = xfs_rtallocate_extent_block(args, + bbno + j, minlen, maxlen, len, &n, rbpp, rsb, prod, &r); if (error) { return error; @@ -586,7 +583,7 @@ xfs_rtallocate_extent_near( * Try to allocate from the summary block * that we found. */ - error = xfs_rtallocate_extent_block(mp, tp, + error = xfs_rtallocate_extent_block(args, bbno + i, minlen, maxlen, len, &n, rbpp, rsb, prod, &r); if (error) { @@ -640,24 +637,24 @@ xfs_rtallocate_extent_near( * specified. If we don't get maxlen then use prod to trim * the length, if given. The lengths are all in rtextents. */ -STATIC int /* error */ +STATIC int xfs_rtallocate_extent_size( - xfs_mount_t *mp, /* file system mount point */ - xfs_trans_t *tp, /* transaction pointer */ - xfs_rtxlen_t minlen, /* minimum length to allocate */ - xfs_rtxlen_t maxlen, /* maximum length to allocate */ - xfs_rtxlen_t *len, /* out: actual length allocated */ - struct xfs_buf **rbpp, /* in/out: summary block buffer */ - xfs_fileoff_t *rsb, /* in/out: summary block number */ - xfs_rtxlen_t prod, /* extent product factor */ - xfs_rtxnum_t *rtx) /* out: start rtext allocated */ + struct xfs_rtalloc_args *args, + xfs_rtxlen_t minlen, /* minimum length to allocate */ + xfs_rtxlen_t maxlen, /* maximum length to allocate */ + xfs_rtxlen_t *len, /* out: actual length allocated */ + struct xfs_buf **rbpp, /* in/out: summary block buffer */ + xfs_fileoff_t *rsb, /* in/out: summary block number */ + xfs_rtxlen_t prod, /* extent product factor */ + xfs_rtxnum_t *rtx) /* out: start rtext allocated */ { - int error; /* error value */ - xfs_fileoff_t i; /* bitmap block number */ - int l; /* level number (loop control) */ - xfs_rtxnum_t n; /* next rtext to be tried */ - xfs_rtxnum_t r; /* result rtext number */ - xfs_suminfo_t sum; /* summary information for extents */ + struct xfs_mount *mp = args->mp; + int error; + xfs_fileoff_t i; /* bitmap block number */ + int l; /* level number (loop control) */ + xfs_rtxnum_t n; /* next rtext to be tried */ + xfs_rtxnum_t r; /* result rtext number */ + xfs_suminfo_t sum; /* summary information for extents */ ASSERT(minlen % prod == 0); ASSERT(maxlen % prod == 0); @@ -678,7 +675,7 @@ xfs_rtallocate_extent_size( /* * Get the summary for this level/block. */ - error = xfs_rtget_summary(mp, tp, l, i, rbpp, rsb, + error = xfs_rtget_summary(args, l, i, rbpp, rsb, &sum); if (error) { return error; @@ -691,7 +688,7 @@ xfs_rtallocate_extent_size( /* * Try allocating the extent. */ - error = xfs_rtallocate_extent_block(mp, tp, i, maxlen, + error = xfs_rtallocate_extent_block(args, i, maxlen, maxlen, len, &n, rbpp, rsb, prod, &r); if (error) { return error; @@ -737,7 +734,7 @@ xfs_rtallocate_extent_size( /* * Get the summary information for this level/block. */ - error = xfs_rtget_summary(mp, tp, l, i, rbpp, rsb, + error = xfs_rtget_summary(args, l, i, rbpp, rsb, &sum); if (error) { return error; @@ -752,7 +749,7 @@ xfs_rtallocate_extent_size( * minlen/maxlen are in the possible range for * this summary level. */ - error = xfs_rtallocate_extent_block(mp, tp, i, + error = xfs_rtallocate_extent_block(args, i, XFS_RTMAX(minlen, 1 << l), XFS_RTMIN(maxlen, (1 << (l + 1)) - 1), len, &n, rbpp, rsb, prod, &r); @@ -1044,6 +1041,12 @@ xfs_growfs_rt( ((sbp->sb_rextents & ((1 << mp->m_blkbit_log) - 1)) != 0); bmbno < nrbmblocks; bmbno++) { + struct xfs_rtalloc_args args = { + .mp = mp, + }; + struct xfs_rtalloc_args nargs = { + .mp = nmp, + }; struct xfs_trans *tp; xfs_rfsblock_t nrblocks_step; @@ -1072,6 +1075,9 @@ xfs_growfs_rt( &tp); if (error) break; + args.tp = tp; + nargs.tp = tp; + /* * Lock out other callers by grabbing the bitmap inode lock. */ @@ -1105,7 +1111,7 @@ xfs_growfs_rt( */ if (sbp->sb_rbmblocks != nsbp->sb_rbmblocks || mp->m_rsumlevels != nmp->m_rsumlevels) { - error = xfs_rtcopy_summary(mp, nmp, tp); + error = xfs_rtcopy_summary(&args, &nargs); if (error) goto error_cancel; } @@ -1131,7 +1137,7 @@ xfs_growfs_rt( * Free new extent. */ bp = NULL; - error = xfs_rtfree_range(nmp, tp, sbp->sb_rextents, + error = xfs_rtfree_range(&nargs, sbp->sb_rextents, nsbp->sb_rextents - sbp->sb_rextents, &bp, &sumbno); if (error) { error_cancel: @@ -1190,24 +1196,27 @@ out_free: * parameters. The length units are all in realtime extents, as is the * result block number. */ -int /* error */ +int xfs_rtallocate_extent( - xfs_trans_t *tp, /* transaction pointer */ - xfs_rtxnum_t start, /* starting rtext number to allocate */ - xfs_rtxlen_t minlen, /* minimum length to allocate */ - xfs_rtxlen_t maxlen, /* maximum length to allocate */ - xfs_rtxlen_t *len, /* out: actual length allocated */ - int wasdel, /* was a delayed allocation extent */ - xfs_rtxlen_t prod, /* extent product factor */ - xfs_rtxnum_t *rtblock) /* out: start rtext allocated */ + struct xfs_trans *tp, + xfs_rtxnum_t start, /* starting rtext number to allocate */ + xfs_rtxlen_t minlen, /* minimum length to allocate */ + xfs_rtxlen_t maxlen, /* maximum length to allocate */ + xfs_rtxlen_t *len, /* out: actual length allocated */ + int wasdel, /* was a delayed allocation extent */ + xfs_rtxlen_t prod, /* extent product factor */ + xfs_rtxnum_t *rtblock) /* out: start rtext allocated */ { - xfs_mount_t *mp = tp->t_mountp; - int error; /* error value */ - xfs_rtxnum_t r; /* result allocated rtext */ - xfs_fileoff_t sb; /* summary file block number */ - struct xfs_buf *sumbp; /* summary file block buffer */ + struct xfs_rtalloc_args args = { + .mp = tp->t_mountp, + .tp = tp, + }; + int error; + xfs_rtxnum_t r; /* result allocated rtext */ + xfs_fileoff_t sb; /* summary file block number */ + struct xfs_buf *sumbp; /* summary file block buffer */ - ASSERT(xfs_isilocked(mp->m_rbmip, XFS_ILOCK_EXCL)); + ASSERT(xfs_isilocked(args.mp->m_rbmip, XFS_ILOCK_EXCL)); ASSERT(minlen > 0 && minlen <= maxlen); /* @@ -1229,11 +1238,11 @@ xfs_rtallocate_extent( retry: sumbp = NULL; if (start == 0) { - error = xfs_rtallocate_extent_size(mp, tp, minlen, maxlen, len, - &sumbp, &sb, prod, &r); + error = xfs_rtallocate_extent_size(&args, minlen, + maxlen, len, &sumbp, &sb, prod, &r); } else { - error = xfs_rtallocate_extent_near(mp, tp, start, minlen, maxlen, - len, &sumbp, &sb, prod, &r); + error = xfs_rtallocate_extent_near(&args, start, minlen, + maxlen, len, &sumbp, &sb, prod, &r); } if (error) -- cgit v1.2.3 From e94b53ff699c2674a9ec083342a5254866210ade Mon Sep 17 00:00:00 2001 From: Omar Sandoval Date: Mon, 16 Oct 2023 10:13:22 -0700 Subject: xfs: cache last bitmap block in realtime allocator Profiling a workload on a highly fragmented realtime device showed a ton of CPU cycles being spent in xfs_trans_read_buf() called by xfs_rtbuf_get(). Further tracing showed that much of that was repeated calls to xfs_rtbuf_get() for the same block of the realtime bitmap. These come from xfs_rtallocate_extent_block(): as it walks through ranges of free bits in the bitmap, each call to xfs_rtcheck_range() and xfs_rtfind_{forw,back}() gets the same bitmap block. If the bitmap block is very fragmented, then this is _a lot_ of buffer lookups. The realtime allocator already passes around a cache of the last used realtime summary block to avoid repeated reads (the parameters rbpp and rsb). We can do the same for the realtime bitmap. This replaces rbpp and rsb with a struct xfs_rtbuf_cache, which caches the most recently used block for both the realtime bitmap and summary. xfs_rtbuf_get() now handles the caching instead of the callers, which requires plumbing xfs_rtbuf_cache to more functions but also makes sure we don't miss anything. Signed-off-by: Omar Sandoval Reviewed-by: Darrick J. Wong Signed-off-by: Darrick J. Wong Reviewed-by: Christoph Hellwig --- fs/xfs/libxfs/xfs_rtbitmap.c | 147 ++++++++++++++++++++++--------------------- fs/xfs/libxfs/xfs_rtbitmap.h | 17 +++-- fs/xfs/scrub/rtsummary.c | 4 +- fs/xfs/xfs_rtalloc.c | 111 +++++++++++++------------------- 4 files changed, 135 insertions(+), 144 deletions(-) (limited to 'fs/xfs') diff --git a/fs/xfs/libxfs/xfs_rtbitmap.c b/fs/xfs/libxfs/xfs_rtbitmap.c index 07841969ada9..5a2d5eaaba57 100644 --- a/fs/xfs/libxfs/xfs_rtbitmap.c +++ b/fs/xfs/libxfs/xfs_rtbitmap.c @@ -47,6 +47,23 @@ const struct xfs_buf_ops xfs_rtbuf_ops = { .verify_write = xfs_rtbuf_verify_write, }; +/* Release cached rt bitmap and summary buffers. */ +void +xfs_rtbuf_cache_relse( + struct xfs_rtalloc_args *args) +{ + if (args->rbmbp) { + xfs_trans_brelse(args->tp, args->rbmbp); + args->rbmbp = NULL; + args->rbmoff = NULLFILEOFF; + } + if (args->sumbp) { + xfs_trans_brelse(args->tp, args->sumbp); + args->sumbp = NULL; + args->sumoff = NULLFILEOFF; + } +} + /* * Get a buffer for the bitmap or summary file block specified. * The buffer is returned read and locked. @@ -59,13 +76,42 @@ xfs_rtbuf_get( struct xfs_buf **bpp) /* output: buffer for the block */ { struct xfs_mount *mp = args->mp; + struct xfs_buf **cbpp; /* cached block buffer */ + xfs_fileoff_t *coffp; /* cached block number */ struct xfs_buf *bp; /* block buffer, result */ struct xfs_inode *ip; /* bitmap or summary inode */ struct xfs_bmbt_irec map; + enum xfs_blft type; int nmap = 1; int error; - ip = issum ? mp->m_rsumip : mp->m_rbmip; + if (issum) { + cbpp = &args->sumbp; + coffp = &args->sumoff; + ip = mp->m_rsumip; + type = XFS_BLFT_RTSUMMARY_BUF; + } else { + cbpp = &args->rbmbp; + coffp = &args->rbmoff; + ip = mp->m_rbmip; + type = XFS_BLFT_RTBITMAP_BUF; + } + + /* + * If we have a cached buffer, and the block number matches, use that. + */ + if (*cbpp && *coffp == block) { + *bpp = *cbpp; + return 0; + } + /* + * Otherwise we have to have to get the buffer. If there was an old + * one, get rid of it first. + */ + if (*cbpp) { + xfs_trans_brelse(args->tp, *cbpp); + *cbpp = NULL; + } error = xfs_bmapi_read(ip, block, 1, &map, &nmap, 0); if (error) @@ -81,9 +127,9 @@ xfs_rtbuf_get( if (error) return error; - xfs_trans_buf_set_type(args->tp, bp, issum ? XFS_BLFT_RTSUMMARY_BUF - : XFS_BLFT_RTBITMAP_BUF); - *bpp = bp; + xfs_trans_buf_set_type(args->tp, bp, type); + *cbpp = *bpp = bp; + *coffp = block; return 0; } @@ -153,7 +199,6 @@ xfs_rtfind_back( /* * Different. Mark where we are and return. */ - xfs_trans_brelse(args->tp, bp); i = bit - XFS_RTHIBIT(wdiff); *rtx = start - i + 1; return 0; @@ -167,7 +212,6 @@ xfs_rtfind_back( /* * If done with this block, get the previous one. */ - xfs_trans_brelse(args->tp, bp); error = xfs_rtbuf_get(args, --block, 0, &bp); if (error) { return error; @@ -194,7 +238,6 @@ xfs_rtfind_back( /* * Different, mark where we are and return. */ - xfs_trans_brelse(args->tp, bp); i += XFS_NBWORD - 1 - XFS_RTHIBIT(wdiff); *rtx = start - i + 1; return 0; @@ -208,7 +251,6 @@ xfs_rtfind_back( /* * If done with this block, get the previous one. */ - xfs_trans_brelse(args->tp, bp); error = xfs_rtbuf_get(args, --block, 0, &bp); if (error) { return error; @@ -236,7 +278,6 @@ xfs_rtfind_back( /* * Different, mark where we are and return. */ - xfs_trans_brelse(args->tp, bp); i += XFS_NBWORD - 1 - XFS_RTHIBIT(wdiff); *rtx = start - i + 1; return 0; @@ -246,7 +287,6 @@ xfs_rtfind_back( /* * No match, return that we scanned the whole area. */ - xfs_trans_brelse(args->tp, bp); *rtx = start - i + 1; return 0; } @@ -316,7 +356,6 @@ xfs_rtfind_forw( /* * Different. Mark where we are and return. */ - xfs_trans_brelse(args->tp, bp); i = XFS_RTLOBIT(wdiff) - bit; *rtx = start + i - 1; return 0; @@ -330,7 +369,6 @@ xfs_rtfind_forw( /* * If done with this block, get the previous one. */ - xfs_trans_brelse(args->tp, bp); error = xfs_rtbuf_get(args, ++block, 0, &bp); if (error) { return error; @@ -357,7 +395,6 @@ xfs_rtfind_forw( /* * Different, mark where we are and return. */ - xfs_trans_brelse(args->tp, bp); i += XFS_RTLOBIT(wdiff); *rtx = start + i - 1; return 0; @@ -371,7 +408,6 @@ xfs_rtfind_forw( /* * If done with this block, get the next one. */ - xfs_trans_brelse(args->tp, bp); error = xfs_rtbuf_get(args, ++block, 0, &bp); if (error) { return error; @@ -397,7 +433,6 @@ xfs_rtfind_forw( /* * Different, mark where we are and return. */ - xfs_trans_brelse(args->tp, bp); i += XFS_RTLOBIT(wdiff); *rtx = start + i - 1; return 0; @@ -407,7 +442,6 @@ xfs_rtfind_forw( /* * No match, return that we scanned the whole area. */ - xfs_trans_brelse(args->tp, bp); *rtx = start + i - 1; return 0; } @@ -442,8 +476,6 @@ xfs_rtmodify_summary_int( int log, /* log2 of extent size */ xfs_fileoff_t bbno, /* bitmap block number */ int delta, /* change to make to summary info */ - struct xfs_buf **rbpp, /* in/out: summary block buffer */ - xfs_fileoff_t *rsb, /* in/out: summary block number */ xfs_suminfo_t *sum) /* out: summary info for this block */ { struct xfs_mount *mp = args->mp; @@ -461,30 +493,11 @@ xfs_rtmodify_summary_int( * Compute the block number in the summary file. */ sb = xfs_rtsumoffs_to_block(mp, so); - /* - * If we have an old buffer, and the block number matches, use that. - */ - if (*rbpp && *rsb == sb) - bp = *rbpp; - /* - * Otherwise we have to get the buffer. - */ - else { - /* - * If there was an old one, get rid of it first. - */ - if (*rbpp) - xfs_trans_brelse(args->tp, *rbpp); - error = xfs_rtbuf_get(args, sb, 1, &bp); - if (error) { - return error; - } - /* - * Remember this buffer and block for the next call. - */ - *rbpp = bp; - *rsb = sb; - } + + error = xfs_rtbuf_get(args, sb, 1, &bp); + if (error) + return error; + /* * Point to the summary information, modify/log it, and/or copy it out. */ @@ -512,11 +525,9 @@ xfs_rtmodify_summary( struct xfs_rtalloc_args *args, int log, /* log2 of extent size */ xfs_fileoff_t bbno, /* bitmap block number */ - int delta, /* change to make to summary info */ - struct xfs_buf **rbpp, /* in/out: summary block buffer */ - xfs_fileoff_t *rsb) /* in/out: summary block number */ + int delta) /* in/out: summary block number */ { - return xfs_rtmodify_summary_int(args, log, bbno, delta, rbpp, rsb, NULL); + return xfs_rtmodify_summary_int(args, log, bbno, delta, NULL); } /* Log rtbitmap block from the word @from to the byte before @next. */ @@ -687,9 +698,7 @@ int xfs_rtfree_range( struct xfs_rtalloc_args *args, xfs_rtxnum_t start, /* starting rtext to free */ - xfs_rtxlen_t len, /* length to free */ - struct xfs_buf **rbpp, /* in/out: summary block buffer */ - xfs_fileoff_t *rsb) /* in/out: summary block number */ + xfs_rtxlen_t len) /* in/out: summary block number */ { struct xfs_mount *mp = args->mp; xfs_rtxnum_t end; /* end of the freed extent */ @@ -718,7 +727,7 @@ xfs_rtfree_range( * Find the next allocated block (end of allocated extent). */ error = xfs_rtfind_forw(args, end, mp->m_sb.sb_rextents - 1, - &postblock); + &postblock); if (error) return error; /* @@ -727,8 +736,8 @@ xfs_rtfree_range( */ if (preblock < start) { error = xfs_rtmodify_summary(args, - XFS_RTBLOCKLOG(start - preblock), - xfs_rtx_to_rbmblock(mp, preblock), -1, rbpp, rsb); + XFS_RTBLOCKLOG(start - preblock), + xfs_rtx_to_rbmblock(mp, preblock), -1); if (error) { return error; } @@ -739,8 +748,8 @@ xfs_rtfree_range( */ if (postblock > end) { error = xfs_rtmodify_summary(args, - XFS_RTBLOCKLOG(postblock - end), - xfs_rtx_to_rbmblock(mp, end + 1), -1, rbpp, rsb); + XFS_RTBLOCKLOG(postblock - end), + xfs_rtx_to_rbmblock(mp, end + 1), -1); if (error) { return error; } @@ -749,10 +758,9 @@ xfs_rtfree_range( * Increment the summary information corresponding to the entire * (new) free extent. */ - error = xfs_rtmodify_summary(args, - XFS_RTBLOCKLOG(postblock + 1 - preblock), - xfs_rtx_to_rbmblock(mp, preblock), 1, rbpp, rsb); - return error; + return xfs_rtmodify_summary(args, + XFS_RTBLOCKLOG(postblock + 1 - preblock), + xfs_rtx_to_rbmblock(mp, preblock), 1); } /* @@ -822,7 +830,6 @@ xfs_rtcheck_range( /* * Different, compute first wrong bit and return. */ - xfs_trans_brelse(args->tp, bp); i = XFS_RTLOBIT(wdiff) - bit; *new = start + i; *stat = 0; @@ -837,7 +844,6 @@ xfs_rtcheck_range( /* * If done with this block, get the next one. */ - xfs_trans_brelse(args->tp, bp); error = xfs_rtbuf_get(args, ++block, 0, &bp); if (error) { return error; @@ -864,7 +870,6 @@ xfs_rtcheck_range( /* * Different, compute first wrong bit and return. */ - xfs_trans_brelse(args->tp, bp); i += XFS_RTLOBIT(wdiff); *new = start + i; *stat = 0; @@ -879,7 +884,6 @@ xfs_rtcheck_range( /* * If done with this block, get the next one. */ - xfs_trans_brelse(args->tp, bp); error = xfs_rtbuf_get(args, ++block, 0, &bp); if (error) { return error; @@ -905,7 +909,6 @@ xfs_rtcheck_range( /* * Different, compute first wrong bit and return. */ - xfs_trans_brelse(args->tp, bp); i += XFS_RTLOBIT(wdiff); *new = start + i; *stat = 0; @@ -916,7 +919,6 @@ xfs_rtcheck_range( /* * Successful, return. */ - xfs_trans_brelse(args->tp, bp); *new = start + i; *stat = 1; return 0; @@ -961,8 +963,6 @@ xfs_rtfree_extent( .tp = tp, }; int error; - xfs_fsblock_t sb; /* summary file block number */ - struct xfs_buf *sumbp = NULL; /* summary file block buffer */ ASSERT(mp->m_rbmip->i_itemp != NULL); ASSERT(xfs_isilocked(mp->m_rbmip, XFS_ILOCK_EXCL)); @@ -974,10 +974,10 @@ xfs_rtfree_extent( /* * Free the range of realtime blocks. */ - error = xfs_rtfree_range(&args, start, len, &sumbp, &sb); - if (error) { - return error; - } + error = xfs_rtfree_range(&args, start, len); + if (error) + goto out; + /* * Mark more blocks free in the superblock. */ @@ -993,7 +993,10 @@ xfs_rtfree_extent( *(uint64_t *)&VFS_I(mp->m_rbmip)->i_atime = 0; xfs_trans_log_inode(tp, mp->m_rbmip, XFS_ILOG_CORE); } - return 0; + error = 0; +out: + xfs_rtbuf_cache_relse(&args); + return error; } /* @@ -1084,6 +1087,7 @@ xfs_rtalloc_query_range( rtstart = rtend + 1; } + xfs_rtbuf_cache_relse(&args); return error; } @@ -1122,6 +1126,7 @@ xfs_rtalloc_extent_is_free( int error; error = xfs_rtcheck_range(&args, start, len, 1, &end, &matches); + xfs_rtbuf_cache_relse(&args); if (error) return error; diff --git a/fs/xfs/libxfs/xfs_rtbitmap.h b/fs/xfs/libxfs/xfs_rtbitmap.h index 52aa301aba7b..253f5b763a6c 100644 --- a/fs/xfs/libxfs/xfs_rtbitmap.h +++ b/fs/xfs/libxfs/xfs_rtbitmap.h @@ -9,6 +9,12 @@ struct xfs_rtalloc_args { struct xfs_mount *mp; struct xfs_trans *tp; + + struct xfs_buf *rbmbp; /* bitmap block buffer */ + struct xfs_buf *sumbp; /* summary block buffer */ + + xfs_fileoff_t rbmoff; /* bitmap block number */ + xfs_fileoff_t sumoff; /* summary block number */ }; static inline xfs_rtblock_t @@ -286,6 +292,8 @@ typedef int (*xfs_rtalloc_query_range_fn)( void *priv); #ifdef CONFIG_XFS_RT +void xfs_rtbuf_cache_relse(struct xfs_rtalloc_args *args); + int xfs_rtbuf_get(struct xfs_rtalloc_args *args, xfs_fileoff_t block, int issum, struct xfs_buf **bpp); int xfs_rtcheck_range(struct xfs_rtalloc_args *args, xfs_rtxnum_t start, @@ -297,13 +305,11 @@ int xfs_rtfind_forw(struct xfs_rtalloc_args *args, xfs_rtxnum_t start, int xfs_rtmodify_range(struct xfs_rtalloc_args *args, xfs_rtxnum_t start, xfs_rtxlen_t len, int val); int xfs_rtmodify_summary_int(struct xfs_rtalloc_args *args, int log, - xfs_fileoff_t bbno, int delta, struct xfs_buf **rbpp, - xfs_fileoff_t *rsb, xfs_suminfo_t *sum); + xfs_fileoff_t bbno, int delta, xfs_suminfo_t *sum); int xfs_rtmodify_summary(struct xfs_rtalloc_args *args, int log, - xfs_fileoff_t bbno, int delta, struct xfs_buf **rbpp, - xfs_fileoff_t *rsb); + xfs_fileoff_t bbno, int delta); int xfs_rtfree_range(struct xfs_rtalloc_args *args, xfs_rtxnum_t start, - xfs_rtxlen_t len, struct xfs_buf **rbpp, xfs_fileoff_t *rsb); + xfs_rtxlen_t len); int xfs_rtalloc_query_range(struct xfs_mount *mp, struct xfs_trans *tp, const struct xfs_rtalloc_rec *low_rec, const struct xfs_rtalloc_rec *high_rec, @@ -343,6 +349,7 @@ unsigned long long xfs_rtsummary_wordcount(struct xfs_mount *mp, # define xfs_rtalloc_query_range(m,t,l,h,f,p) (-ENOSYS) # define xfs_rtalloc_query_all(m,t,f,p) (-ENOSYS) # define xfs_rtbuf_get(m,t,b,i,p) (-ENOSYS) +# define xfs_rtbuf_cache_relse(a) (0) # define xfs_rtalloc_extent_is_free(m,t,s,l,i) (-ENOSYS) static inline xfs_filblks_t xfs_rtbitmap_blockcount(struct xfs_mount *mp, xfs_rtbxlen_t rtextents) diff --git a/fs/xfs/scrub/rtsummary.c b/fs/xfs/scrub/rtsummary.c index 10e83196301c..ec17385fe4b0 100644 --- a/fs/xfs/scrub/rtsummary.c +++ b/fs/xfs/scrub/rtsummary.c @@ -228,7 +228,7 @@ xchk_rtsum_compare( /* Read a block's worth of computed rtsummary file. */ error = xfsum_copyout(sc, sumoff, sc->buf, mp->m_blockwsize); if (error) { - xfs_trans_brelse(sc->tp, bp); + xfs_rtbuf_cache_relse(&args); return error; } @@ -237,7 +237,7 @@ xchk_rtsum_compare( mp->m_blockwsize << XFS_WORDLOG) != 0) xchk_fblock_set_corrupt(sc, XFS_DATA_FORK, off); - xfs_trans_brelse(sc->tp, bp); + xfs_rtbuf_cache_relse(&args); sumoff += mp->m_blockwsize; } diff --git a/fs/xfs/xfs_rtalloc.c b/fs/xfs/xfs_rtalloc.c index 73d3280fbe36..d5b6be45755f 100644 --- a/fs/xfs/xfs_rtalloc.c +++ b/fs/xfs/xfs_rtalloc.c @@ -32,11 +32,9 @@ xfs_rtget_summary( struct xfs_rtalloc_args *args, int log, /* log2 of extent size */ xfs_fileoff_t bbno, /* bitmap block number */ - struct xfs_buf **rbpp, /* in/out: summary block buffer */ - xfs_fileoff_t *rsb, /* in/out: summary block number */ xfs_suminfo_t *sum) /* out: summary info for this block */ { - return xfs_rtmodify_summary_int(args, log, bbno, 0, rbpp, rsb, sum); + return xfs_rtmodify_summary_int(args, log, bbno, 0, sum); } /* @@ -49,8 +47,6 @@ xfs_rtany_summary( int low, /* low log2 extent size */ int high, /* high log2 extent size */ xfs_fileoff_t bbno, /* bitmap block number */ - struct xfs_buf **rbpp, /* in/out: summary block buffer */ - xfs_fileoff_t *rsb, /* in/out: summary block number */ int *stat) /* out: any good extents here? */ { struct xfs_mount *mp = args->mp; @@ -69,7 +65,7 @@ xfs_rtany_summary( /* * Get one summary datum. */ - error = xfs_rtget_summary(args, log, bbno, rbpp, rsb, &sum); + error = xfs_rtget_summary(args, log, bbno, &sum); if (error) { return error; } @@ -103,34 +99,31 @@ xfs_rtcopy_summary( struct xfs_rtalloc_args *nargs) { xfs_fileoff_t bbno; /* bitmap block number */ - struct xfs_buf *bp; /* summary buffer */ int error; int log; /* summary level number (log length) */ xfs_suminfo_t sum; /* summary data */ - xfs_fileoff_t sumbno; /* summary block number */ - bp = NULL; for (log = oargs->mp->m_rsumlevels - 1; log >= 0; log--) { for (bbno = oargs->mp->m_sb.sb_rbmblocks - 1; (xfs_srtblock_t)bbno >= 0; bbno--) { - error = xfs_rtget_summary(oargs, log, bbno, &bp, - &sumbno, &sum); + error = xfs_rtget_summary(oargs, log, bbno, &sum); if (error) - return error; + goto out; if (sum == 0) continue; - error = xfs_rtmodify_summary(oargs, log, bbno, -sum, - &bp, &sumbno); + error = xfs_rtmodify_summary(oargs, log, bbno, -sum); if (error) - return error; - error = xfs_rtmodify_summary(nargs, log, bbno, sum, - &bp, &sumbno); + goto out; + error = xfs_rtmodify_summary(nargs, log, bbno, sum); if (error) - return error; + goto out; ASSERT(sum > 0); } } + error = 0; +out: + xfs_rtbuf_cache_relse(oargs); return 0; } /* @@ -141,9 +134,7 @@ STATIC int xfs_rtallocate_range( struct xfs_rtalloc_args *args, xfs_rtxnum_t start, /* start rtext to allocate */ - xfs_rtxlen_t len, /* length to allocate */ - struct xfs_buf **rbpp, /* in/out: summary block buffer */ - xfs_fileoff_t *rsb) /* in/out: summary block number */ + xfs_rtxlen_t len) /* in/out: summary block number */ { struct xfs_mount *mp = args->mp; xfs_rtxnum_t end; /* end of the allocated rtext */ @@ -165,7 +156,7 @@ xfs_rtallocate_range( * Find the next allocated block (end of free extent). */ error = xfs_rtfind_forw(args, end, mp->m_sb.sb_rextents - 1, - &postblock); + &postblock); if (error) { return error; } @@ -174,8 +165,8 @@ xfs_rtallocate_range( * (old) free extent. */ error = xfs_rtmodify_summary(args, - XFS_RTBLOCKLOG(postblock + 1 - preblock), - xfs_rtx_to_rbmblock(mp, preblock), -1, rbpp, rsb); + XFS_RTBLOCKLOG(postblock + 1 - preblock), + xfs_rtx_to_rbmblock(mp, preblock), -1); if (error) { return error; } @@ -185,8 +176,8 @@ xfs_rtallocate_range( */ if (preblock < start) { error = xfs_rtmodify_summary(args, - XFS_RTBLOCKLOG(start - preblock), - xfs_rtx_to_rbmblock(mp, preblock), 1, rbpp, rsb); + XFS_RTBLOCKLOG(start - preblock), + xfs_rtx_to_rbmblock(mp, preblock), 1); if (error) { return error; } @@ -197,8 +188,8 @@ xfs_rtallocate_range( */ if (postblock > end) { error = xfs_rtmodify_summary(args, - XFS_RTBLOCKLOG(postblock - end), - xfs_rtx_to_rbmblock(mp, end + 1), 1, rbpp, rsb); + XFS_RTBLOCKLOG(postblock - end), + xfs_rtx_to_rbmblock(mp, end + 1), 1); if (error) { return error; } @@ -241,8 +232,6 @@ xfs_rtallocate_extent_block( xfs_rtxlen_t maxlen, /* maximum length to allocate */ xfs_rtxlen_t *len, /* out: actual length allocated */ xfs_rtxnum_t *nextp, /* out: next rtext to try */ - struct xfs_buf **rbpp, /* in/out: summary block buffer */ - xfs_fileoff_t *rsb, /* in/out: summary block number */ xfs_rtxlen_t prod, /* extent product factor */ xfs_rtxnum_t *rtx) /* out: start rtext allocated */ { @@ -278,8 +267,7 @@ xfs_rtallocate_extent_block( /* * i for maxlen is all free, allocate and return that. */ - error = xfs_rtallocate_range(args, i, maxlen, rbpp, - rsb); + error = xfs_rtallocate_range(args, i, maxlen); if (error) { return error; } @@ -331,7 +319,7 @@ xfs_rtallocate_extent_block( /* * Allocate besti for bestlen & return that. */ - error = xfs_rtallocate_range(args, besti, bestlen, rbpp, rsb); + error = xfs_rtallocate_range(args, besti, bestlen); if (error) { return error; } @@ -360,8 +348,6 @@ xfs_rtallocate_extent_exact( xfs_rtxlen_t minlen, /* minimum length to allocate */ xfs_rtxlen_t maxlen, /* maximum length to allocate */ xfs_rtxlen_t *len, /* out: actual length allocated */ - struct xfs_buf **rbpp, /* in/out: summary block buffer */ - xfs_fileoff_t *rsb, /* in/out: summary block number */ xfs_rtxlen_t prod, /* extent product factor */ xfs_rtxnum_t *rtx) /* out: start rtext allocated */ { @@ -383,7 +369,7 @@ xfs_rtallocate_extent_exact( /* * If it is, allocate it and return success. */ - error = xfs_rtallocate_range(args, start, maxlen, rbpp, rsb); + error = xfs_rtallocate_range(args, start, maxlen); if (error) { return error; } @@ -418,7 +404,7 @@ xfs_rtallocate_extent_exact( /* * Allocate what we can and return it. */ - error = xfs_rtallocate_range(args, start, maxlen, rbpp, rsb); + error = xfs_rtallocate_range(args, start, maxlen); if (error) { return error; } @@ -439,8 +425,6 @@ xfs_rtallocate_extent_near( xfs_rtxlen_t minlen, /* minimum length to allocate */ xfs_rtxlen_t maxlen, /* maximum length to allocate */ xfs_rtxlen_t *len, /* out: actual length allocated */ - struct xfs_buf **rbpp, /* in/out: summary block buffer */ - xfs_fileoff_t *rsb, /* in/out: summary block number */ xfs_rtxlen_t prod, /* extent product factor */ xfs_rtxnum_t *rtx) /* out: start rtext allocated */ { @@ -475,7 +459,7 @@ xfs_rtallocate_extent_near( * Try the exact allocation first. */ error = xfs_rtallocate_extent_exact(args, start, minlen, maxlen, len, - rbpp, rsb, prod, &r); + prod, &r); if (error) { return error; } @@ -499,7 +483,7 @@ xfs_rtallocate_extent_near( * starting in this bitmap block. */ error = xfs_rtany_summary(args, log2len, mp->m_rsumlevels - 1, - bbno + i, rbpp, rsb, &any); + bbno + i, &any); if (error) { return error; } @@ -517,8 +501,8 @@ xfs_rtallocate_extent_near( * this block. */ error = xfs_rtallocate_extent_block(args, - bbno + i, minlen, maxlen, len, &n, rbpp, - rsb, prod, &r); + bbno + i, minlen, maxlen, len, + &n, prod, &r); if (error) { return error; } @@ -546,8 +530,9 @@ xfs_rtallocate_extent_near( * this bitmap block. */ error = xfs_rtany_summary(args, - log2len, mp->m_rsumlevels - 1, - bbno + j, rbpp, rsb, &any); + log2len, + mp->m_rsumlevels - 1, + bbno + j, &any); if (error) { return error; } @@ -562,8 +547,9 @@ xfs_rtallocate_extent_near( if (any) continue; error = xfs_rtallocate_extent_block(args, - bbno + j, minlen, maxlen, - len, &n, rbpp, rsb, prod, &r); + bbno + j, minlen, + maxlen, len, &n, prod, + &r); if (error) { return error; } @@ -584,8 +570,8 @@ xfs_rtallocate_extent_near( * that we found. */ error = xfs_rtallocate_extent_block(args, - bbno + i, minlen, maxlen, len, &n, rbpp, - rsb, prod, &r); + bbno + i, minlen, maxlen, len, + &n, prod, &r); if (error) { return error; } @@ -643,8 +629,6 @@ xfs_rtallocate_extent_size( xfs_rtxlen_t minlen, /* minimum length to allocate */ xfs_rtxlen_t maxlen, /* maximum length to allocate */ xfs_rtxlen_t *len, /* out: actual length allocated */ - struct xfs_buf **rbpp, /* in/out: summary block buffer */ - xfs_fileoff_t *rsb, /* in/out: summary block number */ xfs_rtxlen_t prod, /* extent product factor */ xfs_rtxnum_t *rtx) /* out: start rtext allocated */ { @@ -675,8 +659,7 @@ xfs_rtallocate_extent_size( /* * Get the summary for this level/block. */ - error = xfs_rtget_summary(args, l, i, rbpp, rsb, - &sum); + error = xfs_rtget_summary(args, l, i, &sum); if (error) { return error; } @@ -689,7 +672,7 @@ xfs_rtallocate_extent_size( * Try allocating the extent. */ error = xfs_rtallocate_extent_block(args, i, maxlen, - maxlen, len, &n, rbpp, rsb, prod, &r); + maxlen, len, &n, prod, &r); if (error) { return error; } @@ -734,8 +717,7 @@ xfs_rtallocate_extent_size( /* * Get the summary information for this level/block. */ - error = xfs_rtget_summary(args, l, i, rbpp, rsb, - &sum); + error = xfs_rtget_summary(args, l, i, &sum); if (error) { return error; } @@ -752,7 +734,7 @@ xfs_rtallocate_extent_size( error = xfs_rtallocate_extent_block(args, i, XFS_RTMAX(minlen, 1 << l), XFS_RTMIN(maxlen, (1 << (l + 1)) - 1), - len, &n, rbpp, rsb, prod, &r); + len, &n, prod, &r); if (error) { return error; } @@ -941,7 +923,6 @@ xfs_growfs_rt( xfs_extlen_t rbmblocks; /* current number of rt bitmap blocks */ xfs_extlen_t rsumblocks; /* current number of rt summary blks */ xfs_sb_t *sbp; /* old superblock */ - xfs_fileoff_t sumbno; /* summary block number */ uint8_t *rsum_cache; /* old summary cache */ sbp = &mp->m_sb; @@ -1136,9 +1117,9 @@ xfs_growfs_rt( /* * Free new extent. */ - bp = NULL; error = xfs_rtfree_range(&nargs, sbp->sb_rextents, - nsbp->sb_rextents - sbp->sb_rextents, &bp, &sumbno); + nsbp->sb_rextents - sbp->sb_rextents); + xfs_rtbuf_cache_relse(&nargs); if (error) { error_cancel: xfs_trans_cancel(tp); @@ -1211,10 +1192,8 @@ xfs_rtallocate_extent( .mp = tp->t_mountp, .tp = tp, }; - int error; + int error; /* error value */ xfs_rtxnum_t r; /* result allocated rtext */ - xfs_fileoff_t sb; /* summary file block number */ - struct xfs_buf *sumbp; /* summary file block buffer */ ASSERT(xfs_isilocked(args.mp->m_rbmip, XFS_ILOCK_EXCL)); ASSERT(minlen > 0 && minlen <= maxlen); @@ -1236,15 +1215,15 @@ xfs_rtallocate_extent( } retry: - sumbp = NULL; if (start == 0) { error = xfs_rtallocate_extent_size(&args, minlen, - maxlen, len, &sumbp, &sb, prod, &r); + maxlen, len, prod, &r); } else { error = xfs_rtallocate_extent_near(&args, start, minlen, - maxlen, len, &sumbp, &sb, prod, &r); + maxlen, len, prod, &r); } + xfs_rtbuf_cache_relse(&args); if (error) return error; -- cgit v1.2.3 From 5b1d0ae9753f0654ab56c1e06155b3abf2919d71 Mon Sep 17 00:00:00 2001 From: "Darrick J. Wong" Date: Wed, 18 Oct 2023 10:19:41 -0700 Subject: xfs: simplify xfs_rtbuf_get calling conventions Now that xfs_rtalloc_args holds references to the last-read bitmap and summary blocks, we don't need to pass the buffer pointer out of xfs_rtbuf_get. Callers no longer have to xfs_trans_brelse on their own, though they are required to call xfs_rtbuf_cache_relse before the xfs_rtalloc_args goes out of scope. While we're at it, create some trivial helpers so that we don't have to remember if "0" means "bitmap" and "1" means "summary". Signed-off-by: Darrick J. Wong Reviewed-by: Christoph Hellwig --- fs/xfs/libxfs/xfs_rtbitmap.c | 115 ++++++++++++++++++------------------------- fs/xfs/libxfs/xfs_rtbitmap.h | 22 ++++++++- fs/xfs/scrub/rtsummary.c | 5 +- 3 files changed, 71 insertions(+), 71 deletions(-) (limited to 'fs/xfs') diff --git a/fs/xfs/libxfs/xfs_rtbitmap.c b/fs/xfs/libxfs/xfs_rtbitmap.c index 5a2d5eaaba57..9867a6f8f56e 100644 --- a/fs/xfs/libxfs/xfs_rtbitmap.c +++ b/fs/xfs/libxfs/xfs_rtbitmap.c @@ -72,8 +72,7 @@ int xfs_rtbuf_get( struct xfs_rtalloc_args *args, xfs_fileoff_t block, /* block number in bitmap or summary */ - int issum, /* is summary not bitmap */ - struct xfs_buf **bpp) /* output: buffer for the block */ + int issum) /* is summary not bitmap */ { struct xfs_mount *mp = args->mp; struct xfs_buf **cbpp; /* cached block buffer */ @@ -100,10 +99,9 @@ xfs_rtbuf_get( /* * If we have a cached buffer, and the block number matches, use that. */ - if (*cbpp && *coffp == block) { - *bpp = *cbpp; + if (*cbpp && *coffp == block) return 0; - } + /* * Otherwise we have to have to get the buffer. If there was an old * one, get rid of it first. @@ -128,7 +126,7 @@ xfs_rtbuf_get( return error; xfs_trans_buf_set_type(args->tp, bp, type); - *cbpp = *bpp = bp; + *cbpp = bp; *coffp = block; return 0; } @@ -147,7 +145,6 @@ xfs_rtfind_back( struct xfs_mount *mp = args->mp; int bit; /* bit number in the word */ xfs_fileoff_t block; /* bitmap block number */ - struct xfs_buf *bp; /* buf for the block */ int error; /* error value */ xfs_rtxnum_t firstbit; /* first useful bit in the word */ xfs_rtxnum_t i; /* current bit number rel. to start */ @@ -162,10 +159,9 @@ xfs_rtfind_back( * Compute and read in starting bitmap block for starting block. */ block = xfs_rtx_to_rbmblock(mp, start); - error = xfs_rtbuf_get(args, block, 0, &bp); - if (error) { + error = xfs_rtbitmap_read_buf(args, block); + if (error) return error; - } /* * Get the first word's index & point to it. @@ -177,7 +173,7 @@ xfs_rtfind_back( * Compute match value, based on the bit at start: if 1 (free) * then all-ones, else all-zeroes. */ - incore = xfs_rtbitmap_getword(bp, word); + incore = xfs_rtbitmap_getword(args->rbmbp, word); want = (incore & ((xfs_rtword_t)1 << bit)) ? -1 : 0; /* * If the starting position is not word-aligned, deal with the @@ -212,10 +208,9 @@ xfs_rtfind_back( /* * If done with this block, get the previous one. */ - error = xfs_rtbuf_get(args, --block, 0, &bp); - if (error) { + error = xfs_rtbitmap_read_buf(args, --block); + if (error) return error; - } word = mp->m_blockwsize - 1; } @@ -233,7 +228,7 @@ xfs_rtfind_back( /* * Compute difference between actual and desired value. */ - incore = xfs_rtbitmap_getword(bp, word); + incore = xfs_rtbitmap_getword(args->rbmbp, word); if ((wdiff = incore ^ want)) { /* * Different, mark where we are and return. @@ -251,10 +246,9 @@ xfs_rtfind_back( /* * If done with this block, get the previous one. */ - error = xfs_rtbuf_get(args, --block, 0, &bp); - if (error) { + error = xfs_rtbitmap_read_buf(args, --block); + if (error) return error; - } word = mp->m_blockwsize - 1; } @@ -273,7 +267,7 @@ xfs_rtfind_back( /* * Compute difference between actual and desired value. */ - incore = xfs_rtbitmap_getword(bp, word); + incore = xfs_rtbitmap_getword(args->rbmbp, word); if ((wdiff = (incore ^ want) & mask)) { /* * Different, mark where we are and return. @@ -305,7 +299,6 @@ xfs_rtfind_forw( struct xfs_mount *mp = args->mp; int bit; /* bit number in the word */ xfs_fileoff_t block; /* bitmap block number */ - struct xfs_buf *bp; /* buf for the block */ int error; xfs_rtxnum_t i; /* current bit number rel. to start */ xfs_rtxnum_t lastbit;/* last useful bit in the word */ @@ -320,10 +313,9 @@ xfs_rtfind_forw( * Compute and read in starting bitmap block for starting block. */ block = xfs_rtx_to_rbmblock(mp, start); - error = xfs_rtbuf_get(args, block, 0, &bp); - if (error) { + error = xfs_rtbitmap_read_buf(args, block); + if (error) return error; - } /* * Get the first word's index & point to it. @@ -335,7 +327,7 @@ xfs_rtfind_forw( * Compute match value, based on the bit at start: if 1 (free) * then all-ones, else all-zeroes. */ - incore = xfs_rtbitmap_getword(bp, word); + incore = xfs_rtbitmap_getword(args->rbmbp, word); want = (incore & ((xfs_rtword_t)1 << bit)) ? -1 : 0; /* * If the starting position is not word-aligned, deal with the @@ -369,10 +361,9 @@ xfs_rtfind_forw( /* * If done with this block, get the previous one. */ - error = xfs_rtbuf_get(args, ++block, 0, &bp); - if (error) { + error = xfs_rtbitmap_read_buf(args, ++block); + if (error) return error; - } word = 0; } @@ -390,7 +381,7 @@ xfs_rtfind_forw( /* * Compute difference between actual and desired value. */ - incore = xfs_rtbitmap_getword(bp, word); + incore = xfs_rtbitmap_getword(args->rbmbp, word); if ((wdiff = incore ^ want)) { /* * Different, mark where we are and return. @@ -408,10 +399,9 @@ xfs_rtfind_forw( /* * If done with this block, get the next one. */ - error = xfs_rtbuf_get(args, ++block, 0, &bp); - if (error) { + error = xfs_rtbitmap_read_buf(args, ++block); + if (error) return error; - } word = 0; } @@ -428,7 +418,7 @@ xfs_rtfind_forw( /* * Compute difference between actual and desired value. */ - incore = xfs_rtbitmap_getword(bp, word); + incore = xfs_rtbitmap_getword(args->rbmbp, word); if ((wdiff = (incore ^ want) & mask)) { /* * Different, mark where we are and return. @@ -479,7 +469,6 @@ xfs_rtmodify_summary_int( xfs_suminfo_t *sum) /* out: summary info for this block */ { struct xfs_mount *mp = args->mp; - struct xfs_buf *bp; /* buffer for the summary block */ int error; xfs_fileoff_t sb; /* summary fsblock */ xfs_rtsumoff_t so; /* index into the summary file */ @@ -494,7 +483,7 @@ xfs_rtmodify_summary_int( */ sb = xfs_rtsumoffs_to_block(mp, so); - error = xfs_rtbuf_get(args, sb, 1, &bp); + error = xfs_rtsummary_read_buf(args, sb); if (error) return error; @@ -503,7 +492,8 @@ xfs_rtmodify_summary_int( */ infoword = xfs_rtsumoffs_to_infoword(mp, so); if (delta) { - xfs_suminfo_t val = xfs_suminfo_add(bp, infoword, delta); + xfs_suminfo_t val = xfs_suminfo_add(args->sumbp, infoword, + delta); if (mp->m_rsum_cache) { if (val == 0 && log == mp->m_rsum_cache[bbno]) @@ -511,11 +501,11 @@ xfs_rtmodify_summary_int( if (val != 0 && log < mp->m_rsum_cache[bbno]) mp->m_rsum_cache[bbno] = log; } - xfs_trans_log_rtsummary(args->tp, bp, infoword); + xfs_trans_log_rtsummary(args->tp, args->sumbp, infoword); if (sum) *sum = val; } else if (sum) { - *sum = xfs_suminfo_get(bp, infoword); + *sum = xfs_suminfo_get(args->sumbp, infoword); } return 0; } @@ -560,7 +550,6 @@ xfs_rtmodify_range( struct xfs_mount *mp = args->mp; int bit; /* bit number in the word */ xfs_fileoff_t block; /* bitmap block number */ - struct xfs_buf *bp; /* buf for the block */ int error; int i; /* current bit number rel. to start */ int lastbit; /* last useful bit in word */ @@ -576,10 +565,9 @@ xfs_rtmodify_range( /* * Read the bitmap block, and point to its data. */ - error = xfs_rtbuf_get(args, block, 0, &bp); - if (error) { + error = xfs_rtbitmap_read_buf(args, block); + if (error) return error; - } /* * Compute the starting word's address, and starting bit. @@ -603,12 +591,12 @@ xfs_rtmodify_range( /* * Set/clear the active bits. */ - incore = xfs_rtbitmap_getword(bp, word); + incore = xfs_rtbitmap_getword(args->rbmbp, word); if (val) incore |= mask; else incore &= ~mask; - xfs_rtbitmap_setword(bp, word, incore); + xfs_rtbitmap_setword(args->rbmbp, word, incore); i = lastbit - bit; /* * Go on to the next block if that's where the next word is @@ -619,12 +607,11 @@ xfs_rtmodify_range( * Log the changed part of this block. * Get the next one. */ - xfs_trans_log_rtbitmap(args->tp, bp, firstword, + xfs_trans_log_rtbitmap(args->tp, args->rbmbp, firstword, word); - error = xfs_rtbuf_get(args, ++block, 0, &bp); - if (error) { + error = xfs_rtbitmap_read_buf(args, ++block); + if (error) return error; - } firstword = word = 0; } @@ -642,7 +629,7 @@ xfs_rtmodify_range( /* * Set the word value correctly. */ - xfs_rtbitmap_setword(bp, word, val); + xfs_rtbitmap_setword(args->rbmbp, word, val); i += XFS_NBWORD; /* * Go on to the next block if that's where the next word is @@ -653,9 +640,9 @@ xfs_rtmodify_range( * Log the changed part of this block. * Get the next one. */ - xfs_trans_log_rtbitmap(args->tp, bp, firstword, + xfs_trans_log_rtbitmap(args->tp, args->rbmbp, firstword, word); - error = xfs_rtbuf_get(args, ++block, 0, &bp); + error = xfs_rtbitmap_read_buf(args, ++block); if (error) return error; @@ -674,19 +661,19 @@ xfs_rtmodify_range( /* * Set/clear the active bits. */ - incore = xfs_rtbitmap_getword(bp, word); + incore = xfs_rtbitmap_getword(args->rbmbp, word); if (val) incore |= mask; else incore &= ~mask; - xfs_rtbitmap_setword(bp, word, incore); + xfs_rtbitmap_setword(args->rbmbp, word, incore); word++; } /* * Log any remaining changed bytes. */ if (word > firstword) - xfs_trans_log_rtbitmap(args->tp, bp, firstword, word); + xfs_trans_log_rtbitmap(args->tp, args->rbmbp, firstword, word); return 0; } @@ -779,7 +766,6 @@ xfs_rtcheck_range( struct xfs_mount *mp = args->mp; int bit; /* bit number in the word */ xfs_fileoff_t block; /* bitmap block number */ - struct xfs_buf *bp; /* buf for the block */ int error; xfs_rtxnum_t i; /* current bit number rel. to start */ xfs_rtxnum_t lastbit; /* last useful bit in word */ @@ -795,10 +781,9 @@ xfs_rtcheck_range( /* * Read the bitmap block. */ - error = xfs_rtbuf_get(args, block, 0, &bp); - if (error) { + error = xfs_rtbitmap_read_buf(args, block); + if (error) return error; - } /* * Compute the starting word's address, and starting bit. @@ -825,7 +810,7 @@ xfs_rtcheck_range( /* * Compute difference between actual and desired value. */ - incore = xfs_rtbitmap_getword(bp, word); + incore = xfs_rtbitmap_getword(args->rbmbp, word); if ((wdiff = (incore ^ val) & mask)) { /* * Different, compute first wrong bit and return. @@ -844,10 +829,9 @@ xfs_rtcheck_range( /* * If done with this block, get the next one. */ - error = xfs_rtbuf_get(args, ++block, 0, &bp); - if (error) { + error = xfs_rtbitmap_read_buf(args, ++block); + if (error) return error; - } word = 0; } @@ -865,7 +849,7 @@ xfs_rtcheck_range( /* * Compute difference between actual and desired value. */ - incore = xfs_rtbitmap_getword(bp, word); + incore = xfs_rtbitmap_getword(args->rbmbp, word); if ((wdiff = incore ^ val)) { /* * Different, compute first wrong bit and return. @@ -884,10 +868,9 @@ xfs_rtcheck_range( /* * If done with this block, get the next one. */ - error = xfs_rtbuf_get(args, ++block, 0, &bp); - if (error) { + error = xfs_rtbitmap_read_buf(args, ++block); + if (error) return error; - } word = 0; } @@ -904,7 +887,7 @@ xfs_rtcheck_range( /* * Compute difference between actual and desired value. */ - incore = xfs_rtbitmap_getword(bp, word); + incore = xfs_rtbitmap_getword(args->rbmbp, word); if ((wdiff = (incore ^ val) & mask)) { /* * Different, compute first wrong bit and return. diff --git a/fs/xfs/libxfs/xfs_rtbitmap.h b/fs/xfs/libxfs/xfs_rtbitmap.h index 253f5b763a6c..3bda0c175812 100644 --- a/fs/xfs/libxfs/xfs_rtbitmap.h +++ b/fs/xfs/libxfs/xfs_rtbitmap.h @@ -295,7 +295,24 @@ typedef int (*xfs_rtalloc_query_range_fn)( void xfs_rtbuf_cache_relse(struct xfs_rtalloc_args *args); int xfs_rtbuf_get(struct xfs_rtalloc_args *args, xfs_fileoff_t block, - int issum, struct xfs_buf **bpp); + int issum); + +static inline int +xfs_rtbitmap_read_buf( + struct xfs_rtalloc_args *args, + xfs_fileoff_t block) +{ + return xfs_rtbuf_get(args, block, 0); +} + +static inline int +xfs_rtsummary_read_buf( + struct xfs_rtalloc_args *args, + xfs_fileoff_t block) +{ + return xfs_rtbuf_get(args, block, 1); +} + int xfs_rtcheck_range(struct xfs_rtalloc_args *args, xfs_rtxnum_t start, xfs_rtxlen_t len, int val, xfs_rtxnum_t *new, int *stat); int xfs_rtfind_back(struct xfs_rtalloc_args *args, xfs_rtxnum_t start, @@ -348,7 +365,8 @@ unsigned long long xfs_rtsummary_wordcount(struct xfs_mount *mp, # define xfs_rtfree_blocks(t,rb,rl) (-ENOSYS) # define xfs_rtalloc_query_range(m,t,l,h,f,p) (-ENOSYS) # define xfs_rtalloc_query_all(m,t,f,p) (-ENOSYS) -# define xfs_rtbuf_get(m,t,b,i,p) (-ENOSYS) +# define xfs_rtbitmap_read_buf(a,b) (-ENOSYS) +# define xfs_rtsummary_read_buf(a,b) (-ENOSYS) # define xfs_rtbuf_cache_relse(a) (0) # define xfs_rtalloc_extent_is_free(m,t,s,l,i) (-ENOSYS) static inline xfs_filblks_t diff --git a/fs/xfs/scrub/rtsummary.c b/fs/xfs/scrub/rtsummary.c index ec17385fe4b0..cc5ae050dfb2 100644 --- a/fs/xfs/scrub/rtsummary.c +++ b/fs/xfs/scrub/rtsummary.c @@ -193,7 +193,6 @@ xchk_rtsum_compare( .tp = sc->tp, }; struct xfs_mount *mp = sc->mp; - struct xfs_buf *bp; struct xfs_bmbt_irec map; xfs_fileoff_t off; xchk_rtsumoff_t sumoff = 0; @@ -221,7 +220,7 @@ xchk_rtsum_compare( } /* Read a block's worth of ondisk rtsummary file. */ - error = xfs_rtbuf_get(&args, off, 1, &bp); + error = xfs_rtsummary_read_buf(&args, off); if (!xchk_fblock_process_error(sc, XFS_DATA_FORK, off, &error)) return error; @@ -232,7 +231,7 @@ xchk_rtsum_compare( return error; } - ondisk_info = xfs_rsumblock_infoptr(bp, 0); + ondisk_info = xfs_rsumblock_infoptr(args.sumbp, 0); if (memcmp(ondisk_info, sc->buf, mp->m_blockwsize << XFS_WORDLOG) != 0) xchk_fblock_set_corrupt(sc, XFS_DATA_FORK, off); -- cgit v1.2.3 From e2cf427c91494ea0d1173a911090c39665c5fdef Mon Sep 17 00:00:00 2001 From: "Darrick J. Wong" Date: Wed, 18 Oct 2023 10:28:10 -0700 Subject: xfs: simplify rt bitmap/summary block accessor functions Simplify the calling convention of these functions since the xfs_rtalloc_args structure contains the parameters we need. Signed-off-by: Darrick J. Wong Reviewed-by: Christoph Hellwig --- fs/xfs/libxfs/xfs_rtbitmap.c | 61 +++++++++++++++++++++----------------------- fs/xfs/libxfs/xfs_rtbitmap.h | 24 ++++++++--------- fs/xfs/scrub/rtsummary.c | 2 +- 3 files changed, 42 insertions(+), 45 deletions(-) (limited to 'fs/xfs') diff --git a/fs/xfs/libxfs/xfs_rtbitmap.c b/fs/xfs/libxfs/xfs_rtbitmap.c index 9867a6f8f56e..9f806af4f720 100644 --- a/fs/xfs/libxfs/xfs_rtbitmap.c +++ b/fs/xfs/libxfs/xfs_rtbitmap.c @@ -173,7 +173,7 @@ xfs_rtfind_back( * Compute match value, based on the bit at start: if 1 (free) * then all-ones, else all-zeroes. */ - incore = xfs_rtbitmap_getword(args->rbmbp, word); + incore = xfs_rtbitmap_getword(args, word); want = (incore & ((xfs_rtword_t)1 << bit)) ? -1 : 0; /* * If the starting position is not word-aligned, deal with the @@ -228,7 +228,7 @@ xfs_rtfind_back( /* * Compute difference between actual and desired value. */ - incore = xfs_rtbitmap_getword(args->rbmbp, word); + incore = xfs_rtbitmap_getword(args, word); if ((wdiff = incore ^ want)) { /* * Different, mark where we are and return. @@ -267,7 +267,7 @@ xfs_rtfind_back( /* * Compute difference between actual and desired value. */ - incore = xfs_rtbitmap_getword(args->rbmbp, word); + incore = xfs_rtbitmap_getword(args, word); if ((wdiff = (incore ^ want) & mask)) { /* * Different, mark where we are and return. @@ -327,7 +327,7 @@ xfs_rtfind_forw( * Compute match value, based on the bit at start: if 1 (free) * then all-ones, else all-zeroes. */ - incore = xfs_rtbitmap_getword(args->rbmbp, word); + incore = xfs_rtbitmap_getword(args, word); want = (incore & ((xfs_rtword_t)1 << bit)) ? -1 : 0; /* * If the starting position is not word-aligned, deal with the @@ -381,7 +381,7 @@ xfs_rtfind_forw( /* * Compute difference between actual and desired value. */ - incore = xfs_rtbitmap_getword(args->rbmbp, word); + incore = xfs_rtbitmap_getword(args, word); if ((wdiff = incore ^ want)) { /* * Different, mark where we are and return. @@ -418,7 +418,7 @@ xfs_rtfind_forw( /* * Compute difference between actual and desired value. */ - incore = xfs_rtbitmap_getword(args->rbmbp, word); + incore = xfs_rtbitmap_getword(args, word); if ((wdiff = (incore ^ want) & mask)) { /* * Different, mark where we are and return. @@ -439,16 +439,16 @@ xfs_rtfind_forw( /* Log rtsummary counter at @infoword. */ static inline void xfs_trans_log_rtsummary( - struct xfs_trans *tp, - struct xfs_buf *bp, + struct xfs_rtalloc_args *args, unsigned int infoword) { + struct xfs_buf *bp = args->sumbp; size_t first, last; - first = (void *)xfs_rsumblock_infoptr(bp, infoword) - bp->b_addr; + first = (void *)xfs_rsumblock_infoptr(args, infoword) - bp->b_addr; last = first + sizeof(xfs_suminfo_t) - 1; - xfs_trans_log_buf(tp, bp, first, last); + xfs_trans_log_buf(args->tp, bp, first, last); } /* @@ -492,8 +492,7 @@ xfs_rtmodify_summary_int( */ infoword = xfs_rtsumoffs_to_infoword(mp, so); if (delta) { - xfs_suminfo_t val = xfs_suminfo_add(args->sumbp, infoword, - delta); + xfs_suminfo_t val = xfs_suminfo_add(args, infoword, delta); if (mp->m_rsum_cache) { if (val == 0 && log == mp->m_rsum_cache[bbno]) @@ -501,11 +500,11 @@ xfs_rtmodify_summary_int( if (val != 0 && log < mp->m_rsum_cache[bbno]) mp->m_rsum_cache[bbno] = log; } - xfs_trans_log_rtsummary(args->tp, args->sumbp, infoword); + xfs_trans_log_rtsummary(args, infoword); if (sum) *sum = val; } else if (sum) { - *sum = xfs_suminfo_get(args->sumbp, infoword); + *sum = xfs_suminfo_get(args, infoword); } return 0; } @@ -523,17 +522,17 @@ xfs_rtmodify_summary( /* Log rtbitmap block from the word @from to the byte before @next. */ static inline void xfs_trans_log_rtbitmap( - struct xfs_trans *tp, - struct xfs_buf *bp, + struct xfs_rtalloc_args *args, unsigned int from, unsigned int next) { + struct xfs_buf *bp = args->rbmbp; size_t first, last; - first = (void *)xfs_rbmblock_wordptr(bp, from) - bp->b_addr; - last = ((void *)xfs_rbmblock_wordptr(bp, next) - 1) - bp->b_addr; + first = (void *)xfs_rbmblock_wordptr(args, from) - bp->b_addr; + last = ((void *)xfs_rbmblock_wordptr(args, next) - 1) - bp->b_addr; - xfs_trans_log_buf(tp, bp, first, last); + xfs_trans_log_buf(args->tp, bp, first, last); } /* @@ -591,12 +590,12 @@ xfs_rtmodify_range( /* * Set/clear the active bits. */ - incore = xfs_rtbitmap_getword(args->rbmbp, word); + incore = xfs_rtbitmap_getword(args, word); if (val) incore |= mask; else incore &= ~mask; - xfs_rtbitmap_setword(args->rbmbp, word, incore); + xfs_rtbitmap_setword(args, word, incore); i = lastbit - bit; /* * Go on to the next block if that's where the next word is @@ -607,8 +606,7 @@ xfs_rtmodify_range( * Log the changed part of this block. * Get the next one. */ - xfs_trans_log_rtbitmap(args->tp, args->rbmbp, firstword, - word); + xfs_trans_log_rtbitmap(args, firstword, word); error = xfs_rtbitmap_read_buf(args, ++block); if (error) return error; @@ -629,7 +627,7 @@ xfs_rtmodify_range( /* * Set the word value correctly. */ - xfs_rtbitmap_setword(args->rbmbp, word, val); + xfs_rtbitmap_setword(args, word, val); i += XFS_NBWORD; /* * Go on to the next block if that's where the next word is @@ -640,8 +638,7 @@ xfs_rtmodify_range( * Log the changed part of this block. * Get the next one. */ - xfs_trans_log_rtbitmap(args->tp, args->rbmbp, firstword, - word); + xfs_trans_log_rtbitmap(args, firstword, word); error = xfs_rtbitmap_read_buf(args, ++block); if (error) return error; @@ -661,19 +658,19 @@ xfs_rtmodify_range( /* * Set/clear the active bits. */ - incore = xfs_rtbitmap_getword(args->rbmbp, word); + incore = xfs_rtbitmap_getword(args, word); if (val) incore |= mask; else incore &= ~mask; - xfs_rtbitmap_setword(args->rbmbp, word, incore); + xfs_rtbitmap_setword(args, word, incore); word++; } /* * Log any remaining changed bytes. */ if (word > firstword) - xfs_trans_log_rtbitmap(args->tp, args->rbmbp, firstword, word); + xfs_trans_log_rtbitmap(args, firstword, word); return 0; } @@ -810,7 +807,7 @@ xfs_rtcheck_range( /* * Compute difference between actual and desired value. */ - incore = xfs_rtbitmap_getword(args->rbmbp, word); + incore = xfs_rtbitmap_getword(args, word); if ((wdiff = (incore ^ val) & mask)) { /* * Different, compute first wrong bit and return. @@ -849,7 +846,7 @@ xfs_rtcheck_range( /* * Compute difference between actual and desired value. */ - incore = xfs_rtbitmap_getword(args->rbmbp, word); + incore = xfs_rtbitmap_getword(args, word); if ((wdiff = incore ^ val)) { /* * Different, compute first wrong bit and return. @@ -887,7 +884,7 @@ xfs_rtcheck_range( /* * Compute difference between actual and desired value. */ - incore = xfs_rtbitmap_getword(args->rbmbp, word); + incore = xfs_rtbitmap_getword(args, word); if ((wdiff = (incore ^ val) & mask)) { /* * Different, compute first wrong bit and return. diff --git a/fs/xfs/libxfs/xfs_rtbitmap.h b/fs/xfs/libxfs/xfs_rtbitmap.h index 3bda0c175812..c0637057d69c 100644 --- a/fs/xfs/libxfs/xfs_rtbitmap.h +++ b/fs/xfs/libxfs/xfs_rtbitmap.h @@ -172,10 +172,10 @@ xfs_rbmblock_to_rtx( /* Return a pointer to a bitmap word within a rt bitmap block. */ static inline union xfs_rtword_raw * xfs_rbmblock_wordptr( - struct xfs_buf *bp, + struct xfs_rtalloc_args *args, unsigned int index) { - union xfs_rtword_raw *words = bp->b_addr; + union xfs_rtword_raw *words = args->rbmbp->b_addr; return words + index; } @@ -183,10 +183,10 @@ xfs_rbmblock_wordptr( /* Convert an ondisk bitmap word to its incore representation. */ static inline xfs_rtword_t xfs_rtbitmap_getword( - struct xfs_buf *bp, + struct xfs_rtalloc_args *args, unsigned int index) { - union xfs_rtword_raw *word = xfs_rbmblock_wordptr(bp, index); + union xfs_rtword_raw *word = xfs_rbmblock_wordptr(args, index); return word->old; } @@ -194,11 +194,11 @@ xfs_rtbitmap_getword( /* Set an ondisk bitmap word from an incore representation. */ static inline void xfs_rtbitmap_setword( - struct xfs_buf *bp, + struct xfs_rtalloc_args *args, unsigned int index, xfs_rtword_t value) { - union xfs_rtword_raw *word = xfs_rbmblock_wordptr(bp, index); + union xfs_rtword_raw *word = xfs_rbmblock_wordptr(args, index); word->old = value; } @@ -245,10 +245,10 @@ xfs_rtsumoffs_to_infoword( /* Return a pointer to a summary info word within a rt summary block. */ static inline union xfs_suminfo_raw * xfs_rsumblock_infoptr( - struct xfs_buf *bp, + struct xfs_rtalloc_args *args, unsigned int index) { - union xfs_suminfo_raw *info = bp->b_addr; + union xfs_suminfo_raw *info = args->sumbp->b_addr; return info + index; } @@ -256,10 +256,10 @@ xfs_rsumblock_infoptr( /* Get the current value of a summary counter. */ static inline xfs_suminfo_t xfs_suminfo_get( - struct xfs_buf *bp, + struct xfs_rtalloc_args *args, unsigned int index) { - union xfs_suminfo_raw *info = xfs_rsumblock_infoptr(bp, index); + union xfs_suminfo_raw *info = xfs_rsumblock_infoptr(args, index); return info->old; } @@ -267,11 +267,11 @@ xfs_suminfo_get( /* Add to the current value of a summary counter and return the new value. */ static inline xfs_suminfo_t xfs_suminfo_add( - struct xfs_buf *bp, + struct xfs_rtalloc_args *args, unsigned int index, int delta) { - union xfs_suminfo_raw *info = xfs_rsumblock_infoptr(bp, index); + union xfs_suminfo_raw *info = xfs_rsumblock_infoptr(args, index); info->old += delta; return info->old; diff --git a/fs/xfs/scrub/rtsummary.c b/fs/xfs/scrub/rtsummary.c index cc5ae050dfb2..8b15c47408d0 100644 --- a/fs/xfs/scrub/rtsummary.c +++ b/fs/xfs/scrub/rtsummary.c @@ -231,7 +231,7 @@ xchk_rtsum_compare( return error; } - ondisk_info = xfs_rsumblock_infoptr(args.sumbp, 0); + ondisk_info = xfs_rsumblock_infoptr(&args, 0); if (memcmp(ondisk_info, sc->buf, mp->m_blockwsize << XFS_WORDLOG) != 0) xchk_fblock_set_corrupt(sc, XFS_DATA_FORK, off); -- cgit v1.2.3 From e23aaf450de733044a74bc95528f728478b61c2a Mon Sep 17 00:00:00 2001 From: Omar Sandoval Date: Mon, 16 Oct 2023 10:41:55 -0700 Subject: xfs: invert the realtime summary cache In commit 355e3532132b ("xfs: cache minimum realtime summary level"), I added a cache of the minimum level of the realtime summary that has any free extents. However, it turns out that the _maximum_ level is more useful for upcoming optimizations, and basically equivalent for the existing usage. So, let's change the meaning of the cache to be the maximum level + 1, or 0 if there are no free extents. For example, if the cache contains: {0, 4} then there are no free extents starting in realtime bitmap block 0, and there are no free extents larger than or equal to 2^4 blocks starting in realtime bitmap block 1. The cache is a loose upper bound, so there may or may not be free extents smaller than 2^4 blocks in realtime bitmap block 1. Signed-off-by: Omar Sandoval Reviewed-by: Darrick J. Wong Signed-off-by: Darrick J. Wong Reviewed-by: Christoph Hellwig --- fs/xfs/libxfs/xfs_rtbitmap.c | 6 +++--- fs/xfs/xfs_mount.h | 6 +++--- fs/xfs/xfs_rtalloc.c | 31 +++++++++++++++++++------------ 3 files changed, 25 insertions(+), 18 deletions(-) (limited to 'fs/xfs') diff --git a/fs/xfs/libxfs/xfs_rtbitmap.c b/fs/xfs/libxfs/xfs_rtbitmap.c index 9f806af4f720..b332ab490a48 100644 --- a/fs/xfs/libxfs/xfs_rtbitmap.c +++ b/fs/xfs/libxfs/xfs_rtbitmap.c @@ -495,10 +495,10 @@ xfs_rtmodify_summary_int( xfs_suminfo_t val = xfs_suminfo_add(args, infoword, delta); if (mp->m_rsum_cache) { - if (val == 0 && log == mp->m_rsum_cache[bbno]) - mp->m_rsum_cache[bbno]++; - if (val != 0 && log < mp->m_rsum_cache[bbno]) + if (val == 0 && log + 1 == mp->m_rsum_cache[bbno]) mp->m_rsum_cache[bbno] = log; + if (val != 0 && log >= mp->m_rsum_cache[bbno]) + mp->m_rsum_cache[bbno] = log + 1; } xfs_trans_log_rtsummary(args, infoword); if (sum) diff --git a/fs/xfs/xfs_mount.h b/fs/xfs/xfs_mount.h index d8769dc5f6dd..9cd1d570d24d 100644 --- a/fs/xfs/xfs_mount.h +++ b/fs/xfs/xfs_mount.h @@ -101,9 +101,9 @@ typedef struct xfs_mount { /* * Optional cache of rt summary level per bitmap block with the - * invariant that m_rsum_cache[bbno] <= the minimum i for which - * rsum[i][bbno] != 0. Reads and writes are serialized by the rsumip - * inode lock. + * invariant that m_rsum_cache[bbno] > the maximum i for which + * rsum[i][bbno] != 0, or 0 if rsum[i][bbno] == 0 for all i. + * Reads and writes are serialized by the rsumip inode lock. */ uint8_t *m_rsum_cache; struct xfs_mru_cache *m_filestream; /* per-mount filestream data */ diff --git a/fs/xfs/xfs_rtalloc.c b/fs/xfs/xfs_rtalloc.c index d5b6be45755f..6bde64584a37 100644 --- a/fs/xfs/xfs_rtalloc.c +++ b/fs/xfs/xfs_rtalloc.c @@ -54,14 +54,19 @@ xfs_rtany_summary( int log; /* loop counter, log2 of ext. size */ xfs_suminfo_t sum; /* summary data */ - /* There are no extents at levels < m_rsum_cache[bbno]. */ - if (mp->m_rsum_cache && low < mp->m_rsum_cache[bbno]) - low = mp->m_rsum_cache[bbno]; + /* There are no extents at levels >= m_rsum_cache[bbno]. */ + if (mp->m_rsum_cache) { + high = min(high, mp->m_rsum_cache[bbno] - 1); + if (low > high) { + *stat = 0; + return 0; + } + } /* * Loop over logs of extent sizes. */ - for (log = low; log <= high; log++) { + for (log = high; log >= low; log--) { /* * Get one summary datum. */ @@ -82,9 +87,9 @@ xfs_rtany_summary( */ *stat = 0; out: - /* There were no extents at levels < log. */ - if (mp->m_rsum_cache && log > mp->m_rsum_cache[bbno]) - mp->m_rsum_cache[bbno] = log; + /* There were no extents at levels > log. */ + if (mp->m_rsum_cache && log + 1 < mp->m_rsum_cache[bbno]) + mp->m_rsum_cache[bbno] = log + 1; return 0; } @@ -887,12 +892,14 @@ xfs_alloc_rsum_cache( xfs_extlen_t rbmblocks) /* number of rt bitmap blocks */ { /* - * The rsum cache is initialized to all zeroes, which is trivially a - * lower bound on the minimum level with any free extents. We can - * continue without the cache if it couldn't be allocated. + * The rsum cache is initialized to the maximum value, which is + * trivially an upper bound on the maximum level with any free extents. + * We can continue without the cache if it couldn't be allocated. */ - mp->m_rsum_cache = kvzalloc(rbmblocks, GFP_KERNEL); - if (!mp->m_rsum_cache) + mp->m_rsum_cache = kvmalloc(rbmblocks, GFP_KERNEL); + if (mp->m_rsum_cache) + memset(mp->m_rsum_cache, -1, rbmblocks); + else xfs_warn(mp, "could not allocate realtime summary cache"); } -- cgit v1.2.3 From 1b5d63963f9820b1c14883ee56b387586ff72aa0 Mon Sep 17 00:00:00 2001 From: Omar Sandoval Date: Mon, 16 Oct 2023 10:43:42 -0700 Subject: xfs: return maximum free size from xfs_rtany_summary() Instead of only returning whether there is any free space, return the maximum size, which is fast thanks to the previous commit. This will be used by two upcoming optimizations. Reviewed-by: Darrick J. Wong Signed-off-by: Omar Sandoval Signed-off-by: Darrick J. Wong Reviewed-by: Christoph Hellwig --- fs/xfs/xfs_rtalloc.c | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) (limited to 'fs/xfs') diff --git a/fs/xfs/xfs_rtalloc.c b/fs/xfs/xfs_rtalloc.c index 6bde64584a37..c774a4ccdd15 100644 --- a/fs/xfs/xfs_rtalloc.c +++ b/fs/xfs/xfs_rtalloc.c @@ -47,7 +47,7 @@ xfs_rtany_summary( int low, /* low log2 extent size */ int high, /* high log2 extent size */ xfs_fileoff_t bbno, /* bitmap block number */ - int *stat) /* out: any good extents here? */ + int *maxlog) /* out: max log2 extent size free */ { struct xfs_mount *mp = args->mp; int error; @@ -58,7 +58,7 @@ xfs_rtany_summary( if (mp->m_rsum_cache) { high = min(high, mp->m_rsum_cache[bbno] - 1); if (low > high) { - *stat = 0; + *maxlog = -1; return 0; } } @@ -78,14 +78,14 @@ xfs_rtany_summary( * If there are any, return success. */ if (sum) { - *stat = 1; + *maxlog = log; goto out; } } /* * Found nothing, return failure. */ - *stat = 0; + *maxlog = -1; out: /* There were no extents at levels > log. */ if (mp->m_rsum_cache && log + 1 < mp->m_rsum_cache[bbno]) @@ -434,7 +434,7 @@ xfs_rtallocate_extent_near( xfs_rtxnum_t *rtx) /* out: start rtext allocated */ { struct xfs_mount *mp = args->mp; - int any; /* any useful extents from summary */ + int maxlog; /* max useful extent from summary */ xfs_fileoff_t bbno; /* bitmap block number */ int error; int i; /* bitmap block offset (loop control) */ @@ -488,7 +488,7 @@ xfs_rtallocate_extent_near( * starting in this bitmap block. */ error = xfs_rtany_summary(args, log2len, mp->m_rsumlevels - 1, - bbno + i, &any); + bbno + i, &maxlog); if (error) { return error; } @@ -496,7 +496,7 @@ xfs_rtallocate_extent_near( * If there are any useful extents starting here, try * allocating one. */ - if (any) { + if (maxlog >= 0) { /* * On the positive side of the starting location. */ @@ -537,7 +537,7 @@ xfs_rtallocate_extent_near( error = xfs_rtany_summary(args, log2len, mp->m_rsumlevels - 1, - bbno + j, &any); + bbno + j, &maxlog); if (error) { return error; } @@ -549,7 +549,7 @@ xfs_rtallocate_extent_near( * extent given, we've already tried * that allocation, don't do it again. */ - if (any) + if (maxlog >= 0) continue; error = xfs_rtallocate_extent_block(args, bbno + j, minlen, -- cgit v1.2.3 From ec5857bf07639a03d32b8ecb346df634925f8bc2 Mon Sep 17 00:00:00 2001 From: Omar Sandoval Date: Mon, 16 Oct 2023 10:45:46 -0700 Subject: xfs: limit maxlen based on available space in xfs_rtallocate_extent_near() xfs_rtallocate_extent_near() calls xfs_rtallocate_extent_block() with the minlen and maxlen that were passed to it. xfs_rtallocate_extent_block() then scans the bitmap block looking for a free range of size maxlen. If there is none, it has to scan the whole bitmap block before returning the largest range of at least size minlen. For a fragmented realtime device and a large allocation request, it's almost certain that this will have to search the whole bitmap block, leading to high CPU usage. However, the realtime summary tells us the maximum size available in the bitmap block. We can limit the search in xfs_rtallocate_extent_block() to that size and often stop before scanning the whole bitmap block. Signed-off-by: Omar Sandoval Reviewed-by: Darrick J. Wong Signed-off-by: Darrick J. Wong Reviewed-by: Christoph Hellwig --- fs/xfs/xfs_rtalloc.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) (limited to 'fs/xfs') diff --git a/fs/xfs/xfs_rtalloc.c b/fs/xfs/xfs_rtalloc.c index c774a4ccdd15..3aa9634a9e76 100644 --- a/fs/xfs/xfs_rtalloc.c +++ b/fs/xfs/xfs_rtalloc.c @@ -497,6 +497,9 @@ xfs_rtallocate_extent_near( * allocating one. */ if (maxlog >= 0) { + xfs_extlen_t maxavail = + min_t(xfs_rtblock_t, maxlen, + (1ULL << (maxlog + 1)) - 1); /* * On the positive side of the starting location. */ @@ -506,7 +509,7 @@ xfs_rtallocate_extent_near( * this block. */ error = xfs_rtallocate_extent_block(args, - bbno + i, minlen, maxlen, len, + bbno + i, minlen, maxavail, len, &n, prod, &r); if (error) { return error; @@ -553,7 +556,7 @@ xfs_rtallocate_extent_near( continue; error = xfs_rtallocate_extent_block(args, bbno + j, minlen, - maxlen, len, &n, prod, + maxavail, len, &n, prod, &r); if (error) { return error; @@ -575,7 +578,7 @@ xfs_rtallocate_extent_near( * that we found. */ error = xfs_rtallocate_extent_block(args, - bbno + i, minlen, maxlen, len, + bbno + i, minlen, maxavail, len, &n, prod, &r); if (error) { return error; -- cgit v1.2.3 From 85fa2c774397b98f5dc65a4ed6ab17c1a15db158 Mon Sep 17 00:00:00 2001 From: Omar Sandoval Date: Mon, 16 Oct 2023 10:47:04 -0700 Subject: xfs: don't try redundant allocations in xfs_rtallocate_extent_near() xfs_rtallocate_extent_near() tries to find a free extent as close to a target bitmap block given by bbno as possible, which may be before or after bbno. Searching backwards has a complication: the realtime summary accounts for free space _starting_ in a bitmap block, but not straddling or ending in a bitmap block. So, when the negative search finds a free extent in the realtime summary, in order to end up closer to the target, it looks for the end of the free extent. For example, if bbno - 2 has a free extent, then it will check bbno - 1, then bbno - 2. But then if bbno - 3 has a free extent, it will check bbno - 1 again, then bbno - 2 again, and then bbno - 3. This results in a quadratic loop, which is completely pointless since the repeated checks won't find anything new. Fix it by remembering where we last checked up to and continue from there. This also obviates the need for a check of the realtime summary. Signed-off-by: Omar Sandoval Reviewed-by: Darrick J. Wong Signed-off-by: Darrick J. Wong Reviewed-by: Christoph Hellwig --- fs/xfs/xfs_rtalloc.c | 54 +++++++--------------------------------------------- 1 file changed, 7 insertions(+), 47 deletions(-) (limited to 'fs/xfs') diff --git a/fs/xfs/xfs_rtalloc.c b/fs/xfs/xfs_rtalloc.c index 3aa9634a9e76..b743da885ed6 100644 --- a/fs/xfs/xfs_rtalloc.c +++ b/fs/xfs/xfs_rtalloc.c @@ -477,6 +477,7 @@ xfs_rtallocate_extent_near( } bbno = xfs_rtx_to_rbmblock(mp, start); i = 0; + j = -1; ASSERT(minlen != 0); log2len = xfs_highbit32(minlen); /* @@ -527,33 +528,13 @@ xfs_rtallocate_extent_near( */ else { /* i < 0 */ /* - * Loop backwards through the bitmap blocks from - * the starting point-1 up to where we are now. - * There should be an extent which ends in this - * bitmap block and is long enough. + * Loop backwards through the bitmap blocks + * from where we last checked down to where we + * are now. There should be an extent which + * ends in this bitmap block and is long + * enough. */ - for (j = -1; j > i; j--) { - /* - * Grab the summary information for - * this bitmap block. - */ - error = xfs_rtany_summary(args, - log2len, - mp->m_rsumlevels - 1, - bbno + j, &maxlog); - if (error) { - return error; - } - /* - * If there's no extent given in the - * summary that means the extent we - * found must carry over from an - * earlier block. If there is an - * extent given, we've already tried - * that allocation, don't do it again. - */ - if (maxlog >= 0) - continue; + for (; j >= i; j--) { error = xfs_rtallocate_extent_block(args, bbno + j, minlen, maxavail, len, &n, prod, @@ -569,27 +550,6 @@ xfs_rtallocate_extent_near( return 0; } } - /* - * There weren't intervening bitmap blocks - * with a long enough extent, or the - * allocation didn't work for some reason - * (i.e. it's a little * too short). - * Try to allocate from the summary block - * that we found. - */ - error = xfs_rtallocate_extent_block(args, - bbno + i, minlen, maxavail, len, - &n, prod, &r); - if (error) { - return error; - } - /* - * If it works, return the extent. - */ - if (r != NULLRTEXTNO) { - *rtx = r; - return 0; - } } } /* -- cgit v1.2.3 From e0f7422f54b092df7996f21da69824aea496490a Mon Sep 17 00:00:00 2001 From: Omar Sandoval Date: Mon, 16 Oct 2023 10:48:50 -0700 Subject: xfs: don't look for end of extent further than necessary in xfs_rtallocate_extent_near() As explained in the previous commit, xfs_rtallocate_extent_near() looks for the end of a free extent when searching backwards from the target bitmap block. Since the previous commit, it searches from the last bitmap block it checked to the bitmap block containing the start of the extent. This may still be more than necessary, since the free extent may not be that long. We know the maximum size of the free extent from the realtime summary. Use that to compute how many bitmap blocks we actually need to check. Reviewed-by: Darrick J. Wong Signed-off-by: Omar Sandoval Signed-off-by: Darrick J. Wong Reviewed-by: Christoph Hellwig --- fs/xfs/xfs_rtalloc.c | 27 ++++++++++++++++++++++----- 1 file changed, 22 insertions(+), 5 deletions(-) (limited to 'fs/xfs') diff --git a/fs/xfs/xfs_rtalloc.c b/fs/xfs/xfs_rtalloc.c index b743da885ed6..ba66442910b1 100644 --- a/fs/xfs/xfs_rtalloc.c +++ b/fs/xfs/xfs_rtalloc.c @@ -527,13 +527,30 @@ xfs_rtallocate_extent_near( * On the negative side of the starting location. */ else { /* i < 0 */ + int maxblocks; + + /* + * Loop backwards to find the end of the extent + * we found in the realtime summary. + * + * maxblocks is the maximum possible number of + * bitmap blocks from the start of the extent + * to the end of the extent. + */ + if (maxlog == 0) + maxblocks = 0; + else if (maxlog < mp->m_blkbit_log) + maxblocks = 1; + else + maxblocks = 2 << (maxlog - mp->m_blkbit_log); + /* - * Loop backwards through the bitmap blocks - * from where we last checked down to where we - * are now. There should be an extent which - * ends in this bitmap block and is long - * enough. + * We need to check bbno + i + maxblocks down to + * bbno + i. We already checked bbno down to + * bbno + j + 1, so we don't need to check those + * again. */ + j = min(i + maxblocks, j); for (; j >= i; j--) { error = xfs_rtallocate_extent_block(args, bbno + j, minlen, -- cgit v1.2.3 From 2b99e410b28f5a75ae417e6389e767c7745d6fce Mon Sep 17 00:00:00 2001 From: Cheng Lin Date: Tue, 10 Oct 2023 10:09:01 +0800 Subject: xfs: introduce protection for drop nlink When abnormal drop_nlink are detected on the inode, return error, to avoid corruption propagation. Signed-off-by: Cheng Lin Reviewed-by: "Darrick J. Wong" Signed-off-by: Chandan Babu R --- fs/xfs/xfs_inode.c | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'fs/xfs') diff --git a/fs/xfs/xfs_inode.c b/fs/xfs/xfs_inode.c index 4d55f58d99b7..fb85c5c81745 100644 --- a/fs/xfs/xfs_inode.c +++ b/fs/xfs/xfs_inode.c @@ -918,6 +918,13 @@ xfs_droplink( xfs_trans_t *tp, xfs_inode_t *ip) { + if (VFS_I(ip)->i_nlink == 0) { + xfs_alert(ip->i_mount, + "%s: Attempt to drop inode (%llu) with nlink zero.", + __func__, ip->i_ino); + return -EFSCORRUPTED; + } + xfs_trans_ichgtime(tp, ip, XFS_ICHGTIME_CHG); drop_nlink(VFS_I(ip)); -- cgit v1.2.3 From 35dc55b9e80cb9ec4bcb969302000b002b2ed850 Mon Sep 17 00:00:00 2001 From: Christoph Hellwig Date: Wed, 11 Oct 2023 07:16:26 +0200 Subject: xfs: handle nimaps=0 from xfs_bmapi_write in xfs_alloc_file_space If xfs_bmapi_write finds a delalloc extent at the requested range, it tries to convert the entire delalloc extent to a real allocation. But if the allocator cannot find a single free extent large enough to cover the start block of the requested range, xfs_bmapi_write will return 0 but leave *nimaps set to 0. In that case we simply need to keep looping with the same startoffset_fsb so that one of the following allocations will eventually reach the requested range. Note that this could affect any caller of xfs_bmapi_write that covers an existing delayed allocation. As far as I can tell we do not have any other such caller, though - the regular writeback path uses xfs_bmapi_convert_delalloc to convert delayed allocations to real ones, and direct I/O invalidates the page cache first. Signed-off-by: Christoph Hellwig Reviewed-by: "Darrick J. Wong" Signed-off-by: Chandan Babu R --- fs/xfs/xfs_bmap_util.c | 24 +++++++++++++----------- 1 file changed, 13 insertions(+), 11 deletions(-) (limited to 'fs/xfs') diff --git a/fs/xfs/xfs_bmap_util.c b/fs/xfs/xfs_bmap_util.c index c640dfc2d00f..93829d86751d 100644 --- a/fs/xfs/xfs_bmap_util.c +++ b/fs/xfs/xfs_bmap_util.c @@ -774,12 +774,10 @@ xfs_alloc_file_space( { xfs_mount_t *mp = ip->i_mount; xfs_off_t count; - xfs_filblks_t allocated_fsb; xfs_filblks_t allocatesize_fsb; xfs_extlen_t extsz, temp; xfs_fileoff_t startoffset_fsb; xfs_fileoff_t endoffset_fsb; - int nimaps; int rt; xfs_trans_t *tp; xfs_bmbt_irec_t imaps[1], *imapp; @@ -802,7 +800,6 @@ xfs_alloc_file_space( count = len; imapp = &imaps[0]; - nimaps = 1; startoffset_fsb = XFS_B_TO_FSBT(mp, offset); endoffset_fsb = XFS_B_TO_FSB(mp, offset + count); allocatesize_fsb = endoffset_fsb - startoffset_fsb; @@ -813,6 +810,7 @@ xfs_alloc_file_space( while (allocatesize_fsb && !error) { xfs_fileoff_t s, e; unsigned int dblocks, rblocks, resblks; + int nimaps = 1; /* * Determine space reservations for data/realtime. @@ -878,15 +876,19 @@ xfs_alloc_file_space( if (error) break; - allocated_fsb = imapp->br_blockcount; - - if (nimaps == 0) { - error = -ENOSPC; - break; + /* + * If the allocator cannot find a single free extent large + * enough to cover the start block of the requested range, + * xfs_bmapi_write will return 0 but leave *nimaps set to 0. + * + * In that case we simply need to keep looping with the same + * startoffset_fsb so that one of the following allocations + * will eventually reach the requested range. + */ + if (nimaps) { + startoffset_fsb += imapp->br_blockcount; + allocatesize_fsb -= imapp->br_blockcount; } - - startoffset_fsb += allocated_fsb; - allocatesize_fsb -= allocated_fsb; } return error; -- cgit v1.2.3 From 14a537983b228cb050ceca3a5b743d01315dc4aa Mon Sep 17 00:00:00 2001 From: Catherine Hoang Date: Tue, 17 Oct 2023 13:12:08 -0700 Subject: xfs: allow read IO and FICLONE to run concurrently One of our VM cluster management products needs to snapshot KVM image files so that they can be restored in case of failure. Snapshotting is done by redirecting VM disk writes to a sidecar file and using reflink on the disk image, specifically the FICLONE ioctl as used by "cp --reflink". Reflink locks the source and destination files while it operates, which means that reads from the main vm disk image are blocked, causing the vm to stall. When an image file is heavily fragmented, the copy process could take several minutes. Some of the vm image files have 50-100 million extent records, and duplicating that much metadata locks the file for 30 minutes or more. Having activities suspended for such a long time in a cluster node could result in node eviction. Clone operations and read IO do not change any data in the source file, so they should be able to run concurrently. Demote the exclusive locks taken by FICLONE to shared locks to allow reads while cloning. While a clone is in progress, writes will take the IOLOCK_EXCL, so they block until the clone completes. Link: https://lore.kernel.org/linux-xfs/8911B94D-DD29-4D6E-B5BC-32EAF1866245@oracle.com/ Signed-off-by: Catherine Hoang Reviewed-by: "Darrick J. Wong" Reviewed-by: Dave Chinner Reviewed-by: Christoph Hellwig Signed-off-by: Chandan Babu R --- fs/xfs/xfs_file.c | 63 +++++++++++++++++++++++++++++++++++++++++----------- fs/xfs/xfs_inode.c | 17 ++++++++++++++ fs/xfs/xfs_inode.h | 9 ++++++++ fs/xfs/xfs_reflink.c | 4 ++++ 4 files changed, 80 insertions(+), 13 deletions(-) (limited to 'fs/xfs') diff --git a/fs/xfs/xfs_file.c b/fs/xfs/xfs_file.c index 203700278ddb..e33e5e13b95f 100644 --- a/fs/xfs/xfs_file.c +++ b/fs/xfs/xfs_file.c @@ -214,6 +214,43 @@ xfs_ilock_iocb( return 0; } +static int +xfs_ilock_iocb_for_write( + struct kiocb *iocb, + unsigned int *lock_mode) +{ + ssize_t ret; + struct xfs_inode *ip = XFS_I(file_inode(iocb->ki_filp)); + + ret = xfs_ilock_iocb(iocb, *lock_mode); + if (ret) + return ret; + + if (*lock_mode == XFS_IOLOCK_EXCL) + return 0; + if (!xfs_iflags_test(ip, XFS_IREMAPPING)) + return 0; + + xfs_iunlock(ip, *lock_mode); + *lock_mode = XFS_IOLOCK_EXCL; + return xfs_ilock_iocb(iocb, *lock_mode); +} + +static unsigned int +xfs_ilock_for_write_fault( + struct xfs_inode *ip) +{ + /* get a shared lock if no remapping in progress */ + xfs_ilock(ip, XFS_MMAPLOCK_SHARED); + if (!xfs_iflags_test(ip, XFS_IREMAPPING)) + return XFS_MMAPLOCK_SHARED; + + /* wait for remapping to complete */ + xfs_iunlock(ip, XFS_MMAPLOCK_SHARED); + xfs_ilock(ip, XFS_MMAPLOCK_EXCL); + return XFS_MMAPLOCK_EXCL; +} + STATIC ssize_t xfs_file_dio_read( struct kiocb *iocb, @@ -551,7 +588,7 @@ xfs_file_dio_write_aligned( unsigned int iolock = XFS_IOLOCK_SHARED; ssize_t ret; - ret = xfs_ilock_iocb(iocb, iolock); + ret = xfs_ilock_iocb_for_write(iocb, &iolock); if (ret) return ret; ret = xfs_file_write_checks(iocb, from, &iolock); @@ -618,7 +655,7 @@ retry_exclusive: flags = IOMAP_DIO_FORCE_WAIT; } - ret = xfs_ilock_iocb(iocb, iolock); + ret = xfs_ilock_iocb_for_write(iocb, &iolock); if (ret) return ret; @@ -1180,7 +1217,7 @@ xfs_file_remap_range( if (xfs_file_sync_writes(file_in) || xfs_file_sync_writes(file_out)) xfs_log_force_inode(dest); out_unlock: - xfs_iunlock2_io_mmap(src, dest); + xfs_iunlock2_remapping(src, dest); if (ret) trace_xfs_reflink_remap_range_error(dest, ret, _RET_IP_); return remapped > 0 ? remapped : ret; @@ -1328,6 +1365,7 @@ __xfs_filemap_fault( struct inode *inode = file_inode(vmf->vma->vm_file); struct xfs_inode *ip = XFS_I(inode); vm_fault_t ret; + unsigned int lock_mode = 0; trace_xfs_filemap_fault(ip, order, write_fault); @@ -1336,25 +1374,24 @@ __xfs_filemap_fault( file_update_time(vmf->vma->vm_file); } + if (IS_DAX(inode) || write_fault) + lock_mode = xfs_ilock_for_write_fault(XFS_I(inode)); + if (IS_DAX(inode)) { pfn_t pfn; - xfs_ilock(XFS_I(inode), XFS_MMAPLOCK_SHARED); ret = xfs_dax_fault(vmf, order, write_fault, &pfn); if (ret & VM_FAULT_NEEDDSYNC) ret = dax_finish_sync_fault(vmf, order, pfn); - xfs_iunlock(XFS_I(inode), XFS_MMAPLOCK_SHARED); + } else if (write_fault) { + ret = iomap_page_mkwrite(vmf, &xfs_page_mkwrite_iomap_ops); } else { - if (write_fault) { - xfs_ilock(XFS_I(inode), XFS_MMAPLOCK_SHARED); - ret = iomap_page_mkwrite(vmf, - &xfs_page_mkwrite_iomap_ops); - xfs_iunlock(XFS_I(inode), XFS_MMAPLOCK_SHARED); - } else { - ret = filemap_fault(vmf); - } + ret = filemap_fault(vmf); } + if (lock_mode) + xfs_iunlock(XFS_I(inode), lock_mode); + if (write_fault) sb_end_pagefault(inode->i_sb); return ret; diff --git a/fs/xfs/xfs_inode.c b/fs/xfs/xfs_inode.c index fb85c5c81745..f9d29acd72b9 100644 --- a/fs/xfs/xfs_inode.c +++ b/fs/xfs/xfs_inode.c @@ -3628,6 +3628,23 @@ xfs_iunlock2_io_mmap( inode_unlock(VFS_I(ip1)); } +/* Drop the MMAPLOCK and the IOLOCK after a remap completes. */ +void +xfs_iunlock2_remapping( + struct xfs_inode *ip1, + struct xfs_inode *ip2) +{ + xfs_iflags_clear(ip1, XFS_IREMAPPING); + + if (ip1 != ip2) + xfs_iunlock(ip1, XFS_MMAPLOCK_SHARED); + xfs_iunlock(ip2, XFS_MMAPLOCK_EXCL); + + if (ip1 != ip2) + inode_unlock_shared(VFS_I(ip1)); + inode_unlock(VFS_I(ip2)); +} + /* * Reload the incore inode list for this inode. Caller should ensure that * the link count cannot change, either by taking ILOCK_SHARED or otherwise diff --git a/fs/xfs/xfs_inode.h b/fs/xfs/xfs_inode.h index 0c5bdb91152e..3dc47937da5d 100644 --- a/fs/xfs/xfs_inode.h +++ b/fs/xfs/xfs_inode.h @@ -347,6 +347,14 @@ static inline bool xfs_inode_has_large_extent_counts(struct xfs_inode *ip) /* Quotacheck is running but inode has not been added to quota counts. */ #define XFS_IQUOTAUNCHECKED (1 << 14) +/* + * Remap in progress. Callers that wish to update file data while + * holding a shared IOLOCK or MMAPLOCK must drop the lock and retake + * the lock in exclusive mode. Relocking the file will block until + * IREMAPPING is cleared. + */ +#define XFS_IREMAPPING (1U << 15) + /* All inode state flags related to inode reclaim. */ #define XFS_ALL_IRECLAIM_FLAGS (XFS_IRECLAIMABLE | \ XFS_IRECLAIM | \ @@ -595,6 +603,7 @@ void xfs_end_io(struct work_struct *work); int xfs_ilock2_io_mmap(struct xfs_inode *ip1, struct xfs_inode *ip2); void xfs_iunlock2_io_mmap(struct xfs_inode *ip1, struct xfs_inode *ip2); +void xfs_iunlock2_remapping(struct xfs_inode *ip1, struct xfs_inode *ip2); static inline bool xfs_inode_unlinked_incomplete( diff --git a/fs/xfs/xfs_reflink.c b/fs/xfs/xfs_reflink.c index eb9102453aff..658edee8381d 100644 --- a/fs/xfs/xfs_reflink.c +++ b/fs/xfs/xfs_reflink.c @@ -1540,6 +1540,10 @@ xfs_reflink_remap_prep( if (ret) goto out_unlock; + xfs_iflags_set(src, XFS_IREMAPPING); + if (inode_in != inode_out) + xfs_ilock_demote(src, XFS_IOLOCK_EXCL | XFS_MMAPLOCK_EXCL); + return 0; out_unlock: xfs_iunlock2_io_mmap(src, dest); -- cgit v1.2.3