* [PATCH v3 0/4] xfs: Misc changes to XFS realtime
@ 2026-02-19 14:46 Nirjhar Roy (IBM)
2026-02-19 14:46 ` [PATCH v3 1/4] xfs: Fix xfs_last_rt_bmblock() Nirjhar Roy (IBM)
` (3 more replies)
0 siblings, 4 replies; 11+ messages in thread
From: Nirjhar Roy (IBM) @ 2026-02-19 14:46 UTC (permalink / raw)
To: djwong, hch, cem
Cc: linux-xfs, ritesh.list, ojaswin, nirjhar.roy.lists, nirjhar
From: "Nirjhar Roy (IBM)" <nirjhar.roy.lists@gmail.com>
This series has a bug fix and adds some missing operations to
growfs code in the realtime code. Details are in the commit messages.
[v2] -> v3
1. Rebased it on top of latest mainline master(2b7a25df823d) since
xfs_linux was renamed to xfs_platform.h.
2. Add RB from Christoph in patch 2 and 3.
[v1] -> v2
1. Added RB from Christoph in patch 1 and 4.
2. Updated the commit message in patch 4 ("xfs: Add comments for usages of some macros.")
3. Updated the commit message and added some comments in the code explaining
the change in patch 3("xfs: Update lazy counters in xfs_growfs_rt_bmblock()")
4. Removed patch 2 of [v1] - instead added a comment in xfs_log_sb()
explaining why we are not checking the lazy counter enablement while
updating the free rtextent count (sb_frextents).
[v2]-
[v1]- https://lore.kernel.org/all/cover.1770904484.git.nirjhar.roy.lists@gmail.com/
Nirjhar Roy (IBM) (4):
xfs: Fix xfs_last_rt_bmblock()
xfs: Add a comment in xfs_log_sb()
xfs: Update lazy counters in xfs_growfs_rt_bmblock()
xfs: Add comments for usages of some macros.
fs/xfs/libxfs/xfs_sb.c | 3 +++
fs/xfs/xfs_platform.h | 6 ++++++
fs/xfs/xfs_rtalloc.c | 39 +++++++++++++++++++++++++++++++++------
3 files changed, 42 insertions(+), 6 deletions(-)
--
2.43.5
^ permalink raw reply [flat|nested] 11+ messages in thread
* [PATCH v3 1/4] xfs: Fix xfs_last_rt_bmblock()
2026-02-19 14:46 [PATCH v3 0/4] xfs: Misc changes to XFS realtime Nirjhar Roy (IBM)
@ 2026-02-19 14:46 ` Nirjhar Roy (IBM)
2026-02-19 21:42 ` Darrick J. Wong
2026-02-19 14:46 ` [PATCH v3 2/4] xfs: Add a comment in xfs_log_sb() Nirjhar Roy (IBM)
` (2 subsequent siblings)
3 siblings, 1 reply; 11+ messages in thread
From: Nirjhar Roy (IBM) @ 2026-02-19 14:46 UTC (permalink / raw)
To: djwong, hch, cem
Cc: linux-xfs, ritesh.list, ojaswin, nirjhar.roy.lists, nirjhar
From: "Nirjhar Roy (IBM)" <nirjhar.roy.lists@gmail.com>
Bug description:
If the size of the last rtgroup i.e, the rtg passed to
xfs_last_rt_bmblock() is such that the last rtextent falls in 0th word
offset of a bmblock of the bitmap file tracking this (last) rtgroup,
then in that case xfs_last_rt_bmblock() incorrectly returns the next
bmblock number instead of the current/last used bmblock number.
When xfs_last_rt_bmblock() incorrectly returns the next bmblock,
the loop to grow/modify the bmblocks in xfs_growfs_rtg() doesn't
execute and xfs_growfs basically does a nop in certain cases.
xfs_growfs will do a nop when the new size of the fs will have the same
number of rtgroups i.e, we are only growing the last rtgroup.
Reproduce:
$ mkfs.xfs -m metadir=0 -r rtdev=/dev/loop1 /dev/loop0 \
-r rgsize=32768b,size=32769b -f
$ mount -o rtdev=/dev/loop1 /dev/loop0 /mnt/scratch
$ xfs_growfs -R $(( 32769 + 1 )) /mnt/scratch
$ xfs_info /mnt/scratch | grep rtextents
$ # We can see that rtextents hasn't changed
Fix:
Fix this by returning the current/last used bmblock when the last
rtgroup size is not a multiple xfs_rtbitmap_rtx_per_rbmblock()
and the next bmblock when the rtgroup size is a multiple of
xfs_rtbitmap_rtx_per_rbmblock() i.e, the existing blocks are
completely used up.
Also, I have renamed xfs_last_rt_bmblock() to
xfs_last_rt_bmblock_to_extend() to signify that this function
returns the bmblock number to extend and NOT always the last used
bmblock number.
Reviewed-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Nirjhar Roy (IBM) <nirjhar.roy.lists@gmail.com>
---
fs/xfs/xfs_rtalloc.c | 30 ++++++++++++++++++++++++------
1 file changed, 24 insertions(+), 6 deletions(-)
diff --git a/fs/xfs/xfs_rtalloc.c b/fs/xfs/xfs_rtalloc.c
index 90a94a5b6f7e..decbd07b94fd 100644
--- a/fs/xfs/xfs_rtalloc.c
+++ b/fs/xfs/xfs_rtalloc.c
@@ -1079,17 +1079,27 @@ xfs_last_rtgroup_extents(
}
/*
- * Calculate the last rbmblock currently used.
+ * This will return the bitmap block number (indexed at 0) that will be
+ * extended/modified. There are 2 cases here:
+ * 1. The size of the rtg is such that it is a multiple of
+ * xfs_rtbitmap_rtx_per_rbmblock() i.e, an integral number of bitmap blocks
+ * are completely filled up. In this case, we should return
+ * 1 + (the last used bitmap block number).
+ * 2. The size of the rtg is not an multiple of xfs_rtbitmap_rtx_per_rbmblock().
+ * Here we will return the block number of last used block number. In this
+ * case, we will modify the last used bitmap block to extend the size of the
+ * rtgroup.
*
* This also deals with the case where there were no rtextents before.
*/
static xfs_fileoff_t
-xfs_last_rt_bmblock(
+xfs_last_rt_bmblock_to_extend(
struct xfs_rtgroup *rtg)
{
struct xfs_mount *mp = rtg_mount(rtg);
xfs_rgnumber_t rgno = rtg_rgno(rtg);
xfs_fileoff_t bmbno = 0;
+ unsigned int mod = 0;
ASSERT(!mp->m_sb.sb_rgcount || rgno >= mp->m_sb.sb_rgcount - 1);
@@ -1097,9 +1107,16 @@ xfs_last_rt_bmblock(
xfs_rtxnum_t nrext = xfs_last_rtgroup_extents(mp);
/* Also fill up the previous block if not entirely full. */
- bmbno = xfs_rtbitmap_blockcount_len(mp, nrext);
- if (xfs_rtx_to_rbmword(mp, nrext) != 0)
- bmbno--;
+ /* We are doing a -1 to convert it to a 0 based index */
+ bmbno = xfs_rtbitmap_blockcount_len(mp, nrext) - 1;
+ div_u64_rem(nrext, xfs_rtbitmap_rtx_per_rbmblock(mp), &mod);
+ /*
+ * mod = 0 means that all the current blocks are full. So
+ * return the next block number to be used for the rtgroup
+ * growth.
+ */
+ if (mod == 0)
+ bmbno++;
}
return bmbno;
@@ -1204,7 +1221,8 @@ xfs_growfs_rtg(
goto out_rele;
}
- for (bmbno = xfs_last_rt_bmblock(rtg); bmbno < bmblocks; bmbno++) {
+ for (bmbno = xfs_last_rt_bmblock_to_extend(rtg); bmbno < bmblocks;
+ bmbno++) {
error = xfs_growfs_rt_bmblock(rtg, nrblocks, rextsize, bmbno);
if (error)
goto out_error;
--
2.43.5
^ permalink raw reply related [flat|nested] 11+ messages in thread
* [PATCH v3 2/4] xfs: Add a comment in xfs_log_sb()
2026-02-19 14:46 [PATCH v3 0/4] xfs: Misc changes to XFS realtime Nirjhar Roy (IBM)
2026-02-19 14:46 ` [PATCH v3 1/4] xfs: Fix xfs_last_rt_bmblock() Nirjhar Roy (IBM)
@ 2026-02-19 14:46 ` Nirjhar Roy (IBM)
2026-02-19 15:57 ` Darrick J. Wong
2026-02-19 14:46 ` [PATCH v3 3/4] xfs: Update lazy counters in xfs_growfs_rt_bmblock() Nirjhar Roy (IBM)
2026-02-19 14:46 ` [PATCH v3 4/4] xfs: Add comments for usages of some macros Nirjhar Roy (IBM)
3 siblings, 1 reply; 11+ messages in thread
From: Nirjhar Roy (IBM) @ 2026-02-19 14:46 UTC (permalink / raw)
To: djwong, hch, cem
Cc: linux-xfs, ritesh.list, ojaswin, nirjhar.roy.lists, nirjhar
From: "Nirjhar Roy (IBM)" <nirjhar.roy.lists@gmail.com>
Add a comment explaining why the sb_frextents are updated outside the
if (xfs_has_lazycount(mp) check even though it is a lazycounter.
RT groups are supported only in v5 filesystems which always have
lazycounter enabled - so putting it inside the if(xfs_has_lazycount(mp)
check is redundant.
Suggested-by: Christoph Hellwig <hch@lst.de>
Reviewed-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Nirjhar Roy (IBM) <nirjhar.roy.lists@gmail.com>
---
fs/xfs/libxfs/xfs_sb.c | 3 +++
1 file changed, 3 insertions(+)
diff --git a/fs/xfs/libxfs/xfs_sb.c b/fs/xfs/libxfs/xfs_sb.c
index 38d16fe1f6d8..47322adb7690 100644
--- a/fs/xfs/libxfs/xfs_sb.c
+++ b/fs/xfs/libxfs/xfs_sb.c
@@ -1347,6 +1347,9 @@ xfs_log_sb(
* feature was introduced. This counter can go negative due to the way
* we handle nearly-lockless reservations, so we must use the _positive
* variant here to avoid writing out nonsense frextents.
+ *
+ * RT groups are only supported on v5 file systems, which always
+ * have lazy SB counters.
*/
if (xfs_has_rtgroups(mp) && !xfs_has_zoned(mp)) {
mp->m_sb.sb_frextents =
--
2.43.5
^ permalink raw reply related [flat|nested] 11+ messages in thread
* [PATCH v3 3/4] xfs: Update lazy counters in xfs_growfs_rt_bmblock()
2026-02-19 14:46 [PATCH v3 0/4] xfs: Misc changes to XFS realtime Nirjhar Roy (IBM)
2026-02-19 14:46 ` [PATCH v3 1/4] xfs: Fix xfs_last_rt_bmblock() Nirjhar Roy (IBM)
2026-02-19 14:46 ` [PATCH v3 2/4] xfs: Add a comment in xfs_log_sb() Nirjhar Roy (IBM)
@ 2026-02-19 14:46 ` Nirjhar Roy (IBM)
2026-02-19 15:57 ` Darrick J. Wong
2026-02-19 14:46 ` [PATCH v3 4/4] xfs: Add comments for usages of some macros Nirjhar Roy (IBM)
3 siblings, 1 reply; 11+ messages in thread
From: Nirjhar Roy (IBM) @ 2026-02-19 14:46 UTC (permalink / raw)
To: djwong, hch, cem
Cc: linux-xfs, ritesh.list, ojaswin, nirjhar.roy.lists, nirjhar
From: "Nirjhar Roy (IBM)" <nirjhar.roy.lists@gmail.com>
Update lazy counters in xfs_growfs_rt_bmblock() similar to the way it
is done xfs_growfs_data_private(). This is because the lazy counters are
not always updated and synching the counters will avoid inconsistencies
between frexents and rtextents(total realtime extent count). This will
be more useful once realtime shrink is implemented as this will prevent
some transient state to occur where frexents might be greater than
total rtextents.
Reviewed-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Nirjhar Roy (IBM) <nirjhar.roy.lists@gmail.com>
---
fs/xfs/xfs_rtalloc.c | 9 +++++++++
1 file changed, 9 insertions(+)
diff --git a/fs/xfs/xfs_rtalloc.c b/fs/xfs/xfs_rtalloc.c
index decbd07b94fd..9d451474088c 100644
--- a/fs/xfs/xfs_rtalloc.c
+++ b/fs/xfs/xfs_rtalloc.c
@@ -1047,6 +1047,15 @@ xfs_growfs_rt_bmblock(
*/
xfs_trans_resv_calc(mp, &mp->m_resv);
+ /*
+ * Sync sb counters now to reflect the updated values. Lazy counters are
+ * not always updated and in order to avoid inconsistencies between
+ * frextents and rtextents, it is better to sync the counters.
+ */
+
+ if (xfs_has_lazysbcount(mp))
+ xfs_log_sb(args.tp);
+
error = xfs_trans_commit(args.tp);
if (error)
goto out_free;
--
2.43.5
^ permalink raw reply related [flat|nested] 11+ messages in thread
* [PATCH v3 4/4] xfs: Add comments for usages of some macros.
2026-02-19 14:46 [PATCH v3 0/4] xfs: Misc changes to XFS realtime Nirjhar Roy (IBM)
` (2 preceding siblings ...)
2026-02-19 14:46 ` [PATCH v3 3/4] xfs: Update lazy counters in xfs_growfs_rt_bmblock() Nirjhar Roy (IBM)
@ 2026-02-19 14:46 ` Nirjhar Roy (IBM)
2026-02-19 15:54 ` Darrick J. Wong
3 siblings, 1 reply; 11+ messages in thread
From: Nirjhar Roy (IBM) @ 2026-02-19 14:46 UTC (permalink / raw)
To: djwong, hch, cem
Cc: linux-xfs, ritesh.list, ojaswin, nirjhar.roy.lists, nirjhar
From: "Nirjhar Roy (IBM)" <nirjhar.roy.lists@gmail.com>
Add comments explaining when to use XFS_IS_CORRUPT() and ASSERT()
Reviewed-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Nirjhar Roy (IBM) <nirjhar.roy.lists@gmail.com>
---
fs/xfs/xfs_platform.h | 6 ++++++
1 file changed, 6 insertions(+)
diff --git a/fs/xfs/xfs_platform.h b/fs/xfs/xfs_platform.h
index 1e59bf94d1f2..c9ce0450cf7a 100644
--- a/fs/xfs/xfs_platform.h
+++ b/fs/xfs/xfs_platform.h
@@ -235,6 +235,7 @@ int xfs_rw_bdev(struct block_device *bdev, sector_t sector, unsigned int count,
#ifdef XFS_WARN
+/* Please note that this ASSERT doesn't kill the kernel */
#define ASSERT(expr) \
(likely(expr) ? (void)0 : asswarn(NULL, #expr, __FILE__, __LINE__))
@@ -245,6 +246,11 @@ int xfs_rw_bdev(struct block_device *bdev, sector_t sector, unsigned int count,
#endif /* XFS_WARN */
#endif /* DEBUG */
+/*
+ * Use this to catch metadata corruptions that are not caught by the regular
+ * verifiers. The reason is that the verifiers check corruptions only within
+ * the block.
+ */
#define XFS_IS_CORRUPT(mp, expr) \
(unlikely(expr) ? xfs_corruption_error(#expr, XFS_ERRLEVEL_LOW, (mp), \
NULL, 0, __FILE__, __LINE__, \
--
2.43.5
^ permalink raw reply related [flat|nested] 11+ messages in thread
* Re: [PATCH v3 4/4] xfs: Add comments for usages of some macros.
2026-02-19 14:46 ` [PATCH v3 4/4] xfs: Add comments for usages of some macros Nirjhar Roy (IBM)
@ 2026-02-19 15:54 ` Darrick J. Wong
2026-02-20 6:38 ` Nirjhar Roy (IBM)
0 siblings, 1 reply; 11+ messages in thread
From: Darrick J. Wong @ 2026-02-19 15:54 UTC (permalink / raw)
To: Nirjhar Roy (IBM)
Cc: hch, cem, linux-xfs, ritesh.list, ojaswin, nirjhar.roy.lists
On Thu, Feb 19, 2026 at 08:16:50PM +0530, Nirjhar Roy (IBM) wrote:
> From: "Nirjhar Roy (IBM)" <nirjhar.roy.lists@gmail.com>
>
> Add comments explaining when to use XFS_IS_CORRUPT() and ASSERT()
>
> Reviewed-by: Christoph Hellwig <hch@lst.de>
> Signed-off-by: Nirjhar Roy (IBM) <nirjhar.roy.lists@gmail.com>
> ---
> fs/xfs/xfs_platform.h | 6 ++++++
> 1 file changed, 6 insertions(+)
>
> diff --git a/fs/xfs/xfs_platform.h b/fs/xfs/xfs_platform.h
> index 1e59bf94d1f2..c9ce0450cf7a 100644
> --- a/fs/xfs/xfs_platform.h
> +++ b/fs/xfs/xfs_platform.h
> @@ -235,6 +235,7 @@ int xfs_rw_bdev(struct block_device *bdev, sector_t sector, unsigned int count,
>
> #ifdef XFS_WARN
>
> +/* Please note that this ASSERT doesn't kill the kernel */
It will if the kernel has panic_on_warn set.
> #define ASSERT(expr) \
> (likely(expr) ? (void)0 : asswarn(NULL, #expr, __FILE__, __LINE__))
>
> @@ -245,6 +246,11 @@ int xfs_rw_bdev(struct block_device *bdev, sector_t sector, unsigned int count,
> #endif /* XFS_WARN */
> #endif /* DEBUG */
>
> +/*
> + * Use this to catch metadata corruptions that are not caught by the regular
"...not caught by the block or structure verifiers."
> + * verifiers. The reason is that the verifiers check corruptions only within
> + * the block.
"...only within the scope of the object being verified."
> + */
Other than that, I agree with this comment.
--D
> #define XFS_IS_CORRUPT(mp, expr) \
> (unlikely(expr) ? xfs_corruption_error(#expr, XFS_ERRLEVEL_LOW, (mp), \
> NULL, 0, __FILE__, __LINE__, \
> --
> 2.43.5
>
>
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH v3 3/4] xfs: Update lazy counters in xfs_growfs_rt_bmblock()
2026-02-19 14:46 ` [PATCH v3 3/4] xfs: Update lazy counters in xfs_growfs_rt_bmblock() Nirjhar Roy (IBM)
@ 2026-02-19 15:57 ` Darrick J. Wong
0 siblings, 0 replies; 11+ messages in thread
From: Darrick J. Wong @ 2026-02-19 15:57 UTC (permalink / raw)
To: Nirjhar Roy (IBM)
Cc: hch, cem, linux-xfs, ritesh.list, ojaswin, nirjhar.roy.lists
On Thu, Feb 19, 2026 at 08:16:49PM +0530, Nirjhar Roy (IBM) wrote:
> From: "Nirjhar Roy (IBM)" <nirjhar.roy.lists@gmail.com>
>
> Update lazy counters in xfs_growfs_rt_bmblock() similar to the way it
> is done xfs_growfs_data_private(). This is because the lazy counters are
> not always updated and synching the counters will avoid inconsistencies
> between frexents and rtextents(total realtime extent count). This will
> be more useful once realtime shrink is implemented as this will prevent
> some transient state to occur where frexents might be greater than
> total rtextents.
>
> Reviewed-by: Christoph Hellwig <hch@lst.de>
> Signed-off-by: Nirjhar Roy (IBM) <nirjhar.roy.lists@gmail.com>
This makes sense to me, so
Reviewed-by: "Darrick J. Wong" <djwong@kernel.org>
But I have one more question: does xfs_growfs_rt_zoned need this
treatment as well?
--D
> ---
> fs/xfs/xfs_rtalloc.c | 9 +++++++++
> 1 file changed, 9 insertions(+)
>
> diff --git a/fs/xfs/xfs_rtalloc.c b/fs/xfs/xfs_rtalloc.c
> index decbd07b94fd..9d451474088c 100644
> --- a/fs/xfs/xfs_rtalloc.c
> +++ b/fs/xfs/xfs_rtalloc.c
> @@ -1047,6 +1047,15 @@ xfs_growfs_rt_bmblock(
> */
> xfs_trans_resv_calc(mp, &mp->m_resv);
>
> + /*
> + * Sync sb counters now to reflect the updated values. Lazy counters are
> + * not always updated and in order to avoid inconsistencies between
> + * frextents and rtextents, it is better to sync the counters.
> + */
> +
> + if (xfs_has_lazysbcount(mp))
> + xfs_log_sb(args.tp);
> +
> error = xfs_trans_commit(args.tp);
> if (error)
> goto out_free;
> --
> 2.43.5
>
>
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH v3 2/4] xfs: Add a comment in xfs_log_sb()
2026-02-19 14:46 ` [PATCH v3 2/4] xfs: Add a comment in xfs_log_sb() Nirjhar Roy (IBM)
@ 2026-02-19 15:57 ` Darrick J. Wong
0 siblings, 0 replies; 11+ messages in thread
From: Darrick J. Wong @ 2026-02-19 15:57 UTC (permalink / raw)
To: Nirjhar Roy (IBM)
Cc: hch, cem, linux-xfs, ritesh.list, ojaswin, nirjhar.roy.lists
On Thu, Feb 19, 2026 at 08:16:48PM +0530, Nirjhar Roy (IBM) wrote:
> From: "Nirjhar Roy (IBM)" <nirjhar.roy.lists@gmail.com>
>
> Add a comment explaining why the sb_frextents are updated outside the
> if (xfs_has_lazycount(mp) check even though it is a lazycounter.
> RT groups are supported only in v5 filesystems which always have
> lazycounter enabled - so putting it inside the if(xfs_has_lazycount(mp)
> check is redundant.
>
> Suggested-by: Christoph Hellwig <hch@lst.de>
> Reviewed-by: Christoph Hellwig <hch@lst.de>
> Signed-off-by: Nirjhar Roy (IBM) <nirjhar.roy.lists@gmail.com>
Reviewed-by: "Darrick J. Wong" <djwong@kernel.org>
--D
> ---
> fs/xfs/libxfs/xfs_sb.c | 3 +++
> 1 file changed, 3 insertions(+)
>
> diff --git a/fs/xfs/libxfs/xfs_sb.c b/fs/xfs/libxfs/xfs_sb.c
> index 38d16fe1f6d8..47322adb7690 100644
> --- a/fs/xfs/libxfs/xfs_sb.c
> +++ b/fs/xfs/libxfs/xfs_sb.c
> @@ -1347,6 +1347,9 @@ xfs_log_sb(
> * feature was introduced. This counter can go negative due to the way
> * we handle nearly-lockless reservations, so we must use the _positive
> * variant here to avoid writing out nonsense frextents.
> + *
> + * RT groups are only supported on v5 file systems, which always
> + * have lazy SB counters.
> */
> if (xfs_has_rtgroups(mp) && !xfs_has_zoned(mp)) {
> mp->m_sb.sb_frextents =
> --
> 2.43.5
>
>
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH v3 1/4] xfs: Fix xfs_last_rt_bmblock()
2026-02-19 14:46 ` [PATCH v3 1/4] xfs: Fix xfs_last_rt_bmblock() Nirjhar Roy (IBM)
@ 2026-02-19 21:42 ` Darrick J. Wong
2026-02-20 6:33 ` Nirjhar Roy (IBM)
0 siblings, 1 reply; 11+ messages in thread
From: Darrick J. Wong @ 2026-02-19 21:42 UTC (permalink / raw)
To: Nirjhar Roy (IBM)
Cc: hch, cem, linux-xfs, ritesh.list, ojaswin, nirjhar.roy.lists
On Thu, Feb 19, 2026 at 08:16:47PM +0530, Nirjhar Roy (IBM) wrote:
> From: "Nirjhar Roy (IBM)" <nirjhar.roy.lists@gmail.com>
>
> Bug description:
>
> If the size of the last rtgroup i.e, the rtg passed to
> xfs_last_rt_bmblock() is such that the last rtextent falls in 0th word
> offset of a bmblock of the bitmap file tracking this (last) rtgroup,
> then in that case xfs_last_rt_bmblock() incorrectly returns the next
> bmblock number instead of the current/last used bmblock number.
> When xfs_last_rt_bmblock() incorrectly returns the next bmblock,
> the loop to grow/modify the bmblocks in xfs_growfs_rtg() doesn't
> execute and xfs_growfs basically does a nop in certain cases.
>
> xfs_growfs will do a nop when the new size of the fs will have the same
> number of rtgroups i.e, we are only growing the last rtgroup.
>
> Reproduce:
> $ mkfs.xfs -m metadir=0 -r rtdev=/dev/loop1 /dev/loop0 \
> -r rgsize=32768b,size=32769b -f
/me is confused by metadir=0 and rgsize, but I think that's a red
herring, the key here is to create a filesystem with an rt bitmap that's
exactly one bit larger than a full bitmap block, right? And the
reproducer also seems to work if you pass metadir=1 above.
> $ mount -o rtdev=/dev/loop1 /dev/loop0 /mnt/scratch
> $ xfs_growfs -R $(( 32769 + 1 )) /mnt/scratch
> $ xfs_info /mnt/scratch | grep rtextents
> $ # We can see that rtextents hasn't changed
>
> Fix:
> Fix this by returning the current/last used bmblock when the last
> rtgroup size is not a multiple xfs_rtbitmap_rtx_per_rbmblock()
> and the next bmblock when the rtgroup size is a multiple of
> xfs_rtbitmap_rtx_per_rbmblock() i.e, the existing blocks are
> completely used up.
> Also, I have renamed xfs_last_rt_bmblock() to
> xfs_last_rt_bmblock_to_extend() to signify that this function
> returns the bmblock number to extend and NOT always the last used
> bmblock number.
>
> Reviewed-by: Christoph Hellwig <hch@lst.de>
> Signed-off-by: Nirjhar Roy (IBM) <nirjhar.roy.lists@gmail.com>
> ---
> fs/xfs/xfs_rtalloc.c | 30 ++++++++++++++++++++++++------
> 1 file changed, 24 insertions(+), 6 deletions(-)
>
> diff --git a/fs/xfs/xfs_rtalloc.c b/fs/xfs/xfs_rtalloc.c
> index 90a94a5b6f7e..decbd07b94fd 100644
> --- a/fs/xfs/xfs_rtalloc.c
> +++ b/fs/xfs/xfs_rtalloc.c
> @@ -1079,17 +1079,27 @@ xfs_last_rtgroup_extents(
> }
>
> /*
> - * Calculate the last rbmblock currently used.
> + * This will return the bitmap block number (indexed at 0) that will be
> + * extended/modified. There are 2 cases here:
> + * 1. The size of the rtg is such that it is a multiple of
> + * xfs_rtbitmap_rtx_per_rbmblock() i.e, an integral number of bitmap blocks
> + * are completely filled up. In this case, we should return
> + * 1 + (the last used bitmap block number).
Let me try to work through case #1. In this case, there are 32768 rtx
per rtbitmap block and the rt volume is 32768 extents.
xfs_rtbitmap_blockcount_len turns into:
howmany_64(32768, 32768) == 1
In the new code, bmbno will be set to 1-1==0, and mod will be 0, so we
bump bmbno and return 1. IOWs, the growfsrt starts expanding from
rtbitmap block 1.
> + * 2. The size of the rtg is not an multiple of xfs_rtbitmap_rtx_per_rbmblock().
> + * Here we will return the block number of last used block number. In this
> + * case, we will modify the last used bitmap block to extend the size of the
> + * rtgroup.
For case 2, there might be 32768 rtx per rtbitmap block, but now the rt
volume is 32769 rtx. _blockcount_len becomes:
howmany_64(32769, 32768) == 2
In the new code, bmbno will be set to 1. mod will be 1, so we don't
increment bmbno and return 1, so the growfs again starts expanding from
rtbitmap block 1.
Now let's say the rt volume is 32767 rtx. _blockcount_len becomes:
howmany_64(32767, 32768) == 1
bmbno is set to 0. mod now is 32767, so here we also leave bmbno alone.
We return 0, so the growfsrt starts at block 0.
> *
> * This also deals with the case where there were no rtextents before.
What about this case? There are 32768 rtx per rtbitmap block, but the
rt volume is 0 rtx. I think in this case sb_rgcount will be 0, so we
don't do any of the division stuff and simply return 0.
(This is effectively case #3)
I think the logic is correct.
Reviewed-by: "Darrick J. Wong" <djwong@kernel.org>
--D
> */
> static xfs_fileoff_t
> -xfs_last_rt_bmblock(
> +xfs_last_rt_bmblock_to_extend(
> struct xfs_rtgroup *rtg)
> {
> struct xfs_mount *mp = rtg_mount(rtg);
> xfs_rgnumber_t rgno = rtg_rgno(rtg);
> xfs_fileoff_t bmbno = 0;
> + unsigned int mod = 0;
>
> ASSERT(!mp->m_sb.sb_rgcount || rgno >= mp->m_sb.sb_rgcount - 1);
>
> @@ -1097,9 +1107,16 @@ xfs_last_rt_bmblock(
> xfs_rtxnum_t nrext = xfs_last_rtgroup_extents(mp);
>
> /* Also fill up the previous block if not entirely full. */
> - bmbno = xfs_rtbitmap_blockcount_len(mp, nrext);
> - if (xfs_rtx_to_rbmword(mp, nrext) != 0)
> - bmbno--;
> + /* We are doing a -1 to convert it to a 0 based index */
> + bmbno = xfs_rtbitmap_blockcount_len(mp, nrext) - 1;
> + div_u64_rem(nrext, xfs_rtbitmap_rtx_per_rbmblock(mp), &mod);
> + /*
> + * mod = 0 means that all the current blocks are full. So
> + * return the next block number to be used for the rtgroup
> + * growth.
> + */
> + if (mod == 0)
> + bmbno++;
> }
>
> return bmbno;
> @@ -1204,7 +1221,8 @@ xfs_growfs_rtg(
> goto out_rele;
> }
>
> - for (bmbno = xfs_last_rt_bmblock(rtg); bmbno < bmblocks; bmbno++) {
> + for (bmbno = xfs_last_rt_bmblock_to_extend(rtg); bmbno < bmblocks;
> + bmbno++) {
> error = xfs_growfs_rt_bmblock(rtg, nrblocks, rextsize, bmbno);
> if (error)
> goto out_error;
> --
> 2.43.5
>
>
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH v3 1/4] xfs: Fix xfs_last_rt_bmblock()
2026-02-19 21:42 ` Darrick J. Wong
@ 2026-02-20 6:33 ` Nirjhar Roy (IBM)
0 siblings, 0 replies; 11+ messages in thread
From: Nirjhar Roy (IBM) @ 2026-02-20 6:33 UTC (permalink / raw)
To: Darrick J. Wong, Nirjhar Roy (IBM)
Cc: hch, cem, linux-xfs, ritesh.list, ojaswin
On 2/20/26 03:12, Darrick J. Wong wrote:
> On Thu, Feb 19, 2026 at 08:16:47PM +0530, Nirjhar Roy (IBM) wrote:
>> From: "Nirjhar Roy (IBM)" <nirjhar.roy.lists@gmail.com>
>>
>> Bug description:
>>
>> If the size of the last rtgroup i.e, the rtg passed to
>> xfs_last_rt_bmblock() is such that the last rtextent falls in 0th word
>> offset of a bmblock of the bitmap file tracking this (last) rtgroup,
>> then in that case xfs_last_rt_bmblock() incorrectly returns the next
>> bmblock number instead of the current/last used bmblock number.
>> When xfs_last_rt_bmblock() incorrectly returns the next bmblock,
>> the loop to grow/modify the bmblocks in xfs_growfs_rtg() doesn't
>> execute and xfs_growfs basically does a nop in certain cases.
>>
>> xfs_growfs will do a nop when the new size of the fs will have the same
>> number of rtgroups i.e, we are only growing the last rtgroup.
>>
>> Reproduce:
>> $ mkfs.xfs -m metadir=0 -r rtdev=/dev/loop1 /dev/loop0 \
>> -r rgsize=32768b,size=32769b -f
> /me is confused by metadir=0 and rgsize, but I think that's a red
> herring, the key here is to create a filesystem with an rt bitmap that's
> exactly one bit larger than a full bitmap block, right? And the
> reproducer also seems to work if you pass metadir=1 above.
Yeah, right. The logic works with both metadir=0/1. I tried with
metadir=0 just to keep things simple. Also, rgsize with metadir=0 was a
mistake. I will update the commit message in the next revision.
>
>> $ mount -o rtdev=/dev/loop1 /dev/loop0 /mnt/scratch
>> $ xfs_growfs -R $(( 32769 + 1 )) /mnt/scratch
>> $ xfs_info /mnt/scratch | grep rtextents
>> $ # We can see that rtextents hasn't changed
>>
>> Fix:
>> Fix this by returning the current/last used bmblock when the last
>> rtgroup size is not a multiple xfs_rtbitmap_rtx_per_rbmblock()
>> and the next bmblock when the rtgroup size is a multiple of
>> xfs_rtbitmap_rtx_per_rbmblock() i.e, the existing blocks are
>> completely used up.
>> Also, I have renamed xfs_last_rt_bmblock() to
>> xfs_last_rt_bmblock_to_extend() to signify that this function
>> returns the bmblock number to extend and NOT always the last used
>> bmblock number.
>>
>> Reviewed-by: Christoph Hellwig <hch@lst.de>
>> Signed-off-by: Nirjhar Roy (IBM) <nirjhar.roy.lists@gmail.com>
>> ---
>> fs/xfs/xfs_rtalloc.c | 30 ++++++++++++++++++++++++------
>> 1 file changed, 24 insertions(+), 6 deletions(-)
>>
>> diff --git a/fs/xfs/xfs_rtalloc.c b/fs/xfs/xfs_rtalloc.c
>> index 90a94a5b6f7e..decbd07b94fd 100644
>> --- a/fs/xfs/xfs_rtalloc.c
>> +++ b/fs/xfs/xfs_rtalloc.c
>> @@ -1079,17 +1079,27 @@ xfs_last_rtgroup_extents(
>> }
>>
>> /*
>> - * Calculate the last rbmblock currently used.
>> + * This will return the bitmap block number (indexed at 0) that will be
>> + * extended/modified. There are 2 cases here:
>> + * 1. The size of the rtg is such that it is a multiple of
>> + * xfs_rtbitmap_rtx_per_rbmblock() i.e, an integral number of bitmap blocks
>> + * are completely filled up. In this case, we should return
>> + * 1 + (the last used bitmap block number).
> Let me try to work through case #1. In this case, there are 32768 rtx
> per rtbitmap block and the rt volume is 32768 extents.
> xfs_rtbitmap_blockcount_len turns into:
>
> howmany_64(32768, 32768) == 1
>
> In the new code, bmbno will be set to 1-1==0, and mod will be 0, so we
> bump bmbno and return 1. IOWs, the growfsrt starts expanding from
> rtbitmap block 1.
>
>> + * 2. The size of the rtg is not an multiple of xfs_rtbitmap_rtx_per_rbmblock().
>> + * Here we will return the block number of last used block number. In this
>> + * case, we will modify the last used bitmap block to extend the size of the
>> + * rtgroup.
> For case 2, there might be 32768 rtx per rtbitmap block, but now the rt
> volume is 32769 rtx. _blockcount_len becomes:
>
> howmany_64(32769, 32768) == 2
>
> In the new code, bmbno will be set to 1. mod will be 1, so we don't
> increment bmbno and return 1, so the growfs again starts expanding from
> rtbitmap block 1.
>
> Now let's say the rt volume is 32767 rtx. _blockcount_len becomes:
>
> howmany_64(32767, 32768) == 1
>
> bmbno is set to 0. mod now is 32767, so here we also leave bmbno alone.
> We return 0, so the growfsrt starts at block 0.
>
>> *
>> * This also deals with the case where there were no rtextents before.
> What about this case? There are 32768 rtx per rtbitmap block, but the
> rt volume is 0 rtx. I think in this case sb_rgcount will be 0, so we
> don't do any of the division stuff and simply return 0.
>
> (This is effectively case #3)
>
> I think the logic is correct.
> Reviewed-by: "Darrick J. Wong" <djwong@kernel.org>
Thank you for the dry run here.
--NR
>
> --D
>
>> */
>> static xfs_fileoff_t
>> -xfs_last_rt_bmblock(
>> +xfs_last_rt_bmblock_to_extend(
>> struct xfs_rtgroup *rtg)
>> {
>> struct xfs_mount *mp = rtg_mount(rtg);
>> xfs_rgnumber_t rgno = rtg_rgno(rtg);
>> xfs_fileoff_t bmbno = 0;
>> + unsigned int mod = 0;
>>
>> ASSERT(!mp->m_sb.sb_rgcount || rgno >= mp->m_sb.sb_rgcount - 1);
>>
>> @@ -1097,9 +1107,16 @@ xfs_last_rt_bmblock(
>> xfs_rtxnum_t nrext = xfs_last_rtgroup_extents(mp);
>>
>> /* Also fill up the previous block if not entirely full. */
>> - bmbno = xfs_rtbitmap_blockcount_len(mp, nrext);
>> - if (xfs_rtx_to_rbmword(mp, nrext) != 0)
>> - bmbno--;
>> + /* We are doing a -1 to convert it to a 0 based index */
>> + bmbno = xfs_rtbitmap_blockcount_len(mp, nrext) - 1;
>> + div_u64_rem(nrext, xfs_rtbitmap_rtx_per_rbmblock(mp), &mod);
>> + /*
>> + * mod = 0 means that all the current blocks are full. So
>> + * return the next block number to be used for the rtgroup
>> + * growth.
>> + */
>> + if (mod == 0)
>> + bmbno++;
>> }
>>
>> return bmbno;
>> @@ -1204,7 +1221,8 @@ xfs_growfs_rtg(
>> goto out_rele;
>> }
>>
>> - for (bmbno = xfs_last_rt_bmblock(rtg); bmbno < bmblocks; bmbno++) {
>> + for (bmbno = xfs_last_rt_bmblock_to_extend(rtg); bmbno < bmblocks;
>> + bmbno++) {
>> error = xfs_growfs_rt_bmblock(rtg, nrblocks, rextsize, bmbno);
>> if (error)
>> goto out_error;
>> --
>> 2.43.5
>>
>>
--
Nirjhar Roy
Linux Kernel Developer
IBM, Bangalore
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH v3 4/4] xfs: Add comments for usages of some macros.
2026-02-19 15:54 ` Darrick J. Wong
@ 2026-02-20 6:38 ` Nirjhar Roy (IBM)
0 siblings, 0 replies; 11+ messages in thread
From: Nirjhar Roy (IBM) @ 2026-02-20 6:38 UTC (permalink / raw)
To: Darrick J. Wong, Nirjhar Roy (IBM)
Cc: hch, cem, linux-xfs, ritesh.list, ojaswin
On 2/19/26 21:24, Darrick J. Wong wrote:
> On Thu, Feb 19, 2026 at 08:16:50PM +0530, Nirjhar Roy (IBM) wrote:
>> From: "Nirjhar Roy (IBM)" <nirjhar.roy.lists@gmail.com>
>>
>> Add comments explaining when to use XFS_IS_CORRUPT() and ASSERT()
>>
>> Reviewed-by: Christoph Hellwig <hch@lst.de>
>> Signed-off-by: Nirjhar Roy (IBM) <nirjhar.roy.lists@gmail.com>
>> ---
>> fs/xfs/xfs_platform.h | 6 ++++++
>> 1 file changed, 6 insertions(+)
>>
>> diff --git a/fs/xfs/xfs_platform.h b/fs/xfs/xfs_platform.h
>> index 1e59bf94d1f2..c9ce0450cf7a 100644
>> --- a/fs/xfs/xfs_platform.h
>> +++ b/fs/xfs/xfs_platform.h
>> @@ -235,6 +235,7 @@ int xfs_rw_bdev(struct block_device *bdev, sector_t sector, unsigned int count,
>>
>> #ifdef XFS_WARN
>>
>> +/* Please note that this ASSERT doesn't kill the kernel */
> It will if the kernel has panic_on_warn set.
>
>> #define ASSERT(expr) \
>> (likely(expr) ? (void)0 : asswarn(NULL, #expr, __FILE__, __LINE__))
>>
>> @@ -245,6 +246,11 @@ int xfs_rw_bdev(struct block_device *bdev, sector_t sector, unsigned int count,
>> #endif /* XFS_WARN */
>> #endif /* DEBUG */
>>
>> +/*
>> + * Use this to catch metadata corruptions that are not caught by the regular
> "...not caught by the block or structure verifiers."
>
>> + * verifiers. The reason is that the verifiers check corruptions only within
>> + * the block.
> "...only within the scope of the object being verified."
>
>> + */
> Other than that, I agree with this comment.
Sure, I will update the comment as per your suggestions. Thank you.
--NR
>
> --D
>
>> #define XFS_IS_CORRUPT(mp, expr) \
>> (unlikely(expr) ? xfs_corruption_error(#expr, XFS_ERRLEVEL_LOW, (mp), \
>> NULL, 0, __FILE__, __LINE__, \
>> --
>> 2.43.5
>>
>>
--
Nirjhar Roy
Linux Kernel Developer
IBM, Bangalore
^ permalink raw reply [flat|nested] 11+ messages in thread
end of thread, other threads:[~2026-02-20 6:39 UTC | newest]
Thread overview: 11+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-02-19 14:46 [PATCH v3 0/4] xfs: Misc changes to XFS realtime Nirjhar Roy (IBM)
2026-02-19 14:46 ` [PATCH v3 1/4] xfs: Fix xfs_last_rt_bmblock() Nirjhar Roy (IBM)
2026-02-19 21:42 ` Darrick J. Wong
2026-02-20 6:33 ` Nirjhar Roy (IBM)
2026-02-19 14:46 ` [PATCH v3 2/4] xfs: Add a comment in xfs_log_sb() Nirjhar Roy (IBM)
2026-02-19 15:57 ` Darrick J. Wong
2026-02-19 14:46 ` [PATCH v3 3/4] xfs: Update lazy counters in xfs_growfs_rt_bmblock() Nirjhar Roy (IBM)
2026-02-19 15:57 ` Darrick J. Wong
2026-02-19 14:46 ` [PATCH v3 4/4] xfs: Add comments for usages of some macros Nirjhar Roy (IBM)
2026-02-19 15:54 ` Darrick J. Wong
2026-02-20 6:38 ` Nirjhar Roy (IBM)
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox