From: "Darrick J. Wong" <djwong@kernel.org>
To: Christoph Hellwig <hch@lst.de>
Cc: Carlos Maiolino <cem@kernel.org>, linux-xfs@vger.kernel.org
Subject: Re: [PATCH 1/2] xfs: track the number of blocks in each buftarg
Date: Mon, 18 Aug 2025 13:48:30 -0700 [thread overview]
Message-ID: <20250818204830.GY7965@frogsfrogsfrogs> (raw)
In-Reply-To: <20250818051155.1486253-2-hch@lst.de>
On Mon, Aug 18, 2025 at 07:11:23AM +0200, Christoph Hellwig wrote:
> Add a bt_nr_blocks to track the number of blocks in each buftarg, and
> replace the check that hard codes sb_dblock in xfs_buf_map_verify with
> this new value so that it is correct for non-ddev buftargs. The
> RT buftarg only has a superblock in the first block, so it is unlikely
> to trigger this, or are we likely to ever have enough blocks in the
> in-memory buftargs, but we might as well get the check right.
>
> Fixes: 10616b806d1d ("xfs: fix _xfs_buf_find oops on blocks beyond the filesystem end")
> Signed-off-by: Christoph Hellwig <hch@lst.de>
> ---
> fs/xfs/xfs_buf.c | 38 +++++++++++++++++++----------------
> fs/xfs/xfs_buf.h | 4 +++-
> fs/xfs/xfs_buf_item_recover.c | 7 +++++++
> fs/xfs/xfs_super.c | 7 ++++---
> fs/xfs/xfs_trans.c | 21 +++++++++----------
> 5 files changed, 45 insertions(+), 32 deletions(-)
>
> diff --git a/fs/xfs/xfs_buf.c b/fs/xfs/xfs_buf.c
> index f9ef3b2a332a..b9b89f1243a0 100644
> --- a/fs/xfs/xfs_buf.c
> +++ b/fs/xfs/xfs_buf.c
> @@ -397,7 +397,7 @@ xfs_buf_map_verify(
> * Corrupted block numbers can get through to here, unfortunately, so we
> * have to check that the buffer falls within the filesystem bounds.
> */
> - eofs = XFS_FSB_TO_BB(btp->bt_mount, btp->bt_mount->m_sb.sb_dblocks);
> + eofs = XFS_FSB_TO_BB(btp->bt_mount, btp->bt_nr_blocks);
> if (map->bm_bn < 0 || map->bm_bn >= eofs) {
> xfs_alert(btp->bt_mount,
> "%s: daddr 0x%llx out of range, EOFS 0x%llx",
> @@ -1720,26 +1720,27 @@ xfs_configure_buftarg_atomic_writes(
> int
> xfs_configure_buftarg(
> struct xfs_buftarg *btp,
> - unsigned int sectorsize)
> -{
> - int error;
> + unsigned int sectorsize,
> + xfs_rfsblock_t nr_blocks)
> +{
> + if (btp->bt_bdev) {
> + int error;
> +
> + error = bdev_validate_blocksize(btp->bt_bdev, sectorsize);
> + if (error) {
> + xfs_warn(btp->bt_mount,
> + "Cannot use blocksize %u on device %pg, err %d",
> + sectorsize, btp->bt_bdev, error);
> + return -EINVAL;
> + }
>
> - ASSERT(btp->bt_bdev != NULL);
> + if (bdev_can_atomic_write(btp->bt_bdev))
> + xfs_configure_buftarg_atomic_writes(btp);
> + }
>
> - /* Set up metadata sector size info */
> btp->bt_meta_sectorsize = sectorsize;
> btp->bt_meta_sectormask = sectorsize - 1;
> -
> - error = bdev_validate_blocksize(btp->bt_bdev, sectorsize);
> - if (error) {
> - xfs_warn(btp->bt_mount,
> - "Cannot use blocksize %u on device %pg, err %d",
> - sectorsize, btp->bt_bdev, error);
> - return -EINVAL;
> - }
> -
> - if (bdev_can_atomic_write(btp->bt_bdev))
> - xfs_configure_buftarg_atomic_writes(btp);
> + btp->bt_nr_blocks = nr_blocks;
> return 0;
> }
>
> @@ -1749,6 +1750,9 @@ xfs_init_buftarg(
> size_t logical_sectorsize,
> const char *descr)
> {
> + /* The maximum size of the buftarg is only known once the sb is read. */
> + btp->bt_nr_blocks = (xfs_rfsblock_t)-1;
> +
> /* Set up device logical sector size mask */
> btp->bt_logical_sectorsize = logical_sectorsize;
> btp->bt_logical_sectormask = logical_sectorsize - 1;
> diff --git a/fs/xfs/xfs_buf.h b/fs/xfs/xfs_buf.h
> index b269e115d9ac..a9b3def89cfb 100644
> --- a/fs/xfs/xfs_buf.h
> +++ b/fs/xfs/xfs_buf.h
> @@ -103,6 +103,7 @@ struct xfs_buftarg {
> size_t bt_meta_sectormask;
> size_t bt_logical_sectorsize;
> size_t bt_logical_sectormask;
> + xfs_rfsblock_t bt_nr_blocks;
>
> /* LRU control structures */
> struct shrinker *bt_shrinker;
> @@ -372,7 +373,8 @@ struct xfs_buftarg *xfs_alloc_buftarg(struct xfs_mount *mp,
> extern void xfs_free_buftarg(struct xfs_buftarg *);
> extern void xfs_buftarg_wait(struct xfs_buftarg *);
> extern void xfs_buftarg_drain(struct xfs_buftarg *);
> -int xfs_configure_buftarg(struct xfs_buftarg *btp, unsigned int sectorsize);
> +int xfs_configure_buftarg(struct xfs_buftarg *btp, unsigned int sectorsize,
> + xfs_rfsblock_t nr_blocks);
>
> #define xfs_readonly_buftarg(buftarg) bdev_read_only((buftarg)->bt_bdev)
>
> diff --git a/fs/xfs/xfs_buf_item_recover.c b/fs/xfs/xfs_buf_item_recover.c
> index 5d58e2ae4972..d43234e04174 100644
> --- a/fs/xfs/xfs_buf_item_recover.c
> +++ b/fs/xfs/xfs_buf_item_recover.c
> @@ -736,6 +736,13 @@ xlog_recover_do_primary_sb_buffer(
> */
> xfs_sb_from_disk(&mp->m_sb, dsb);
>
> + /*
> + * Grow can change the device size. Mirror that into the buftarg.
> + */
> + mp->m_ddev_targp->bt_nr_blocks = mp->m_sb.sb_dblocks;
> + if (mp->m_rtdev_targp && mp->m_rtdev_targp != mp->m_ddev_targp)
> + mp->m_rtdev_targp->bt_nr_blocks = mp->m_sb.sb_dblocks;
> +
> if (mp->m_sb.sb_agcount < orig_agcount) {
> xfs_alert(mp, "Shrinking AG count in log recovery not supported");
> return -EFSCORRUPTED;
> diff --git a/fs/xfs/xfs_super.c b/fs/xfs/xfs_super.c
> index bb0a82635a77..78f0c4707c22 100644
> --- a/fs/xfs/xfs_super.c
> +++ b/fs/xfs/xfs_super.c
> @@ -541,7 +541,8 @@ xfs_setup_devices(
> {
> int error;
>
> - error = xfs_configure_buftarg(mp->m_ddev_targp, mp->m_sb.sb_sectsize);
> + error = xfs_configure_buftarg(mp->m_ddev_targp, mp->m_sb.sb_sectsize,
> + mp->m_sb.sb_dblocks);
> if (error)
> return error;
>
> @@ -551,7 +552,7 @@ xfs_setup_devices(
> if (xfs_has_sector(mp))
> log_sector_size = mp->m_sb.sb_logsectsize;
> error = xfs_configure_buftarg(mp->m_logdev_targp,
> - log_sector_size);
> + log_sector_size, mp->m_sb.sb_logblocks);
> if (error)
> return error;
> }
> @@ -565,7 +566,7 @@ xfs_setup_devices(
> mp->m_rtdev_targp = mp->m_ddev_targp;
> } else if (mp->m_rtname) {
> error = xfs_configure_buftarg(mp->m_rtdev_targp,
> - mp->m_sb.sb_sectsize);
> + mp->m_sb.sb_sectsize, mp->m_sb.sb_rblocks);
> if (error)
> return error;
> }
> diff --git a/fs/xfs/xfs_trans.c b/fs/xfs/xfs_trans.c
> index 575e7028f423..584bd725ef18 100644
> --- a/fs/xfs/xfs_trans.c
> +++ b/fs/xfs/xfs_trans.c
> @@ -452,19 +452,17 @@ xfs_trans_mod_sb(
> */
> STATIC void
> xfs_trans_apply_sb_deltas(
> - xfs_trans_t *tp)
> + struct xfs_trans *tp)
> {
> - struct xfs_dsb *sbp;
> - struct xfs_buf *bp;
> - int whole = 0;
> -
> - bp = xfs_trans_getsb(tp);
> - sbp = bp->b_addr;
> + struct xfs_mount *mp = tp->t_mountp;
> + struct xfs_buf *bp = xfs_trans_getsb(tp);
> + struct xfs_dsb *sbp = bp->b_addr;
> + int whole = 0;
>
> /*
> * Only update the superblock counters if we are logging them
> */
> - if (!xfs_has_lazysbcount((tp->t_mountp))) {
> + if (!xfs_has_lazysbcount(mp)) {
> if (tp->t_icount_delta)
> be64_add_cpu(&sbp->sb_icount, tp->t_icount_delta);
> if (tp->t_ifree_delta)
> @@ -491,8 +489,7 @@ xfs_trans_apply_sb_deltas(
> * write the correct value ondisk.
> */
> if ((tp->t_frextents_delta || tp->t_res_frextents_delta) &&
> - !xfs_has_rtgroups(tp->t_mountp)) {
> - struct xfs_mount *mp = tp->t_mountp;
> + !xfs_has_rtgroups(mp)) {
> int64_t rtxdelta;
>
> rtxdelta = tp->t_frextents_delta + tp->t_res_frextents_delta;
> @@ -505,6 +502,7 @@ xfs_trans_apply_sb_deltas(
>
> if (tp->t_dblocks_delta) {
> be64_add_cpu(&sbp->sb_dblocks, tp->t_dblocks_delta);
> + mp->m_ddev_targp->bt_nr_blocks += tp->t_dblocks_delta;
> whole = 1;
> }
> if (tp->t_agcount_delta) {
> @@ -524,7 +522,7 @@ xfs_trans_apply_sb_deltas(
> * recompute the ondisk rtgroup block log. The incore values
> * will be recomputed in xfs_trans_unreserve_and_mod_sb.
> */
> - if (xfs_has_rtgroups(tp->t_mountp)) {
> + if (xfs_has_rtgroups(mp)) {
> sbp->sb_rgblklog = xfs_compute_rgblklog(
> be32_to_cpu(sbp->sb_rgextents),
> be32_to_cpu(sbp->sb_rextsize));
> @@ -537,6 +535,7 @@ xfs_trans_apply_sb_deltas(
> }
> if (tp->t_rblocks_delta) {
> be64_add_cpu(&sbp->sb_rblocks, tp->t_rblocks_delta);
> + mp->m_rtdev_targp->bt_nr_blocks += tp->t_dblocks_delta;
Should this be += tp->t_rblocks_delta here?
--D
> whole = 1;
> }
> if (tp->t_rextents_delta) {
> --
> 2.47.2
>
>
next prev parent reply other threads:[~2025-08-18 20:48 UTC|newest]
Thread overview: 18+ messages / expand[flat|nested] mbox.gz Atom feed top
2025-08-18 5:11 store the buftarg size in the buftarg Christoph Hellwig
2025-08-18 5:11 ` [PATCH 1/2] xfs: track the number of blocks in each buftarg Christoph Hellwig
2025-08-18 20:48 ` Darrick J. Wong [this message]
2025-08-19 8:06 ` Christoph Hellwig
2025-08-18 5:11 ` [PATCH 2/2] xfs: use bt_nr_blocks in xfs_dax_translate_range Christoph Hellwig
2025-08-18 20:49 ` Darrick J. Wong
-- strict thread matches above, loose matches on Subject: below --
2025-08-25 11:19 store the buftarg size in the buftarg v2 Christoph Hellwig
2025-08-25 11:19 ` [PATCH 1/2] xfs: track the number of blocks in each buftarg Christoph Hellwig
2025-08-25 15:26 ` Darrick J. Wong
2025-08-26 13:28 ` Christoph Hellwig
2025-08-26 5:42 ` Dave Chinner
2025-08-26 13:29 ` Christoph Hellwig
2025-09-16 13:52 store the buftarg size in the buftarg v3 Christoph Hellwig
2025-09-16 13:52 ` [PATCH 1/2] xfs: track the number of blocks in each buftarg Christoph Hellwig
2025-09-17 21:26 ` Dave Chinner
2025-09-19 13:12 store the buftarg size in the buftarg v4 Christoph Hellwig
2025-09-19 13:12 ` [PATCH 1/2] xfs: track the number of blocks in each buftarg Christoph Hellwig
2025-09-19 17:52 ` Darrick J. Wong
2025-10-13 5:46 ` Darrick J. Wong
2025-10-13 6:29 ` Christoph Hellwig
2025-10-13 14:54 ` Darrick J. Wong
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20250818204830.GY7965@frogsfrogsfrogs \
--to=djwong@kernel.org \
--cc=cem@kernel.org \
--cc=hch@lst.de \
--cc=linux-xfs@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox