All of lore.kernel.org
 help / color / mirror / Atom feed
* [RFC v1.1] xfs-linux: rtalloc-speedups-6.7 updated to b67199695696
@ 2023-10-17 15:37 Darrick J. Wong
  2023-10-17 15:43 ` Darrick J. Wong
                   ` (5 more replies)
  0 siblings, 6 replies; 91+ messages in thread
From: Darrick J. Wong @ 2023-10-17 15:37 UTC (permalink / raw)
  To: dchinner, hch, linux-xfs, osandov, osandov

Hi folks,

It turns out that yesterday's branch broke bisection, so I've push -f'd
a work branch for all of our realtime cleanups and optimizations in the
rtalloc-speedups-6.7 branch of the xfs-linux repository at:

https://git.kernel.org/pub/scm/linux/kernel/git/djwong/xfs-linux.git

I started by rebasing last week's rt cleanups patchsets against 6.6-rc6
TOT instead of djwong-dev, then I added Dave's xfs_rtalloc_args cleanup,
and then added Omar's rt allocator speedups.  This branch has now
survived overnight testing.

The new head of the rtalloc-speedups-6.7 branch is commit:

b67199695696 xfs: don't look for end of extent further than necessary in xfs_rtallocate_extent_near()

36 new commits:

Darrick J. Wong (28):
[6953ad8d0bae] xfs: make xchk_iget safer in the presence of corrupt inode btrees
[1948e87e4723] xfs: bump max fsgeom struct version
[c0f654f9e230] xfs: hoist freeing of rt data fork extent mappings
[03cc2dc5552c] xfs: prevent rt growfs when quota is enabled
[b9a1d7039b5b] xfs: rt stubs should return negative errnos when rt disabled
[2f21b6b1abff] xfs: fix units conversion error in xfs_bmap_del_extent_delay
[003e9f00c1bb] xfs: make sure maxlen is still congruent with prod when rounding down
[869a7bb10764] xfs: move the xfs_rtbitmap.c declarations to xfs_rtbitmap.h
[6e8471604ee5] xfs: convert xfs_extlen_t to xfs_rtxlen_t in the rt allocator
[1e98fe26bd18] xfs: convert rt bitmap/summary block numbers to xfs_fileoff_t
[fab6068dbd4c] xfs: convert rt bitmap extent lengths to xfs_rtbxlen_t
[b5b1ec2011f7] xfs: rename xfs_verify_rtext to xfs_verify_rtbext
[efafd16f2dcb] xfs: convert rt extent numbers to xfs_rtxnum_t
[e902ec670453] xfs: create a helper to convert rtextents to rtblocks
[d0069a4dc6bb] xfs: create a helper to compute leftovers of realtime extents
[c317ec75fe0d] xfs: create a helper to convert extlen to rtextlen
[316da55c7ecf] xfs: create helpers to convert rt block numbers to rt extent numbers
[0e90edd13659] xfs: convert do_div calls to xfs_rtb_to_rtx helper calls
[2d4cf0892cfe] xfs: create rt extent rounding helpers for realtime extent blocks
[f538cf95a5b8] xfs: use shifting and masking when converting rt extents, if possible
[e780da4b8067] xfs: convert the rtbitmap block and bit macros to static inline functions
[710a06e09cfe] xfs: remove XFS_BLOCKWSIZE and XFS_BLOCKWMASK macros
[a705854970f8] xfs: convert open-coded xfs_rtword_t pointer accesses to helper
[4cecf034d685] xfs: convert rt summary macros to helpers
[4d9e06b25a33] xfs: create helpers for rtbitmap block/wordcount computations
[625af2f8cf01] xfs: use accessor functions for bitmap words
[c7078ff43a80] xfs: create helpers for rtsummary block/wordcount computations
[ac9c57723b70] xfs: use accessor functions for summary info words

Dave Chinner (1):
[98ab1a255b81] xfs: consolidate realtime allocation arguments

Omar Sandoval (6):
[947d029f1677] xfs: cache last bitmap block in realtime allocator
[36cb8887dc72] xfs: invert the realtime summary cache
[c6bebaf43313] xfs: return maximum free size from xfs_rtany_summary()
[ff31bbc39fb6] xfs: limit maxlen based on available space in xfs_rtallocate_extent_near()
[90127b4188e3] xfs: don't try redundant allocations in xfs_rtallocate_extent_near()
[b67199695696] xfs: don't look for end of extent further than necessary in xfs_rtallocate_extent_near()

Shiyang Ruan (1):
[1937b0813e81] mm, pmem, xfs: Introduce MF_MEM_PRE_REMOVE for unbind

Code Diffstat:

drivers/dax/super.c            |   3 +-
fs/xfs/libxfs/xfs_bmap.c       |  45 +--
fs/xfs/libxfs/xfs_format.h     |  34 +-
fs/xfs/libxfs/xfs_rtbitmap.c   | 733 +++++++++++++++++++++++++----------------
fs/xfs/libxfs/xfs_rtbitmap.h   | 326 ++++++++++++++++++
fs/xfs/libxfs/xfs_sb.c         |   2 +
fs/xfs/libxfs/xfs_sb.h         |   2 +-
fs/xfs/libxfs/xfs_trans_resv.c |  10 +-
fs/xfs/libxfs/xfs_types.c      |   4 +-
fs/xfs/libxfs/xfs_types.h      |  10 +-
fs/xfs/scrub/bmap.c            |   2 +-
fs/xfs/scrub/common.c          |   6 +-
fs/xfs/scrub/common.h          |  19 ++
fs/xfs/scrub/fscounters.c      |   2 +-
fs/xfs/scrub/inode.c           |   7 +-
fs/xfs/scrub/rtbitmap.c        |  28 +-
fs/xfs/scrub/rtsummary.c       |  57 ++--
fs/xfs/scrub/trace.c           |   1 +
fs/xfs/scrub/trace.h           |   9 +-
fs/xfs/xfs_bmap_util.c         |  50 ++-
fs/xfs/xfs_fsmap.c             |  15 +-
fs/xfs/xfs_inode_item.c        |   3 +-
fs/xfs/xfs_ioctl.c             |   5 +-
fs/xfs/xfs_linux.h             |  12 +
fs/xfs/xfs_mount.h             |   8 +-
fs/xfs/xfs_notify_failure.c    | 108 +++++-
fs/xfs/xfs_ondisk.h            |   4 +
fs/xfs/xfs_rtalloc.c           | 602 +++++++++++++++++----------------
fs/xfs/xfs_rtalloc.h           |  94 +-----
fs/xfs/xfs_super.c             |   3 +-
fs/xfs/xfs_trans.c             |   7 +-
include/linux/mm.h             |   1 +
mm/memory-failure.c            |  21 +-
33 files changed, 1391 insertions(+), 842 deletions(-)
create mode 100644 fs/xfs/libxfs/xfs_rtbitmap.h


^ permalink raw reply	[flat|nested] 91+ messages in thread

* Re: [RFC v1.1] xfs-linux: rtalloc-speedups-6.7 updated to b67199695696
  2023-10-17 15:37 [RFC v1.1] xfs-linux: rtalloc-speedups-6.7 updated to b67199695696 Darrick J. Wong
@ 2023-10-17 15:43 ` Darrick J. Wong
  2023-10-17 15:45 ` [PATCHSET RFC v1.1 0/4] xfs: minor bugfixes for rt stuff Darrick J. Wong
                   ` (4 subsequent siblings)
  5 siblings, 0 replies; 91+ messages in thread
From: Darrick J. Wong @ 2023-10-17 15:43 UTC (permalink / raw)
  To: dchinner, hch, linux-xfs, osandov, osandov

On Tue, Oct 17, 2023 at 08:37:41AM -0700, Darrick J. Wong wrote:
> Hi folks,
> 
> It turns out that yesterday's branch broke bisection, so I've push -f'd
> a work branch for all of our realtime cleanups and optimizations in the
> rtalloc-speedups-6.7 branch of the xfs-linux repository at:
> 
> https://git.kernel.org/pub/scm/linux/kernel/git/djwong/xfs-linux.git
> 
> I started by rebasing last week's rt cleanups patchsets against 6.6-rc6
> TOT instead of djwong-dev, then I added Dave's xfs_rtalloc_args cleanup,
> and then added Omar's rt allocator speedups.  This branch has now
> survived overnight testing.
> 
> The new head of the rtalloc-speedups-6.7 branch is commit:
> 
> b67199695696 xfs: don't look for end of extent further than necessary in xfs_rtallocate_extent_near()

...and I've already had to push -f to include Christoph's RVBs on Omar's
series.  Make that:

160fc7cbdcf9 xfs: don't look for end of extent further than necessary in xfs_rtallocate_extent_near()

--D

> 
> 36 new commits:
> 
> Darrick J. Wong (28):
> [6953ad8d0bae] xfs: make xchk_iget safer in the presence of corrupt inode btrees
> [1948e87e4723] xfs: bump max fsgeom struct version
> [c0f654f9e230] xfs: hoist freeing of rt data fork extent mappings
> [03cc2dc5552c] xfs: prevent rt growfs when quota is enabled
> [b9a1d7039b5b] xfs: rt stubs should return negative errnos when rt disabled
> [2f21b6b1abff] xfs: fix units conversion error in xfs_bmap_del_extent_delay
> [003e9f00c1bb] xfs: make sure maxlen is still congruent with prod when rounding down
> [869a7bb10764] xfs: move the xfs_rtbitmap.c declarations to xfs_rtbitmap.h
> [6e8471604ee5] xfs: convert xfs_extlen_t to xfs_rtxlen_t in the rt allocator
> [1e98fe26bd18] xfs: convert rt bitmap/summary block numbers to xfs_fileoff_t
> [fab6068dbd4c] xfs: convert rt bitmap extent lengths to xfs_rtbxlen_t
> [b5b1ec2011f7] xfs: rename xfs_verify_rtext to xfs_verify_rtbext
> [efafd16f2dcb] xfs: convert rt extent numbers to xfs_rtxnum_t
> [e902ec670453] xfs: create a helper to convert rtextents to rtblocks
> [d0069a4dc6bb] xfs: create a helper to compute leftovers of realtime extents
> [c317ec75fe0d] xfs: create a helper to convert extlen to rtextlen
> [316da55c7ecf] xfs: create helpers to convert rt block numbers to rt extent numbers
> [0e90edd13659] xfs: convert do_div calls to xfs_rtb_to_rtx helper calls
> [2d4cf0892cfe] xfs: create rt extent rounding helpers for realtime extent blocks
> [f538cf95a5b8] xfs: use shifting and masking when converting rt extents, if possible
> [e780da4b8067] xfs: convert the rtbitmap block and bit macros to static inline functions
> [710a06e09cfe] xfs: remove XFS_BLOCKWSIZE and XFS_BLOCKWMASK macros
> [a705854970f8] xfs: convert open-coded xfs_rtword_t pointer accesses to helper
> [4cecf034d685] xfs: convert rt summary macros to helpers
> [4d9e06b25a33] xfs: create helpers for rtbitmap block/wordcount computations
> [625af2f8cf01] xfs: use accessor functions for bitmap words
> [c7078ff43a80] xfs: create helpers for rtsummary block/wordcount computations
> [ac9c57723b70] xfs: use accessor functions for summary info words
> 
> Dave Chinner (1):
> [98ab1a255b81] xfs: consolidate realtime allocation arguments
> 
> Omar Sandoval (6):
> [947d029f1677] xfs: cache last bitmap block in realtime allocator
> [36cb8887dc72] xfs: invert the realtime summary cache
> [c6bebaf43313] xfs: return maximum free size from xfs_rtany_summary()
> [ff31bbc39fb6] xfs: limit maxlen based on available space in xfs_rtallocate_extent_near()
> [90127b4188e3] xfs: don't try redundant allocations in xfs_rtallocate_extent_near()
> [b67199695696] xfs: don't look for end of extent further than necessary in xfs_rtallocate_extent_near()
> 
> Shiyang Ruan (1):
> [1937b0813e81] mm, pmem, xfs: Introduce MF_MEM_PRE_REMOVE for unbind
> 
> Code Diffstat:
> 
> drivers/dax/super.c            |   3 +-
> fs/xfs/libxfs/xfs_bmap.c       |  45 +--
> fs/xfs/libxfs/xfs_format.h     |  34 +-
> fs/xfs/libxfs/xfs_rtbitmap.c   | 733 +++++++++++++++++++++++++----------------
> fs/xfs/libxfs/xfs_rtbitmap.h   | 326 ++++++++++++++++++
> fs/xfs/libxfs/xfs_sb.c         |   2 +
> fs/xfs/libxfs/xfs_sb.h         |   2 +-
> fs/xfs/libxfs/xfs_trans_resv.c |  10 +-
> fs/xfs/libxfs/xfs_types.c      |   4 +-
> fs/xfs/libxfs/xfs_types.h      |  10 +-
> fs/xfs/scrub/bmap.c            |   2 +-
> fs/xfs/scrub/common.c          |   6 +-
> fs/xfs/scrub/common.h          |  19 ++
> fs/xfs/scrub/fscounters.c      |   2 +-
> fs/xfs/scrub/inode.c           |   7 +-
> fs/xfs/scrub/rtbitmap.c        |  28 +-
> fs/xfs/scrub/rtsummary.c       |  57 ++--
> fs/xfs/scrub/trace.c           |   1 +
> fs/xfs/scrub/trace.h           |   9 +-
> fs/xfs/xfs_bmap_util.c         |  50 ++-
> fs/xfs/xfs_fsmap.c             |  15 +-
> fs/xfs/xfs_inode_item.c        |   3 +-
> fs/xfs/xfs_ioctl.c             |   5 +-
> fs/xfs/xfs_linux.h             |  12 +
> fs/xfs/xfs_mount.h             |   8 +-
> fs/xfs/xfs_notify_failure.c    | 108 +++++-
> fs/xfs/xfs_ondisk.h            |   4 +
> fs/xfs/xfs_rtalloc.c           | 602 +++++++++++++++++----------------
> fs/xfs/xfs_rtalloc.h           |  94 +-----
> fs/xfs/xfs_super.c             |   3 +-
> fs/xfs/xfs_trans.c             |   7 +-
> include/linux/mm.h             |   1 +
> mm/memory-failure.c            |  21 +-
> 33 files changed, 1391 insertions(+), 842 deletions(-)
> create mode 100644 fs/xfs/libxfs/xfs_rtbitmap.h
> 

^ permalink raw reply	[flat|nested] 91+ messages in thread

* [PATCHSET RFC v1.1 0/4] xfs: minor bugfixes for rt stuff
  2023-10-17 15:37 [RFC v1.1] xfs-linux: rtalloc-speedups-6.7 updated to b67199695696 Darrick J. Wong
  2023-10-17 15:43 ` Darrick J. Wong
@ 2023-10-17 15:45 ` Darrick J. Wong
  2023-10-17 15:47   ` [PATCH 1/4] xfs: bump max fsgeom struct version Darrick J. Wong
                     ` (3 more replies)
  2023-10-17 15:46 ` [PATCHSET RFC v1.1 0/8] xfs: clean up realtime type usage Darrick J. Wong
                   ` (3 subsequent siblings)
  5 siblings, 4 replies; 91+ messages in thread
From: Darrick J. Wong @ 2023-10-17 15:45 UTC (permalink / raw)
  To: djwong; +Cc: Christoph Hellwig, osandov, linux-xfs, hch

Hi all,

This is a preparatory patchset that fixes a few miscellaneous bugs
before we start in on larger cleanups of realtime units usage.

v1.1: various cleanups suggested by hch

If you're going to start using this code, I strongly recommend pulling
from my git trees, which are linked below.

With a bit of luck, this should all go splendidly.
Comments and questions are, as always, welcome.

--D

kernel git tree:
https://git.kernel.org/cgit/linux/kernel/git/djwong/xfs-linux.git/log/?h=realtime-fixes-6.7
---
 fs/xfs/libxfs/xfs_bmap.c     |   19 +++----------------
 fs/xfs/libxfs/xfs_rtbitmap.c |   33 +++++++++++++++++++++++++++++++++
 fs/xfs/libxfs/xfs_sb.h       |    2 +-
 fs/xfs/xfs_rtalloc.c         |    2 +-
 fs/xfs/xfs_rtalloc.h         |   27 ++++++++++++++++-----------
 5 files changed, 54 insertions(+), 29 deletions(-)


^ permalink raw reply	[flat|nested] 91+ messages in thread

* [PATCHSET RFC v1.1 0/8] xfs: clean up realtime type usage
  2023-10-17 15:37 [RFC v1.1] xfs-linux: rtalloc-speedups-6.7 updated to b67199695696 Darrick J. Wong
  2023-10-17 15:43 ` Darrick J. Wong
  2023-10-17 15:45 ` [PATCHSET RFC v1.1 0/4] xfs: minor bugfixes for rt stuff Darrick J. Wong
@ 2023-10-17 15:46 ` Darrick J. Wong
  2023-10-17 15:48   ` [PATCH 1/8] xfs: fix units conversion error in xfs_bmap_del_extent_delay Darrick J. Wong
                     ` (7 more replies)
  2023-10-17 15:46 ` [PATCHSET RFC v1.1 0/7] xfs: refactor rt extent unit conversions Darrick J. Wong
                   ` (2 subsequent siblings)
  5 siblings, 8 replies; 91+ messages in thread
From: Darrick J. Wong @ 2023-10-17 15:46 UTC (permalink / raw)
  To: djwong; +Cc: Christoph Hellwig, osandov, linux-xfs, hch

Hi all,

The realtime code uses xfs_rtblock_t and xfs_fsblock_t in a lot of
places, and it's very confusing.  Clean up all the type usage so that an
xfs_rtblock_t is always a block within the realtime volume, an
xfs_fileoff_t is always a file offset within a realtime metadata file,
and an xfs_rtxnumber_t is always a rt extent within the realtime volume.

v1.1: various cleanups suggested by hch

If you're going to start using this code, I strongly recommend pulling
from my git trees, which are linked below.

With a bit of luck, this should all go splendidly.
Comments and questions are, as always, welcome.

--D

kernel git tree:
https://git.kernel.org/cgit/linux/kernel/git/djwong/xfs-linux.git/log/?h=clean-up-realtime-units-6.7
---
 fs/xfs/libxfs/xfs_bmap.c     |    8 +
 fs/xfs/libxfs/xfs_format.h   |    2 
 fs/xfs/libxfs/xfs_rtbitmap.c |  121 ++++++++++----------
 fs/xfs/libxfs/xfs_rtbitmap.h |   79 +++++++++++++
 fs/xfs/libxfs/xfs_types.c    |    4 -
 fs/xfs/libxfs/xfs_types.h    |    8 +
 fs/xfs/scrub/bmap.c          |    2 
 fs/xfs/scrub/fscounters.c    |    2 
 fs/xfs/scrub/rtbitmap.c      |   12 +-
 fs/xfs/scrub/rtsummary.c     |    4 -
 fs/xfs/scrub/trace.h         |    7 +
 fs/xfs/xfs_bmap_util.c       |   18 +--
 fs/xfs/xfs_fsmap.c           |    2 
 fs/xfs/xfs_rtalloc.c         |  248 +++++++++++++++++++++++-------------------
 fs/xfs/xfs_rtalloc.h         |   89 +--------------
 15 files changed, 319 insertions(+), 287 deletions(-)
 create mode 100644 fs/xfs/libxfs/xfs_rtbitmap.h


^ permalink raw reply	[flat|nested] 91+ messages in thread

* [PATCHSET RFC v1.1 0/7] xfs: refactor rt extent unit conversions
  2023-10-17 15:37 [RFC v1.1] xfs-linux: rtalloc-speedups-6.7 updated to b67199695696 Darrick J. Wong
                   ` (2 preceding siblings ...)
  2023-10-17 15:46 ` [PATCHSET RFC v1.1 0/8] xfs: clean up realtime type usage Darrick J. Wong
@ 2023-10-17 15:46 ` Darrick J. Wong
  2023-10-17 15:50   ` [PATCH 1/7] xfs: create a helper to convert rtextents to rtblocks Darrick J. Wong
                     ` (6 more replies)
  2023-10-17 15:46 ` [PATCHSET RFC v1.1 0/8] xfs: refactor rtbitmap/summary macros Darrick J. Wong
  2023-10-17 15:46 ` [PATCHSET RFC 2.1 0/7] xfs: CPU usage optimizations for realtime allocator Darrick J. Wong
  5 siblings, 7 replies; 91+ messages in thread
From: Darrick J. Wong @ 2023-10-17 15:46 UTC (permalink / raw)
  To: djwong; +Cc: Christoph Hellwig, osandov, linux-xfs, hch

Hi all,

This series replaces all the open-coded integer division and
multiplication conversions between rt blocks and rt extents with calls
to static inline helpers.  Having cleaned all that up, the helpers are
augmented to skip the expensive operations in favor of bit shifts and
masking if the rt extent size is a power of two.

v1.1: various cleanups suggested by hch

If you're going to start using this code, I strongly recommend pulling
from my git trees, which are linked below.

With a bit of luck, this should all go splendidly.
Comments and questions are, as always, welcome.

--D

kernel git tree:
https://git.kernel.org/cgit/linux/kernel/git/djwong/xfs-linux.git/log/?h=refactor-rt-unit-conversions-6.7
---
 fs/xfs/libxfs/xfs_bmap.c       |   20 +++---
 fs/xfs/libxfs/xfs_rtbitmap.c   |    4 +
 fs/xfs/libxfs/xfs_rtbitmap.h   |  125 ++++++++++++++++++++++++++++++++++++++++
 fs/xfs/libxfs/xfs_sb.c         |    2 +
 fs/xfs/libxfs/xfs_trans_resv.c |    3 +
 fs/xfs/scrub/inode.c           |    3 +
 fs/xfs/scrub/rtbitmap.c        |   18 ++----
 fs/xfs/scrub/rtsummary.c       |    4 +
 fs/xfs/xfs_bmap_util.c         |   38 +++++-------
 fs/xfs/xfs_fsmap.c             |   13 ++--
 fs/xfs/xfs_inode_item.c        |    3 +
 fs/xfs/xfs_ioctl.c             |    5 +-
 fs/xfs/xfs_linux.h             |   12 ++++
 fs/xfs/xfs_mount.h             |    2 +
 fs/xfs/xfs_rtalloc.c           |    4 +
 fs/xfs/xfs_super.c             |    3 +
 fs/xfs/xfs_trans.c             |    7 ++
 17 files changed, 200 insertions(+), 66 deletions(-)


^ permalink raw reply	[flat|nested] 91+ messages in thread

* [PATCHSET RFC v1.1 0/8] xfs: refactor rtbitmap/summary macros
  2023-10-17 15:37 [RFC v1.1] xfs-linux: rtalloc-speedups-6.7 updated to b67199695696 Darrick J. Wong
                   ` (3 preceding siblings ...)
  2023-10-17 15:46 ` [PATCHSET RFC v1.1 0/7] xfs: refactor rt extent unit conversions Darrick J. Wong
@ 2023-10-17 15:46 ` Darrick J. Wong
  2023-10-17 15:52   ` [PATCH 1/8] xfs: convert the rtbitmap block and bit macros to static inline functions Darrick J. Wong
                     ` (8 more replies)
  2023-10-17 15:46 ` [PATCHSET RFC 2.1 0/7] xfs: CPU usage optimizations for realtime allocator Darrick J. Wong
  5 siblings, 9 replies; 91+ messages in thread
From: Darrick J. Wong @ 2023-10-17 15:46 UTC (permalink / raw)
  To: djwong; +Cc: Christoph Hellwig, osandov, linux-xfs, hch

Hi all,

In preparation for adding block headers and enforcing endian order in
rtbitmap and rtsummary blocks, replace open-coded geometry computations
and fugly macros with proper helper functions that can be typechecked.
Soon we'll be needing to add more complex logic to the helpers.

v1.1: various cleanups suggested by hch

If you're going to start using this code, I strongly recommend pulling
from my git trees, which are linked below.

With a bit of luck, this should all go splendidly.
Comments and questions are, as always, welcome.

--D

kernel git tree:
https://git.kernel.org/cgit/linux/kernel/git/djwong/xfs-linux.git/log/?h=refactor-rtbitmap-macros-6.7
---
 fs/xfs/libxfs/xfs_format.h     |   32 +++--
 fs/xfs/libxfs/xfs_rtbitmap.c   |  270 +++++++++++++++++++++++++++++-----------
 fs/xfs/libxfs/xfs_rtbitmap.h   |  115 +++++++++++++++++
 fs/xfs/libxfs/xfs_trans_resv.c |    9 +
 fs/xfs/libxfs/xfs_types.h      |    2 
 fs/xfs/scrub/rtsummary.c       |   39 +++---
 fs/xfs/scrub/trace.c           |    1 
 fs/xfs/scrub/trace.h           |    4 -
 fs/xfs/xfs_ondisk.h            |    4 +
 fs/xfs/xfs_rtalloc.c           |   39 +++---
 10 files changed, 377 insertions(+), 138 deletions(-)


^ permalink raw reply	[flat|nested] 91+ messages in thread

* [PATCHSET RFC 2.1 0/7] xfs: CPU usage optimizations for realtime allocator
  2023-10-17 15:37 [RFC v1.1] xfs-linux: rtalloc-speedups-6.7 updated to b67199695696 Darrick J. Wong
                   ` (4 preceding siblings ...)
  2023-10-17 15:46 ` [PATCHSET RFC v1.1 0/8] xfs: refactor rtbitmap/summary macros Darrick J. Wong
@ 2023-10-17 15:46 ` Darrick J. Wong
  2023-10-17 15:54   ` [PATCH 1/7] xfs: consolidate realtime allocation arguments Darrick J. Wong
                     ` (7 more replies)
  5 siblings, 8 replies; 91+ messages in thread
From: Darrick J. Wong @ 2023-10-17 15:46 UTC (permalink / raw)
  To: djwong
  Cc: Christoph Hellwig, Omar Sandoval, Dave Chinner, osandov, osandov,
	linux-xfs, hch

Hi all,

Hello,

This is version 2 of my XFS realtime allocator opimization patch series.

Changes since v1 [1]:

- Fixed potential overflow in patch 4.
- Changed deprecated typedefs to normal struct names
- Fixed broken indentation
- Used xfs_fileoff_t instead of xfs_fsblock_t where appropriate.
- Added calls to xfs_rtbuf_cache_relse anywhere that the cache is used
  instead of relying on the buffers being dirtied and thus attached to
  the transaction.
- Clarified comments and commit messages in a few places.
- Added Darrick's Reviewed-bys.

Cover letter from v1:

Our distributed storage system uses XFS's realtime device support as a
way to split an XFS filesystem between an SSD and an HDD -- we configure
the HDD as the realtime device so that metadata goes on the SSD and data
goes on the HDD.

We've been running this in production for a few years now, so we have
some fairly fragmented filesystems. This has exposed various CPU
inefficiencies in the realtime allocator. These became even worse when
we experimented with using XFS_XFLAG_EXTSIZE to force files to be
allocated contiguously.

This series adds several optimizations that don't change the realtime
allocator's decisions, but make them happen more efficiently, mainly by
avoiding redundant work. We've tested these in production and measured
~10% lower CPU utilization. Furthermore, it made it possible to use
XFS_XFLAG_EXTSIZE to force contiguous allocations -- without these
patches, our most fragmented systems would become unresponsive due to
high CPU usage in the realtime allocator, but with them, CPU utilization
is actually ~4-6% lower than before, and disk I/O utilization is 15-20%
lower.

Patches 2 and 3 are preparations for later optimizations; the remaining
patches are the optimizations themselves.

1: https://lore.kernel.org/linux-xfs/cover.1687296675.git.osandov@osandov.com/

v2.1: djwong rebased everything atop his own clenaups, added dave's rtalloc_args

If you're going to start using this code, I strongly recommend pulling
from my git trees, which are linked below.

With a bit of luck, this should all go splendidly.
Comments and questions are, as always, welcome.

--D

kernel git tree:
https://git.kernel.org/cgit/linux/kernel/git/djwong/xfs-linux.git/log/?h=rtalloc-speedups-6.7
---
 fs/xfs/libxfs/xfs_rtbitmap.c |  441 ++++++++++++++++++++---------------------
 fs/xfs/libxfs/xfs_rtbitmap.h |   53 +++--
 fs/xfs/scrub/rtsummary.c     |   10 +
 fs/xfs/xfs_mount.h           |    6 -
 fs/xfs/xfs_rtalloc.c         |  455 ++++++++++++++++++++----------------------
 5 files changed, 476 insertions(+), 489 deletions(-)


^ permalink raw reply	[flat|nested] 91+ messages in thread

* [PATCH 1/4] xfs: bump max fsgeom struct version
  2023-10-17 15:45 ` [PATCHSET RFC v1.1 0/4] xfs: minor bugfixes for rt stuff Darrick J. Wong
@ 2023-10-17 15:47   ` Darrick J. Wong
  2023-10-17 15:47   ` [PATCH 2/4] xfs: hoist freeing of rt data fork extent mappings Darrick J. Wong
                     ` (2 subsequent siblings)
  3 siblings, 0 replies; 91+ messages in thread
From: Darrick J. Wong @ 2023-10-17 15:47 UTC (permalink / raw)
  To: djwong; +Cc: Christoph Hellwig, osandov, linux-xfs, hch

From: Darrick J. Wong <djwong@kernel.org>

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 <djwong@kernel.org>
Reviewed-by: Christoph Hellwig <hch@lst.de>
---
 fs/xfs/libxfs/xfs_sb.h |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)


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,


^ permalink raw reply related	[flat|nested] 91+ messages in thread

* [PATCH 2/4] xfs: hoist freeing of rt data fork extent mappings
  2023-10-17 15:45 ` [PATCHSET RFC v1.1 0/4] xfs: minor bugfixes for rt stuff Darrick J. Wong
  2023-10-17 15:47   ` [PATCH 1/4] xfs: bump max fsgeom struct version Darrick J. Wong
@ 2023-10-17 15:47   ` Darrick J. Wong
  2023-10-17 16:00     ` Christoph Hellwig
  2023-10-17 15:47   ` [PATCH 3/4] xfs: prevent rt growfs when quota is enabled Darrick J. Wong
  2023-10-17 15:47   ` [PATCH 4/4] xfs: rt stubs should return negative errnos when rt disabled Darrick J. Wong
  3 siblings, 1 reply; 91+ messages in thread
From: Darrick J. Wong @ 2023-10-17 15:47 UTC (permalink / raw)
  To: djwong; +Cc: osandov, linux-xfs, hch

From: Darrick J. Wong <djwong@kernel.org>

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 <djwong@kernel.org>
---
 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(-)


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)


^ permalink raw reply related	[flat|nested] 91+ messages in thread

* [PATCH 3/4] xfs: prevent rt growfs when quota is enabled
  2023-10-17 15:45 ` [PATCHSET RFC v1.1 0/4] xfs: minor bugfixes for rt stuff Darrick J. Wong
  2023-10-17 15:47   ` [PATCH 1/4] xfs: bump max fsgeom struct version Darrick J. Wong
  2023-10-17 15:47   ` [PATCH 2/4] xfs: hoist freeing of rt data fork extent mappings Darrick J. Wong
@ 2023-10-17 15:47   ` Darrick J. Wong
  2023-10-17 15:47   ` [PATCH 4/4] xfs: rt stubs should return negative errnos when rt disabled Darrick J. Wong
  3 siblings, 0 replies; 91+ messages in thread
From: Darrick J. Wong @ 2023-10-17 15:47 UTC (permalink / raw)
  To: djwong; +Cc: Christoph Hellwig, osandov, linux-xfs, hch

From: Darrick J. Wong <djwong@kernel.org>

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 <djwong@kernel.org>
Reviewed-by: Christoph Hellwig <hch@lst.de>
---
 fs/xfs/xfs_rtalloc.c |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)


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;


^ permalink raw reply related	[flat|nested] 91+ messages in thread

* [PATCH 4/4] xfs: rt stubs should return negative errnos when rt disabled
  2023-10-17 15:45 ` [PATCHSET RFC v1.1 0/4] xfs: minor bugfixes for rt stuff Darrick J. Wong
                     ` (2 preceding siblings ...)
  2023-10-17 15:47   ` [PATCH 3/4] xfs: prevent rt growfs when quota is enabled Darrick J. Wong
@ 2023-10-17 15:47   ` Darrick J. Wong
  3 siblings, 0 replies; 91+ messages in thread
From: Darrick J. Wong @ 2023-10-17 15:47 UTC (permalink / raw)
  To: djwong; +Cc: Christoph Hellwig, osandov, linux-xfs, hch

From: Darrick J. Wong <djwong@kernel.org>

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 <djwong@kernel.org>
Reviewed-by: Christoph Hellwig <hch@lst.de>
---
 fs/xfs/xfs_rtalloc.h |   24 ++++++++++++------------
 1 file changed, 12 insertions(+), 12 deletions(-)


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 */
 


^ permalink raw reply related	[flat|nested] 91+ messages in thread

* [PATCH 1/8] xfs: fix units conversion error in xfs_bmap_del_extent_delay
  2023-10-17 15:46 ` [PATCHSET RFC v1.1 0/8] xfs: clean up realtime type usage Darrick J. Wong
@ 2023-10-17 15:48   ` Darrick J. Wong
  2023-10-17 16:01     ` Christoph Hellwig
  2023-10-17 15:48   ` [PATCH 2/8] xfs: make sure maxlen is still congruent with prod when rounding down Darrick J. Wong
                     ` (6 subsequent siblings)
  7 siblings, 1 reply; 91+ messages in thread
From: Darrick J. Wong @ 2023-10-17 15:48 UTC (permalink / raw)
  To: djwong; +Cc: osandov, linux-xfs, hch

From: Darrick J. Wong <djwong@kernel.org>

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 <djwong@kernel.org>
---
 fs/xfs/libxfs/xfs_bmap.c |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)


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);


^ permalink raw reply related	[flat|nested] 91+ messages in thread

* [PATCH 2/8] xfs: make sure maxlen is still congruent with prod when rounding down
  2023-10-17 15:46 ` [PATCHSET RFC v1.1 0/8] xfs: clean up realtime type usage Darrick J. Wong
  2023-10-17 15:48   ` [PATCH 1/8] xfs: fix units conversion error in xfs_bmap_del_extent_delay Darrick J. Wong
@ 2023-10-17 15:48   ` Darrick J. Wong
  2023-10-17 15:48   ` [PATCH 3/8] xfs: move the xfs_rtbitmap.c declarations to xfs_rtbitmap.h Darrick J. Wong
                     ` (5 subsequent siblings)
  7 siblings, 0 replies; 91+ messages in thread
From: Darrick J. Wong @ 2023-10-17 15:48 UTC (permalink / raw)
  To: djwong; +Cc: Christoph Hellwig, osandov, linux-xfs, hch

From: Darrick J. Wong <djwong@kernel.org>

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 <djwong@kernel.org>
Reviewed-by: Christoph Hellwig <hch@lst.de>
---
 fs/xfs/xfs_rtalloc.c |   31 ++++++++++++++++++++++++++-----
 1 file changed, 26 insertions(+), 5 deletions(-)


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);
 
 	/*


^ permalink raw reply related	[flat|nested] 91+ messages in thread

* [PATCH 3/8] xfs: move the xfs_rtbitmap.c declarations to xfs_rtbitmap.h
  2023-10-17 15:46 ` [PATCHSET RFC v1.1 0/8] xfs: clean up realtime type usage Darrick J. Wong
  2023-10-17 15:48   ` [PATCH 1/8] xfs: fix units conversion error in xfs_bmap_del_extent_delay Darrick J. Wong
  2023-10-17 15:48   ` [PATCH 2/8] xfs: make sure maxlen is still congruent with prod when rounding down Darrick J. Wong
@ 2023-10-17 15:48   ` Darrick J. Wong
  2023-10-17 15:48   ` [PATCH 4/8] xfs: convert xfs_extlen_t to xfs_rtxlen_t in the rt allocator Darrick J. Wong
                     ` (4 subsequent siblings)
  7 siblings, 0 replies; 91+ messages in thread
From: Darrick J. Wong @ 2023-10-17 15:48 UTC (permalink / raw)
  To: djwong; +Cc: Christoph Hellwig, osandov, linux-xfs, hch

From: Darrick J. Wong <djwong@kernel.org>

Move all the declarations for functionality in xfs_rtbitmap.c into a
separate xfs_rtbitmap.h header file.

Signed-off-by: Darrick J. Wong <djwong@kernel.org>
Reviewed-by: Christoph Hellwig <hch@lst.de>
---
 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


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(


^ permalink raw reply related	[flat|nested] 91+ messages in thread

* [PATCH 4/8] xfs: convert xfs_extlen_t to xfs_rtxlen_t in the rt allocator
  2023-10-17 15:46 ` [PATCHSET RFC v1.1 0/8] xfs: clean up realtime type usage Darrick J. Wong
                     ` (2 preceding siblings ...)
  2023-10-17 15:48   ` [PATCH 3/8] xfs: move the xfs_rtbitmap.c declarations to xfs_rtbitmap.h Darrick J. Wong
@ 2023-10-17 15:48   ` Darrick J. Wong
  2023-10-17 15:49   ` [PATCH 5/8] xfs: convert rt bitmap/summary block numbers to xfs_fileoff_t Darrick J. Wong
                     ` (3 subsequent siblings)
  7 siblings, 0 replies; 91+ messages in thread
From: Darrick J. Wong @ 2023-10-17 15:48 UTC (permalink / raw)
  To: djwong; +Cc: Christoph Hellwig, osandov, linux-xfs, hch

From: Darrick J. Wong <djwong@kernel.org>

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 <djwong@kernel.org>
Reviewed-by: Christoph Hellwig <hch@lst.de>
---
 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(-)


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 */
 
 /*


^ permalink raw reply related	[flat|nested] 91+ messages in thread

* [PATCH 5/8] xfs: convert rt bitmap/summary block numbers to xfs_fileoff_t
  2023-10-17 15:46 ` [PATCHSET RFC v1.1 0/8] xfs: clean up realtime type usage Darrick J. Wong
                     ` (3 preceding siblings ...)
  2023-10-17 15:48   ` [PATCH 4/8] xfs: convert xfs_extlen_t to xfs_rtxlen_t in the rt allocator Darrick J. Wong
@ 2023-10-17 15:49   ` Darrick J. Wong
  2023-10-17 15:49   ` [PATCH 6/8] xfs: convert rt bitmap extent lengths to xfs_rtbxlen_t Darrick J. Wong
                     ` (2 subsequent siblings)
  7 siblings, 0 replies; 91+ messages in thread
From: Darrick J. Wong @ 2023-10-17 15:49 UTC (permalink / raw)
  To: djwong; +Cc: Christoph Hellwig, osandov, linux-xfs, hch

From: Darrick J. Wong <djwong@kernel.org>

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 <djwong@kernel.org>
Reviewed-by: Christoph Hellwig <hch@lst.de>
---
 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(-)


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));


^ permalink raw reply related	[flat|nested] 91+ messages in thread

* [PATCH 6/8] xfs: convert rt bitmap extent lengths to xfs_rtbxlen_t
  2023-10-17 15:46 ` [PATCHSET RFC v1.1 0/8] xfs: clean up realtime type usage Darrick J. Wong
                     ` (4 preceding siblings ...)
  2023-10-17 15:49   ` [PATCH 5/8] xfs: convert rt bitmap/summary block numbers to xfs_fileoff_t Darrick J. Wong
@ 2023-10-17 15:49   ` Darrick J. Wong
  2023-10-17 15:49   ` [PATCH 7/8] xfs: rename xfs_verify_rtext to xfs_verify_rtbext Darrick J. Wong
  2023-10-17 15:49   ` [PATCH 8/8] xfs: convert rt extent numbers to xfs_rtxnum_t Darrick J. Wong
  7 siblings, 0 replies; 91+ messages in thread
From: Darrick J. Wong @ 2023-10-17 15:49 UTC (permalink / raw)
  To: djwong; +Cc: Christoph Hellwig, osandov, linux-xfs, hch

From: Darrick J. Wong <djwong@kernel.org>

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 <djwong@kernel.org>
Reviewed-by: Christoph Hellwig <hch@lst.de>
---
 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(-)


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)


^ permalink raw reply related	[flat|nested] 91+ messages in thread

* [PATCH 7/8] xfs: rename xfs_verify_rtext to xfs_verify_rtbext
  2023-10-17 15:46 ` [PATCHSET RFC v1.1 0/8] xfs: clean up realtime type usage Darrick J. Wong
                     ` (5 preceding siblings ...)
  2023-10-17 15:49   ` [PATCH 6/8] xfs: convert rt bitmap extent lengths to xfs_rtbxlen_t Darrick J. Wong
@ 2023-10-17 15:49   ` Darrick J. Wong
  2023-10-17 15:49   ` [PATCH 8/8] xfs: convert rt extent numbers to xfs_rtxnum_t Darrick J. Wong
  7 siblings, 0 replies; 91+ messages in thread
From: Darrick J. Wong @ 2023-10-17 15:49 UTC (permalink / raw)
  To: djwong; +Cc: Christoph Hellwig, osandov, linux-xfs, hch

From: Darrick J. Wong <djwong@kernel.org>

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 <djwong@kernel.org>
Reviewed-by: Christoph Hellwig <hch@lst.de>
---
 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(-)


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;
 	}


^ permalink raw reply related	[flat|nested] 91+ messages in thread

* [PATCH 8/8] xfs: convert rt extent numbers to xfs_rtxnum_t
  2023-10-17 15:46 ` [PATCHSET RFC v1.1 0/8] xfs: clean up realtime type usage Darrick J. Wong
                     ` (6 preceding siblings ...)
  2023-10-17 15:49   ` [PATCH 7/8] xfs: rename xfs_verify_rtext to xfs_verify_rtbext Darrick J. Wong
@ 2023-10-17 15:49   ` Darrick J. Wong
  7 siblings, 0 replies; 91+ messages in thread
From: Darrick J. Wong @ 2023-10-17 15:49 UTC (permalink / raw)
  To: djwong; +Cc: Christoph Hellwig, osandov, linux-xfs, hch

From: Darrick J. Wong <djwong@kernel.org>

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 <djwong@kernel.org>
Reviewed-by: Christoph Hellwig <hch@lst.de>
---
 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(-)


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 @@ xfs_bmap_rtalloc(
 	 * 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 @@ xfs_bmap_rtalloc(
 		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 @@ xfs_growfs_rt(
 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 @@ xfs_rtallocate_extent(
 	/*
 	 * 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.


^ permalink raw reply related	[flat|nested] 91+ messages in thread

* [PATCH 1/7] xfs: create a helper to convert rtextents to rtblocks
  2023-10-17 15:46 ` [PATCHSET RFC v1.1 0/7] xfs: refactor rt extent unit conversions Darrick J. Wong
@ 2023-10-17 15:50   ` Darrick J. Wong
  2023-10-17 15:50   ` [PATCH 2/7] xfs: create a helper to compute leftovers of realtime extents Darrick J. Wong
                     ` (5 subsequent siblings)
  6 siblings, 0 replies; 91+ messages in thread
From: Darrick J. Wong @ 2023-10-17 15:50 UTC (permalink / raw)
  To: djwong; +Cc: Christoph Hellwig, osandov, linux-xfs, hch

From: Darrick J. Wong <djwong@kernel.org>

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 <djwong@kernel.org>
Reviewed-by: Christoph Hellwig <hch@lst.de>
---
 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(-)


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 @@ xfs_bmap_rtalloc(
 	 * 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 @@ xfs_bmap_rtalloc(
 		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 @@ xfs_bmap_rtalloc(
 		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 <linux/magic.h>
@@ -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;


^ permalink raw reply related	[flat|nested] 91+ messages in thread

* [PATCH 2/7] xfs: create a helper to compute leftovers of realtime extents
  2023-10-17 15:46 ` [PATCHSET RFC v1.1 0/7] xfs: refactor rt extent unit conversions Darrick J. Wong
  2023-10-17 15:50   ` [PATCH 1/7] xfs: create a helper to convert rtextents to rtblocks Darrick J. Wong
@ 2023-10-17 15:50   ` Darrick J. Wong
  2023-10-17 15:50   ` [PATCH 3/7] xfs: create a helper to convert extlen to rtextlen Darrick J. Wong
                     ` (4 subsequent siblings)
  6 siblings, 0 replies; 91+ messages in thread
From: Darrick J. Wong @ 2023-10-17 15:50 UTC (permalink / raw)
  To: djwong; +Cc: Christoph Hellwig, osandov, linux-xfs, hch

From: Darrick J. Wong <djwong@kernel.org>

Create a helper to compute the misalignment between a file extent
(xfs_extlen_t) and a realtime extent.

Signed-off-by: Darrick J. Wong <djwong@kernel.org>
Reviewed-by: Christoph Hellwig <hch@lst.de>
---
 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(-)


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 @@ xfs_bmap_rtalloc(
 	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 <linux/iversion.h>
 
@@ -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 <linux/mount.h>
 #include <linux/namei.h>
@@ -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;
 	}
 


^ permalink raw reply related	[flat|nested] 91+ messages in thread

* [PATCH 3/7] xfs: create a helper to convert extlen to rtextlen
  2023-10-17 15:46 ` [PATCHSET RFC v1.1 0/7] xfs: refactor rt extent unit conversions Darrick J. Wong
  2023-10-17 15:50   ` [PATCH 1/7] xfs: create a helper to convert rtextents to rtblocks Darrick J. Wong
  2023-10-17 15:50   ` [PATCH 2/7] xfs: create a helper to compute leftovers of realtime extents Darrick J. Wong
@ 2023-10-17 15:50   ` Darrick J. Wong
  2023-10-17 15:50   ` [PATCH 4/7] xfs: create helpers to convert rt block numbers to rt extent numbers Darrick J. Wong
                     ` (3 subsequent siblings)
  6 siblings, 0 replies; 91+ messages in thread
From: Darrick J. Wong @ 2023-10-17 15:50 UTC (permalink / raw)
  To: djwong; +Cc: Christoph Hellwig, osandov, linux-xfs, hch

From: Darrick J. Wong <djwong@kernel.org>

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 <djwong@kernel.org>
Reviewed-by: Christoph Hellwig <hch@lst.de>
---
 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(-)


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 @@ xfs_bmap_rtalloc(
 		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 @@ xfs_bmap_rtalloc(
 		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;


^ permalink raw reply related	[flat|nested] 91+ messages in thread

* [PATCH 4/7] xfs: create helpers to convert rt block numbers to rt extent numbers
  2023-10-17 15:46 ` [PATCHSET RFC v1.1 0/7] xfs: refactor rt extent unit conversions Darrick J. Wong
                     ` (2 preceding siblings ...)
  2023-10-17 15:50   ` [PATCH 3/7] xfs: create a helper to convert extlen to rtextlen Darrick J. Wong
@ 2023-10-17 15:50   ` Darrick J. Wong
  2023-10-17 16:04     ` Christoph Hellwig
  2023-10-17 15:51   ` [PATCH 5/7] xfs: convert do_div calls to xfs_rtb_to_rtx helper calls Darrick J. Wong
                     ` (2 subsequent siblings)
  6 siblings, 1 reply; 91+ messages in thread
From: Darrick J. Wong @ 2023-10-17 15:50 UTC (permalink / raw)
  To: djwong; +Cc: osandov, linux-xfs, hch

From: Darrick J. Wong <djwong@kernel.org>

Create helpers to do unit conversions of rt block numbers to rt extent
numbers.  There are two variations -- the suffix "t" denotes the one
that returns only the truncated extent number; the other one also
returns the misalignment.  Convert all the div_u64_rem users; we'll do
the do_div users in the next patch.

Signed-off-by: Darrick J. Wong <djwong@kernel.org>
---
 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(-)


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.
  */


^ permalink raw reply related	[flat|nested] 91+ messages in thread

* [PATCH 5/7] xfs: convert do_div calls to xfs_rtb_to_rtx helper calls
  2023-10-17 15:46 ` [PATCHSET RFC v1.1 0/7] xfs: refactor rt extent unit conversions Darrick J. Wong
                     ` (3 preceding siblings ...)
  2023-10-17 15:50   ` [PATCH 4/7] xfs: create helpers to convert rt block numbers to rt extent numbers Darrick J. Wong
@ 2023-10-17 15:51   ` Darrick J. Wong
  2023-10-17 16:05     ` Christoph Hellwig
  2023-10-17 15:51   ` [PATCH 6/7] xfs: create rt extent rounding helpers for realtime extent blocks Darrick J. Wong
  2023-10-17 15:51   ` [PATCH 7/7] xfs: use shifting and masking when converting rt extents, if possible Darrick J. Wong
  6 siblings, 1 reply; 91+ messages in thread
From: Darrick J. Wong @ 2023-10-17 15:51 UTC (permalink / raw)
  To: djwong; +Cc: osandov, linux-xfs, hch

From: Darrick J. Wong <djwong@kernel.org>

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 <djwong@kernel.org>
---
 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(-)


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 @@ xchk_rtbitmap(
 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 @@ xfs_bmap_rtalloc(
 	 * 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;


^ permalink raw reply related	[flat|nested] 91+ messages in thread

* [PATCH 6/7] xfs: create rt extent rounding helpers for realtime extent blocks
  2023-10-17 15:46 ` [PATCHSET RFC v1.1 0/7] xfs: refactor rt extent unit conversions Darrick J. Wong
                     ` (4 preceding siblings ...)
  2023-10-17 15:51   ` [PATCH 5/7] xfs: convert do_div calls to xfs_rtb_to_rtx helper calls Darrick J. Wong
@ 2023-10-17 15:51   ` Darrick J. Wong
  2023-10-17 15:51   ` [PATCH 7/7] xfs: use shifting and masking when converting rt extents, if possible Darrick J. Wong
  6 siblings, 0 replies; 91+ messages in thread
From: Darrick J. Wong @ 2023-10-17 15:51 UTC (permalink / raw)
  To: djwong; +Cc: Christoph Hellwig, osandov, linux-xfs, hch

From: Darrick J. Wong <djwong@kernel.org>

Create a pair of functions to round rtblock numbers up or down to the
nearest rt extent.

Signed-off-by: Darrick J. Wong <djwong@kernel.org>
Reviewed-by: Christoph Hellwig <hch@lst.de>
---
 fs/xfs/libxfs/xfs_rtbitmap.h |   18 ++++++++++++++++++
 fs/xfs/xfs_bmap_util.c       |    8 +++-----
 2 files changed, 21 insertions(+), 5 deletions(-)


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);
 	}
 
 	/*


^ permalink raw reply related	[flat|nested] 91+ messages in thread

* [PATCH 7/7] xfs: use shifting and masking when converting rt extents, if possible
  2023-10-17 15:46 ` [PATCHSET RFC v1.1 0/7] xfs: refactor rt extent unit conversions Darrick J. Wong
                     ` (5 preceding siblings ...)
  2023-10-17 15:51   ` [PATCH 6/7] xfs: create rt extent rounding helpers for realtime extent blocks Darrick J. Wong
@ 2023-10-17 15:51   ` Darrick J. Wong
  6 siblings, 0 replies; 91+ messages in thread
From: Darrick J. Wong @ 2023-10-17 15:51 UTC (permalink / raw)
  To: djwong; +Cc: Christoph Hellwig, osandov, linux-xfs, hch

From: Darrick J. Wong <djwong@kernel.org>

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 <djwong@kernel.org>
Reviewed-by: Christoph Hellwig <hch@lst.de>
---
 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(+)


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;


^ permalink raw reply related	[flat|nested] 91+ messages in thread

* [PATCH 1/8] xfs: convert the rtbitmap block and bit macros to static inline functions
  2023-10-17 15:46 ` [PATCHSET RFC v1.1 0/8] xfs: refactor rtbitmap/summary macros Darrick J. Wong
@ 2023-10-17 15:52   ` Darrick J. Wong
  2023-10-17 15:52   ` [PATCH 2/8] xfs: remove XFS_BLOCKWSIZE and XFS_BLOCKWMASK macros Darrick J. Wong
                     ` (7 subsequent siblings)
  8 siblings, 0 replies; 91+ messages in thread
From: Darrick J. Wong @ 2023-10-17 15:52 UTC (permalink / raw)
  To: djwong; +Cc: Christoph Hellwig, osandov, linux-xfs, hch

From: Darrick J. Wong <djwong@kernel.org>

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 <djwong@kernel.org>
Reviewed-by: Christoph Hellwig <hch@lst.de>
---
 fs/xfs/libxfs/xfs_format.h   |    5 -----
 fs/xfs/libxfs/xfs_rtbitmap.c |   22 +++++++++++-----------
 fs/xfs/libxfs/xfs_rtbitmap.h |   27 +++++++++++++++++++++++++++
 fs/xfs/scrub/rtsummary.c     |    2 +-
 fs/xfs/xfs_rtalloc.c         |   20 ++++++++++----------
 5 files changed, 49 insertions(+), 27 deletions(-)


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..f7c744f1600a 100644
--- a/fs/xfs/libxfs/xfs_rtbitmap.c
+++ b/fs/xfs/libxfs/xfs_rtbitmap.c
@@ -116,7 +116,7 @@ xfs_rtfind_back(
 	/*
 	 * 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;
@@ -291,7 +291,7 @@ xfs_rtfind_forw(
 	/*
 	 * 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;
@@ -552,7 +552,7 @@ xfs_rtmodify_range(
 	/*
 	 * 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;
 }
 
@@ -786,7 +786,7 @@ xfs_rtcheck_range(
 	/*
 	 * 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;
 		}
 	}
 	/*


^ permalink raw reply related	[flat|nested] 91+ messages in thread

* [PATCH 2/8] xfs: remove XFS_BLOCKWSIZE and XFS_BLOCKWMASK macros
  2023-10-17 15:46 ` [PATCHSET RFC v1.1 0/8] xfs: refactor rtbitmap/summary macros Darrick J. Wong
  2023-10-17 15:52   ` [PATCH 1/8] xfs: convert the rtbitmap block and bit macros to static inline functions Darrick J. Wong
@ 2023-10-17 15:52   ` Darrick J. Wong
  2023-10-17 15:52   ` [PATCH 3/8] xfs: convert open-coded xfs_rtword_t pointer accesses to helper Darrick J. Wong
                     ` (6 subsequent siblings)
  8 siblings, 0 replies; 91+ messages in thread
From: Darrick J. Wong @ 2023-10-17 15:52 UTC (permalink / raw)
  To: djwong; +Cc: Christoph Hellwig, osandov, linux-xfs, hch

From: Darrick J. Wong <djwong@kernel.org>

Remove these trivial macros since they're not even part of the ondisk
format.

Signed-off-by: Darrick J. Wong <djwong@kernel.org>
Reviewed-by: Christoph Hellwig <hch@lst.de>
---
 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(-)


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 f7c744f1600a..6ec539aa1b92 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. */


^ permalink raw reply related	[flat|nested] 91+ messages in thread

* [PATCH 3/8] xfs: convert open-coded xfs_rtword_t pointer accesses to helper
  2023-10-17 15:46 ` [PATCHSET RFC v1.1 0/8] xfs: refactor rtbitmap/summary macros Darrick J. Wong
  2023-10-17 15:52   ` [PATCH 1/8] xfs: convert the rtbitmap block and bit macros to static inline functions Darrick J. Wong
  2023-10-17 15:52   ` [PATCH 2/8] xfs: remove XFS_BLOCKWSIZE and XFS_BLOCKWMASK macros Darrick J. Wong
@ 2023-10-17 15:52   ` Darrick J. Wong
  2023-10-17 16:31     ` Christoph Hellwig
  2023-10-17 15:52   ` [PATCH 4/8] xfs: convert rt summary macros to helpers Darrick J. Wong
                     ` (5 subsequent siblings)
  8 siblings, 1 reply; 91+ messages in thread
From: Darrick J. Wong @ 2023-10-17 15:52 UTC (permalink / raw)
  To: djwong; +Cc: osandov, linux-xfs, hch

From: Darrick J. Wong <djwong@kernel.org>

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 <djwong@kernel.org>
---
 fs/xfs/libxfs/xfs_rtbitmap.c |   59 ++++++++++++++++++++++--------------------
 fs/xfs/libxfs/xfs_rtbitmap.h |   11 ++++++++
 2 files changed, 42 insertions(+), 28 deletions(-)


diff --git a/fs/xfs/libxfs/xfs_rtbitmap.c b/fs/xfs/libxfs/xfs_rtbitmap.c
index 6ec539aa1b92..ce8a218f8e65 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.
  */


^ permalink raw reply related	[flat|nested] 91+ messages in thread

* [PATCH 4/8] xfs: convert rt summary macros to helpers
  2023-10-17 15:46 ` [PATCHSET RFC v1.1 0/8] xfs: refactor rtbitmap/summary macros Darrick J. Wong
                     ` (2 preceding siblings ...)
  2023-10-17 15:52   ` [PATCH 3/8] xfs: convert open-coded xfs_rtword_t pointer accesses to helper Darrick J. Wong
@ 2023-10-17 15:52   ` Darrick J. Wong
  2023-10-17 15:53   ` [PATCH 5/8] xfs: create helpers for rtbitmap block/wordcount computations Darrick J. Wong
                     ` (4 subsequent siblings)
  8 siblings, 0 replies; 91+ messages in thread
From: Darrick J. Wong @ 2023-10-17 15:52 UTC (permalink / raw)
  To: djwong; +Cc: Christoph Hellwig, osandov, linux-xfs, hch

From: Darrick J. Wong <djwong@kernel.org>

Convert the realtime summary file macros to helper functions so that we
can improve type checking.

Signed-off-by: Darrick J. Wong <djwong@kernel.org>
Reviewed-by: Christoph Hellwig <hch@lst.de>
---
 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     |   10 ++++----
 5 files changed, 64 insertions(+), 17 deletions(-)


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 ce8a218f8e65..093a4b7b00f0 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..9503e32ee07a 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);


^ permalink raw reply related	[flat|nested] 91+ messages in thread

* [PATCH 5/8] xfs: create helpers for rtbitmap block/wordcount computations
  2023-10-17 15:46 ` [PATCHSET RFC v1.1 0/8] xfs: refactor rtbitmap/summary macros Darrick J. Wong
                     ` (3 preceding siblings ...)
  2023-10-17 15:52   ` [PATCH 4/8] xfs: convert rt summary macros to helpers Darrick J. Wong
@ 2023-10-17 15:53   ` Darrick J. Wong
  2023-10-17 16:33     ` Christoph Hellwig
  2023-10-17 15:53   ` [PATCH 6/8] xfs: use accessor functions for bitmap words Darrick J. Wong
                     ` (3 subsequent siblings)
  8 siblings, 1 reply; 91+ messages in thread
From: Darrick J. Wong @ 2023-10-17 15:53 UTC (permalink / raw)
  To: djwong; +Cc: osandov, linux-xfs, hch

From: Darrick J. Wong <djwong@kernel.org>

Create helper functions that compute the number of blocks or words
necessary to store the rt bitmap.

Signed-off-by: Darrick J. Wong <djwong@kernel.org>
---
 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(-)


diff --git a/fs/xfs/libxfs/xfs_rtbitmap.c b/fs/xfs/libxfs/xfs_rtbitmap.c
index 093a4b7b00f0..ff3d10d67bde 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 9503e32ee07a..ae51fb982808 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;


^ permalink raw reply related	[flat|nested] 91+ messages in thread

* [PATCH 6/8] xfs: use accessor functions for bitmap words
  2023-10-17 15:46 ` [PATCHSET RFC v1.1 0/8] xfs: refactor rtbitmap/summary macros Darrick J. Wong
                     ` (4 preceding siblings ...)
  2023-10-17 15:53   ` [PATCH 5/8] xfs: create helpers for rtbitmap block/wordcount computations Darrick J. Wong
@ 2023-10-17 15:53   ` Darrick J. Wong
  2023-10-17 18:53     ` Christoph Hellwig
  2023-10-17 15:53   ` [PATCH 7/8] xfs: create helpers for rtsummary block/wordcount computations Darrick J. Wong
                     ` (2 subsequent siblings)
  8 siblings, 1 reply; 91+ messages in thread
From: Darrick J. Wong @ 2023-10-17 15:53 UTC (permalink / raw)
  To: djwong; +Cc: osandov, linux-xfs, hch

From: Darrick J. Wong <djwong@kernel.org>

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.

Signed-off-by: Darrick J. Wong <djwong@kernel.org>
---
 fs/xfs/libxfs/xfs_format.h   |    8 ++++
 fs/xfs/libxfs/xfs_rtbitmap.c |   78 +++++++++++++++++++++++++++++++-----------
 fs/xfs/libxfs/xfs_rtbitmap.h |    8 +++-
 fs/xfs/xfs_ondisk.h          |    3 ++
 4 files changed, 74 insertions(+), 23 deletions(-)


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 ff3d10d67bde..f8daaff947fc 100644
--- a/fs/xfs/libxfs/xfs_rtbitmap.c
+++ b/fs/xfs/libxfs/xfs_rtbitmap.c
@@ -87,6 +87,25 @@ xfs_rtbuf_get(
 	return 0;
 }
 
+/* Convert an ondisk bitmap word to its incore representation. */
+inline xfs_rtword_t
+xfs_rtbitmap_getword(
+	struct xfs_mount	*mp,
+	union xfs_rtword_raw	*wordptr)
+{
+	return wordptr->old;
+}
+
+/* Set an ondisk bitmap word from an incore representation. */
+inline void
+xfs_rtbitmap_setword(
+	struct xfs_mount	*mp,
+	union xfs_rtword_raw	*wordptr,
+	xfs_rtword_t		incore)
+{
+	wordptr->old = incore;
+}
+
 /*
  * Searching backward from start to limit, find the first block whose
  * allocated/free state is different from start's.
@@ -99,7 +118,7 @@ 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 */
+	union xfs_rtword_raw *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 +129,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;
 	int		word;		/* word number in the buffer */
 
 	/*
@@ -132,7 +152,8 @@ xfs_rtfind_back(
 	 * 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(mp, b);
+	want = (incore & ((xfs_rtword_t)1 << bit)) ? -1 : 0;
 	/*
 	 * If the starting position is not word-aligned, deal with the
 	 * partial word.
@@ -149,7 +170,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.
 			 */
@@ -195,7 +216,8 @@ xfs_rtfind_back(
 		/*
 		 * Compute difference between actual and desired value.
 		 */
-		if ((wdiff = *b ^ want)) {
+		incore = xfs_rtbitmap_getword(mp, b);
+		if ((wdiff = incore ^ want)) {
 			/*
 			 * Different, mark where we are and return.
 			 */
@@ -242,7 +264,8 @@ xfs_rtfind_back(
 		/*
 		 * Compute difference between actual and desired value.
 		 */
-		if ((wdiff = (*b ^ want) & mask)) {
+		incore = xfs_rtbitmap_getword(mp, b);
+		if ((wdiff = (incore ^ want) & mask)) {
 			/*
 			 * Different, mark where we are and return.
 			 */
@@ -273,7 +296,7 @@ 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 */
+	union xfs_rtword_raw *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 +307,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;
 	int		word;		/* word number in the buffer */
 
 	/*
@@ -306,7 +330,8 @@ xfs_rtfind_forw(
 	 * 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(mp, b);
+	want = (incore & ((xfs_rtword_t)1 << bit)) ? -1 : 0;
 	/*
 	 * If the starting position is not word-aligned, deal with the
 	 * partial word.
@@ -322,7 +347,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.
 			 */
@@ -368,7 +393,8 @@ xfs_rtfind_forw(
 		/*
 		 * Compute difference between actual and desired value.
 		 */
-		if ((wdiff = *b ^ want)) {
+		incore = xfs_rtbitmap_getword(mp, b);
+		if ((wdiff = incore ^ want)) {
 			/*
 			 * Different, mark where we are and return.
 			 */
@@ -413,7 +439,8 @@ xfs_rtfind_forw(
 		/*
 		 * Compute difference between actual and desired value.
 		 */
-		if ((wdiff = (*b ^ want) & mask)) {
+		incore = xfs_rtbitmap_getword(mp, b);
+		if ((wdiff = (incore ^ want) & mask)) {
 			/*
 			 * Different, mark where we are and return.
 			 */
@@ -539,15 +566,16 @@ 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 */
+	union xfs_rtword_raw *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 */
+	union xfs_rtword_raw *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;
 	int		word;		/* word number in the buffer */
 
 	/*
@@ -585,10 +613,12 @@ xfs_rtmodify_range(
 		/*
 		 * Set/clear the active bits.
 		 */
+		incore = xfs_rtbitmap_getword(mp, b);
 		if (val)
-			*b |= mask;
+			incore |= mask;
 		else
-			*b &= ~mask;
+			incore &= ~mask;
+		xfs_rtbitmap_setword(mp, b, incore);
 		i = lastbit - bit;
 		/*
 		 * Go on to the next block if that's where the next word is
@@ -629,7 +659,7 @@ xfs_rtmodify_range(
 		/*
 		 * Set the word value correctly.
 		 */
-		*b = val;
+		xfs_rtbitmap_setword(mp, b, val);
 		i += XFS_NBWORD;
 		/*
 		 * Go on to the next block if that's where the next word is
@@ -669,10 +699,12 @@ xfs_rtmodify_range(
 		/*
 		 * Set/clear the active bits.
 		 */
+		incore = xfs_rtbitmap_getword(mp, b);
 		if (val)
-			*b |= mask;
+			incore |= mask;
 		else
-			*b &= ~mask;
+			incore &= ~mask;
+		xfs_rtbitmap_setword(mp, b, incore);
 		b++;
 	}
 	/*
@@ -775,7 +807,7 @@ 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 */
+	union xfs_rtword_raw *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 */
@@ -784,6 +816,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;
 	int		word;		/* word number in the buffer */
 
 	/*
@@ -824,7 +857,8 @@ xfs_rtcheck_range(
 		/*
 		 * Compute difference between actual and desired value.
 		 */
-		if ((wdiff = (*b ^ val) & mask)) {
+		incore = xfs_rtbitmap_getword(mp, b);
+		if ((wdiff = (incore ^ val) & mask)) {
 			/*
 			 * Different, compute first wrong bit and return.
 			 */
@@ -871,7 +905,8 @@ xfs_rtcheck_range(
 		/*
 		 * Compute difference between actual and desired value.
 		 */
-		if ((wdiff = *b ^ val)) {
+		incore = xfs_rtbitmap_getword(mp, b);
+		if ((wdiff = incore ^ val)) {
 			/*
 			 * Different, compute first wrong bit and return.
 			 */
@@ -917,7 +952,8 @@ xfs_rtcheck_range(
 		/*
 		 * Compute difference between actual and desired value.
 		 */
-		if ((wdiff = (*b ^ val) & mask)) {
+		incore = xfs_rtbitmap_getword(mp, b);
+		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..4e33e84afa7a 100644
--- a/fs/xfs/libxfs/xfs_rtbitmap.h
+++ b/fs/xfs/libxfs/xfs_rtbitmap.h
@@ -159,12 +159,12 @@ 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;
 }
@@ -285,6 +285,10 @@ 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_rtword_t xfs_rtbitmap_getword(struct xfs_mount *mp,
+		union xfs_rtword_raw *wordptr);
+void xfs_rtbitmap_setword(struct xfs_mount *mp,
+		union xfs_rtword_raw *wordptr, xfs_rtword_t incore);
 #else /* CONFIG_XFS_RT */
 # define xfs_rtfree_extent(t,b,l)			(-ENOSYS)
 # define xfs_rtfree_blocks(t,rb,rl)			(-ENOSYS)
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


^ permalink raw reply related	[flat|nested] 91+ messages in thread

* [PATCH 7/8] xfs: create helpers for rtsummary block/wordcount computations
  2023-10-17 15:46 ` [PATCHSET RFC v1.1 0/8] xfs: refactor rtbitmap/summary macros Darrick J. Wong
                     ` (5 preceding siblings ...)
  2023-10-17 15:53   ` [PATCH 6/8] xfs: use accessor functions for bitmap words Darrick J. Wong
@ 2023-10-17 15:53   ` Darrick J. Wong
  2023-10-17 15:53   ` [PATCH 8/8] xfs: use accessor functions for summary info words Darrick J. Wong
  2023-10-18  2:10   ` [PATCHSET RFC v1.2 0/4] xfs: refactor rtbitmap/summary accessors Darrick J. Wong
  8 siblings, 0 replies; 91+ messages in thread
From: Darrick J. Wong @ 2023-10-17 15:53 UTC (permalink / raw)
  To: djwong; +Cc: Christoph Hellwig, osandov, linux-xfs, hch

From: Darrick J. Wong <djwong@kernel.org>

Create helper functions that compute the number of blocks or words
necessary to store the rt summary file.

Signed-off-by: Darrick J. Wong <djwong@kernel.org>
Reviewed-by: Christoph Hellwig <hch@lst.de>
---
 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(-)


diff --git a/fs/xfs/libxfs/xfs_rtbitmap.c b/fs/xfs/libxfs/xfs_rtbitmap.c
index f8daaff947fc..cd10e4a7f21e 100644
--- a/fs/xfs/libxfs/xfs_rtbitmap.c
+++ b/fs/xfs/libxfs/xfs_rtbitmap.c
@@ -1198,3 +1198,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 4e33e84afa7a..c4b013929457 100644
--- a/fs/xfs/libxfs/xfs_rtbitmap.h
+++ b/fs/xfs/libxfs/xfs_rtbitmap.h
@@ -289,6 +289,11 @@ xfs_rtword_t xfs_rtbitmap_getword(struct xfs_mount *mp,
 		union xfs_rtword_raw *wordptr);
 void xfs_rtbitmap_setword(struct xfs_mount *mp,
 		union xfs_rtword_raw *wordptr, xfs_rtword_t incore);
+
+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)
@@ -303,6 +308,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.


^ permalink raw reply related	[flat|nested] 91+ messages in thread

* [PATCH 8/8] xfs: use accessor functions for summary info words
  2023-10-17 15:46 ` [PATCHSET RFC v1.1 0/8] xfs: refactor rtbitmap/summary macros Darrick J. Wong
                     ` (6 preceding siblings ...)
  2023-10-17 15:53   ` [PATCH 7/8] xfs: create helpers for rtsummary block/wordcount computations Darrick J. Wong
@ 2023-10-17 15:53   ` Darrick J. Wong
  2023-10-18  2:10   ` [PATCHSET RFC v1.2 0/4] xfs: refactor rtbitmap/summary accessors Darrick J. Wong
  8 siblings, 0 replies; 91+ messages in thread
From: Darrick J. Wong @ 2023-10-17 15:53 UTC (permalink / raw)
  To: djwong; +Cc: osandov, linux-xfs, hch

From: Darrick J. Wong <djwong@kernel.org>

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 <djwong@kernel.org>
---
 fs/xfs/libxfs/xfs_format.h   |    8 ++++++++
 fs/xfs/libxfs/xfs_rtbitmap.c |   29 ++++++++++++++++++++++++-----
 fs/xfs/libxfs/xfs_rtbitmap.h |    8 ++++++--
 fs/xfs/scrub/rtsummary.c     |   20 +++++++++++---------
 fs/xfs/scrub/trace.c         |    1 +
 fs/xfs/scrub/trace.h         |    4 ++--
 fs/xfs/xfs_ondisk.h          |    1 +
 7 files changed, 53 insertions(+), 18 deletions(-)


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 cd10e4a7f21e..63a83e728724 100644
--- a/fs/xfs/libxfs/xfs_rtbitmap.c
+++ b/fs/xfs/libxfs/xfs_rtbitmap.c
@@ -459,6 +459,23 @@ xfs_rtfind_forw(
 	return 0;
 }
 
+inline xfs_suminfo_t
+xfs_suminfo_get(
+	struct xfs_mount	*mp,
+	union xfs_suminfo_raw	*infoptr)
+{
+	return infoptr->old;
+}
+
+inline void
+xfs_suminfo_add(
+	struct xfs_mount	*mp,
+	union xfs_suminfo_raw	*infoptr,
+	int			delta)
+{
+	infoptr->old += delta;
+}
+
 /*
  * Read and/or modify the summary information for a given extent size,
  * bitmap block combination.
@@ -483,7 +500,7 @@ 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 */
+	union xfs_suminfo_raw *sp;		/* pointer to returned data */
 	unsigned int	infoword;
 
 	/*
@@ -526,17 +543,19 @@ xfs_rtmodify_summary_int(
 	if (delta) {
 		uint first = (uint)((char *)sp - (char *)bp->b_addr);
 
-		*sp += delta;
+		xfs_suminfo_add(mp, sp, delta);
 		if (mp->m_rsum_cache) {
-			if (*sp == 0 && log == mp->m_rsum_cache[bbno])
+			xfs_suminfo_t	val = xfs_suminfo_get(mp, sp);
+
+			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_buf(tp, bp, first, first + sizeof(*sp) - 1);
 	}
 	if (sum)
-		*sum = *sp;
+		*sum = xfs_suminfo_get(mp, sp);
 	return 0;
 }
 
diff --git a/fs/xfs/libxfs/xfs_rtbitmap.h b/fs/xfs/libxfs/xfs_rtbitmap.h
index c4b013929457..6a0d8b8af36d 100644
--- a/fs/xfs/libxfs/xfs_rtbitmap.h
+++ b/fs/xfs/libxfs/xfs_rtbitmap.h
@@ -209,12 +209,12 @@ 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;
 }
@@ -294,6 +294,10 @@ 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);
+xfs_suminfo_t xfs_suminfo_get(struct xfs_mount *mp,
+		union xfs_suminfo_raw *infoptr);
+void xfs_suminfo_add(struct xfs_mount *mp, union xfs_suminfo_raw *infoptr,
+		int delta);
 #else /* CONFIG_XFS_RT */
 # define xfs_rtfree_extent(t,b,l)			(-ENOSYS)
 # define xfs_rtfree_blocks(t,rb,rl)			(-ENOSYS)
diff --git a/fs/xfs/scrub/rtsummary.c b/fs/xfs/scrub/rtsummary.c
index ae51fb982808..c6fdb65f20e2 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,10 +104,10 @@ 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);
 }
 
@@ -123,7 +125,7 @@ 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;
 	int				error = 0;
 
 	if (xchk_should_terminate(sc, &error))
@@ -147,9 +149,9 @@ xchk_rtsum_record_free(
 	if (error)
 		return error;
 
-	v++;
+	xfs_suminfo_add(mp, &v, 1);
 	trace_xchk_rtsum_record_free(mp, rec->ar_startext, rec->ar_extcount,
-			lenlog, offs, v);
+			lenlog, offs, &v);
 
 	return xfsum_store(sc, offs, v);
 }
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..95befb325cc0 100644
--- a/fs/xfs/scrub/trace.h
+++ b/fs/xfs/scrub/trace.h
@@ -1038,7 +1038,7 @@ 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),
+		 union xfs_suminfo_raw *v),
 	TP_ARGS(mp, start, len, log, pos, v),
 	TP_STRUCT__entry(
 		__field(dev_t, dev)
@@ -1056,7 +1056,7 @@ TRACE_EVENT(xchk_rtsum_record_free,
 		__entry->len = len;
 		__entry->log = log;
 		__entry->pos = pos;
-		__entry->v = v;
+		__entry->v = xfs_suminfo_get(mp, v);
 	),
 	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),
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


^ permalink raw reply related	[flat|nested] 91+ messages in thread

* [PATCH 1/7] xfs: consolidate realtime allocation arguments
  2023-10-17 15:46 ` [PATCHSET RFC 2.1 0/7] xfs: CPU usage optimizations for realtime allocator Darrick J. Wong
@ 2023-10-17 15:54   ` Darrick J. Wong
  2023-10-18  6:16     ` Christoph Hellwig
  2023-10-17 15:54   ` [PATCH 2/7] xfs: cache last bitmap block in realtime allocator Darrick J. Wong
                     ` (6 subsequent siblings)
  7 siblings, 1 reply; 91+ messages in thread
From: Darrick J. Wong @ 2023-10-17 15:54 UTC (permalink / raw)
  To: djwong; +Cc: Dave Chinner, osandov, osandov, linux-xfs, hch

From: Dave Chinner <dchinner@redhat.com>

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 <dchinner@redhat.com>
Reviewed-by: Darrick J. Wong <djwong@kernel.org>
Signed-off-by: Darrick J. Wong <djwong@kernel.org>
---
 fs/xfs/libxfs/xfs_rtbitmap.c |  371 +++++++++++++++++++++---------------------
 fs/xfs/libxfs/xfs_rtbitmap.h |   46 +++--
 fs/xfs/scrub/rtsummary.c     |    6 +
 fs/xfs/xfs_rtalloc.c         |  317 ++++++++++++++++++------------------
 4 files changed, 380 insertions(+), 360 deletions(-)


diff --git a/fs/xfs/libxfs/xfs_rtbitmap.c b/fs/xfs/libxfs/xfs_rtbitmap.c
index 63a83e728724..5a7994e031f3 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->mount;
+	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;		/* error value */
 
 	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->trans, 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->trans, bp, issum ? XFS_BLFT_RTSUMMARY_BUF
 					     : XFS_BLFT_RTBITMAP_BUF);
 	*bpp = bp;
 	return 0;
@@ -112,31 +112,31 @@ xfs_rtbitmap_setword(
  */
 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 */
 {
-	union xfs_rtword_raw *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_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;
-	int		word;		/* word number in the buffer */
+	struct xfs_mount	*mp = args->mount;
+	union xfs_rtword_raw	*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_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;
+	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;
 	}
@@ -174,7 +174,7 @@ xfs_rtfind_back(
 			/*
 			 * Different.  Mark where we are and return.
 			 */
-			xfs_trans_brelse(tp, bp);
+			xfs_trans_brelse(args->trans, bp);
 			i = bit - XFS_RTHIBIT(wdiff);
 			*rtx = start - i + 1;
 			return 0;
@@ -188,8 +188,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->trans, bp);
+			error = xfs_rtbuf_get(args, --block, 0, &bp);
 			if (error) {
 				return error;
 			}
@@ -221,7 +221,7 @@ xfs_rtfind_back(
 			/*
 			 * Different, mark where we are and return.
 			 */
-			xfs_trans_brelse(tp, bp);
+			xfs_trans_brelse(args->trans, bp);
 			i += XFS_NBWORD - 1 - XFS_RTHIBIT(wdiff);
 			*rtx = start - i + 1;
 			return 0;
@@ -235,8 +235,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->trans, bp);
+			error = xfs_rtbuf_get(args, --block, 0, &bp);
 			if (error) {
 				return error;
 			}
@@ -269,7 +269,7 @@ xfs_rtfind_back(
 			/*
 			 * Different, mark where we are and return.
 			 */
-			xfs_trans_brelse(tp, bp);
+			xfs_trans_brelse(args->trans, bp);
 			i += XFS_NBWORD - 1 - XFS_RTHIBIT(wdiff);
 			*rtx = start - i + 1;
 			return 0;
@@ -279,7 +279,7 @@ xfs_rtfind_back(
 	/*
 	 * No match, return that we scanned the whole area.
 	 */
-	xfs_trans_brelse(tp, bp);
+	xfs_trans_brelse(args->trans, bp);
 	*rtx = start - i + 1;
 	return 0;
 }
@@ -290,31 +290,31 @@ 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 */
 {
-	union xfs_rtword_raw *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_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;
-	int		word;		/* word number in the buffer */
+	struct xfs_mount	*mp = args->mount;
+	union xfs_rtword_raw	*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_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;
+	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;
 	}
@@ -351,7 +351,7 @@ xfs_rtfind_forw(
 			/*
 			 * Different.  Mark where we are and return.
 			 */
-			xfs_trans_brelse(tp, bp);
+			xfs_trans_brelse(args->trans, bp);
 			i = XFS_RTLOBIT(wdiff) - bit;
 			*rtx = start + i - 1;
 			return 0;
@@ -365,8 +365,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->trans, bp);
+			error = xfs_rtbuf_get(args, ++block, 0, &bp);
 			if (error) {
 				return error;
 			}
@@ -398,7 +398,7 @@ xfs_rtfind_forw(
 			/*
 			 * Different, mark where we are and return.
 			 */
-			xfs_trans_brelse(tp, bp);
+			xfs_trans_brelse(args->trans, bp);
 			i += XFS_RTLOBIT(wdiff);
 			*rtx = start + i - 1;
 			return 0;
@@ -412,8 +412,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->trans, bp);
+			error = xfs_rtbuf_get(args, ++block, 0, &bp);
 			if (error) {
 				return error;
 			}
@@ -444,7 +444,7 @@ xfs_rtfind_forw(
 			/*
 			 * Different, mark where we are and return.
 			 */
-			xfs_trans_brelse(tp, bp);
+			xfs_trans_brelse(args->trans, bp);
 			i += XFS_RTLOBIT(wdiff);
 			*rtx = start + i - 1;
 			return 0;
@@ -454,7 +454,7 @@ xfs_rtfind_forw(
 	/*
 	 * No match, return that we scanned the whole area.
 	 */
-	xfs_trans_brelse(tp, bp);
+	xfs_trans_brelse(args->trans, bp);
 	*rtx = start + i - 1;
 	return 0;
 }
@@ -487,21 +487,21 @@ xfs_suminfo_add(
  */
 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 */
-	union xfs_suminfo_raw *sp;		/* pointer to returned data */
-	unsigned int	infoword;
+	struct xfs_mount	*mp = args->mount;
+	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 */
+	union xfs_suminfo_raw	*sp;		/* pointer to returned data */
+	unsigned int		infoword;
 
 	/*
 	 * Compute entry number in the summary file.
@@ -524,8 +524,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->trans, *rbpp);
+		error = xfs_rtbuf_get(args, sb, 1, &bp);
 		if (error) {
 			return error;
 		}
@@ -552,7 +552,7 @@ xfs_rtmodify_summary_int(
 			if (val != 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_buf(args->trans, bp, first, first + sizeof(*sp) - 1);
 	}
 	if (sum)
 		*sum = xfs_suminfo_get(mp, sp);
@@ -561,16 +561,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);
 }
 
 /*
@@ -579,23 +577,23 @@ xfs_rtmodify_summary(
  */
 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 */
 {
-	union xfs_rtword_raw *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 */
-	union xfs_rtword_raw *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;
-	int		word;		/* word number in the buffer */
+	struct xfs_mount	*mp = args->mount;
+	union xfs_rtword_raw	*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 */
+	union xfs_rtword_raw	*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;
+	int			word;		/* word number in the buffer */
 
 	/*
 	 * Compute starting bitmap block number.
@@ -604,7 +602,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;
 	}
@@ -648,10 +646,10 @@ xfs_rtmodify_range(
 			 * Log the changed part of this block.
 			 * Get the next one.
 			 */
-			xfs_trans_log_buf(tp, bp,
+			xfs_trans_log_buf(args->trans, bp,
 				(uint)((char *)first - (char *)bp->b_addr),
 				(uint)((char *)b - (char *)bp->b_addr));
-			error = xfs_rtbuf_get(mp, tp, ++block, 0, &bp);
+			error = xfs_rtbuf_get(args, ++block, 0, &bp);
 			if (error) {
 				return error;
 			}
@@ -689,10 +687,10 @@ xfs_rtmodify_range(
 			 * Log the changed part of this block.
 			 * Get the next one.
 			 */
-			xfs_trans_log_buf(tp, bp,
+			xfs_trans_log_buf(args->trans, bp,
 				(uint)((char *)first - (char *)bp->b_addr),
 				(uint)((char *)b - (char *)bp->b_addr));
-			error = xfs_rtbuf_get(mp, tp, ++block, 0, &bp);
+			error = xfs_rtbuf_get(args, ++block, 0, &bp);
 			if (error) {
 				return error;
 			}
@@ -730,9 +728,9 @@ xfs_rtmodify_range(
 	 * 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_buf(args->trans, bp,
+				(uint)((char *)first - (char *)bp->b_addr),
+				(uint)((char *)b - (char *)bp->b_addr - 1));
 	return 0;
 }
 
@@ -742,23 +740,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->mount;
+	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;
 	}
@@ -767,14 +765,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;
@@ -783,7 +781,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) {
@@ -795,7 +793,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) {
@@ -806,7 +804,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;
@@ -818,25 +816,25 @@ 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 */
 {
-	union xfs_rtword_raw *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_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;
-	int		word;		/* word number in the buffer */
+	struct xfs_mount	*mp = args->mount;
+	union xfs_rtword_raw	*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_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;
+	int			word;		/* word number in the buffer */
 
 	/*
 	 * Compute starting bitmap block number
@@ -845,7 +843,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;
 	}
@@ -881,7 +879,7 @@ xfs_rtcheck_range(
 			/*
 			 * Different, compute first wrong bit and return.
 			 */
-			xfs_trans_brelse(tp, bp);
+			xfs_trans_brelse(args->trans, bp);
 			i = XFS_RTLOBIT(wdiff) - bit;
 			*new = start + i;
 			*stat = 0;
@@ -896,8 +894,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->trans, bp);
+			error = xfs_rtbuf_get(args, ++block, 0, &bp);
 			if (error) {
 				return error;
 			}
@@ -929,7 +927,7 @@ xfs_rtcheck_range(
 			/*
 			 * Different, compute first wrong bit and return.
 			 */
-			xfs_trans_brelse(tp, bp);
+			xfs_trans_brelse(args->trans, bp);
 			i += XFS_RTLOBIT(wdiff);
 			*new = start + i;
 			*stat = 0;
@@ -944,8 +942,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->trans, bp);
+			error = xfs_rtbuf_get(args, ++block, 0, &bp);
 			if (error) {
 				return error;
 			}
@@ -976,7 +974,7 @@ xfs_rtcheck_range(
 			/*
 			 * Different, compute first wrong bit and return.
 			 */
-			xfs_trans_brelse(tp, bp);
+			xfs_trans_brelse(args->trans, bp);
 			i += XFS_RTLOBIT(wdiff);
 			*new = start + i;
 			*stat = 0;
@@ -987,7 +985,7 @@ xfs_rtcheck_range(
 	/*
 	 * Successful, return.
 	 */
-	xfs_trans_brelse(tp, bp);
+	xfs_trans_brelse(args->trans, bp);
 	*new = start + i;
 	*stat = 1;
 	return 0;
@@ -999,23 +997,22 @@ xfs_rtcheck_range(
  */
 STATIC int				/* error */
 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
@@ -1023,28 +1020,30 @@ xfs_rtcheck_alloc_range(
  */
 int					/* error */
 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 = {
+		.mount		= mp,
+		.trans		= tp,
+	};
+	int			error;		/* error value */
+	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;
 	}
@@ -1109,6 +1108,10 @@ xfs_rtalloc_query_range(
 	xfs_rtalloc_query_range_fn	fn,
 	void				*priv)
 {
+	struct xfs_rtalloc_args		args = {
+		.mount	= mp,
+		.trans	= tp,
+	};
 	struct xfs_rtalloc_rec		rec;
 	xfs_rtxnum_t			rtstart;
 	xfs_rtxnum_t			rtend;
@@ -1128,13 +1131,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;
 
@@ -1179,11 +1182,15 @@ xfs_rtalloc_extent_is_free(
 	xfs_rtxlen_t			len,
 	bool				*is_free)
 {
+	struct xfs_rtalloc_args		args = {
+		.mount			= mp,
+		.trans			= 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 6a0d8b8af36d..39da0adf0f45 100644
--- a/fs/xfs/libxfs/xfs_rtbitmap.h
+++ b/fs/xfs/libxfs/xfs_rtbitmap.h
@@ -234,29 +234,29 @@ 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);
+struct xfs_rtalloc_args {
+	struct xfs_mount	*mount;
+	struct xfs_trans	*trans;
+};
+
+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 c6fdb65f20e2..3f6f6efe7375 100644
--- a/fs/xfs/scrub/rtsummary.c
+++ b/fs/xfs/scrub/rtsummary.c
@@ -178,6 +178,10 @@ STATIC int
 xchk_rtsum_compare(
 	struct xfs_scrub	*sc)
 {
+	struct xfs_rtalloc_args args = {
+		.mount = sc->mp,
+		.trans = sc->tp,
+	};
 	struct xfs_mount	*mp = sc->mp;
 	struct xfs_buf		*bp;
 	struct xfs_bmbt_irec	map;
@@ -206,7 +210,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..922d2fdcf953 100644
--- a/fs/xfs/xfs_rtalloc.c
+++ b/fs/xfs/xfs_rtalloc.c
@@ -29,15 +29,14 @@
  */
 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);
 }
 
 /*
@@ -46,18 +45,18 @@ xfs_rtget_summary(
  */
 STATIC int				/* error */
 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->mount;
+	int			error;		/* error value */
+	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;
 		}
@@ -100,33 +99,32 @@ xfs_rtany_summary(
  */
 STATIC int				/* error */
 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;		/* error return value */
+	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->mount->m_rsumlevels - 1; log >= 0; log--) {
+		for (bbno = oargs->mount->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;
@@ -141,17 +139,17 @@ xfs_rtcopy_summary(
  */
 STATIC int				/* error */
 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->mount;
+	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 */
 
 	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;
 }
 
@@ -237,25 +235,25 @@ xfs_rtallocate_clamp_len(
  */
 STATIC int				/* error */
 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->mount;
+	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 */
 
 	/*
 	 * 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;
 		}
@@ -357,28 +355,27 @@ xfs_rtallocate_extent_block(
  */
 STATIC int				/* error */
 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;		/* 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) */
 
 	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;
 	}
@@ -437,25 +434,25 @@ xfs_rtallocate_extent_exact(
  */
 STATIC int				/* error */
 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->mount;
+	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 */
 
 	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) {
@@ -642,22 +639,22 @@ xfs_rtallocate_extent_near(
  */
 STATIC int				/* error */
 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->mount;
+	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 */
 
 	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 = {
+			.mount	= mp,
+		};
+		struct xfs_rtalloc_args	nargs = {
+			.mount	= nmp,
+		};
 		struct xfs_trans	*tp;
 		xfs_rfsblock_t		nrblocks_step;
 
@@ -1072,6 +1075,9 @@ xfs_growfs_rt(
 				&tp);
 		if (error)
 			break;
+		args.trans = tp;
+		nargs.trans = 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:
@@ -1192,22 +1198,25 @@ xfs_growfs_rt(
  */
 int					/* error */
 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,		/* 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 */
 {
-	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 = {
+		.mount		= tp->t_mountp,
+		.trans		= tp,
+	};
+	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(mp->m_rbmip, XFS_ILOCK_EXCL));
+	ASSERT(xfs_isilocked(args.mount->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)


^ permalink raw reply related	[flat|nested] 91+ messages in thread

* [PATCH 2/7] xfs: cache last bitmap block in realtime allocator
  2023-10-17 15:46 ` [PATCHSET RFC 2.1 0/7] xfs: CPU usage optimizations for realtime allocator Darrick J. Wong
  2023-10-17 15:54   ` [PATCH 1/7] xfs: consolidate realtime allocation arguments Darrick J. Wong
@ 2023-10-17 15:54   ` Darrick J. Wong
  2023-10-18  6:19     ` Christoph Hellwig
  2023-10-18 18:28     ` Darrick J. Wong
  2023-10-17 15:54   ` [PATCH 3/7] xfs: invert the realtime summary cache Darrick J. Wong
                     ` (5 subsequent siblings)
  7 siblings, 2 replies; 91+ messages in thread
From: Darrick J. Wong @ 2023-10-17 15:54 UTC (permalink / raw)
  To: djwong; +Cc: Omar Sandoval, Christoph Hellwig, osandov, osandov, linux-xfs, hch

From: Omar Sandoval <osandov@fb.com>

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 <osandov@fb.com>
Reviewed-by: Darrick J. Wong <djwong@kernel.org>
Signed-off-by: Darrick J. Wong <djwong@kernel.org>
Reviewed-by: Christoph Hellwig <hch@lst.de>
---
 fs/xfs/libxfs/xfs_rtbitmap.c |  130 ++++++++++++++++++++----------------------
 fs/xfs/libxfs/xfs_rtbitmap.h |   17 ++++-
 fs/xfs/scrub/rtsummary.c     |    4 +
 fs/xfs/xfs_rtalloc.c         |  109 ++++++++++++++---------------------
 4 files changed, 120 insertions(+), 140 deletions(-)


diff --git a/fs/xfs/libxfs/xfs_rtbitmap.c b/fs/xfs/libxfs/xfs_rtbitmap.c
index 5a7994e031f3..428a3a5b660d 100644
--- a/fs/xfs/libxfs/xfs_rtbitmap.c
+++ b/fs/xfs/libxfs/xfs_rtbitmap.c
@@ -47,6 +47,20 @@ const struct xfs_buf_ops xfs_rtbuf_ops = {
 	.verify_write = xfs_rtbuf_verify_write,
 };
 
+void
+xfs_rtbuf_cache_relse(
+	struct xfs_rtalloc_args	*args)
+{
+	if (args->bbuf) {
+		xfs_trans_brelse(args->trans, args->bbuf);
+		args->bbuf = NULL;
+	}
+	if (args->sbuf) {
+		xfs_trans_brelse(args->trans, args->sbuf);
+		args->sbuf = NULL;
+	}
+}
+
 /*
  * Get a buffer for the bitmap or summary file block specified.
  * The buffer is returned read and locked.
@@ -59,12 +73,32 @@ xfs_rtbuf_get(
 	struct xfs_buf		**bpp)		/* output: buffer for the block */
 {
 	struct xfs_mount	*mp = args->mount;
+	struct xfs_buf		**cbpp;		/* cached block buffer */
+	xfs_fsblock_t		*cbp;		/* cached block number */
 	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;		/* error value */
 
+	cbpp = issum ? &args->bbuf : &args->sbuf;
+	cbp = issum ? &args->bblock : &args->sblock;
+	/*
+	 * If we have a cached buffer, and the block number matches, use that.
+	 */
+	if (*cbpp && *cbp == 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->trans, *cbpp);
+		*cbpp = NULL;
+	}
+
 	ip = issum ? mp->m_rsumip : mp->m_rbmip;
 
 	error = xfs_bmapi_read(ip, block, 1, &map, &nmap, 0);
@@ -83,7 +117,8 @@ xfs_rtbuf_get(
 
 	xfs_trans_buf_set_type(args->trans, bp, issum ? XFS_BLFT_RTSUMMARY_BUF
 					     : XFS_BLFT_RTBITMAP_BUF);
-	*bpp = bp;
+	*cbpp = *bpp = bp;
+	*cbp = block;
 	return 0;
 }
 
@@ -174,7 +209,6 @@ xfs_rtfind_back(
 			/*
 			 * Different.  Mark where we are and return.
 			 */
-			xfs_trans_brelse(args->trans, bp);
 			i = bit - XFS_RTHIBIT(wdiff);
 			*rtx = start - i + 1;
 			return 0;
@@ -188,7 +222,6 @@ xfs_rtfind_back(
 			/*
 			 * If done with this block, get the previous one.
 			 */
-			xfs_trans_brelse(args->trans, bp);
 			error = xfs_rtbuf_get(args, --block, 0, &bp);
 			if (error) {
 				return error;
@@ -221,7 +254,6 @@ xfs_rtfind_back(
 			/*
 			 * Different, mark where we are and return.
 			 */
-			xfs_trans_brelse(args->trans, bp);
 			i += XFS_NBWORD - 1 - XFS_RTHIBIT(wdiff);
 			*rtx = start - i + 1;
 			return 0;
@@ -235,7 +267,6 @@ xfs_rtfind_back(
 			/*
 			 * If done with this block, get the previous one.
 			 */
-			xfs_trans_brelse(args->trans, bp);
 			error = xfs_rtbuf_get(args, --block, 0, &bp);
 			if (error) {
 				return error;
@@ -269,7 +300,6 @@ xfs_rtfind_back(
 			/*
 			 * Different, mark where we are and return.
 			 */
-			xfs_trans_brelse(args->trans, bp);
 			i += XFS_NBWORD - 1 - XFS_RTHIBIT(wdiff);
 			*rtx = start - i + 1;
 			return 0;
@@ -279,7 +309,6 @@ xfs_rtfind_back(
 	/*
 	 * No match, return that we scanned the whole area.
 	 */
-	xfs_trans_brelse(args->trans, bp);
 	*rtx = start - i + 1;
 	return 0;
 }
@@ -351,7 +380,6 @@ xfs_rtfind_forw(
 			/*
 			 * Different.  Mark where we are and return.
 			 */
-			xfs_trans_brelse(args->trans, bp);
 			i = XFS_RTLOBIT(wdiff) - bit;
 			*rtx = start + i - 1;
 			return 0;
@@ -365,7 +393,6 @@ xfs_rtfind_forw(
 			/*
 			 * If done with this block, get the previous one.
 			 */
-			xfs_trans_brelse(args->trans, bp);
 			error = xfs_rtbuf_get(args, ++block, 0, &bp);
 			if (error) {
 				return error;
@@ -398,7 +425,6 @@ xfs_rtfind_forw(
 			/*
 			 * Different, mark where we are and return.
 			 */
-			xfs_trans_brelse(args->trans, bp);
 			i += XFS_RTLOBIT(wdiff);
 			*rtx = start + i - 1;
 			return 0;
@@ -412,7 +438,6 @@ xfs_rtfind_forw(
 			/*
 			 * If done with this block, get the next one.
 			 */
-			xfs_trans_brelse(args->trans, bp);
 			error = xfs_rtbuf_get(args, ++block, 0, &bp);
 			if (error) {
 				return error;
@@ -444,7 +469,6 @@ xfs_rtfind_forw(
 			/*
 			 * Different, mark where we are and return.
 			 */
-			xfs_trans_brelse(args->trans, bp);
 			i += XFS_RTLOBIT(wdiff);
 			*rtx = start + i - 1;
 			return 0;
@@ -454,7 +478,6 @@ xfs_rtfind_forw(
 	/*
 	 * No match, return that we scanned the whole area.
 	 */
-	xfs_trans_brelse(args->trans, bp);
 	*rtx = start + i - 1;
 	return 0;
 }
@@ -491,8 +514,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->mount;
@@ -511,30 +532,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->trans, *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.
 	 */
@@ -564,11 +566,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);
 }
 
 /*
@@ -742,9 +742,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->mount;
 	xfs_rtxnum_t		end;		/* end of the freed extent */
@@ -773,7 +771,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;
 	/*
@@ -782,8 +780,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;
 		}
@@ -794,8 +792,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;
 		}
@@ -804,10 +802,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);
 }
 
 /*
@@ -879,7 +876,6 @@ xfs_rtcheck_range(
 			/*
 			 * Different, compute first wrong bit and return.
 			 */
-			xfs_trans_brelse(args->trans, bp);
 			i = XFS_RTLOBIT(wdiff) - bit;
 			*new = start + i;
 			*stat = 0;
@@ -894,7 +890,6 @@ xfs_rtcheck_range(
 			/*
 			 * If done with this block, get the next one.
 			 */
-			xfs_trans_brelse(args->trans, bp);
 			error = xfs_rtbuf_get(args, ++block, 0, &bp);
 			if (error) {
 				return error;
@@ -927,7 +922,6 @@ xfs_rtcheck_range(
 			/*
 			 * Different, compute first wrong bit and return.
 			 */
-			xfs_trans_brelse(args->trans, bp);
 			i += XFS_RTLOBIT(wdiff);
 			*new = start + i;
 			*stat = 0;
@@ -942,7 +936,6 @@ xfs_rtcheck_range(
 			/*
 			 * If done with this block, get the next one.
 			 */
-			xfs_trans_brelse(args->trans, bp);
 			error = xfs_rtbuf_get(args, ++block, 0, &bp);
 			if (error) {
 				return error;
@@ -974,7 +967,6 @@ xfs_rtcheck_range(
 			/*
 			 * Different, compute first wrong bit and return.
 			 */
-			xfs_trans_brelse(args->trans, bp);
 			i += XFS_RTLOBIT(wdiff);
 			*new = start + i;
 			*stat = 0;
@@ -985,7 +977,6 @@ xfs_rtcheck_range(
 	/*
 	 * Successful, return.
 	 */
-	xfs_trans_brelse(args->trans, bp);
 	*new = start + i;
 	*stat = 1;
 	return 0;
@@ -1030,8 +1021,6 @@ xfs_rtfree_extent(
 		.trans		= tp,
 	};
 	int			error;		/* error value */
-	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));
@@ -1043,10 +1032,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.
 	 */
@@ -1062,7 +1051,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;
 }
 
 /*
@@ -1153,6 +1145,7 @@ xfs_rtalloc_query_range(
 		rtstart = rtend + 1;
 	}
 
+	xfs_rtbuf_cache_relse(&args);
 	return error;
 }
 
@@ -1191,6 +1184,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 39da0adf0f45..720856192818 100644
--- a/fs/xfs/libxfs/xfs_rtbitmap.h
+++ b/fs/xfs/libxfs/xfs_rtbitmap.h
@@ -237,8 +237,16 @@ typedef int (*xfs_rtalloc_query_range_fn)(
 struct xfs_rtalloc_args {
 	struct xfs_mount	*mount;
 	struct xfs_trans	*trans;
+
+	struct xfs_buf *bbuf;	/* bitmap block buffer */
+	struct xfs_buf *sbuf;	/* summary block buffer */
+
+	xfs_fileoff_t bblock;	/* bitmap block number */
+	xfs_fileoff_t sblock;	/* summary block number */
 };
 
+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,
@@ -250,13 +258,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,
@@ -304,6 +310,7 @@ void xfs_suminfo_add(struct xfs_mount *mp, union xfs_suminfo_raw *infoptr,
 # 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 3f6f6efe7375..e711e68ff996 100644
--- a/fs/xfs/scrub/rtsummary.c
+++ b/fs/xfs/scrub/rtsummary.c
@@ -217,7 +217,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;
 		}
 
@@ -225,7 +225,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 922d2fdcf953..f481efcf8445 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->mount;
@@ -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;		/* error return value */
 	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->mount->m_rsumlevels - 1; log >= 0; log--) {
 		for (bbno = oargs->mount->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				/* error */
 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->mount;
 	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);
@@ -1213,8 +1194,6 @@ xfs_rtallocate_extent(
 	};
 	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.mount->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;
 


^ permalink raw reply related	[flat|nested] 91+ messages in thread

* [PATCH 3/7] xfs: invert the realtime summary cache
  2023-10-17 15:46 ` [PATCHSET RFC 2.1 0/7] xfs: CPU usage optimizations for realtime allocator Darrick J. Wong
  2023-10-17 15:54   ` [PATCH 1/7] xfs: consolidate realtime allocation arguments Darrick J. Wong
  2023-10-17 15:54   ` [PATCH 2/7] xfs: cache last bitmap block in realtime allocator Darrick J. Wong
@ 2023-10-17 15:54   ` Darrick J. Wong
  2023-10-17 15:54   ` [PATCH 4/7] xfs: return maximum free size from xfs_rtany_summary() Darrick J. Wong
                     ` (4 subsequent siblings)
  7 siblings, 0 replies; 91+ messages in thread
From: Darrick J. Wong @ 2023-10-17 15:54 UTC (permalink / raw)
  To: djwong; +Cc: Omar Sandoval, Christoph Hellwig, osandov, osandov, linux-xfs, hch

From: Omar Sandoval <osandov@fb.com>

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 <osandov@fb.com>
Reviewed-by: Darrick J. Wong <djwong@kernel.org>
Signed-off-by: Darrick J. Wong <djwong@kernel.org>
Reviewed-by: Christoph Hellwig <hch@lst.de>
---
 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(-)


diff --git a/fs/xfs/libxfs/xfs_rtbitmap.c b/fs/xfs/libxfs/xfs_rtbitmap.c
index 428a3a5b660d..c8b1f977fdbf 100644
--- a/fs/xfs/libxfs/xfs_rtbitmap.c
+++ b/fs/xfs/libxfs/xfs_rtbitmap.c
@@ -549,10 +549,10 @@ xfs_rtmodify_summary_int(
 		if (mp->m_rsum_cache) {
 			xfs_suminfo_t	val = xfs_suminfo_get(mp, sp);
 
-			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_buf(args->trans, bp, first, first + sizeof(*sp) - 1);
 	}
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 f481efcf8445..336c130fc90f 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");
 }
 


^ permalink raw reply related	[flat|nested] 91+ messages in thread

* [PATCH 4/7] xfs: return maximum free size from xfs_rtany_summary()
  2023-10-17 15:46 ` [PATCHSET RFC 2.1 0/7] xfs: CPU usage optimizations for realtime allocator Darrick J. Wong
                     ` (2 preceding siblings ...)
  2023-10-17 15:54   ` [PATCH 3/7] xfs: invert the realtime summary cache Darrick J. Wong
@ 2023-10-17 15:54   ` Darrick J. Wong
  2023-10-17 15:55   ` [PATCH 5/7] xfs: limit maxlen based on available space in xfs_rtallocate_extent_near() Darrick J. Wong
                     ` (3 subsequent siblings)
  7 siblings, 0 replies; 91+ messages in thread
From: Darrick J. Wong @ 2023-10-17 15:54 UTC (permalink / raw)
  To: djwong; +Cc: Omar Sandoval, Christoph Hellwig, osandov, osandov, linux-xfs, hch

From: Omar Sandoval <osandov@fb.com>

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 <djwong@kernel.org>
Signed-off-by: Omar Sandoval <osandov@fb.com>
Signed-off-by: Darrick J. Wong <djwong@kernel.org>
Reviewed-by: Christoph Hellwig <hch@lst.de>
---
 fs/xfs/xfs_rtalloc.c |   18 +++++++++---------
 1 file changed, 9 insertions(+), 9 deletions(-)


diff --git a/fs/xfs/xfs_rtalloc.c b/fs/xfs/xfs_rtalloc.c
index 336c130fc90f..9003acad590d 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->mount;
 	int			error;		/* error value */
@@ -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->mount;
-	int			any;		/* any useful extents from summary */
+	int			maxlog;		/* max useful extent from summary */
 	xfs_fileoff_t		bbno;		/* bitmap block number */
 	int			error;		/* error value */
 	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,


^ permalink raw reply related	[flat|nested] 91+ messages in thread

* [PATCH 5/7] xfs: limit maxlen based on available space in xfs_rtallocate_extent_near()
  2023-10-17 15:46 ` [PATCHSET RFC 2.1 0/7] xfs: CPU usage optimizations for realtime allocator Darrick J. Wong
                     ` (3 preceding siblings ...)
  2023-10-17 15:54   ` [PATCH 4/7] xfs: return maximum free size from xfs_rtany_summary() Darrick J. Wong
@ 2023-10-17 15:55   ` Darrick J. Wong
  2023-10-17 15:55   ` [PATCH 6/7] xfs: don't try redundant allocations " Darrick J. Wong
                     ` (2 subsequent siblings)
  7 siblings, 0 replies; 91+ messages in thread
From: Darrick J. Wong @ 2023-10-17 15:55 UTC (permalink / raw)
  To: djwong; +Cc: Omar Sandoval, Christoph Hellwig, osandov, osandov, linux-xfs, hch

From: Omar Sandoval <osandov@fb.com>

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 <osandov@fb.com>
Reviewed-by: Darrick J. Wong <djwong@kernel.org>
Signed-off-by: Darrick J. Wong <djwong@kernel.org>
Reviewed-by: Christoph Hellwig <hch@lst.de>
---
 fs/xfs/xfs_rtalloc.c |    9 ++++++---
 1 file changed, 6 insertions(+), 3 deletions(-)


diff --git a/fs/xfs/xfs_rtalloc.c b/fs/xfs/xfs_rtalloc.c
index 9003acad590d..5f94407925ad 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;


^ permalink raw reply related	[flat|nested] 91+ messages in thread

* [PATCH 6/7] xfs: don't try redundant allocations in xfs_rtallocate_extent_near()
  2023-10-17 15:46 ` [PATCHSET RFC 2.1 0/7] xfs: CPU usage optimizations for realtime allocator Darrick J. Wong
                     ` (4 preceding siblings ...)
  2023-10-17 15:55   ` [PATCH 5/7] xfs: limit maxlen based on available space in xfs_rtallocate_extent_near() Darrick J. Wong
@ 2023-10-17 15:55   ` Darrick J. Wong
  2023-10-17 15:55   ` [PATCH 7/7] xfs: don't look for end of extent further than necessary " Darrick J. Wong
  2023-10-19  0:00   ` [PATCHSET v2.2 0/9] xfs: CPU usage optimizations for realtime allocator Darrick J. Wong
  7 siblings, 0 replies; 91+ messages in thread
From: Darrick J. Wong @ 2023-10-17 15:55 UTC (permalink / raw)
  To: djwong; +Cc: Omar Sandoval, Christoph Hellwig, osandov, osandov, linux-xfs, hch

From: Omar Sandoval <osandov@fb.com>

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 <osandov@fb.com>
Reviewed-by: Darrick J. Wong <djwong@kernel.org>
Signed-off-by: Darrick J. Wong <djwong@kernel.org>
Reviewed-by: Christoph Hellwig <hch@lst.de>
---
 fs/xfs/xfs_rtalloc.c |   54 ++++++--------------------------------------------
 1 file changed, 7 insertions(+), 47 deletions(-)


diff --git a/fs/xfs/xfs_rtalloc.c b/fs/xfs/xfs_rtalloc.c
index 5f94407925ad..12a7959913da 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;
-				}
 			}
 		}
 		/*


^ permalink raw reply related	[flat|nested] 91+ messages in thread

* [PATCH 7/7] xfs: don't look for end of extent further than necessary in xfs_rtallocate_extent_near()
  2023-10-17 15:46 ` [PATCHSET RFC 2.1 0/7] xfs: CPU usage optimizations for realtime allocator Darrick J. Wong
                     ` (5 preceding siblings ...)
  2023-10-17 15:55   ` [PATCH 6/7] xfs: don't try redundant allocations " Darrick J. Wong
@ 2023-10-17 15:55   ` Darrick J. Wong
  2023-10-19  0:00   ` [PATCHSET v2.2 0/9] xfs: CPU usage optimizations for realtime allocator Darrick J. Wong
  7 siblings, 0 replies; 91+ messages in thread
From: Darrick J. Wong @ 2023-10-17 15:55 UTC (permalink / raw)
  To: djwong; +Cc: Omar Sandoval, Christoph Hellwig, osandov, osandov, linux-xfs, hch

From: Omar Sandoval <osandov@fb.com>

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 <djwong@kernel.org>
Signed-off-by: Omar Sandoval <osandov@fb.com>
Signed-off-by: Darrick J. Wong <djwong@kernel.org>
Reviewed-by: Christoph Hellwig <hch@lst.de>
---
 fs/xfs/xfs_rtalloc.c |   27 ++++++++++++++++++++++-----
 1 file changed, 22 insertions(+), 5 deletions(-)


diff --git a/fs/xfs/xfs_rtalloc.c b/fs/xfs/xfs_rtalloc.c
index 12a7959913da..512c63dd7cab 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 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.
+				 * 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);
+
+				/*
+				 * 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,


^ permalink raw reply related	[flat|nested] 91+ messages in thread

* Re: [PATCH 2/4] xfs: hoist freeing of rt data fork extent mappings
  2023-10-17 15:47   ` [PATCH 2/4] xfs: hoist freeing of rt data fork extent mappings Darrick J. Wong
@ 2023-10-17 16:00     ` Christoph Hellwig
  0 siblings, 0 replies; 91+ messages in thread
From: Christoph Hellwig @ 2023-10-17 16:00 UTC (permalink / raw)
  To: Darrick J. Wong; +Cc: osandov, linux-xfs, hch

On Tue, Oct 17, 2023 at 08:47:19AM -0700, Darrick J. Wong wrote:
> From: Darrick J. Wong <djwong@kernel.org>
> 
> 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.

Looks good:

Reviewed-by: Christoph Hellwig <hch@lst.de>

^ permalink raw reply	[flat|nested] 91+ messages in thread

* Re: [PATCH 1/8] xfs: fix units conversion error in xfs_bmap_del_extent_delay
  2023-10-17 15:48   ` [PATCH 1/8] xfs: fix units conversion error in xfs_bmap_del_extent_delay Darrick J. Wong
@ 2023-10-17 16:01     ` Christoph Hellwig
  0 siblings, 0 replies; 91+ messages in thread
From: Christoph Hellwig @ 2023-10-17 16:01 UTC (permalink / raw)
  To: Darrick J. Wong; +Cc: osandov, linux-xfs, hch

Looks good:

Reviewed-by: Christoph Hellwig <hch@lst.de>

^ permalink raw reply	[flat|nested] 91+ messages in thread

* Re: [PATCH 4/7] xfs: create helpers to convert rt block numbers to rt extent numbers
  2023-10-17 15:50   ` [PATCH 4/7] xfs: create helpers to convert rt block numbers to rt extent numbers Darrick J. Wong
@ 2023-10-17 16:04     ` Christoph Hellwig
  0 siblings, 0 replies; 91+ messages in thread
From: Christoph Hellwig @ 2023-10-17 16:04 UTC (permalink / raw)
  To: Darrick J. Wong; +Cc: osandov, linux-xfs, hch

On Tue, Oct 17, 2023 at 08:50:59AM -0700, Darrick J. Wong wrote:
> From: Darrick J. Wong <djwong@kernel.org>
> 
> Create helpers to do unit conversions of rt block numbers to rt extent
> numbers.  There are two variations -- the suffix "t" denotes the one
> that returns only the truncated extent number; the other one also
> returns the misalignment.  Convert all the div_u64_rem users; we'll do

This need a little update for the new naming scheme.

Otherwise looks good:

Reviewed-by: Christoph Hellwig <hch@lst.de>

^ permalink raw reply	[flat|nested] 91+ messages in thread

* Re: [PATCH 5/7] xfs: convert do_div calls to xfs_rtb_to_rtx helper calls
  2023-10-17 15:51   ` [PATCH 5/7] xfs: convert do_div calls to xfs_rtb_to_rtx helper calls Darrick J. Wong
@ 2023-10-17 16:05     ` Christoph Hellwig
  0 siblings, 0 replies; 91+ messages in thread
From: Christoph Hellwig @ 2023-10-17 16:05 UTC (permalink / raw)
  To: Darrick J. Wong; +Cc: osandov, linux-xfs, hch

Looks good:

Reviewed-by: Christoph Hellwig <hch@lst.de>

^ permalink raw reply	[flat|nested] 91+ messages in thread

* Re: [PATCH 3/8] xfs: convert open-coded xfs_rtword_t pointer accesses to helper
  2023-10-17 15:52   ` [PATCH 3/8] xfs: convert open-coded xfs_rtword_t pointer accesses to helper Darrick J. Wong
@ 2023-10-17 16:31     ` Christoph Hellwig
  0 siblings, 0 replies; 91+ messages in thread
From: Christoph Hellwig @ 2023-10-17 16:31 UTC (permalink / raw)
  To: Darrick J. Wong; +Cc: osandov, linux-xfs, hch

Looks good:

Reviewed-by: Christoph Hellwig <hch@lst.de>


^ permalink raw reply	[flat|nested] 91+ messages in thread

* Re: [PATCH 5/8] xfs: create helpers for rtbitmap block/wordcount computations
  2023-10-17 15:53   ` [PATCH 5/8] xfs: create helpers for rtbitmap block/wordcount computations Darrick J. Wong
@ 2023-10-17 16:33     ` Christoph Hellwig
  0 siblings, 0 replies; 91+ messages in thread
From: Christoph Hellwig @ 2023-10-17 16:33 UTC (permalink / raw)
  To: Darrick J. Wong; +Cc: osandov, linux-xfs, hch

Looks good:

Reviewed-by: Christoph Hellwig <hch@lst.de>

^ permalink raw reply	[flat|nested] 91+ messages in thread

* Re: [PATCH 6/8] xfs: use accessor functions for bitmap words
  2023-10-17 15:53   ` [PATCH 6/8] xfs: use accessor functions for bitmap words Darrick J. Wong
@ 2023-10-17 18:53     ` Christoph Hellwig
  2023-10-18  2:01       ` Darrick J. Wong
  0 siblings, 1 reply; 91+ messages in thread
From: Christoph Hellwig @ 2023-10-17 18:53 UTC (permalink / raw)
  To: Darrick J. Wong; +Cc: osandov, linux-xfs, hch

On Tue, Oct 17, 2023 at 08:53:21AM -0700, Darrick J. Wong wrote:
> From: Darrick J. Wong <djwong@kernel.org>
> 
> 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.

So per the last round I'd much prefer no exposing the xfs_rtword_raw
to the callers.  I've cooked up the patch below to do this, and it
seems to survive the absolute basic testing so far.  One interesting
thing is that as far as I can tell all but one of the
xfs_trans_log_buf calls in the pre-existing code were wrong as they
were missing the usual '- 1' for the last parameter.

For reasons I can't explain the version with this patch also happens
to actually generate smaller binary code as well:

hch@brick:~/work/xfs$ size xfs_rtbitmap.o*
   text	   data	    bss	    dec	    hex	filename
   7763	      0	      0	   7763	   1e53	xfs_rtbitmap.o.new
   7833	      0	      0	   7833	   1e99	xfs_rtbitmap.o.old

---
diff --git a/fs/xfs/libxfs/xfs_rtbitmap.c b/fs/xfs/libxfs/xfs_rtbitmap.c
index f8daaff947fce8..6ca48fe8a9e1d3 100644
--- a/fs/xfs/libxfs/xfs_rtbitmap.c
+++ b/fs/xfs/libxfs/xfs_rtbitmap.c
@@ -90,20 +90,35 @@ xfs_rtbuf_get(
 /* Convert an ondisk bitmap word to its incore representation. */
 inline xfs_rtword_t
 xfs_rtbitmap_getword(
-	struct xfs_mount	*mp,
-	union xfs_rtword_raw	*wordptr)
+	struct xfs_buf		*bp,
+	unsigned int		index)
 {
-	return wordptr->old;
+	union xfs_rtword_raw	*words = bp->b_addr;
+
+	return words[index].old;
 }
 
 /* Set an ondisk bitmap word from an incore representation. */
 inline void
 xfs_rtbitmap_setword(
-	struct xfs_mount	*mp,
-	union xfs_rtword_raw	*wordptr,
+	struct xfs_buf		*bp,
+	unsigned int		index,
 	xfs_rtword_t		incore)
 {
-	wordptr->old = incore;
+	union xfs_rtword_raw	*words = bp->b_addr;
+
+	words[index].old = incore;
+}
+
+static inline void
+xfs_trans_log_rtbitmap(
+	struct xfs_trans	*tp,
+	struct xfs_buf		*bp,
+	int			from,
+	int			to)
+{
+	xfs_trans_log_buf(tp, bp, from * sizeof(union xfs_rtword_raw),
+			  to * sizeof(union xfs_rtword_raw) - 1);
 }
 
 /*
@@ -118,7 +133,6 @@ xfs_rtfind_back(
 	xfs_rtxnum_t	limit,		/* last rtext to look at */
 	xfs_rtxnum_t	*rtx)		/* out: start rtext found */
 {
-	union xfs_rtword_raw *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 */
@@ -145,14 +159,13 @@ 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.
 	 */
-	incore = xfs_rtbitmap_getword(mp, b);
+	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
@@ -195,12 +208,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 {
 		/*
@@ -216,7 +223,7 @@ xfs_rtfind_back(
 		/*
 		 * Compute difference between actual and desired value.
 		 */
-		incore = xfs_rtbitmap_getword(mp, b);
+		incore = xfs_rtbitmap_getword(bp, word);
 		if ((wdiff = incore ^ want)) {
 			/*
 			 * Different, mark where we are and return.
@@ -242,12 +249,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--;
 		}
 	}
 	/*
@@ -264,7 +265,7 @@ xfs_rtfind_back(
 		/*
 		 * Compute difference between actual and desired value.
 		 */
-		incore = xfs_rtbitmap_getword(mp, b);
+		incore = xfs_rtbitmap_getword(bp, word);
 		if ((wdiff = (incore ^ want) & mask)) {
 			/*
 			 * Different, mark where we are and return.
@@ -296,7 +297,6 @@ xfs_rtfind_forw(
 	xfs_rtxnum_t	limit,		/* last rtext to look at */
 	xfs_rtxnum_t	*rtx)		/* out: start rtext found */
 {
-	union xfs_rtword_raw *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 */
@@ -323,14 +323,13 @@ 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.
 	 */
-	incore = xfs_rtbitmap_getword(mp, b);
+	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
@@ -372,12 +371,6 @@ xfs_rtfind_forw(
 			}
 
 			word = 0;
-			b = xfs_rbmblock_wordptr(bp, word);
-		} else {
-			/*
-			 * Go on to the previous word in the buffer.
-			 */
-			b++;
 		}
 	} else {
 		/*
@@ -393,7 +386,7 @@ xfs_rtfind_forw(
 		/*
 		 * Compute difference between actual and desired value.
 		 */
-		incore = xfs_rtbitmap_getword(mp, b);
+		incore = xfs_rtbitmap_getword(bp, word);
 		if ((wdiff = incore ^ want)) {
 			/*
 			 * Different, mark where we are and return.
@@ -419,12 +412,6 @@ xfs_rtfind_forw(
 			}
 
 			word = 0;
-			b = xfs_rbmblock_wordptr(bp, word);
-		} else {
-			/*
-			 * Go on to the next word in the buffer.
-			 */
-			b++;
 		}
 	}
 	/*
@@ -439,7 +426,7 @@ xfs_rtfind_forw(
 		/*
 		 * Compute difference between actual and desired value.
 		 */
-		incore = xfs_rtbitmap_getword(mp, b);
+		incore = xfs_rtbitmap_getword(bp, word);
 		if ((wdiff = (incore ^ want) & mask)) {
 			/*
 			 * Different, mark where we are and return.
@@ -566,12 +553,11 @@ xfs_rtmodify_range(
 	xfs_rtxlen_t	len,		/* length of extent to modify */
 	int		val)		/* 1 for free, 0 for allocated */
 {
-	union xfs_rtword_raw *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 */
-	union xfs_rtword_raw *first;		/* first used word in the buffer */
+	int		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 */
@@ -593,8 +579,7 @@ xfs_rtmodify_range(
 	/*
 	 * Compute the starting word's address, and starting bit.
 	 */
-	word = xfs_rtx_to_rbmword(mp, start);
-	first = b = xfs_rbmblock_wordptr(bp, word);
+	first = word = xfs_rtx_to_rbmword(mp, start);
 	bit = (int)(start & (XFS_NBWORD - 1));
 	/*
 	 * 0 (allocated) => all zeroes; 1 (free) => all ones.
@@ -613,12 +598,12 @@ xfs_rtmodify_range(
 		/*
 		 * Set/clear the active bits.
 		 */
-		incore = xfs_rtbitmap_getword(mp, b);
+		incore = xfs_rtbitmap_getword(bp, word);
 		if (val)
 			incore |= mask;
 		else
 			incore &= ~mask;
-		xfs_rtbitmap_setword(mp, b, incore);
+		xfs_rtbitmap_setword(bp, word, incore);
 		i = lastbit - bit;
 		/*
 		 * Go on to the next block if that's where the next word is
@@ -629,21 +614,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, first, word);
 			error = xfs_rtbuf_get(mp, tp, ++block, 0, &bp);
 			if (error) {
 				return error;
 			}
 
-			word = 0;
-			first = b = xfs_rbmblock_wordptr(bp, word);
-		} else {
-			/*
-			 * Go on to the next word in the buffer
-			 */
-			b++;
+			first = word = 0;
 		}
 	} else {
 		/*
@@ -659,7 +636,7 @@ xfs_rtmodify_range(
 		/*
 		 * Set the word value correctly.
 		 */
-		xfs_rtbitmap_setword(mp, 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
@@ -670,21 +647,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, first, word);
 			error = xfs_rtbuf_get(mp, tp, ++block, 0, &bp);
 			if (error) {
 				return error;
 			}
 
-			word = 0;
-			first = b = xfs_rbmblock_wordptr(bp, word);
-		} else {
-			/*
-			 * Go on to the next word in the buffer
-			 */
-			b++;
+			first = word = 0;
 		}
 	}
 	/*
@@ -699,21 +668,19 @@ xfs_rtmodify_range(
 		/*
 		 * Set/clear the active bits.
 		 */
-		incore = xfs_rtbitmap_getword(mp, b);
+		incore = xfs_rtbitmap_getword(bp, word);
 		if (val)
 			incore |= mask;
 		else
 			incore &= ~mask;
-		xfs_rtbitmap_setword(mp, b, incore);
-		b++;
+		xfs_rtbitmap_setword(bp, word, incore);
+		word++;
 	}
 	/*
 	 * 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));
+	if (word > first)
+		xfs_trans_log_rtbitmap(tp, bp, first, word);
 	return 0;
 }
 
@@ -807,7 +774,6 @@ xfs_rtcheck_range(
 	xfs_rtxnum_t	*new,		/* out: first rtext not matching */
 	int		*stat)		/* out: 1 for matches, 0 for not */
 {
-	union xfs_rtword_raw *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 */
@@ -835,7 +801,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.
@@ -857,7 +822,7 @@ xfs_rtcheck_range(
 		/*
 		 * Compute difference between actual and desired value.
 		 */
-		incore = xfs_rtbitmap_getword(mp, b);
+		incore = xfs_rtbitmap_getword(bp, word);
 		if ((wdiff = (incore ^ val) & mask)) {
 			/*
 			 * Different, compute first wrong bit and return.
@@ -884,12 +849,6 @@ xfs_rtcheck_range(
 			}
 
 			word = 0;
-			b = xfs_rbmblock_wordptr(bp, word);
-		} else {
-			/*
-			 * Go on to the next word in the buffer.
-			 */
-			b++;
 		}
 	} else {
 		/*
@@ -905,7 +864,7 @@ xfs_rtcheck_range(
 		/*
 		 * Compute difference between actual and desired value.
 		 */
-		incore = xfs_rtbitmap_getword(mp, b);
+		incore = xfs_rtbitmap_getword(bp, word);
 		if ((wdiff = incore ^ val)) {
 			/*
 			 * Different, compute first wrong bit and return.
@@ -932,12 +891,6 @@ xfs_rtcheck_range(
 			}
 
 			word = 0;
-			b = xfs_rbmblock_wordptr(bp, word);
-		} else {
-			/*
-			 * Go on to the next word in the buffer.
-			 */
-			b++;
 		}
 	}
 	/*
@@ -952,7 +905,7 @@ xfs_rtcheck_range(
 		/*
 		 * Compute difference between actual and desired value.
 		 */
-		incore = xfs_rtbitmap_getword(mp, b);
+		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 4e33e84afa7ad6..ec14e6adb8364a 100644
--- a/fs/xfs/libxfs/xfs_rtbitmap.h
+++ b/fs/xfs/libxfs/xfs_rtbitmap.h
@@ -158,17 +158,6 @@ xfs_rbmblock_to_rtx(
 	return rbmoff << mp->m_blkbit_log;
 }
 
-/* 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,
-	unsigned int		index)
-{
-	union xfs_rtword_raw	*words = bp->b_addr;
-
-	return words + index;
-}
-
 /*
  * Convert a rt extent length and rt bitmap block number to a xfs_suminfo_t
  * offset within the rt summary file.
@@ -285,10 +274,10 @@ 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_rtword_t xfs_rtbitmap_getword(struct xfs_mount *mp,
-		union xfs_rtword_raw *wordptr);
-void xfs_rtbitmap_setword(struct xfs_mount *mp,
-		union xfs_rtword_raw *wordptr, xfs_rtword_t incore);
+xfs_rtword_t xfs_rtbitmap_getword(struct xfs_buf *bp, unsigned int index);
+void xfs_rtbitmap_setword(struct xfs_buf *bp, unsigned int index,
+		xfs_rtword_t incore);
+
 #else /* CONFIG_XFS_RT */
 # define xfs_rtfree_extent(t,b,l)			(-ENOSYS)
 # define xfs_rtfree_blocks(t,rb,rl)			(-ENOSYS)


^ permalink raw reply related	[flat|nested] 91+ messages in thread

* Re: [PATCH 6/8] xfs: use accessor functions for bitmap words
  2023-10-17 18:53     ` Christoph Hellwig
@ 2023-10-18  2:01       ` Darrick J. Wong
  2023-10-18  4:50         ` Christoph Hellwig
  0 siblings, 1 reply; 91+ messages in thread
From: Darrick J. Wong @ 2023-10-18  2:01 UTC (permalink / raw)
  To: Christoph Hellwig; +Cc: osandov, linux-xfs

On Tue, Oct 17, 2023 at 08:53:16PM +0200, Christoph Hellwig wrote:
> On Tue, Oct 17, 2023 at 08:53:21AM -0700, Darrick J. Wong wrote:
> > From: Darrick J. Wong <djwong@kernel.org>
> > 
> > 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.
> 
> So per the last round I'd much prefer no exposing the xfs_rtword_raw
> to the callers.  I've cooked up the patch below to do this, and it
> seems to survive the absolute basic testing so far.  One interesting
> thing is that as far as I can tell all but one of the
> xfs_trans_log_buf calls in the pre-existing code were wrong as they
> were missing the usual '- 1' for the last parameter.
> 
> For reasons I can't explain the version with this patch also happens
> to actually generate smaller binary code as well:
> 
> hch@brick:~/work/xfs$ size xfs_rtbitmap.o*
>    text	   data	    bss	    dec	    hex	filename
>    7763	      0	      0	   7763	   1e53	xfs_rtbitmap.o.new
>    7833	      0	      0	   7833	   1e99	xfs_rtbitmap.o.old

Probably not having to maintain b and word as separate variables...

> ---
> diff --git a/fs/xfs/libxfs/xfs_rtbitmap.c b/fs/xfs/libxfs/xfs_rtbitmap.c
> index f8daaff947fce8..6ca48fe8a9e1d3 100644
> --- a/fs/xfs/libxfs/xfs_rtbitmap.c
> +++ b/fs/xfs/libxfs/xfs_rtbitmap.c
> @@ -90,20 +90,35 @@ xfs_rtbuf_get(
>  /* Convert an ondisk bitmap word to its incore representation. */
>  inline xfs_rtword_t
>  xfs_rtbitmap_getword(
> -	struct xfs_mount	*mp,
> -	union xfs_rtword_raw	*wordptr)
> +	struct xfs_buf		*bp,
> +	unsigned int		index)
>  {
> -	return wordptr->old;
> +	union xfs_rtword_raw	*words = bp->b_addr;
> +
> +	return words[index].old;
>  }
>  
>  /* Set an ondisk bitmap word from an incore representation. */
>  inline void
>  xfs_rtbitmap_setword(
> -	struct xfs_mount	*mp,
> -	union xfs_rtword_raw	*wordptr,
> +	struct xfs_buf		*bp,
> +	unsigned int		index,
>  	xfs_rtword_t		incore)
>  {
> -	wordptr->old = incore;
> +	union xfs_rtword_raw	*words = bp->b_addr;
> +
> +	words[index].old = incore;
> +}
> +
> +static inline void
> +xfs_trans_log_rtbitmap(
> +	struct xfs_trans	*tp,
> +	struct xfs_buf		*bp,
> +	int			from,
> +	int			to)
> +{
> +	xfs_trans_log_buf(tp, bp, from * sizeof(union xfs_rtword_raw),
> +			  to * sizeof(union xfs_rtword_raw) - 1);
>  }

I'll make a separate patch with new xfs_trans_log_rt{bitmap,summary}
helpers.  Dunno if we care about a Fixes: tag for that off by one error
since its only effect was to log more of the bitmap than was strictly
necessary and I don't think that's worth bothering the LTS folks about.

>  
>  /*
> @@ -118,7 +133,6 @@ xfs_rtfind_back(
>  	xfs_rtxnum_t	limit,		/* last rtext to look at */
>  	xfs_rtxnum_t	*rtx)		/* out: start rtext found */
>  {
> -	union xfs_rtword_raw *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 */
> @@ -145,14 +159,13 @@ 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.
>  	 */
> -	incore = xfs_rtbitmap_getword(mp, b);
> +	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
> @@ -195,12 +208,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--;

Yay this goes away!

>  		}
>  	} else {
>  		/*

<snip to a function that uses setword>

> @@ -566,12 +553,11 @@ xfs_rtmodify_range(
>  	xfs_rtxlen_t	len,		/* length of extent to modify */
>  	int		val)		/* 1 for free, 0 for allocated */
>  {
> -	union xfs_rtword_raw *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 */
> -	union xfs_rtword_raw *first;		/* first used word in the buffer */
> +	int		first;		/* first used word in the buffer */

/me notes that the xfs_rtx_to_rbmword function returns an unsigned int,
will clean that up...

>  	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 */
> @@ -593,8 +579,7 @@ xfs_rtmodify_range(
>  	/*
>  	 * Compute the starting word's address, and starting bit.
>  	 */
> -	word = xfs_rtx_to_rbmword(mp, start);
> -	first = b = xfs_rbmblock_wordptr(bp, word);
> +	first = word = xfs_rtx_to_rbmword(mp, start);
>  	bit = (int)(start & (XFS_NBWORD - 1));
>  	/*
>  	 * 0 (allocated) => all zeroes; 1 (free) => all ones.
> @@ -613,12 +598,12 @@ xfs_rtmodify_range(
>  		/*
>  		 * Set/clear the active bits.
>  		 */
> -		incore = xfs_rtbitmap_getword(mp, b);
> +		incore = xfs_rtbitmap_getword(bp, word);
>  		if (val)
>  			incore |= mask;
>  		else
>  			incore &= ~mask;
> -		xfs_rtbitmap_setword(mp, b, incore);
> +		xfs_rtbitmap_setword(bp, word, incore);

Yay!

>  		i = lastbit - bit;
>  		/*
>  		 * Go on to the next block if that's where the next word is

<snip more of the same>

> diff --git a/fs/xfs/libxfs/xfs_rtbitmap.h b/fs/xfs/libxfs/xfs_rtbitmap.h
> index 4e33e84afa7ad6..ec14e6adb8364a 100644
> --- a/fs/xfs/libxfs/xfs_rtbitmap.h
> +++ b/fs/xfs/libxfs/xfs_rtbitmap.h
> @@ -158,17 +158,6 @@ xfs_rbmblock_to_rtx(
>  	return rbmoff << mp->m_blkbit_log;
>  }
>  
> -/* 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,
> -	unsigned int		index)
> -{
> -	union xfs_rtword_raw	*words = bp->b_addr;
> -
> -	return words + index;
> -}

Note that I still need this (and the _infoptr helper) for online repair
to be able to generate an in-memory replacement of the bitmap and
summary file and then be able to memcpy the words into the new ondisk
file.

That said, I also noticed that the _rtbitmap_[gs]etword and
_suminfo_{get,add} functions can be static inlines in xfs_rtbitmap.h, so
I'll put them right after here and the compiler will (hopefully)
collapse the nested inlines into something fairly compact.

Ok, I've made all those changes and I'll resend this patchset tomorrow
after letting it test overnight.

--D

> -
>  /*
>   * Convert a rt extent length and rt bitmap block number to a xfs_suminfo_t
>   * offset within the rt summary file.
> @@ -285,10 +274,10 @@ 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_rtword_t xfs_rtbitmap_getword(struct xfs_mount *mp,
> -		union xfs_rtword_raw *wordptr);
> -void xfs_rtbitmap_setword(struct xfs_mount *mp,
> -		union xfs_rtword_raw *wordptr, xfs_rtword_t incore);
> +xfs_rtword_t xfs_rtbitmap_getword(struct xfs_buf *bp, unsigned int index);
> +void xfs_rtbitmap_setword(struct xfs_buf *bp, unsigned int index,
> +		xfs_rtword_t incore);
> +
>  #else /* CONFIG_XFS_RT */
>  # define xfs_rtfree_extent(t,b,l)			(-ENOSYS)
>  # define xfs_rtfree_blocks(t,rb,rl)			(-ENOSYS)
> 

^ permalink raw reply	[flat|nested] 91+ messages in thread

* [PATCHSET RFC v1.2 0/4] xfs: refactor rtbitmap/summary accessors
  2023-10-17 15:46 ` [PATCHSET RFC v1.1 0/8] xfs: refactor rtbitmap/summary macros Darrick J. Wong
                     ` (7 preceding siblings ...)
  2023-10-17 15:53   ` [PATCH 8/8] xfs: use accessor functions for summary info words Darrick J. Wong
@ 2023-10-18  2:10   ` Darrick J. Wong
  2023-10-18  2:10     ` [PATCH 1/4] xfs: create a helper to handle logging parts of rt bitmap blocks Darrick J. Wong
                       ` (3 more replies)
  8 siblings, 4 replies; 91+ messages in thread
From: Darrick J. Wong @ 2023-10-18  2:10 UTC (permalink / raw)
  To: djwong; +Cc: Christoph Hellwig, osandov, hch, linux-xfs

Hi all,

Since the rtbitmap and rtsummary accessor functions have proven more
controversial than the rest of the macro refactoring, split the patchset
into two to make review easier.

v1.1: various cleanups suggested by hch
v1.2: rework the accessor functions to reduce the amount of cursor
      tracking required, and create explicit bitmap/summary logging
      functions

If you're going to start using this code, I strongly recommend pulling
from my git trees, which are linked below.

With a bit of luck, this should all go splendidly.
Comments and questions are, as always, welcome.

--D

kernel git tree:
https://git.kernel.org/cgit/linux/kernel/git/djwong/xfs-linux.git/log/?h=refactor-rtbitmap-accessors-6.7
---
 fs/xfs/libxfs/xfs_format.h   |   16 +++
 fs/xfs/libxfs/xfs_rtbitmap.c |  200 ++++++++++++++++++++++--------------------
 fs/xfs/libxfs/xfs_rtbitmap.h |   62 ++++++++++++-
 fs/xfs/scrub/rtsummary.c     |   30 ++++--
 fs/xfs/scrub/trace.c         |    1 
 fs/xfs/scrub/trace.h         |   10 +-
 fs/xfs/xfs_ondisk.h          |    4 +
 fs/xfs/xfs_rtalloc.c         |   17 +---
 8 files changed, 216 insertions(+), 124 deletions(-)


^ permalink raw reply	[flat|nested] 91+ messages in thread

* [PATCH 1/4] xfs: create a helper to handle logging parts of rt bitmap blocks
  2023-10-18  2:10   ` [PATCHSET RFC v1.2 0/4] xfs: refactor rtbitmap/summary accessors Darrick J. Wong
@ 2023-10-18  2:10     ` Darrick J. Wong
  2023-10-18  4:52       ` Christoph Hellwig
  2023-10-18  2:10     ` [PATCH 2/4] xfs: use accessor functions for bitmap words Darrick J. Wong
                       ` (2 subsequent siblings)
  3 siblings, 1 reply; 91+ messages in thread
From: Darrick J. Wong @ 2023-10-18  2:10 UTC (permalink / raw)
  To: djwong; +Cc: Christoph Hellwig, osandov, hch, linux-xfs

From: Darrick J. Wong <djwong@kernel.org>

Create an explicit helper function to log parts of rt bitmap blocks.
While we're at it, fix an off-by-one error in two of the the rtbitmap
logging calls that led to unnecessarily large log items but was
otherwise benign.

Suggested-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Darrick J. Wong <djwong@kernel.org>
---
 fs/xfs/libxfs/xfs_rtbitmap.c |   49 +++++++++++++++++++++++++++++-------------
 1 file changed, 34 insertions(+), 15 deletions(-)


diff --git a/fs/xfs/libxfs/xfs_rtbitmap.c b/fs/xfs/libxfs/xfs_rtbitmap.c
index aefa2b0747a5..d05bd0218885 100644
--- a/fs/xfs/libxfs/xfs_rtbitmap.c
+++ b/fs/xfs/libxfs/xfs_rtbitmap.c
@@ -432,6 +432,18 @@ 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)
+{
+	xfs_trans_log_buf(tp, bp,
+			infoword * sizeof(xfs_suminfo_t),
+			(infoword + 1) * sizeof(xfs_suminfo_t) - 1);
+}
+
 /*
  * Read and/or modify the summary information for a given extent size,
  * bitmap block combination.
@@ -497,8 +509,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 +516,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 +537,19 @@ 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)
+{
+	xfs_trans_log_buf(tp, bp,
+			from * sizeof(xfs_rtword_t),
+			next * sizeof(xfs_rtword_t) - 1);
+}
+
 /*
  * Set the given range of bitmap bits to the given value.
  * Do whatever I/O and logging is required.
@@ -548,6 +571,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 +589,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 +623,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 +662,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 +693,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;
 }
 


^ permalink raw reply related	[flat|nested] 91+ messages in thread

* [PATCH 2/4] xfs: use accessor functions for bitmap words
  2023-10-18  2:10   ` [PATCHSET RFC v1.2 0/4] xfs: refactor rtbitmap/summary accessors Darrick J. Wong
  2023-10-18  2:10     ` [PATCH 1/4] xfs: create a helper to handle logging parts of rt bitmap blocks Darrick J. Wong
@ 2023-10-18  2:10     ` Darrick J. Wong
  2023-10-18  2:19       ` Darrick J. Wong
  2023-10-18  4:54       ` Christoph Hellwig
  2023-10-18  2:10     ` [PATCH 3/4] xfs: create helpers for rtsummary block/wordcount computations Darrick J. Wong
  2023-10-18  2:10     ` [PATCH 4/4] xfs: use accessor functions for summary info words Darrick J. Wong
  3 siblings, 2 replies; 91+ messages in thread
From: Darrick J. Wong @ 2023-10-18  2:10 UTC (permalink / raw)
  To: djwong; +Cc: osandov, hch, linux-xfs

From: Darrick J. Wong <djwong@kernel.org>

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.

Signed-off-by: Darrick J. Wong <djwong@kernel.org>
---
 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(-)


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 d05bd0218885..0e83eca507dd 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.
 			 */
@@ -562,15 +542,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 */
 
@@ -590,7 +569,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.
@@ -609,10 +587,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
@@ -630,12 +610,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 {
 		/*
@@ -651,7 +625,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
@@ -669,12 +643,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++;
 		}
 	}
 	/*
@@ -689,17 +657,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;
 }
@@ -794,7 +763,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 */
@@ -803,6 +771,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 */
 
 	/*
@@ -821,7 +790,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.
@@ -843,7 +811,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.
 			 */
@@ -869,12 +838,6 @@ xfs_rtcheck_range(
 			}
 
 			word = 0;
-			b = xfs_rbmblock_wordptr(bp, word);
-		} else {
-			/*
-			 * Go on to the next word in the buffer.
-			 */
-			b++;
 		}
 	} else {
 		/*
@@ -890,7 +853,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.
 			 */
@@ -916,12 +880,6 @@ xfs_rtcheck_range(
 			}
 
 			word = 0;
-			b = xfs_rbmblock_wordptr(bp, word);
-		} else {
-			/*
-			 * Go on to the next word in the buffer.
-			 */
-			b++;
 		}
 	}
 	/*
@@ -936,7 +894,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


^ permalink raw reply related	[flat|nested] 91+ messages in thread

* [PATCH 3/4] xfs: create helpers for rtsummary block/wordcount computations
  2023-10-18  2:10   ` [PATCHSET RFC v1.2 0/4] xfs: refactor rtbitmap/summary accessors Darrick J. Wong
  2023-10-18  2:10     ` [PATCH 1/4] xfs: create a helper to handle logging parts of rt bitmap blocks Darrick J. Wong
  2023-10-18  2:10     ` [PATCH 2/4] xfs: use accessor functions for bitmap words Darrick J. Wong
@ 2023-10-18  2:10     ` Darrick J. Wong
  2023-10-18  2:10     ` [PATCH 4/4] xfs: use accessor functions for summary info words Darrick J. Wong
  3 siblings, 0 replies; 91+ messages in thread
From: Darrick J. Wong @ 2023-10-18  2:10 UTC (permalink / raw)
  To: djwong; +Cc: Christoph Hellwig, osandov, hch, linux-xfs

From: Darrick J. Wong <djwong@kernel.org>

Create helper functions that compute the number of blocks or words
necessary to store the rt summary file.

Signed-off-by: Darrick J. Wong <djwong@kernel.org>
Reviewed-by: Christoph Hellwig <hch@lst.de>
---
 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(-)


diff --git a/fs/xfs/libxfs/xfs_rtbitmap.c b/fs/xfs/libxfs/xfs_rtbitmap.c
index 0e83eca507dd..4ef54bfbb3da 100644
--- a/fs/xfs/libxfs/xfs_rtbitmap.c
+++ b/fs/xfs/libxfs/xfs_rtbitmap.c
@@ -1140,3 +1140,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.


^ permalink raw reply related	[flat|nested] 91+ messages in thread

* [PATCH 4/4] xfs: use accessor functions for summary info words
  2023-10-18  2:10   ` [PATCHSET RFC v1.2 0/4] xfs: refactor rtbitmap/summary accessors Darrick J. Wong
                       ` (2 preceding siblings ...)
  2023-10-18  2:10     ` [PATCH 3/4] xfs: create helpers for rtsummary block/wordcount computations Darrick J. Wong
@ 2023-10-18  2:10     ` Darrick J. Wong
  2023-10-18  5:19       ` Christoph Hellwig
  3 siblings, 1 reply; 91+ messages in thread
From: Darrick J. Wong @ 2023-10-18  2:10 UTC (permalink / raw)
  To: djwong; +Cc: osandov, hch, linux-xfs

From: Darrick J. Wong <djwong@kernel.org>

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 <djwong@kernel.org>
---
 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     |   30 +++++++++++++++++++++---------
 fs/xfs/scrub/trace.c         |    1 +
 fs/xfs/scrub/trace.h         |   10 +++++-----
 fs/xfs/xfs_ondisk.h          |    1 +
 7 files changed, 70 insertions(+), 23 deletions(-)


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 4ef54bfbb3da..93de330e9cae 100644
--- a/fs/xfs/libxfs/xfs_rtbitmap.c
+++ b/fs/xfs/libxfs/xfs_rtbitmap.c
@@ -448,7 +448,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;
 
 	/*
@@ -487,19 +486,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 ae51fb982808..6ef1fd7e086b 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);
 }
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


^ permalink raw reply related	[flat|nested] 91+ messages in thread

* Re: [PATCH 2/4] xfs: use accessor functions for bitmap words
  2023-10-18  2:10     ` [PATCH 2/4] xfs: use accessor functions for bitmap words Darrick J. Wong
@ 2023-10-18  2:19       ` Darrick J. Wong
  2023-10-18  4:54       ` Christoph Hellwig
  1 sibling, 0 replies; 91+ messages in thread
From: Darrick J. Wong @ 2023-10-18  2:19 UTC (permalink / raw)
  To: osandov, hch, linux-xfs

On Tue, Oct 17, 2023 at 07:10:31PM -0700, Darrick J. Wong wrote:
> From: Darrick J. Wong <djwong@kernel.org>
> 
> 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.
> 

Oh, I should add:
Suggested-by: Christoph Hellwig <hch@lst.de>

--D

> Signed-off-by: Darrick J. Wong <djwong@kernel.org>
> ---
>  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(-)
> 
> 
> 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 d05bd0218885..0e83eca507dd 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.
>  			 */
> @@ -562,15 +542,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 */
>  
> @@ -590,7 +569,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.
> @@ -609,10 +587,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
> @@ -630,12 +610,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 {
>  		/*
> @@ -651,7 +625,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
> @@ -669,12 +643,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++;
>  		}
>  	}
>  	/*
> @@ -689,17 +657,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;
>  }
> @@ -794,7 +763,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 */
> @@ -803,6 +771,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 */
>  
>  	/*
> @@ -821,7 +790,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.
> @@ -843,7 +811,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.
>  			 */
> @@ -869,12 +838,6 @@ xfs_rtcheck_range(
>  			}
>  
>  			word = 0;
> -			b = xfs_rbmblock_wordptr(bp, word);
> -		} else {
> -			/*
> -			 * Go on to the next word in the buffer.
> -			 */
> -			b++;
>  		}
>  	} else {
>  		/*
> @@ -890,7 +853,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.
>  			 */
> @@ -916,12 +880,6 @@ xfs_rtcheck_range(
>  			}
>  
>  			word = 0;
> -			b = xfs_rbmblock_wordptr(bp, word);
> -		} else {
> -			/*
> -			 * Go on to the next word in the buffer.
> -			 */
> -			b++;
>  		}
>  	}
>  	/*
> @@ -936,7 +894,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
> 

^ permalink raw reply	[flat|nested] 91+ messages in thread

* Re: [PATCH 6/8] xfs: use accessor functions for bitmap words
  2023-10-18  2:01       ` Darrick J. Wong
@ 2023-10-18  4:50         ` Christoph Hellwig
  0 siblings, 0 replies; 91+ messages in thread
From: Christoph Hellwig @ 2023-10-18  4:50 UTC (permalink / raw)
  To: Darrick J. Wong; +Cc: Christoph Hellwig, osandov, linux-xfs

On Tue, Oct 17, 2023 at 07:01:01PM -0700, Darrick J. Wong wrote:
> Note that I still need this (and the _infoptr helper) for online repair
> to be able to generate an in-memory replacement of the bitmap and
> summary file and then be able to memcpy the words into the new ondisk
> file.
> 
> That said, I also noticed that the _rtbitmap_[gs]etword and
> _suminfo_{get,add} functions can be static inlines in xfs_rtbitmap.h, so
> I'll put them right after here and the compiler will (hopefully)
> collapse the nested inlines into something fairly compact.
> 
> Ok, I've made all those changes and I'll resend this patchset tomorrow
> after letting it test overnight.

Ok.  We'll also need to do the same for the summary file.  I still offer
to do the full work myself, but I won't have time for that until next
week.  I didn't really have time for this hack either, but I just carved
it off..

^ permalink raw reply	[flat|nested] 91+ messages in thread

* Re: [PATCH 1/4] xfs: create a helper to handle logging parts of rt bitmap blocks
  2023-10-18  2:10     ` [PATCH 1/4] xfs: create a helper to handle logging parts of rt bitmap blocks Darrick J. Wong
@ 2023-10-18  4:52       ` Christoph Hellwig
  0 siblings, 0 replies; 91+ messages in thread
From: Christoph Hellwig @ 2023-10-18  4:52 UTC (permalink / raw)
  To: Darrick J. Wong; +Cc: Christoph Hellwig, osandov, linux-xfs

Looks good:

Reviewed-by: Christoph Hellwig <hch@lst.de>

^ permalink raw reply	[flat|nested] 91+ messages in thread

* Re: [PATCH 2/4] xfs: use accessor functions for bitmap words
  2023-10-18  2:10     ` [PATCH 2/4] xfs: use accessor functions for bitmap words Darrick J. Wong
  2023-10-18  2:19       ` Darrick J. Wong
@ 2023-10-18  4:54       ` Christoph Hellwig
  2023-10-18  4:54         ` Christoph Hellwig
  2023-10-18 16:27         ` Darrick J. Wong
  1 sibling, 2 replies; 91+ messages in thread
From: Christoph Hellwig @ 2023-10-18  4:54 UTC (permalink / raw)
  To: Darrick J. Wong; +Cc: osandov, hch, linux-xfs

> +/* 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;
> +}

Before getting rid of xfs_rbmblock_wordptr I initially did this as:

	return xfs_rbmblock_wordptr(bp, index)->old;

and
	xfs_rbmblock_wordptr(bp, index)->old = value;

which looks a little neater to me.

Otherwise looks good:

Signed-off-by: Christoph Hellwig <hch@lst.de>

^ permalink raw reply	[flat|nested] 91+ messages in thread

* Re: [PATCH 2/4] xfs: use accessor functions for bitmap words
  2023-10-18  4:54       ` Christoph Hellwig
@ 2023-10-18  4:54         ` Christoph Hellwig
  2023-10-18 16:27         ` Darrick J. Wong
  1 sibling, 0 replies; 91+ messages in thread
From: Christoph Hellwig @ 2023-10-18  4:54 UTC (permalink / raw)
  To: Darrick J. Wong; +Cc: osandov, hch, linux-xfs

On Wed, Oct 18, 2023 at 06:54:25AM +0200, Christoph Hellwig wrote:
> Signed-off-by: Christoph Hellwig <hch@lst.de>

Err:

Reviewed-by: Christoph Hellwig <hch@lst.de>

^ permalink raw reply	[flat|nested] 91+ messages in thread

* Re: [PATCH 4/4] xfs: use accessor functions for summary info words
  2023-10-18  2:10     ` [PATCH 4/4] xfs: use accessor functions for summary info words Darrick J. Wong
@ 2023-10-18  5:19       ` Christoph Hellwig
  2023-10-18  5:31         ` Darrick J. Wong
  0 siblings, 1 reply; 91+ messages in thread
From: Christoph Hellwig @ 2023-10-18  5:19 UTC (permalink / raw)
  To: Darrick J. Wong; +Cc: osandov, hch, linux-xfs

On Tue, Oct 17, 2023 at 07:10:42PM -0700, Darrick J. Wong wrote:
> +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;
> +}

Same nitpick as for the bitmap version.

Otherwise this looks good:

Signed-off-by: Christoph Hellwig <hch@lst.de>


... to actually understand the mess in xfs_rtmodify_summary_int I had
to do the (untested) refactoring below.  I'll probably resubmit it after
the whole series which touches a lot of this:


diff --git a/fs/xfs/libxfs/xfs_rtbitmap.c b/fs/xfs/libxfs/xfs_rtbitmap.c
index 2118c6f177a135..7b09caa747a720 100644
--- a/fs/xfs/libxfs/xfs_rtbitmap.c
+++ b/fs/xfs/libxfs/xfs_rtbitmap.c
@@ -433,78 +433,69 @@ xfs_trans_log_rtsummary(
  * Summary information is returned in *sum if specified.
  * If no delta is specified, returns summary only.
  */
-int
-xfs_rtmodify_summary_int(
+static int
+xfs_rtmodify_summary_find(
 	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 */
+	unsigned int	*word)
 {
 	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 */
+	xfs_fileoff_t	sb;		/* summary fsblock */
 
 	/*
 	 * Compute entry number in the summary file.
 	 */
 	so = xfs_rtsumoffs(mp, log, bbno);
+
 	/*
 	 * Compute the block number in the summary file.
 	 */
 	sb = xfs_rtsumoffs_to_block(mp, so);
+
+	/*
+	 * Compute the word index into the summary.
+	 */
+	*word = xfs_rtsumoffs_to_infoword(mp, so);
+
 	/*
 	 * If we have an old buffer, and the block number matches, use that.
 	 */
 	if (*rbpp && *rsb == sb)
-		bp = *rbpp;
+		return 0;
+
 	/*
-	 * Otherwise we have to get the buffer.
+	 * Otherwise we have to get a new buffer.
+	 * If there was an old one, get rid of it first.
 	 */
-	else {
-		/*
-		 * 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);
-		if (error) {
-			return error;
-		}
-		/*
-		 * Remember this buffer and block for the next call.
-		 */
-		*rbpp = bp;
-		*rsb = sb;
-	}
+	if (*rbpp)
+		xfs_trans_brelse(tp, *rbpp);
+	error = xfs_rtbuf_get(mp, tp, sb, 1, &bp);
+	if (error)
+		return error;
+
 	/*
-	 * Point to the summary information, modify/log it, and/or copy it out.
+	 * Remember this buffer and block for the next call.
 	 */
-	if (delta) {
-		unsigned int	infoword = xfs_rtsumoffs_to_infoword(mp, so);
-		xfs_suminfo_t	val = xfs_suminfo_add(bp, 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])
-				mp->m_rsum_cache[bbno] = log;
-		}
-		xfs_trans_log_rtsummary(tp, bp, infoword);
-		if (sum)
-			*sum = val;
-	} else if (sum) {
-		unsigned int	infoword = xfs_rtsumoffs_to_infoword(mp, so);
-
-		*sum = xfs_suminfo_get(bp, infoword);
-	}
+	*rbpp = bp;
+	*rsb = sb;
 	return 0;
 }
 
+/*
+ * Read and/or modify the summary information for a given extent size,
+ * bitmap block combination.
+ * Keeps track of a current summary block, so we don't keep reading
+ * it from the buffer cache.
+ *
+ * Summary information is returned in *sum if specified.
+ * If no delta is specified, returns summary only.
+ */
 int
 xfs_rtmodify_summary(
 	xfs_mount_t	*mp,		/* file system mount structure */
@@ -515,8 +506,51 @@ xfs_rtmodify_summary(
 	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);
+	int		error;
+	unsigned int	word;
+	xfs_suminfo_t	val;
+
+	error = xfs_rtmodify_summary_find(mp, tp, log, bbno, rbpp, rsb, &word);
+	if (error)
+		return error;
+
+	/*
+	 * Modify and log the summary information.
+	 */
+	val = xfs_suminfo_add(*rbpp, word, 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])
+			mp->m_rsum_cache[bbno] = log;
+	}
+	xfs_trans_log_rtsummary(tp, *rbpp, word);
+	return 0;
+}
+
+/*
+ * Read and return the summary information for a given extent size,
+ * bitmap block combination.
+ * Keeps track of a current summary block, so we don't keep reading
+ * it from the buffer cache.
+ */
+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 */
+{
+	int		error;
+	unsigned int	word;
+
+	error = xfs_rtmodify_summary_find(mp, tp, log, bbno, rbpp, rsb, &word);
+	if (!error)
+		*sum = xfs_suminfo_get(*rbpp, word);
+	return error;
 }
 
 /* Log rtbitmap block from the word @from to the byte before @next. */
diff --git a/fs/xfs/libxfs/xfs_rtbitmap.h b/fs/xfs/libxfs/xfs_rtbitmap.h
index fdfa98e0ee52f7..6d23a77def50dd 100644
--- a/fs/xfs/libxfs/xfs_rtbitmap.h
+++ b/fs/xfs/libxfs/xfs_rtbitmap.h
@@ -294,13 +294,12 @@ int xfs_rtfind_forw(struct xfs_mount *mp, struct xfs_trans *tp,
 		    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_rtget_summary(struct xfs_mount *mp, struct xfs_trans *tp, int log,
+		      xfs_fileoff_t bbno, struct xfs_buf **rbpp,
+		      xfs_fileoff_t *rsb, xfs_suminfo_t *sum);
 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);
diff --git a/fs/xfs/xfs_rtalloc.c b/fs/xfs/xfs_rtalloc.c
index 3be6bda2fd920c..22bc8b3b724a5b 100644
--- a/fs/xfs/xfs_rtalloc.c
+++ b/fs/xfs/xfs_rtalloc.c
@@ -21,25 +21,6 @@
 #include "xfs_sb.h"
 #include "xfs_rtbitmap.h"
 
-/*
- * Read and return the summary information for a given extent size,
- * bitmap block combination.
- * Keeps track of a current summary block, so we don't keep reading
- * it from the buffer cache.
- */
-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 */
-{
-	return xfs_rtmodify_summary_int(mp, tp, 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.

^ permalink raw reply related	[flat|nested] 91+ messages in thread

* Re: [PATCH 4/4] xfs: use accessor functions for summary info words
  2023-10-18  5:19       ` Christoph Hellwig
@ 2023-10-18  5:31         ` Darrick J. Wong
  2023-10-18  5:35           ` Christoph Hellwig
  2023-10-18  6:16           ` Darrick J. Wong
  0 siblings, 2 replies; 91+ messages in thread
From: Darrick J. Wong @ 2023-10-18  5:31 UTC (permalink / raw)
  To: Christoph Hellwig; +Cc: osandov, linux-xfs

On Wed, Oct 18, 2023 at 07:19:34AM +0200, Christoph Hellwig wrote:
> On Tue, Oct 17, 2023 at 07:10:42PM -0700, Darrick J. Wong wrote:
> > +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;
> > +}
> 
> Same nitpick as for the bitmap version.
> 
> Otherwise this looks good:
> 
> Signed-off-by: Christoph Hellwig <hch@lst.de>

Assuming you also meant "Reviewed-by" here too? :)

> ... to actually understand the mess in xfs_rtmodify_summary_int I had
> to do the (untested) refactoring below.  I'll probably resubmit it after
> the whole series which touches a lot of this:

I'll take a look tomorrow, but yeah, xfs_rtmodify_summary_int is
confusing.

Annoyingly, I think there's a bug in new logging helpers, because all
the shutdown tests are falling all over themselves:

https://djwong.org/fstests/output/.c6b00f80b1e68bd5a3b17a7f7fbe97bab28dab740d7acf9e3fa879c3ae0c56c0/.02425ea8cdb6100e408b20dceac80a46f53f6fa1587fb4af7fba2810f2b8d0fd/?C=M;O=A

Will look at /that/ first thing...

--D

> 
> diff --git a/fs/xfs/libxfs/xfs_rtbitmap.c b/fs/xfs/libxfs/xfs_rtbitmap.c
> index 2118c6f177a135..7b09caa747a720 100644
> --- a/fs/xfs/libxfs/xfs_rtbitmap.c
> +++ b/fs/xfs/libxfs/xfs_rtbitmap.c
> @@ -433,78 +433,69 @@ xfs_trans_log_rtsummary(
>   * Summary information is returned in *sum if specified.
>   * If no delta is specified, returns summary only.
>   */
> -int
> -xfs_rtmodify_summary_int(
> +static int
> +xfs_rtmodify_summary_find(
>  	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 */
> +	unsigned int	*word)
>  {
>  	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 */
> +	xfs_fileoff_t	sb;		/* summary fsblock */
>  
>  	/*
>  	 * Compute entry number in the summary file.
>  	 */
>  	so = xfs_rtsumoffs(mp, log, bbno);
> +
>  	/*
>  	 * Compute the block number in the summary file.
>  	 */
>  	sb = xfs_rtsumoffs_to_block(mp, so);
> +
> +	/*
> +	 * Compute the word index into the summary.
> +	 */
> +	*word = xfs_rtsumoffs_to_infoword(mp, so);
> +
>  	/*
>  	 * If we have an old buffer, and the block number matches, use that.
>  	 */
>  	if (*rbpp && *rsb == sb)
> -		bp = *rbpp;
> +		return 0;
> +
>  	/*
> -	 * Otherwise we have to get the buffer.
> +	 * Otherwise we have to get a new buffer.
> +	 * If there was an old one, get rid of it first.
>  	 */
> -	else {
> -		/*
> -		 * 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);
> -		if (error) {
> -			return error;
> -		}
> -		/*
> -		 * Remember this buffer and block for the next call.
> -		 */
> -		*rbpp = bp;
> -		*rsb = sb;
> -	}
> +	if (*rbpp)
> +		xfs_trans_brelse(tp, *rbpp);
> +	error = xfs_rtbuf_get(mp, tp, sb, 1, &bp);
> +	if (error)
> +		return error;
> +
>  	/*
> -	 * Point to the summary information, modify/log it, and/or copy it out.
> +	 * Remember this buffer and block for the next call.
>  	 */
> -	if (delta) {
> -		unsigned int	infoword = xfs_rtsumoffs_to_infoword(mp, so);
> -		xfs_suminfo_t	val = xfs_suminfo_add(bp, 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])
> -				mp->m_rsum_cache[bbno] = log;
> -		}
> -		xfs_trans_log_rtsummary(tp, bp, infoword);
> -		if (sum)
> -			*sum = val;
> -	} else if (sum) {
> -		unsigned int	infoword = xfs_rtsumoffs_to_infoword(mp, so);
> -
> -		*sum = xfs_suminfo_get(bp, infoword);
> -	}
> +	*rbpp = bp;
> +	*rsb = sb;
>  	return 0;
>  }
>  
> +/*
> + * Read and/or modify the summary information for a given extent size,
> + * bitmap block combination.
> + * Keeps track of a current summary block, so we don't keep reading
> + * it from the buffer cache.
> + *
> + * Summary information is returned in *sum if specified.
> + * If no delta is specified, returns summary only.
> + */
>  int
>  xfs_rtmodify_summary(
>  	xfs_mount_t	*mp,		/* file system mount structure */
> @@ -515,8 +506,51 @@ xfs_rtmodify_summary(
>  	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);
> +	int		error;
> +	unsigned int	word;
> +	xfs_suminfo_t	val;
> +
> +	error = xfs_rtmodify_summary_find(mp, tp, log, bbno, rbpp, rsb, &word);
> +	if (error)
> +		return error;
> +
> +	/*
> +	 * Modify and log the summary information.
> +	 */
> +	val = xfs_suminfo_add(*rbpp, word, 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])
> +			mp->m_rsum_cache[bbno] = log;
> +	}
> +	xfs_trans_log_rtsummary(tp, *rbpp, word);
> +	return 0;
> +}
> +
> +/*
> + * Read and return the summary information for a given extent size,
> + * bitmap block combination.
> + * Keeps track of a current summary block, so we don't keep reading
> + * it from the buffer cache.
> + */
> +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 */
> +{
> +	int		error;
> +	unsigned int	word;
> +
> +	error = xfs_rtmodify_summary_find(mp, tp, log, bbno, rbpp, rsb, &word);
> +	if (!error)
> +		*sum = xfs_suminfo_get(*rbpp, word);
> +	return error;
>  }
>  
>  /* Log rtbitmap block from the word @from to the byte before @next. */
> diff --git a/fs/xfs/libxfs/xfs_rtbitmap.h b/fs/xfs/libxfs/xfs_rtbitmap.h
> index fdfa98e0ee52f7..6d23a77def50dd 100644
> --- a/fs/xfs/libxfs/xfs_rtbitmap.h
> +++ b/fs/xfs/libxfs/xfs_rtbitmap.h
> @@ -294,13 +294,12 @@ int xfs_rtfind_forw(struct xfs_mount *mp, struct xfs_trans *tp,
>  		    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_rtget_summary(struct xfs_mount *mp, struct xfs_trans *tp, int log,
> +		      xfs_fileoff_t bbno, struct xfs_buf **rbpp,
> +		      xfs_fileoff_t *rsb, xfs_suminfo_t *sum);
>  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);
> diff --git a/fs/xfs/xfs_rtalloc.c b/fs/xfs/xfs_rtalloc.c
> index 3be6bda2fd920c..22bc8b3b724a5b 100644
> --- a/fs/xfs/xfs_rtalloc.c
> +++ b/fs/xfs/xfs_rtalloc.c
> @@ -21,25 +21,6 @@
>  #include "xfs_sb.h"
>  #include "xfs_rtbitmap.h"
>  
> -/*
> - * Read and return the summary information for a given extent size,
> - * bitmap block combination.
> - * Keeps track of a current summary block, so we don't keep reading
> - * it from the buffer cache.
> - */
> -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 */
> -{
> -	return xfs_rtmodify_summary_int(mp, tp, 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.

^ permalink raw reply	[flat|nested] 91+ messages in thread

* Re: [PATCH 4/4] xfs: use accessor functions for summary info words
  2023-10-18  5:31         ` Darrick J. Wong
@ 2023-10-18  5:35           ` Christoph Hellwig
  2023-10-18  6:16           ` Darrick J. Wong
  1 sibling, 0 replies; 91+ messages in thread
From: Christoph Hellwig @ 2023-10-18  5:35 UTC (permalink / raw)
  To: Darrick J. Wong; +Cc: Christoph Hellwig, osandov, linux-xfs

On Tue, Oct 17, 2023 at 10:31:27PM -0700, Darrick J. Wong wrote:
> > Signed-off-by: Christoph Hellwig <hch@lst.de>
> 
> Assuming you also meant "Reviewed-by" here too? :)

Yes:

Reviewed-by: Christoph Hellwig <hch@lst.de>

^ permalink raw reply	[flat|nested] 91+ messages in thread

* Re: [PATCH 4/4] xfs: use accessor functions for summary info words
  2023-10-18  5:31         ` Darrick J. Wong
  2023-10-18  5:35           ` Christoph Hellwig
@ 2023-10-18  6:16           ` Darrick J. Wong
  1 sibling, 0 replies; 91+ messages in thread
From: Darrick J. Wong @ 2023-10-18  6:16 UTC (permalink / raw)
  To: Christoph Hellwig; +Cc: osandov, linux-xfs

On Tue, Oct 17, 2023 at 10:31:27PM -0700, Darrick J. Wong wrote:
> On Wed, Oct 18, 2023 at 07:19:34AM +0200, Christoph Hellwig wrote:
> > On Tue, Oct 17, 2023 at 07:10:42PM -0700, Darrick J. Wong wrote:
> > > +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;
> > > +}
> > 
> > Same nitpick as for the bitmap version.
> > 
> > Otherwise this looks good:
> > 
> > Signed-off-by: Christoph Hellwig <hch@lst.de>
> 
> Assuming you also meant "Reviewed-by" here too? :)
> 
> > ... to actually understand the mess in xfs_rtmodify_summary_int I had
> > to do the (untested) refactoring below.  I'll probably resubmit it after
> > the whole series which touches a lot of this:
> 
> I'll take a look tomorrow, but yeah, xfs_rtmodify_summary_int is
> confusing.
> 
> Annoyingly, I think there's a bug in new logging helpers, because all
> the shutdown tests are falling all over themselves:
> 
> https://djwong.org/fstests/output/.c6b00f80b1e68bd5a3b17a7f7fbe97bab28dab740d7acf9e3fa879c3ae0c56c0/.02425ea8cdb6100e408b20dceac80a46f53f6fa1587fb4af7fba2810f2b8d0fd/?C=M;O=A
> 
> Will look at /that/ first thing...

Oh rats, I forgot to adjust the xfs_trans_log_rtbitmap offsets for the
block headers added in the rtgroups patchset.

--D

> --D
> 
> > 
> > diff --git a/fs/xfs/libxfs/xfs_rtbitmap.c b/fs/xfs/libxfs/xfs_rtbitmap.c
> > index 2118c6f177a135..7b09caa747a720 100644
> > --- a/fs/xfs/libxfs/xfs_rtbitmap.c
> > +++ b/fs/xfs/libxfs/xfs_rtbitmap.c
> > @@ -433,78 +433,69 @@ xfs_trans_log_rtsummary(
> >   * Summary information is returned in *sum if specified.
> >   * If no delta is specified, returns summary only.
> >   */
> > -int
> > -xfs_rtmodify_summary_int(
> > +static int
> > +xfs_rtmodify_summary_find(
> >  	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 */
> > +	unsigned int	*word)
> >  {
> >  	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 */
> > +	xfs_fileoff_t	sb;		/* summary fsblock */
> >  
> >  	/*
> >  	 * Compute entry number in the summary file.
> >  	 */
> >  	so = xfs_rtsumoffs(mp, log, bbno);
> > +
> >  	/*
> >  	 * Compute the block number in the summary file.
> >  	 */
> >  	sb = xfs_rtsumoffs_to_block(mp, so);
> > +
> > +	/*
> > +	 * Compute the word index into the summary.
> > +	 */
> > +	*word = xfs_rtsumoffs_to_infoword(mp, so);
> > +
> >  	/*
> >  	 * If we have an old buffer, and the block number matches, use that.
> >  	 */
> >  	if (*rbpp && *rsb == sb)
> > -		bp = *rbpp;
> > +		return 0;
> > +
> >  	/*
> > -	 * Otherwise we have to get the buffer.
> > +	 * Otherwise we have to get a new buffer.
> > +	 * If there was an old one, get rid of it first.
> >  	 */
> > -	else {
> > -		/*
> > -		 * 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);
> > -		if (error) {
> > -			return error;
> > -		}
> > -		/*
> > -		 * Remember this buffer and block for the next call.
> > -		 */
> > -		*rbpp = bp;
> > -		*rsb = sb;
> > -	}
> > +	if (*rbpp)
> > +		xfs_trans_brelse(tp, *rbpp);
> > +	error = xfs_rtbuf_get(mp, tp, sb, 1, &bp);
> > +	if (error)
> > +		return error;
> > +
> >  	/*
> > -	 * Point to the summary information, modify/log it, and/or copy it out.
> > +	 * Remember this buffer and block for the next call.
> >  	 */
> > -	if (delta) {
> > -		unsigned int	infoword = xfs_rtsumoffs_to_infoword(mp, so);
> > -		xfs_suminfo_t	val = xfs_suminfo_add(bp, 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])
> > -				mp->m_rsum_cache[bbno] = log;
> > -		}
> > -		xfs_trans_log_rtsummary(tp, bp, infoword);
> > -		if (sum)
> > -			*sum = val;
> > -	} else if (sum) {
> > -		unsigned int	infoword = xfs_rtsumoffs_to_infoword(mp, so);
> > -
> > -		*sum = xfs_suminfo_get(bp, infoword);
> > -	}
> > +	*rbpp = bp;
> > +	*rsb = sb;
> >  	return 0;
> >  }
> >  
> > +/*
> > + * Read and/or modify the summary information for a given extent size,
> > + * bitmap block combination.
> > + * Keeps track of a current summary block, so we don't keep reading
> > + * it from the buffer cache.
> > + *
> > + * Summary information is returned in *sum if specified.
> > + * If no delta is specified, returns summary only.
> > + */
> >  int
> >  xfs_rtmodify_summary(
> >  	xfs_mount_t	*mp,		/* file system mount structure */
> > @@ -515,8 +506,51 @@ xfs_rtmodify_summary(
> >  	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);
> > +	int		error;
> > +	unsigned int	word;
> > +	xfs_suminfo_t	val;
> > +
> > +	error = xfs_rtmodify_summary_find(mp, tp, log, bbno, rbpp, rsb, &word);
> > +	if (error)
> > +		return error;
> > +
> > +	/*
> > +	 * Modify and log the summary information.
> > +	 */
> > +	val = xfs_suminfo_add(*rbpp, word, 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])
> > +			mp->m_rsum_cache[bbno] = log;
> > +	}
> > +	xfs_trans_log_rtsummary(tp, *rbpp, word);
> > +	return 0;
> > +}
> > +
> > +/*
> > + * Read and return the summary information for a given extent size,
> > + * bitmap block combination.
> > + * Keeps track of a current summary block, so we don't keep reading
> > + * it from the buffer cache.
> > + */
> > +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 */
> > +{
> > +	int		error;
> > +	unsigned int	word;
> > +
> > +	error = xfs_rtmodify_summary_find(mp, tp, log, bbno, rbpp, rsb, &word);
> > +	if (!error)
> > +		*sum = xfs_suminfo_get(*rbpp, word);
> > +	return error;
> >  }
> >  
> >  /* Log rtbitmap block from the word @from to the byte before @next. */
> > diff --git a/fs/xfs/libxfs/xfs_rtbitmap.h b/fs/xfs/libxfs/xfs_rtbitmap.h
> > index fdfa98e0ee52f7..6d23a77def50dd 100644
> > --- a/fs/xfs/libxfs/xfs_rtbitmap.h
> > +++ b/fs/xfs/libxfs/xfs_rtbitmap.h
> > @@ -294,13 +294,12 @@ int xfs_rtfind_forw(struct xfs_mount *mp, struct xfs_trans *tp,
> >  		    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_rtget_summary(struct xfs_mount *mp, struct xfs_trans *tp, int log,
> > +		      xfs_fileoff_t bbno, struct xfs_buf **rbpp,
> > +		      xfs_fileoff_t *rsb, xfs_suminfo_t *sum);
> >  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);
> > diff --git a/fs/xfs/xfs_rtalloc.c b/fs/xfs/xfs_rtalloc.c
> > index 3be6bda2fd920c..22bc8b3b724a5b 100644
> > --- a/fs/xfs/xfs_rtalloc.c
> > +++ b/fs/xfs/xfs_rtalloc.c
> > @@ -21,25 +21,6 @@
> >  #include "xfs_sb.h"
> >  #include "xfs_rtbitmap.h"
> >  
> > -/*
> > - * Read and return the summary information for a given extent size,
> > - * bitmap block combination.
> > - * Keeps track of a current summary block, so we don't keep reading
> > - * it from the buffer cache.
> > - */
> > -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 */
> > -{
> > -	return xfs_rtmodify_summary_int(mp, tp, 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.

^ permalink raw reply	[flat|nested] 91+ messages in thread

* Re: [PATCH 1/7] xfs: consolidate realtime allocation arguments
  2023-10-17 15:54   ` [PATCH 1/7] xfs: consolidate realtime allocation arguments Darrick J. Wong
@ 2023-10-18  6:16     ` Christoph Hellwig
  2023-10-18 17:04       ` Darrick J. Wong
  0 siblings, 1 reply; 91+ messages in thread
From: Christoph Hellwig @ 2023-10-18  6:16 UTC (permalink / raw)
  To: Darrick J. Wong; +Cc: Dave Chinner, osandov, osandov, linux-xfs, hch

On Tue, Oct 17, 2023 at 08:54:08AM -0700, Darrick J. Wong wrote:
> From: Dave Chinner <dchinner@redhat.com>
> 
> 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....

Overall this looks good to me, but a few cosmetic comments:

> +	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 */

we should either also document the new args argument, or drop all the
other argument comments like we've done in many places.  If we want
to keep them it would be good to do the trivial reformatting so that
they don't extend over the 80 character readability limit.

> +	struct xfs_mount	*mp = args->mount;

mount is a bit of an odd name for the member.  We usuall calls this
mp in most structures like our normal variable name (with tp->t_mountp
as one notable odd exception).

> +	error = xfs_trans_read_buf(mp, args->trans, mp->m_ddev_targp,
>  				   XFS_FSB_TO_DADDR(mp, map.br_startblock),
>  				   mp->m_bsize, 0, &bp, &xfs_rtbuf_ops);

->trans has some precedence in the dir/attr code, but I think tp
would still be more logical.


^ permalink raw reply	[flat|nested] 91+ messages in thread

* Re: [PATCH 2/7] xfs: cache last bitmap block in realtime allocator
  2023-10-17 15:54   ` [PATCH 2/7] xfs: cache last bitmap block in realtime allocator Darrick J. Wong
@ 2023-10-18  6:19     ` Christoph Hellwig
  2023-10-18 16:33       ` Darrick J. Wong
  2023-10-18 18:28     ` Darrick J. Wong
  1 sibling, 1 reply; 91+ messages in thread
From: Christoph Hellwig @ 2023-10-18  6:19 UTC (permalink / raw)
  To: Darrick J. Wong; +Cc: Omar Sandoval, Christoph Hellwig, osandov, linux-xfs

On Tue, Oct 17, 2023 at 08:54:23AM -0700, Darrick J. Wong wrote:
>   * The buffer is returned read and locked.
> @@ -59,12 +73,32 @@ xfs_rtbuf_get(
>  	struct xfs_buf		**bpp)		/* output: buffer for the block */
>  {
>  	struct xfs_mount	*mp = args->mount;
> +	struct xfs_buf		**cbpp;		/* cached block buffer */
> +	xfs_fsblock_t		*cbp;		/* cached block number */
>  	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;		/* error value */
>  
> +	cbpp = issum ? &args->bbuf : &args->sbuf;
> +	cbp = issum ? &args->bblock : &args->sblock;

Now that we have the summary/bitmap buffers in the args structure,
it seems like we can also drop the bp argument from xfs_rtbuf_get and
just the pointer in the args structue in the callers.


^ permalink raw reply	[flat|nested] 91+ messages in thread

* Re: [PATCH 2/4] xfs: use accessor functions for bitmap words
  2023-10-18  4:54       ` Christoph Hellwig
  2023-10-18  4:54         ` Christoph Hellwig
@ 2023-10-18 16:27         ` Darrick J. Wong
  2023-10-18 16:28           ` Christoph Hellwig
  1 sibling, 1 reply; 91+ messages in thread
From: Darrick J. Wong @ 2023-10-18 16:27 UTC (permalink / raw)
  To: Christoph Hellwig; +Cc: osandov, linux-xfs

On Wed, Oct 18, 2023 at 06:54:25AM +0200, Christoph Hellwig wrote:
> > +/* 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;
> > +}
> 
> Before getting rid of xfs_rbmblock_wordptr I initially did this as:
> 
> 	return xfs_rbmblock_wordptr(bp, index)->old;
> 
> and
> 	xfs_rbmblock_wordptr(bp, index)->old = value;
> 
> which looks a little neater to me.

I set up the function in that (for now) verbose manner to reduce the
diff when the rtgroups patchset redefines the ondisk format to include a
block header (and crcs) and enforces endiannness:

/* 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);

        if (xfs_has_rtgroups(bp->b_mount))
                return le32_to_cpu(word->rtg);
        return word->old;
}

So I hope you don't mind if I leave it the way it is now. :)

--D

> Otherwise looks good:
> 
> Signed-off-by: Christoph Hellwig <hch@lst.de>

^ permalink raw reply	[flat|nested] 91+ messages in thread

* Re: [PATCH 2/4] xfs: use accessor functions for bitmap words
  2023-10-18 16:27         ` Darrick J. Wong
@ 2023-10-18 16:28           ` Christoph Hellwig
  0 siblings, 0 replies; 91+ messages in thread
From: Christoph Hellwig @ 2023-10-18 16:28 UTC (permalink / raw)
  To: Darrick J. Wong; +Cc: Christoph Hellwig, osandov, linux-xfs

On Wed, Oct 18, 2023 at 09:27:49AM -0700, Darrick J. Wong wrote:
> So I hope you don't mind if I leave it the way it is now. :)

Fine with me, just wanted to throw my two cents in.


^ permalink raw reply	[flat|nested] 91+ messages in thread

* Re: [PATCH 2/7] xfs: cache last bitmap block in realtime allocator
  2023-10-18  6:19     ` Christoph Hellwig
@ 2023-10-18 16:33       ` Darrick J. Wong
  2023-10-19  0:00         ` Darrick J. Wong
  0 siblings, 1 reply; 91+ messages in thread
From: Darrick J. Wong @ 2023-10-18 16:33 UTC (permalink / raw)
  To: Christoph Hellwig; +Cc: Omar Sandoval, osandov, linux-xfs

On Wed, Oct 18, 2023 at 08:19:11AM +0200, Christoph Hellwig wrote:
> On Tue, Oct 17, 2023 at 08:54:23AM -0700, Darrick J. Wong wrote:
> >   * The buffer is returned read and locked.
> > @@ -59,12 +73,32 @@ xfs_rtbuf_get(
> >  	struct xfs_buf		**bpp)		/* output: buffer for the block */
> >  {
> >  	struct xfs_mount	*mp = args->mount;
> > +	struct xfs_buf		**cbpp;		/* cached block buffer */
> > +	xfs_fsblock_t		*cbp;		/* cached block number */
> >  	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;		/* error value */
> >  
> > +	cbpp = issum ? &args->bbuf : &args->sbuf;
> > +	cbp = issum ? &args->bblock : &args->sblock;
> 
> Now that we have the summary/bitmap buffers in the args structure,
> it seems like we can also drop the bp argument from xfs_rtbuf_get and
> just the pointer in the args structue in the callers.

Yeah, I was wondering about that too -- either we take a second refcount
on @bp and pass it out via **bpp, or callers can pluck it from @args
directly and call _cache_relse before @args goes out of scope.

I'll remove **bpp since it's redundant.

--D

^ permalink raw reply	[flat|nested] 91+ messages in thread

* Re: [PATCH 1/7] xfs: consolidate realtime allocation arguments
  2023-10-18  6:16     ` Christoph Hellwig
@ 2023-10-18 17:04       ` Darrick J. Wong
  0 siblings, 0 replies; 91+ messages in thread
From: Darrick J. Wong @ 2023-10-18 17:04 UTC (permalink / raw)
  To: Christoph Hellwig; +Cc: Dave Chinner, osandov, osandov, linux-xfs

On Wed, Oct 18, 2023 at 08:16:48AM +0200, Christoph Hellwig wrote:
> On Tue, Oct 17, 2023 at 08:54:08AM -0700, Darrick J. Wong wrote:
> > From: Dave Chinner <dchinner@redhat.com>
> > 
> > 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....
> 
> Overall this looks good to me, but a few cosmetic comments:
> 
> > +	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 */
> 
> we should either also document the new args argument, or drop all the
> other argument comments like we've done in many places.  If we want
> to keep them it would be good to do the trivial reformatting so that
> they don't extend over the 80 character readability limit.

I prefer to leave the comments because they were immensely helpful for
figuring out the correct variable types in the refactoring series.  If
they can help someone else (e.g. 2024 me) figure out what this code
does, they're worth leaving in.

However, I'll fix the formatting errors to try to get the lines back to
around 80col.  I'll also get rid of the pointless comments like:

int error; /* error value */

> > +	struct xfs_mount	*mp = args->mount;
> 
> mount is a bit of an odd name for the member.  We usuall calls this
> mp in most structures like our normal variable name (with tp->t_mountp
> as one notable odd exception).
> 
> > +	error = xfs_trans_read_buf(mp, args->trans, mp->m_ddev_targp,
> >  				   XFS_FSB_TO_DADDR(mp, map.br_startblock),
> >  				   mp->m_bsize, 0, &bp, &xfs_rtbuf_ops);
> 
> ->trans has some precedence in the dir/attr code, but I think tp
> would still be more logical.

Agreed.

--D

^ permalink raw reply	[flat|nested] 91+ messages in thread

* Re: [PATCH 2/7] xfs: cache last bitmap block in realtime allocator
  2023-10-17 15:54   ` [PATCH 2/7] xfs: cache last bitmap block in realtime allocator Darrick J. Wong
  2023-10-18  6:19     ` Christoph Hellwig
@ 2023-10-18 18:28     ` Darrick J. Wong
  1 sibling, 0 replies; 91+ messages in thread
From: Darrick J. Wong @ 2023-10-18 18:28 UTC (permalink / raw)
  To: Omar Sandoval, Christoph Hellwig, osandov, linux-xfs

On Tue, Oct 17, 2023 at 08:54:23AM -0700, Darrick J. Wong wrote:
> From: Omar Sandoval <osandov@fb.com>
> 
> 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 <osandov@fb.com>
> Reviewed-by: Darrick J. Wong <djwong@kernel.org>
> Signed-off-by: Darrick J. Wong <djwong@kernel.org>
> Reviewed-by: Christoph Hellwig <hch@lst.de>
> ---
>  fs/xfs/libxfs/xfs_rtbitmap.c |  130 ++++++++++++++++++++----------------------
>  fs/xfs/libxfs/xfs_rtbitmap.h |   17 ++++-
>  fs/xfs/scrub/rtsummary.c     |    4 +
>  fs/xfs/xfs_rtalloc.c         |  109 ++++++++++++++---------------------
>  4 files changed, 120 insertions(+), 140 deletions(-)
> 
> 
> diff --git a/fs/xfs/libxfs/xfs_rtbitmap.c b/fs/xfs/libxfs/xfs_rtbitmap.c
> index 5a7994e031f3..428a3a5b660d 100644
> --- a/fs/xfs/libxfs/xfs_rtbitmap.c
> +++ b/fs/xfs/libxfs/xfs_rtbitmap.c
> @@ -47,6 +47,20 @@ const struct xfs_buf_ops xfs_rtbuf_ops = {
>  	.verify_write = xfs_rtbuf_verify_write,
>  };
>  
> +void
> +xfs_rtbuf_cache_relse(
> +	struct xfs_rtalloc_args	*args)
> +{
> +	if (args->bbuf) {
> +		xfs_trans_brelse(args->trans, args->bbuf);
> +		args->bbuf = NULL;
> +	}
> +	if (args->sbuf) {
> +		xfs_trans_brelse(args->trans, args->sbuf);
> +		args->sbuf = NULL;
> +	}
> +}
> +
>  /*
>   * Get a buffer for the bitmap or summary file block specified.
>   * The buffer is returned read and locked.
> @@ -59,12 +73,32 @@ xfs_rtbuf_get(
>  	struct xfs_buf		**bpp)		/* output: buffer for the block */
>  {
>  	struct xfs_mount	*mp = args->mount;
> +	struct xfs_buf		**cbpp;		/* cached block buffer */
> +	xfs_fsblock_t		*cbp;		/* cached block number */

Nit: xfs_fileoff_t, not xfs_fsblock_t.

>  	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;		/* error value */
>  
> +	cbpp = issum ? &args->bbuf : &args->sbuf;

This logic is backwards, will fix before the next revision.

I'll also rename bbuf->rbmbp, sbuf->sumbp, bblock->rbmoff,
sblock->sumoff to make the names a bit more consistent.

> +	cbp = issum ? &args->bblock : &args->sblock;

And I'll change cbp to coffp because it's a file offset.

--D

> +	/*
> +	 * If we have a cached buffer, and the block number matches, use that.
> +	 */
> +	if (*cbpp && *cbp == 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->trans, *cbpp);
> +		*cbpp = NULL;
> +	}
> +
>  	ip = issum ? mp->m_rsumip : mp->m_rbmip;
>  
>  	error = xfs_bmapi_read(ip, block, 1, &map, &nmap, 0);
> @@ -83,7 +117,8 @@ xfs_rtbuf_get(
>  
>  	xfs_trans_buf_set_type(args->trans, bp, issum ? XFS_BLFT_RTSUMMARY_BUF
>  					     : XFS_BLFT_RTBITMAP_BUF);
> -	*bpp = bp;
> +	*cbpp = *bpp = bp;
> +	*cbp = block;
>  	return 0;
>  }
>  
> @@ -174,7 +209,6 @@ xfs_rtfind_back(
>  			/*
>  			 * Different.  Mark where we are and return.
>  			 */
> -			xfs_trans_brelse(args->trans, bp);
>  			i = bit - XFS_RTHIBIT(wdiff);
>  			*rtx = start - i + 1;
>  			return 0;
> @@ -188,7 +222,6 @@ xfs_rtfind_back(
>  			/*
>  			 * If done with this block, get the previous one.
>  			 */
> -			xfs_trans_brelse(args->trans, bp);
>  			error = xfs_rtbuf_get(args, --block, 0, &bp);
>  			if (error) {
>  				return error;
> @@ -221,7 +254,6 @@ xfs_rtfind_back(
>  			/*
>  			 * Different, mark where we are and return.
>  			 */
> -			xfs_trans_brelse(args->trans, bp);
>  			i += XFS_NBWORD - 1 - XFS_RTHIBIT(wdiff);
>  			*rtx = start - i + 1;
>  			return 0;
> @@ -235,7 +267,6 @@ xfs_rtfind_back(
>  			/*
>  			 * If done with this block, get the previous one.
>  			 */
> -			xfs_trans_brelse(args->trans, bp);
>  			error = xfs_rtbuf_get(args, --block, 0, &bp);
>  			if (error) {
>  				return error;
> @@ -269,7 +300,6 @@ xfs_rtfind_back(
>  			/*
>  			 * Different, mark where we are and return.
>  			 */
> -			xfs_trans_brelse(args->trans, bp);
>  			i += XFS_NBWORD - 1 - XFS_RTHIBIT(wdiff);
>  			*rtx = start - i + 1;
>  			return 0;
> @@ -279,7 +309,6 @@ xfs_rtfind_back(
>  	/*
>  	 * No match, return that we scanned the whole area.
>  	 */
> -	xfs_trans_brelse(args->trans, bp);
>  	*rtx = start - i + 1;
>  	return 0;
>  }
> @@ -351,7 +380,6 @@ xfs_rtfind_forw(
>  			/*
>  			 * Different.  Mark where we are and return.
>  			 */
> -			xfs_trans_brelse(args->trans, bp);
>  			i = XFS_RTLOBIT(wdiff) - bit;
>  			*rtx = start + i - 1;
>  			return 0;
> @@ -365,7 +393,6 @@ xfs_rtfind_forw(
>  			/*
>  			 * If done with this block, get the previous one.
>  			 */
> -			xfs_trans_brelse(args->trans, bp);
>  			error = xfs_rtbuf_get(args, ++block, 0, &bp);
>  			if (error) {
>  				return error;
> @@ -398,7 +425,6 @@ xfs_rtfind_forw(
>  			/*
>  			 * Different, mark where we are and return.
>  			 */
> -			xfs_trans_brelse(args->trans, bp);
>  			i += XFS_RTLOBIT(wdiff);
>  			*rtx = start + i - 1;
>  			return 0;
> @@ -412,7 +438,6 @@ xfs_rtfind_forw(
>  			/*
>  			 * If done with this block, get the next one.
>  			 */
> -			xfs_trans_brelse(args->trans, bp);
>  			error = xfs_rtbuf_get(args, ++block, 0, &bp);
>  			if (error) {
>  				return error;
> @@ -444,7 +469,6 @@ xfs_rtfind_forw(
>  			/*
>  			 * Different, mark where we are and return.
>  			 */
> -			xfs_trans_brelse(args->trans, bp);
>  			i += XFS_RTLOBIT(wdiff);
>  			*rtx = start + i - 1;
>  			return 0;
> @@ -454,7 +478,6 @@ xfs_rtfind_forw(
>  	/*
>  	 * No match, return that we scanned the whole area.
>  	 */
> -	xfs_trans_brelse(args->trans, bp);
>  	*rtx = start + i - 1;
>  	return 0;
>  }
> @@ -491,8 +514,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->mount;
> @@ -511,30 +532,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->trans, *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.
>  	 */
> @@ -564,11 +566,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);
>  }
>  
>  /*
> @@ -742,9 +742,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->mount;
>  	xfs_rtxnum_t		end;		/* end of the freed extent */
> @@ -773,7 +771,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;
>  	/*
> @@ -782,8 +780,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;
>  		}
> @@ -794,8 +792,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;
>  		}
> @@ -804,10 +802,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);
>  }
>  
>  /*
> @@ -879,7 +876,6 @@ xfs_rtcheck_range(
>  			/*
>  			 * Different, compute first wrong bit and return.
>  			 */
> -			xfs_trans_brelse(args->trans, bp);
>  			i = XFS_RTLOBIT(wdiff) - bit;
>  			*new = start + i;
>  			*stat = 0;
> @@ -894,7 +890,6 @@ xfs_rtcheck_range(
>  			/*
>  			 * If done with this block, get the next one.
>  			 */
> -			xfs_trans_brelse(args->trans, bp);
>  			error = xfs_rtbuf_get(args, ++block, 0, &bp);
>  			if (error) {
>  				return error;
> @@ -927,7 +922,6 @@ xfs_rtcheck_range(
>  			/*
>  			 * Different, compute first wrong bit and return.
>  			 */
> -			xfs_trans_brelse(args->trans, bp);
>  			i += XFS_RTLOBIT(wdiff);
>  			*new = start + i;
>  			*stat = 0;
> @@ -942,7 +936,6 @@ xfs_rtcheck_range(
>  			/*
>  			 * If done with this block, get the next one.
>  			 */
> -			xfs_trans_brelse(args->trans, bp);
>  			error = xfs_rtbuf_get(args, ++block, 0, &bp);
>  			if (error) {
>  				return error;
> @@ -974,7 +967,6 @@ xfs_rtcheck_range(
>  			/*
>  			 * Different, compute first wrong bit and return.
>  			 */
> -			xfs_trans_brelse(args->trans, bp);
>  			i += XFS_RTLOBIT(wdiff);
>  			*new = start + i;
>  			*stat = 0;
> @@ -985,7 +977,6 @@ xfs_rtcheck_range(
>  	/*
>  	 * Successful, return.
>  	 */
> -	xfs_trans_brelse(args->trans, bp);
>  	*new = start + i;
>  	*stat = 1;
>  	return 0;
> @@ -1030,8 +1021,6 @@ xfs_rtfree_extent(
>  		.trans		= tp,
>  	};
>  	int			error;		/* error value */
> -	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));
> @@ -1043,10 +1032,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.
>  	 */
> @@ -1062,7 +1051,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;
>  }
>  
>  /*
> @@ -1153,6 +1145,7 @@ xfs_rtalloc_query_range(
>  		rtstart = rtend + 1;
>  	}
>  
> +	xfs_rtbuf_cache_relse(&args);
>  	return error;
>  }
>  
> @@ -1191,6 +1184,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 39da0adf0f45..720856192818 100644
> --- a/fs/xfs/libxfs/xfs_rtbitmap.h
> +++ b/fs/xfs/libxfs/xfs_rtbitmap.h
> @@ -237,8 +237,16 @@ typedef int (*xfs_rtalloc_query_range_fn)(
>  struct xfs_rtalloc_args {
>  	struct xfs_mount	*mount;
>  	struct xfs_trans	*trans;
> +
> +	struct xfs_buf *bbuf;	/* bitmap block buffer */
> +	struct xfs_buf *sbuf;	/* summary block buffer */
> +
> +	xfs_fileoff_t bblock;	/* bitmap block number */
> +	xfs_fileoff_t sblock;	/* summary block number */
>  };
>  
> +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,
> @@ -250,13 +258,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,
> @@ -304,6 +310,7 @@ void xfs_suminfo_add(struct xfs_mount *mp, union xfs_suminfo_raw *infoptr,
>  # 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 3f6f6efe7375..e711e68ff996 100644
> --- a/fs/xfs/scrub/rtsummary.c
> +++ b/fs/xfs/scrub/rtsummary.c
> @@ -217,7 +217,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;
>  		}
>  
> @@ -225,7 +225,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 922d2fdcf953..f481efcf8445 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->mount;
> @@ -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;		/* error return value */
>  	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->mount->m_rsumlevels - 1; log >= 0; log--) {
>  		for (bbno = oargs->mount->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				/* error */
>  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->mount;
>  	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);
> @@ -1213,8 +1194,6 @@ xfs_rtallocate_extent(
>  	};
>  	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.mount->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;
>  
> 

^ permalink raw reply	[flat|nested] 91+ messages in thread

* Re: [PATCH 2/7] xfs: cache last bitmap block in realtime allocator
  2023-10-18 16:33       ` Darrick J. Wong
@ 2023-10-19  0:00         ` Darrick J. Wong
  0 siblings, 0 replies; 91+ messages in thread
From: Darrick J. Wong @ 2023-10-19  0:00 UTC (permalink / raw)
  To: Christoph Hellwig; +Cc: Omar Sandoval, osandov, linux-xfs

On Wed, Oct 18, 2023 at 09:33:15AM -0700, Darrick J. Wong wrote:
> On Wed, Oct 18, 2023 at 08:19:11AM +0200, Christoph Hellwig wrote:
> > On Tue, Oct 17, 2023 at 08:54:23AM -0700, Darrick J. Wong wrote:
> > >   * The buffer is returned read and locked.
> > > @@ -59,12 +73,32 @@ xfs_rtbuf_get(
> > >  	struct xfs_buf		**bpp)		/* output: buffer for the block */
> > >  {
> > >  	struct xfs_mount	*mp = args->mount;
> > > +	struct xfs_buf		**cbpp;		/* cached block buffer */
> > > +	xfs_fsblock_t		*cbp;		/* cached block number */
> > >  	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;		/* error value */
> > >  
> > > +	cbpp = issum ? &args->bbuf : &args->sbuf;
> > > +	cbp = issum ? &args->bblock : &args->sblock;
> > 
> > Now that we have the summary/bitmap buffers in the args structure,
> > it seems like we can also drop the bp argument from xfs_rtbuf_get and
> > just the pointer in the args structue in the callers.
> 
> Yeah, I was wondering about that too -- either we take a second refcount
> on @bp and pass it out via **bpp, or callers can pluck it from @args
> directly and call _cache_relse before @args goes out of scope.
> 
> I'll remove **bpp since it's redundant.

Ok, I'm about to send out a v2.2 of Omar's patches with whitespace
cleanups for Dave's suggestionpatch:

 xfs: consolidate realtime allocation arguments

I also added a couple new patches to do the cleanups we talked about
here:

 xfs: simplify xfs_rtbuf_get calling conventions
 xfs: simplify rt bitmap/summary block accessor functions

--D

> --D

^ permalink raw reply	[flat|nested] 91+ messages in thread

* [PATCHSET v2.2 0/9] xfs: CPU usage optimizations for realtime allocator
  2023-10-17 15:46 ` [PATCHSET RFC 2.1 0/7] xfs: CPU usage optimizations for realtime allocator Darrick J. Wong
                     ` (6 preceding siblings ...)
  2023-10-17 15:55   ` [PATCH 7/7] xfs: don't look for end of extent further than necessary " Darrick J. Wong
@ 2023-10-19  0:00   ` Darrick J. Wong
  2023-10-19  0:00     ` [PATCH 1/9] xfs: consolidate realtime allocation arguments Darrick J. Wong
                       ` (8 more replies)
  7 siblings, 9 replies; 91+ messages in thread
From: Darrick J. Wong @ 2023-10-19  0:00 UTC (permalink / raw)
  To: djwong
  Cc: Omar Sandoval, Christoph Hellwig, Dave Chinner, osandov,
	linux-xfs, osandov, hch

Hi all,

This is [Omar']s version 2 of his XFS realtime allocator opimization patch
series.

Changes since v1 [1]:

- Fixed potential overflow in patch 4.
- Changed deprecated typedefs to normal struct names
- Fixed broken indentation
- Used xfs_fileoff_t instead of xfs_fsblock_t where appropriate.
- Added calls to xfs_rtbuf_cache_relse anywhere that the cache is used
  instead of relying on the buffers being dirtied and thus attached to
  the transaction.
- Clarified comments and commit messages in a few places.
- Added Darrick's Reviewed-bys.

Cover letter from v1:

Our distributed storage system uses XFS's realtime device support as a
way to split an XFS filesystem between an SSD and an HDD -- we configure
the HDD as the realtime device so that metadata goes on the SSD and data
goes on the HDD.

We've been running this in production for a few years now, so we have
some fairly fragmented filesystems. This has exposed various CPU
inefficiencies in the realtime allocator. These became even worse when
we experimented with using XFS_XFLAG_EXTSIZE to force files to be
allocated contiguously.

This series adds several optimizations that don't change the realtime
allocator's decisions, but make them happen more efficiently, mainly by
avoiding redundant work. We've tested these in production and measured
~10% lower CPU utilization. Furthermore, it made it possible to use
XFS_XFLAG_EXTSIZE to force contiguous allocations -- without these
patches, our most fragmented systems would become unresponsive due to
high CPU usage in the realtime allocator, but with them, CPU utilization
is actually ~4-6% lower than before, and disk I/O utilization is 15-20%
lower.

Patches 2 and 3 are preparations for later optimizations; the remaining
patches are the optimizations themselves.

1: https://lore.kernel.org/linux-xfs/cover.1687296675.git.osandov@osandov.com/

v2.1: djwong rebased everything atop his own cleanups, added dave's rtalloc_args
v2.2: rebase with new apis and clean them up too

If you're going to start using this code, I strongly recommend pulling
from my git trees, which are linked below.

With a bit of luck, this should all go splendidly.
Comments and questions are, as always, welcome.

--D

kernel git tree:
https://git.kernel.org/cgit/linux/kernel/git/djwong/xfs-linux.git/log/?h=rtalloc-speedups-6.7
---
 fs/xfs/libxfs/xfs_rtbitmap.c |  525 +++++++++++++++++++++---------------------
 fs/xfs/libxfs/xfs_rtbitmap.h |   97 +++++---
 fs/xfs/scrub/rtsummary.c     |   13 +
 fs/xfs/xfs_mount.h           |    6 
 fs/xfs/xfs_rtalloc.c         |  471 ++++++++++++++++++--------------------
 5 files changed, 554 insertions(+), 558 deletions(-)


^ permalink raw reply	[flat|nested] 91+ messages in thread

* [PATCH 1/9] xfs: consolidate realtime allocation arguments
  2023-10-19  0:00   ` [PATCHSET v2.2 0/9] xfs: CPU usage optimizations for realtime allocator Darrick J. Wong
@ 2023-10-19  0:00     ` Darrick J. Wong
  2023-10-19  5:08       ` Christoph Hellwig
  2023-10-19  0:01     ` [PATCH 2/9] xfs: cache last bitmap block in realtime allocator Darrick J. Wong
                       ` (7 subsequent siblings)
  8 siblings, 1 reply; 91+ messages in thread
From: Darrick J. Wong @ 2023-10-19  0:00 UTC (permalink / raw)
  To: djwong; +Cc: Dave Chinner, osandov, linux-xfs, osandov, hch

From: Dave Chinner <dchinner@redhat.com>

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 <dchinner@redhat.com>
Reviewed-by: Darrick J. Wong <djwong@kernel.org>
Signed-off-by: Darrick J. Wong <djwong@kernel.org>
---
 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(-)


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..c46f9235315f 100644
--- a/fs/xfs/libxfs/xfs_rtbitmap.h
+++ b/fs/xfs/libxfs/xfs_rtbitmap.h
@@ -281,29 +281,29 @@ 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);
+struct xfs_rtalloc_args {
+	struct xfs_mount	*mp;
+	struct xfs_trans	*tp;
+};
+
+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 @@ xfs_rtany_summary(
  * 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 @@ xfs_growfs_rt(
  * 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)


^ permalink raw reply related	[flat|nested] 91+ messages in thread

* [PATCH 2/9] xfs: cache last bitmap block in realtime allocator
  2023-10-19  0:00   ` [PATCHSET v2.2 0/9] xfs: CPU usage optimizations for realtime allocator Darrick J. Wong
  2023-10-19  0:00     ` [PATCH 1/9] xfs: consolidate realtime allocation arguments Darrick J. Wong
@ 2023-10-19  0:01     ` Darrick J. Wong
  2023-10-19  0:01     ` [PATCH 3/9] xfs: simplify xfs_rtbuf_get calling conventions Darrick J. Wong
                       ` (6 subsequent siblings)
  8 siblings, 0 replies; 91+ messages in thread
From: Darrick J. Wong @ 2023-10-19  0:01 UTC (permalink / raw)
  To: djwong; +Cc: Omar Sandoval, Christoph Hellwig, osandov, linux-xfs, osandov, hch

From: Omar Sandoval <osandov@fb.com>

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 <osandov@fb.com>
Reviewed-by: Darrick J. Wong <djwong@kernel.org>
Signed-off-by: Darrick J. Wong <djwong@kernel.org>
Reviewed-by: Christoph Hellwig <hch@lst.de>
---
 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(-)


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 c46f9235315f..7f959f9472c6 100644
--- a/fs/xfs/libxfs/xfs_rtbitmap.h
+++ b/fs/xfs/libxfs/xfs_rtbitmap.h
@@ -284,8 +284,16 @@ typedef int (*xfs_rtalloc_query_range_fn)(
 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 */
 };
 
+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;
 


^ permalink raw reply related	[flat|nested] 91+ messages in thread

* [PATCH 3/9] xfs: simplify xfs_rtbuf_get calling conventions
  2023-10-19  0:00   ` [PATCHSET v2.2 0/9] xfs: CPU usage optimizations for realtime allocator Darrick J. Wong
  2023-10-19  0:00     ` [PATCH 1/9] xfs: consolidate realtime allocation arguments Darrick J. Wong
  2023-10-19  0:01     ` [PATCH 2/9] xfs: cache last bitmap block in realtime allocator Darrick J. Wong
@ 2023-10-19  0:01     ` Darrick J. Wong
  2023-10-19  5:11       ` Christoph Hellwig
  2023-10-19  0:01     ` [PATCH 4/9] xfs: simplify rt bitmap/summary block accessor functions Darrick J. Wong
                       ` (5 subsequent siblings)
  8 siblings, 1 reply; 91+ messages in thread
From: Darrick J. Wong @ 2023-10-19  0:01 UTC (permalink / raw)
  To: djwong; +Cc: osandov, linux-xfs, osandov, hch

From: Darrick J. Wong <djwong@kernel.org>

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 <djwong@kernel.org>
---
 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(-)


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 7f959f9472c6..9516bc333828 100644
--- a/fs/xfs/libxfs/xfs_rtbitmap.h
+++ b/fs/xfs/libxfs/xfs_rtbitmap.h
@@ -295,7 +295,24 @@ struct xfs_rtalloc_args {
 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);


^ permalink raw reply related	[flat|nested] 91+ messages in thread

* [PATCH 4/9] xfs: simplify rt bitmap/summary block accessor functions
  2023-10-19  0:00   ` [PATCHSET v2.2 0/9] xfs: CPU usage optimizations for realtime allocator Darrick J. Wong
                       ` (2 preceding siblings ...)
  2023-10-19  0:01     ` [PATCH 3/9] xfs: simplify xfs_rtbuf_get calling conventions Darrick J. Wong
@ 2023-10-19  0:01     ` Darrick J. Wong
  2023-10-19  5:13       ` Christoph Hellwig
  2023-10-19  0:01     ` [PATCH 5/9] xfs: invert the realtime summary cache Darrick J. Wong
                       ` (4 subsequent siblings)
  8 siblings, 1 reply; 91+ messages in thread
From: Darrick J. Wong @ 2023-10-19  0:01 UTC (permalink / raw)
  To: djwong; +Cc: osandov, linux-xfs, osandov, hch

From: Darrick J. Wong <djwong@kernel.org>

Simplify the calling convention of these functions since the
xfs_rtalloc_args structure contains the parameters we need.

Signed-off-by: Darrick J. Wong <djwong@kernel.org>
---
 fs/xfs/libxfs/xfs_rtbitmap.c |   61 ++++++++++++++++++++----------------------
 fs/xfs/libxfs/xfs_rtbitmap.h |   46 ++++++++++++++++----------------
 fs/xfs/scrub/rtsummary.c     |    2 +
 3 files changed, 53 insertions(+), 56 deletions(-)


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 9516bc333828..c0637057d69c 100644
--- a/fs/xfs/libxfs/xfs_rtbitmap.h
+++ b/fs/xfs/libxfs/xfs_rtbitmap.h
@@ -6,6 +6,17 @@
 #ifndef __XFS_RTBITMAP_H__
 #define	__XFS_RTBITMAP_H__
 
+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
 xfs_rtx_to_rtb(
 	struct xfs_mount	*mp,
@@ -161,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;
 }
@@ -172,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;
 }
@@ -183,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;
 }
@@ -234,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;
 }
@@ -245,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;
 }
@@ -256,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;
@@ -281,17 +292,6 @@ typedef int (*xfs_rtalloc_query_range_fn)(
 	void				*priv);
 
 #ifdef CONFIG_XFS_RT
-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 */
-};
-
 void xfs_rtbuf_cache_relse(struct xfs_rtalloc_args *args);
 
 int xfs_rtbuf_get(struct xfs_rtalloc_args *args, xfs_fileoff_t block,
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);


^ permalink raw reply related	[flat|nested] 91+ messages in thread

* [PATCH 5/9] xfs: invert the realtime summary cache
  2023-10-19  0:00   ` [PATCHSET v2.2 0/9] xfs: CPU usage optimizations for realtime allocator Darrick J. Wong
                       ` (3 preceding siblings ...)
  2023-10-19  0:01     ` [PATCH 4/9] xfs: simplify rt bitmap/summary block accessor functions Darrick J. Wong
@ 2023-10-19  0:01     ` Darrick J. Wong
  2023-10-19  0:01     ` [PATCH 6/9] xfs: return maximum free size from xfs_rtany_summary() Darrick J. Wong
                       ` (3 subsequent siblings)
  8 siblings, 0 replies; 91+ messages in thread
From: Darrick J. Wong @ 2023-10-19  0:01 UTC (permalink / raw)
  To: djwong; +Cc: Omar Sandoval, Christoph Hellwig, osandov, linux-xfs, osandov, hch

From: Omar Sandoval <osandov@fb.com>

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 <osandov@fb.com>
Reviewed-by: Darrick J. Wong <djwong@kernel.org>
Signed-off-by: Darrick J. Wong <djwong@kernel.org>
Reviewed-by: Christoph Hellwig <hch@lst.de>
---
 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(-)


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");
 }
 


^ permalink raw reply related	[flat|nested] 91+ messages in thread

* [PATCH 6/9] xfs: return maximum free size from xfs_rtany_summary()
  2023-10-19  0:00   ` [PATCHSET v2.2 0/9] xfs: CPU usage optimizations for realtime allocator Darrick J. Wong
                       ` (4 preceding siblings ...)
  2023-10-19  0:01     ` [PATCH 5/9] xfs: invert the realtime summary cache Darrick J. Wong
@ 2023-10-19  0:01     ` Darrick J. Wong
  2023-10-19  0:01     ` [PATCH 7/9] xfs: limit maxlen based on available space in xfs_rtallocate_extent_near() Darrick J. Wong
                       ` (2 subsequent siblings)
  8 siblings, 0 replies; 91+ messages in thread
From: Darrick J. Wong @ 2023-10-19  0:01 UTC (permalink / raw)
  To: djwong; +Cc: Omar Sandoval, Christoph Hellwig, osandov, linux-xfs, osandov, hch

From: Omar Sandoval <osandov@fb.com>

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 <djwong@kernel.org>
Signed-off-by: Omar Sandoval <osandov@fb.com>
Signed-off-by: Darrick J. Wong <djwong@kernel.org>
Reviewed-by: Christoph Hellwig <hch@lst.de>
---
 fs/xfs/xfs_rtalloc.c |   18 +++++++++---------
 1 file changed, 9 insertions(+), 9 deletions(-)


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,


^ permalink raw reply related	[flat|nested] 91+ messages in thread

* [PATCH 7/9] xfs: limit maxlen based on available space in xfs_rtallocate_extent_near()
  2023-10-19  0:00   ` [PATCHSET v2.2 0/9] xfs: CPU usage optimizations for realtime allocator Darrick J. Wong
                       ` (5 preceding siblings ...)
  2023-10-19  0:01     ` [PATCH 6/9] xfs: return maximum free size from xfs_rtany_summary() Darrick J. Wong
@ 2023-10-19  0:01     ` Darrick J. Wong
  2023-10-19  0:01     ` [PATCH 8/9] xfs: don't try redundant allocations " Darrick J. Wong
  2023-10-19  0:01     ` [PATCH 9/9] xfs: don't look for end of extent further than necessary " Darrick J. Wong
  8 siblings, 0 replies; 91+ messages in thread
From: Darrick J. Wong @ 2023-10-19  0:01 UTC (permalink / raw)
  To: djwong; +Cc: Omar Sandoval, Christoph Hellwig, osandov, linux-xfs, osandov, hch

From: Omar Sandoval <osandov@fb.com>

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 <osandov@fb.com>
Reviewed-by: Darrick J. Wong <djwong@kernel.org>
Signed-off-by: Darrick J. Wong <djwong@kernel.org>
Reviewed-by: Christoph Hellwig <hch@lst.de>
---
 fs/xfs/xfs_rtalloc.c |    9 ++++++---
 1 file changed, 6 insertions(+), 3 deletions(-)


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;


^ permalink raw reply related	[flat|nested] 91+ messages in thread

* [PATCH 8/9] xfs: don't try redundant allocations in xfs_rtallocate_extent_near()
  2023-10-19  0:00   ` [PATCHSET v2.2 0/9] xfs: CPU usage optimizations for realtime allocator Darrick J. Wong
                       ` (6 preceding siblings ...)
  2023-10-19  0:01     ` [PATCH 7/9] xfs: limit maxlen based on available space in xfs_rtallocate_extent_near() Darrick J. Wong
@ 2023-10-19  0:01     ` Darrick J. Wong
  2023-10-19  0:01     ` [PATCH 9/9] xfs: don't look for end of extent further than necessary " Darrick J. Wong
  8 siblings, 0 replies; 91+ messages in thread
From: Darrick J. Wong @ 2023-10-19  0:01 UTC (permalink / raw)
  To: djwong; +Cc: Omar Sandoval, Christoph Hellwig, osandov, linux-xfs, osandov, hch

From: Omar Sandoval <osandov@fb.com>

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 <osandov@fb.com>
Reviewed-by: Darrick J. Wong <djwong@kernel.org>
Signed-off-by: Darrick J. Wong <djwong@kernel.org>
Reviewed-by: Christoph Hellwig <hch@lst.de>
---
 fs/xfs/xfs_rtalloc.c |   54 ++++++--------------------------------------------
 1 file changed, 7 insertions(+), 47 deletions(-)


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;
-				}
 			}
 		}
 		/*


^ permalink raw reply related	[flat|nested] 91+ messages in thread

* [PATCH 9/9] xfs: don't look for end of extent further than necessary in xfs_rtallocate_extent_near()
  2023-10-19  0:00   ` [PATCHSET v2.2 0/9] xfs: CPU usage optimizations for realtime allocator Darrick J. Wong
                       ` (7 preceding siblings ...)
  2023-10-19  0:01     ` [PATCH 8/9] xfs: don't try redundant allocations " Darrick J. Wong
@ 2023-10-19  0:01     ` Darrick J. Wong
  8 siblings, 0 replies; 91+ messages in thread
From: Darrick J. Wong @ 2023-10-19  0:01 UTC (permalink / raw)
  To: djwong; +Cc: Omar Sandoval, Christoph Hellwig, osandov, linux-xfs, osandov, hch

From: Omar Sandoval <osandov@fb.com>

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 <djwong@kernel.org>
Signed-off-by: Omar Sandoval <osandov@fb.com>
Signed-off-by: Darrick J. Wong <djwong@kernel.org>
Reviewed-by: Christoph Hellwig <hch@lst.de>
---
 fs/xfs/xfs_rtalloc.c |   27 ++++++++++++++++++++++-----
 1 file changed, 22 insertions(+), 5 deletions(-)


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 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.
+				 * 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);
+
+				/*
+				 * 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,


^ permalink raw reply related	[flat|nested] 91+ messages in thread

* Re: [PATCH 1/9] xfs: consolidate realtime allocation arguments
  2023-10-19  0:00     ` [PATCH 1/9] xfs: consolidate realtime allocation arguments Darrick J. Wong
@ 2023-10-19  5:08       ` Christoph Hellwig
  0 siblings, 0 replies; 91+ messages in thread
From: Christoph Hellwig @ 2023-10-19  5:08 UTC (permalink / raw)
  To: Darrick J. Wong; +Cc: Dave Chinner, osandov, linux-xfs, osandov, hch

Looks good:

Reviewed-by: Christoph Hellwig <hch@lst.de>

^ permalink raw reply	[flat|nested] 91+ messages in thread

* Re: [PATCH 3/9] xfs: simplify xfs_rtbuf_get calling conventions
  2023-10-19  0:01     ` [PATCH 3/9] xfs: simplify xfs_rtbuf_get calling conventions Darrick J. Wong
@ 2023-10-19  5:11       ` Christoph Hellwig
  0 siblings, 0 replies; 91+ messages in thread
From: Christoph Hellwig @ 2023-10-19  5:11 UTC (permalink / raw)
  To: Darrick J. Wong; +Cc: osandov, linux-xfs, osandov, hch

Looks good:

Reviewed-by: Christoph Hellwig <hch@lst.de>

^ permalink raw reply	[flat|nested] 91+ messages in thread

* Re: [PATCH 4/9] xfs: simplify rt bitmap/summary block accessor functions
  2023-10-19  0:01     ` [PATCH 4/9] xfs: simplify rt bitmap/summary block accessor functions Darrick J. Wong
@ 2023-10-19  5:13       ` Christoph Hellwig
  2023-10-19 16:13         ` Darrick J. Wong
  0 siblings, 1 reply; 91+ messages in thread
From: Christoph Hellwig @ 2023-10-19  5:13 UTC (permalink / raw)
  To: Darrick J. Wong; +Cc: osandov, linux-xfs, osandov, hch

If you for some reason need to respin the series again it would be nice
to just add the strut xfs_rtalloc_args definition at the top of the header
from the beginning.

Otherwise looks good:

Reviewed-by: Christoph Hellwig <hch@lst.de>

^ permalink raw reply	[flat|nested] 91+ messages in thread

* Re: [PATCH 4/9] xfs: simplify rt bitmap/summary block accessor functions
  2023-10-19  5:13       ` Christoph Hellwig
@ 2023-10-19 16:13         ` Darrick J. Wong
  0 siblings, 0 replies; 91+ messages in thread
From: Darrick J. Wong @ 2023-10-19 16:13 UTC (permalink / raw)
  To: Christoph Hellwig; +Cc: osandov, linux-xfs, osandov

On Thu, Oct 19, 2023 at 07:13:16AM +0200, Christoph Hellwig wrote:
> If you for some reason need to respin the series again it would be nice
> to just add the strut xfs_rtalloc_args definition at the top of the header
> from the beginning.

Will do!

Thank you for reviewing all my cleanups and Omar's rtalloc fixes.  I
very much enjoyed the quick feedback, which made iterating the patchset
so much easier.

Looking forward to the next time we get to do this,

--D

> Otherwise looks good:
> 
> Reviewed-by: Christoph Hellwig <hch@lst.de>

^ permalink raw reply	[flat|nested] 91+ messages in thread

* [PATCH 4/7] xfs: create helpers to convert rt block numbers to rt extent numbers
  2023-10-19 16:20 [PATCHSET v1.1 0/7] xfs: refactor rt extent unit conversions Darrick J. Wong
@ 2023-10-19 16:25 ` Darrick J. Wong
  0 siblings, 0 replies; 91+ messages in thread
From: Darrick J. Wong @ 2023-10-19 16:25 UTC (permalink / raw)
  To: djwong; +Cc: Christoph Hellwig, linux-xfs, osandov, hch

From: Darrick J. Wong <djwong@kernel.org>

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 <djwong@kernel.org>
Reviewed-by: Christoph Hellwig <hch@lst.de>
---
 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(-)


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.
  */


^ permalink raw reply related	[flat|nested] 91+ messages in thread

* Re: [PATCH 4/7] xfs: create helpers to convert rt block numbers to rt extent numbers
  2023-10-12 17:58     ` Darrick J. Wong
@ 2023-10-13  4:25       ` Christoph Hellwig
  0 siblings, 0 replies; 91+ messages in thread
From: Christoph Hellwig @ 2023-10-13  4:25 UTC (permalink / raw)
  To: Darrick J. Wong; +Cc: Christoph Hellwig, linux-xfs, osandov

On Thu, Oct 12, 2023 at 10:58:33AM -0700, Darrick J. Wong wrote:
> <nod> I've decided to go with:

This looks good to me, thanks.


^ permalink raw reply	[flat|nested] 91+ messages in thread

* Re: [PATCH 4/7] xfs: create helpers to convert rt block numbers to rt extent numbers
  2023-10-12  5:17   ` Christoph Hellwig
@ 2023-10-12 17:58     ` Darrick J. Wong
  2023-10-13  4:25       ` Christoph Hellwig
  0 siblings, 1 reply; 91+ messages in thread
From: Darrick J. Wong @ 2023-10-12 17:58 UTC (permalink / raw)
  To: Christoph Hellwig; +Cc: linux-xfs, osandov

On Thu, Oct 12, 2023 at 07:17:13AM +0200, Christoph Hellwig wrote:
> On Wed, Oct 11, 2023 at 11:05:27AM -0700, Darrick J. Wong wrote:
> > From: Darrick J. Wong <djwong@kernel.org>
> > 
> > Create helpers to do unit conversions of rt block numbers to rt extent
> > numbers.  There are two variations -- the suffix "t" denotes the one
> > that returns only the truncated extent number; the other one also
> > returns the misalignment.  Convert all the div_u64_rem users; we'll do
> > the do_div users in the next patch.
> 
> When trying to work with thee helpers I found the t prefix here a bit
> weird, as it works different than the T in say XFS_B_TO_FSB
> vs XFS_B_TO_FSBT which give you different results for the two versions.
> Here we get the same returned result, just with the additional
> return for the remainder.
> 
> Maybe have xfs_rtb_to_rtx and xfs_rtb_to_rtx_rem for the version with
> the modulo?

<nod> I've decided to go with:

/* 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);
}

> We also have quite a few places that only care about the mod,
> so an additƣonal xfs_rtb_rem/mod might be useful as well.

Agreed, I had noticed that there were a fair number of places where
we're really only checking for rtx alignment.  xfs_rtb_to_rtxoff is
the new helper.

--D

^ permalink raw reply	[flat|nested] 91+ messages in thread

* Re: [PATCH 4/7] xfs: create helpers to convert rt block numbers to rt extent numbers
  2023-10-11 18:05 ` [PATCH 4/7] xfs: create helpers to convert rt block numbers to rt extent numbers Darrick J. Wong
@ 2023-10-12  5:17   ` Christoph Hellwig
  2023-10-12 17:58     ` Darrick J. Wong
  0 siblings, 1 reply; 91+ messages in thread
From: Christoph Hellwig @ 2023-10-12  5:17 UTC (permalink / raw)
  To: Darrick J. Wong; +Cc: linux-xfs, osandov, hch

On Wed, Oct 11, 2023 at 11:05:27AM -0700, Darrick J. Wong wrote:
> From: Darrick J. Wong <djwong@kernel.org>
> 
> Create helpers to do unit conversions of rt block numbers to rt extent
> numbers.  There are two variations -- the suffix "t" denotes the one
> that returns only the truncated extent number; the other one also
> returns the misalignment.  Convert all the div_u64_rem users; we'll do
> the do_div users in the next patch.

When trying to work with thee helpers I found the t prefix here a bit
weird, as it works different than the T in say XFS_B_TO_FSB
vs XFS_B_TO_FSBT which give you different results for the two versions.
Here we get the same returned result, just with the additional
return for the remainder.

Maybe have xfs_rtb_to_rtx and xfs_rtb_to_rtx_rem for the version with
the modulo?

We also have quite a few places that only care about the mod,
so an additƣonal xfs_rtb_rem/mod might be useful as well.


^ permalink raw reply	[flat|nested] 91+ messages in thread

* [PATCH 4/7] xfs: create helpers to convert rt block numbers to rt extent numbers
  2023-10-11 18:01 [PATCHSET RFC v1.0 0/7] xfs: refactor rt extent unit conversions Darrick J. Wong
@ 2023-10-11 18:05 ` Darrick J. Wong
  2023-10-12  5:17   ` Christoph Hellwig
  0 siblings, 1 reply; 91+ messages in thread
From: Darrick J. Wong @ 2023-10-11 18:05 UTC (permalink / raw)
  To: djwong; +Cc: linux-xfs, osandov, hch

From: Darrick J. Wong <djwong@kernel.org>

Create helpers to do unit conversions of rt block numbers to rt extent
numbers.  There are two variations -- the suffix "t" denotes the one
that returns only the truncated extent number; the other one also
returns the misalignment.  Convert all the div_u64_rem users; we'll do
the do_div users in the next patch.

Signed-off-by: Darrick J. Wong <djwong@kernel.org>
---
 fs/xfs/libxfs/xfs_bmap.c     |    7 +++----
 fs/xfs/libxfs/xfs_rtbitmap.c |    4 ++--
 fs/xfs/libxfs/xfs_rtbitmap.h |   17 +++++++++++++++++
 fs/xfs/libxfs/xfs_swapext.c  |    7 ++++---
 fs/xfs/xfs_rtalloc.c         |    8 ++++----
 5 files changed, 30 insertions(+), 13 deletions(-)


diff --git a/fs/xfs/libxfs/xfs_bmap.c b/fs/xfs/libxfs/xfs_bmap.c
index 82dc95944374e..463174af94333 100644
--- a/fs/xfs/libxfs/xfs_bmap.c
+++ b/fs/xfs/libxfs/xfs_bmap.c
@@ -5336,7 +5336,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;
@@ -5433,8 +5432,7 @@ __xfs_bunmapi(
 		if (!isrt || (flags & XFS_BMAPI_REMAP))
 			goto delete;
 
-		sum = del.br_startblock + del.br_blockcount;
-		div_u64_rem(sum, mp->m_sb.sb_rextsize, &mod);
+		xfs_rtb_to_rtx(mp, del.br_startblock + del.br_blockcount, &mod);
 		if (mod) {
 			/*
 			 * Realtime extent not lined up at the end.
@@ -5481,7 +5479,8 @@ __xfs_bunmapi(
 				goto error0;
 			goto nodelete;
 		}
-		div_u64_rem(del.br_startblock, mp->m_sb.sb_rextsize, &mod);
+
+		xfs_rtb_to_rtx(mp, del.br_startblock, &mod);
 		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 ce14436811319..de54386cf52f3 100644
--- a/fs/xfs/libxfs/xfs_rtbitmap.c
+++ b/fs/xfs/libxfs/xfs_rtbitmap.c
@@ -1031,13 +1031,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_rtx(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_rtx(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 e2a36fc157c4c..bdd4858a794c2 100644
--- a/fs/xfs/libxfs/xfs_rtbitmap.h
+++ b/fs/xfs/libxfs/xfs_rtbitmap.h
@@ -39,6 +39,23 @@ xfs_extlen_to_rtxlen(
 	return len / mp->m_sb.sb_rextsize;
 }
 
+static inline xfs_rtxnum_t
+xfs_rtb_to_rtx(
+	struct xfs_mount	*mp,
+	xfs_rtblock_t		rtbno,
+	xfs_extlen_t		*mod)
+{
+	return div_u64_rem(rtbno, mp->m_sb.sb_rextsize, mod);
+}
+
+static inline xfs_rtxnum_t
+xfs_rtb_to_rtxt(
+	struct xfs_mount	*mp,
+	xfs_rtblock_t		rtbno)
+{
+	return div_u64(rtbno, mp->m_sb.sb_rextsize);
+}
+
 /*
  * Functions for walking free space rtextents in the realtime bitmap.
  */
diff --git a/fs/xfs/libxfs/xfs_swapext.c b/fs/xfs/libxfs/xfs_swapext.c
index b1d66e0cfac91..6107ec7d8d568 100644
--- a/fs/xfs/libxfs/xfs_swapext.c
+++ b/fs/xfs/libxfs/xfs_swapext.c
@@ -30,6 +30,7 @@
 #include "xfs_dir2_priv.h"
 #include "xfs_dir2.h"
 #include "xfs_symlink_remote.h"
+#include "xfs_rtbitmap.h"
 
 struct kmem_cache	*xfs_swapext_intent_cache;
 
@@ -202,19 +203,19 @@ xfs_swapext_check_rt_extents(
 					  irec2.br_blockcount);
 
 		/* Both mappings must be aligned to the realtime extent size. */
-		div_u64_rem(irec1.br_startoff, mp->m_sb.sb_rextsize, &mod);
+		xfs_rtb_to_rtx(mp, irec1.br_startoff, &mod);
 		if (mod) {
 			ASSERT(mod == 0);
 			return -EINVAL;
 		}
 
-		div_u64_rem(irec2.br_startoff, mp->m_sb.sb_rextsize, &mod);
+		xfs_rtb_to_rtx(mp, irec1.br_startoff, &mod);
 		if (mod) {
 			ASSERT(mod == 0);
 			return -EINVAL;
 		}
 
-		div_u64_rem(irec1.br_blockcount, mp->m_sb.sb_rextsize, &mod);
+		xfs_rtb_to_rtx(mp, irec1.br_blockcount, &mod);
 		if (mod) {
 			ASSERT(mod == 0);
 			return -EINVAL;
diff --git a/fs/xfs/xfs_rtalloc.c b/fs/xfs/xfs_rtalloc.c
index 4bb776911a4fb..d3a5112f21156 100644
--- a/fs/xfs/xfs_rtalloc.c
+++ b/fs/xfs/xfs_rtalloc.c
@@ -1496,16 +1496,16 @@ xfs_rtfile_want_conversion(
 	struct xfs_bmbt_irec	*irec)
 {
 	xfs_fileoff_t		rext_next;
-	uint32_t		modoff, modcnt;
+	xfs_extlen_t		modoff, modcnt;
 
 	if (irec->br_state != XFS_EXT_UNWRITTEN)
 		return false;
 
-	div_u64_rem(irec->br_startoff, mp->m_sb.sb_rextsize, &modoff);
+	xfs_rtb_to_rtx(mp, irec->br_startoff, &modoff);
 	if (modoff == 0) {
-		uint64_t	rexts = div_u64_rem(irec->br_blockcount,
-						mp->m_sb.sb_rextsize, &modcnt);
+		xfs_rtbxlen_t	rexts;
 
+		rexts = xfs_rtb_to_rtx(mp, irec->br_blockcount, &modcnt);
 		if (rexts > 0) {
 			/*
 			 * Unwritten mapping starts at an rt extent boundary


^ permalink raw reply related	[flat|nested] 91+ messages in thread

* [PATCH 4/7] xfs: create helpers to convert rt block numbers to rt extent numbers
  2022-12-30 22:17 [PATCHSET v1.0 0/7] xfs: refactor rt extent unit conversions Darrick J. Wong
@ 2022-12-30 22:17 ` Darrick J. Wong
  0 siblings, 0 replies; 91+ messages in thread
From: Darrick J. Wong @ 2022-12-30 22:17 UTC (permalink / raw)
  To: djwong; +Cc: linux-xfs

From: Darrick J. Wong <djwong@kernel.org>

Create helpers to do unit conversions of rt block numbers to rt extent
numbers.  There are two variations -- the suffix "t" denotes the one
that returns only the truncated extent number; the other one also
returns the misalignment.

Signed-off-by: Darrick J. Wong <djwong@kernel.org>
---
 fs/xfs/libxfs/xfs_bmap.c     |    7 +++----
 fs/xfs/libxfs/xfs_rtbitmap.c |    4 ++--
 fs/xfs/libxfs/xfs_rtbitmap.h |   17 +++++++++++++++++
 fs/xfs/libxfs/xfs_swapext.c  |    7 ++++---
 fs/xfs/xfs_rtalloc.c         |    8 ++++----
 5 files changed, 30 insertions(+), 13 deletions(-)


diff --git a/fs/xfs/libxfs/xfs_bmap.c b/fs/xfs/libxfs/xfs_bmap.c
index 888b51a09acb..055432476ef0 100644
--- a/fs/xfs/libxfs/xfs_bmap.c
+++ b/fs/xfs/libxfs/xfs_bmap.c
@@ -5371,7 +5371,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;
@@ -5468,8 +5467,7 @@ __xfs_bunmapi(
 		if (!isrt || (flags & XFS_BMAPI_REMAP))
 			goto delete;
 
-		sum = del.br_startblock + del.br_blockcount;
-		div_u64_rem(sum, mp->m_sb.sb_rextsize, &mod);
+		xfs_rtb_to_rtx(mp, del.br_startblock + del.br_blockcount, &mod);
 		if (mod) {
 			/*
 			 * Realtime extent not lined up at the end.
@@ -5516,7 +5514,8 @@ __xfs_bunmapi(
 				goto error0;
 			goto nodelete;
 		}
-		div_u64_rem(del.br_startblock, mp->m_sb.sb_rextsize, &mod);
+
+		xfs_rtb_to_rtx(mp, del.br_startblock, &mod);
 		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 ce1443681131..de54386cf52f 100644
--- a/fs/xfs/libxfs/xfs_rtbitmap.c
+++ b/fs/xfs/libxfs/xfs_rtbitmap.c
@@ -1031,13 +1031,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_rtx(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_rtx(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..bdd4858a794c 100644
--- a/fs/xfs/libxfs/xfs_rtbitmap.h
+++ b/fs/xfs/libxfs/xfs_rtbitmap.h
@@ -39,6 +39,23 @@ xfs_extlen_to_rtxlen(
 	return len / mp->m_sb.sb_rextsize;
 }
 
+static inline xfs_rtxnum_t
+xfs_rtb_to_rtx(
+	struct xfs_mount	*mp,
+	xfs_rtblock_t		rtbno,
+	xfs_extlen_t		*mod)
+{
+	return div_u64_rem(rtbno, mp->m_sb.sb_rextsize, mod);
+}
+
+static inline xfs_rtxnum_t
+xfs_rtb_to_rtxt(
+	struct xfs_mount	*mp,
+	xfs_rtblock_t		rtbno)
+{
+	return div_u64(rtbno, mp->m_sb.sb_rextsize);
+}
+
 /*
  * Functions for walking free space rtextents in the realtime bitmap.
  */
diff --git a/fs/xfs/libxfs/xfs_swapext.c b/fs/xfs/libxfs/xfs_swapext.c
index 42df372d1a89..36f03b0bf4ed 100644
--- a/fs/xfs/libxfs/xfs_swapext.c
+++ b/fs/xfs/libxfs/xfs_swapext.c
@@ -30,6 +30,7 @@
 #include "xfs_dir2_priv.h"
 #include "xfs_dir2.h"
 #include "xfs_symlink_remote.h"
+#include "xfs_rtbitmap.h"
 
 struct kmem_cache	*xfs_swapext_intent_cache;
 
@@ -215,19 +216,19 @@ xfs_swapext_check_rt_extents(
 					  irec2.br_blockcount);
 
 		/* Both mappings must be aligned to the realtime extent size. */
-		div_u64_rem(irec1.br_startoff, mp->m_sb.sb_rextsize, &mod);
+		xfs_rtb_to_rtx(mp, irec1.br_startoff, &mod);
 		if (mod) {
 			ASSERT(mod == 0);
 			return -EINVAL;
 		}
 
-		div_u64_rem(irec2.br_startoff, mp->m_sb.sb_rextsize, &mod);
+		xfs_rtb_to_rtx(mp, irec1.br_startoff, &mod);
 		if (mod) {
 			ASSERT(mod == 0);
 			return -EINVAL;
 		}
 
-		div_u64_rem(irec1.br_blockcount, mp->m_sb.sb_rextsize, &mod);
+		xfs_rtb_to_rtx(mp, irec1.br_blockcount, &mod);
 		if (mod) {
 			ASSERT(mod == 0);
 			return -EINVAL;
diff --git a/fs/xfs/xfs_rtalloc.c b/fs/xfs/xfs_rtalloc.c
index 40b6df0ad633..04a468f4cb8a 100644
--- a/fs/xfs/xfs_rtalloc.c
+++ b/fs/xfs/xfs_rtalloc.c
@@ -1494,16 +1494,16 @@ xfs_rtfile_want_conversion(
 	struct xfs_bmbt_irec	*irec)
 {
 	xfs_fileoff_t		rext_next;
-	uint32_t		modoff, modcnt;
+	xfs_extlen_t		modoff, modcnt;
 
 	if (irec->br_state != XFS_EXT_UNWRITTEN)
 		return false;
 
-	div_u64_rem(irec->br_startoff, mp->m_sb.sb_rextsize, &modoff);
+	xfs_rtb_to_rtx(mp, irec->br_startoff, &modoff);
 	if (modoff == 0) {
-		uint64_t	rexts = div_u64_rem(irec->br_blockcount,
-						mp->m_sb.sb_rextsize, &modcnt);
+		xfs_rtbxlen_t	rexts;
 
+		rexts = xfs_rtb_to_rtx(mp, irec->br_blockcount, &modcnt);
 		if (rexts > 0) {
 			/*
 			 * Unwritten mapping starts at an rt extent boundary


^ permalink raw reply related	[flat|nested] 91+ messages in thread

end of thread, other threads:[~2023-10-19 16:25 UTC | newest]

Thread overview: 91+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2023-10-17 15:37 [RFC v1.1] xfs-linux: rtalloc-speedups-6.7 updated to b67199695696 Darrick J. Wong
2023-10-17 15:43 ` Darrick J. Wong
2023-10-17 15:45 ` [PATCHSET RFC v1.1 0/4] xfs: minor bugfixes for rt stuff Darrick J. Wong
2023-10-17 15:47   ` [PATCH 1/4] xfs: bump max fsgeom struct version Darrick J. Wong
2023-10-17 15:47   ` [PATCH 2/4] xfs: hoist freeing of rt data fork extent mappings Darrick J. Wong
2023-10-17 16:00     ` Christoph Hellwig
2023-10-17 15:47   ` [PATCH 3/4] xfs: prevent rt growfs when quota is enabled Darrick J. Wong
2023-10-17 15:47   ` [PATCH 4/4] xfs: rt stubs should return negative errnos when rt disabled Darrick J. Wong
2023-10-17 15:46 ` [PATCHSET RFC v1.1 0/8] xfs: clean up realtime type usage Darrick J. Wong
2023-10-17 15:48   ` [PATCH 1/8] xfs: fix units conversion error in xfs_bmap_del_extent_delay Darrick J. Wong
2023-10-17 16:01     ` Christoph Hellwig
2023-10-17 15:48   ` [PATCH 2/8] xfs: make sure maxlen is still congruent with prod when rounding down Darrick J. Wong
2023-10-17 15:48   ` [PATCH 3/8] xfs: move the xfs_rtbitmap.c declarations to xfs_rtbitmap.h Darrick J. Wong
2023-10-17 15:48   ` [PATCH 4/8] xfs: convert xfs_extlen_t to xfs_rtxlen_t in the rt allocator Darrick J. Wong
2023-10-17 15:49   ` [PATCH 5/8] xfs: convert rt bitmap/summary block numbers to xfs_fileoff_t Darrick J. Wong
2023-10-17 15:49   ` [PATCH 6/8] xfs: convert rt bitmap extent lengths to xfs_rtbxlen_t Darrick J. Wong
2023-10-17 15:49   ` [PATCH 7/8] xfs: rename xfs_verify_rtext to xfs_verify_rtbext Darrick J. Wong
2023-10-17 15:49   ` [PATCH 8/8] xfs: convert rt extent numbers to xfs_rtxnum_t Darrick J. Wong
2023-10-17 15:46 ` [PATCHSET RFC v1.1 0/7] xfs: refactor rt extent unit conversions Darrick J. Wong
2023-10-17 15:50   ` [PATCH 1/7] xfs: create a helper to convert rtextents to rtblocks Darrick J. Wong
2023-10-17 15:50   ` [PATCH 2/7] xfs: create a helper to compute leftovers of realtime extents Darrick J. Wong
2023-10-17 15:50   ` [PATCH 3/7] xfs: create a helper to convert extlen to rtextlen Darrick J. Wong
2023-10-17 15:50   ` [PATCH 4/7] xfs: create helpers to convert rt block numbers to rt extent numbers Darrick J. Wong
2023-10-17 16:04     ` Christoph Hellwig
2023-10-17 15:51   ` [PATCH 5/7] xfs: convert do_div calls to xfs_rtb_to_rtx helper calls Darrick J. Wong
2023-10-17 16:05     ` Christoph Hellwig
2023-10-17 15:51   ` [PATCH 6/7] xfs: create rt extent rounding helpers for realtime extent blocks Darrick J. Wong
2023-10-17 15:51   ` [PATCH 7/7] xfs: use shifting and masking when converting rt extents, if possible Darrick J. Wong
2023-10-17 15:46 ` [PATCHSET RFC v1.1 0/8] xfs: refactor rtbitmap/summary macros Darrick J. Wong
2023-10-17 15:52   ` [PATCH 1/8] xfs: convert the rtbitmap block and bit macros to static inline functions Darrick J. Wong
2023-10-17 15:52   ` [PATCH 2/8] xfs: remove XFS_BLOCKWSIZE and XFS_BLOCKWMASK macros Darrick J. Wong
2023-10-17 15:52   ` [PATCH 3/8] xfs: convert open-coded xfs_rtword_t pointer accesses to helper Darrick J. Wong
2023-10-17 16:31     ` Christoph Hellwig
2023-10-17 15:52   ` [PATCH 4/8] xfs: convert rt summary macros to helpers Darrick J. Wong
2023-10-17 15:53   ` [PATCH 5/8] xfs: create helpers for rtbitmap block/wordcount computations Darrick J. Wong
2023-10-17 16:33     ` Christoph Hellwig
2023-10-17 15:53   ` [PATCH 6/8] xfs: use accessor functions for bitmap words Darrick J. Wong
2023-10-17 18:53     ` Christoph Hellwig
2023-10-18  2:01       ` Darrick J. Wong
2023-10-18  4:50         ` Christoph Hellwig
2023-10-17 15:53   ` [PATCH 7/8] xfs: create helpers for rtsummary block/wordcount computations Darrick J. Wong
2023-10-17 15:53   ` [PATCH 8/8] xfs: use accessor functions for summary info words Darrick J. Wong
2023-10-18  2:10   ` [PATCHSET RFC v1.2 0/4] xfs: refactor rtbitmap/summary accessors Darrick J. Wong
2023-10-18  2:10     ` [PATCH 1/4] xfs: create a helper to handle logging parts of rt bitmap blocks Darrick J. Wong
2023-10-18  4:52       ` Christoph Hellwig
2023-10-18  2:10     ` [PATCH 2/4] xfs: use accessor functions for bitmap words Darrick J. Wong
2023-10-18  2:19       ` Darrick J. Wong
2023-10-18  4:54       ` Christoph Hellwig
2023-10-18  4:54         ` Christoph Hellwig
2023-10-18 16:27         ` Darrick J. Wong
2023-10-18 16:28           ` Christoph Hellwig
2023-10-18  2:10     ` [PATCH 3/4] xfs: create helpers for rtsummary block/wordcount computations Darrick J. Wong
2023-10-18  2:10     ` [PATCH 4/4] xfs: use accessor functions for summary info words Darrick J. Wong
2023-10-18  5:19       ` Christoph Hellwig
2023-10-18  5:31         ` Darrick J. Wong
2023-10-18  5:35           ` Christoph Hellwig
2023-10-18  6:16           ` Darrick J. Wong
2023-10-17 15:46 ` [PATCHSET RFC 2.1 0/7] xfs: CPU usage optimizations for realtime allocator Darrick J. Wong
2023-10-17 15:54   ` [PATCH 1/7] xfs: consolidate realtime allocation arguments Darrick J. Wong
2023-10-18  6:16     ` Christoph Hellwig
2023-10-18 17:04       ` Darrick J. Wong
2023-10-17 15:54   ` [PATCH 2/7] xfs: cache last bitmap block in realtime allocator Darrick J. Wong
2023-10-18  6:19     ` Christoph Hellwig
2023-10-18 16:33       ` Darrick J. Wong
2023-10-19  0:00         ` Darrick J. Wong
2023-10-18 18:28     ` Darrick J. Wong
2023-10-17 15:54   ` [PATCH 3/7] xfs: invert the realtime summary cache Darrick J. Wong
2023-10-17 15:54   ` [PATCH 4/7] xfs: return maximum free size from xfs_rtany_summary() Darrick J. Wong
2023-10-17 15:55   ` [PATCH 5/7] xfs: limit maxlen based on available space in xfs_rtallocate_extent_near() Darrick J. Wong
2023-10-17 15:55   ` [PATCH 6/7] xfs: don't try redundant allocations " Darrick J. Wong
2023-10-17 15:55   ` [PATCH 7/7] xfs: don't look for end of extent further than necessary " Darrick J. Wong
2023-10-19  0:00   ` [PATCHSET v2.2 0/9] xfs: CPU usage optimizations for realtime allocator Darrick J. Wong
2023-10-19  0:00     ` [PATCH 1/9] xfs: consolidate realtime allocation arguments Darrick J. Wong
2023-10-19  5:08       ` Christoph Hellwig
2023-10-19  0:01     ` [PATCH 2/9] xfs: cache last bitmap block in realtime allocator Darrick J. Wong
2023-10-19  0:01     ` [PATCH 3/9] xfs: simplify xfs_rtbuf_get calling conventions Darrick J. Wong
2023-10-19  5:11       ` Christoph Hellwig
2023-10-19  0:01     ` [PATCH 4/9] xfs: simplify rt bitmap/summary block accessor functions Darrick J. Wong
2023-10-19  5:13       ` Christoph Hellwig
2023-10-19 16:13         ` Darrick J. Wong
2023-10-19  0:01     ` [PATCH 5/9] xfs: invert the realtime summary cache Darrick J. Wong
2023-10-19  0:01     ` [PATCH 6/9] xfs: return maximum free size from xfs_rtany_summary() Darrick J. Wong
2023-10-19  0:01     ` [PATCH 7/9] xfs: limit maxlen based on available space in xfs_rtallocate_extent_near() Darrick J. Wong
2023-10-19  0:01     ` [PATCH 8/9] xfs: don't try redundant allocations " Darrick J. Wong
2023-10-19  0:01     ` [PATCH 9/9] xfs: don't look for end of extent further than necessary " Darrick J. Wong
  -- strict thread matches above, loose matches on Subject: below --
2023-10-19 16:20 [PATCHSET v1.1 0/7] xfs: refactor rt extent unit conversions Darrick J. Wong
2023-10-19 16:25 ` [PATCH 4/7] xfs: create helpers to convert rt block numbers to rt extent numbers Darrick J. Wong
2023-10-11 18:01 [PATCHSET RFC v1.0 0/7] xfs: refactor rt extent unit conversions Darrick J. Wong
2023-10-11 18:05 ` [PATCH 4/7] xfs: create helpers to convert rt block numbers to rt extent numbers Darrick J. Wong
2023-10-12  5:17   ` Christoph Hellwig
2023-10-12 17:58     ` Darrick J. Wong
2023-10-13  4:25       ` Christoph Hellwig
2022-12-30 22:17 [PATCHSET v1.0 0/7] xfs: refactor rt extent unit conversions Darrick J. Wong
2022-12-30 22:17 ` [PATCH 4/7] xfs: create helpers to convert rt block numbers to rt extent numbers Darrick J. Wong

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.