* [PATCHSET 1/2] xfsprogs: new libxfs code from kernel 6.19
@ 2026-02-19 23:43 Darrick J. Wong
2026-02-19 23:43 ` [PATCH 01/12] xfs: error tag to force zeroing on debug kernels Darrick J. Wong
` (11 more replies)
0 siblings, 12 replies; 16+ messages in thread
From: Darrick J. Wong @ 2026-02-19 23:43 UTC (permalink / raw)
To: djwong, aalbersh
Cc: brauner, axboe, dlemoal, cmaiolino, cem, hans.holmberg, bfoster,
martin.petersen, hch, linux-xfs
Hi all,
Port kernel libxfs code to userspace.
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
xfsprogs git tree:
https://git.kernel.org/cgit/linux/kernel/git/djwong/xfsprogs-dev.git/log/?h=libxfs-6.19-sync
---
Commits in this patchset:
* xfs: error tag to force zeroing on debug kernels
* xfs: use blkdev_report_zones_cached()
* xfs: add a xfs_groups_to_rfsbs helper
* xfs: use a lockref for the xfs_dquot reference count
* xfs: add a XLOG_CYCLE_DATA_SIZE constant
* xfs: remove xlog_in_core_2_t
* xfs: remove the xlog_rec_header_t typedef
* xfs: remove xarray mark for reclaimable zones
* xfs: validate that zoned RT devices are zone aligned
* xfs: mark __xfs_rtgroup_extents static
* xfs: fix an overly long line in xfs_rtgroup_calc_geometry
* xfs: set max_agbno to allow sparse alloc of last full inode chunk
---
include/libxlog.h | 4 ++-
libxfs/xfs_errortag.h | 6 +++--
libxfs/xfs_group.h | 9 ++++++++
libxfs/xfs_log_format.h | 38 ++++++++++++++++----------------
libxfs/xfs_ondisk.h | 6 +++--
libxfs/xfs_quota_defs.h | 4 +--
libxfs/xfs_rtgroup.h | 16 +++++++-------
configure.ac | 1 +
include/builddefs.in | 1 +
libxfs/Makefile | 4 +++
libxfs/rdwr.c | 2 +-
libxfs/xfs_ialloc.c | 11 +++++----
libxfs/xfs_rtgroup.c | 53 +++++++++++++++++++++++----------------------
libxfs/xfs_sb.c | 15 +++++++++++++
libxfs/xfs_zones.c | 1 +
libxlog/util.c | 6 +++--
libxlog/xfs_log_recover.c | 52 +++++++++++++++++++++++++-------------------
logprint/log_dump.c | 4 ++-
m4/package_libcdev.m4 | 18 +++++++++++++++
19 files changed, 155 insertions(+), 96 deletions(-)
^ permalink raw reply [flat|nested] 16+ messages in thread
* [PATCH 01/12] xfs: error tag to force zeroing on debug kernels
2026-02-19 23:43 [PATCHSET 1/2] xfsprogs: new libxfs code from kernel 6.19 Darrick J. Wong
@ 2026-02-19 23:43 ` Darrick J. Wong
2026-02-19 23:44 ` [PATCH 02/12] xfs: use blkdev_report_zones_cached() Darrick J. Wong
` (10 subsequent siblings)
11 siblings, 0 replies; 16+ messages in thread
From: Darrick J. Wong @ 2026-02-19 23:43 UTC (permalink / raw)
To: djwong, aalbersh; +Cc: bfoster, brauner, hch, linux-xfs
From: Brian Foster <bfoster@redhat.com>
Source kernel commit: 66d78a11479cfea00e8d1d9d3e33f3db1597e6bf
iomap_zero_range() has to cover various corner cases that are
difficult to test on production kernels because it is used in fairly
limited use cases. For example, it is currently only used by XFS and
mostly only in partial block zeroing cases.
While it's possible to test most of these functional cases, we can
provide more robust test coverage by co-opting fallocate zero range
to invoke zeroing of the entire range instead of the more efficient
block punch/allocate sequence. Add an errortag to occasionally
invoke forced zeroing.
Signed-off-by: Brian Foster <bfoster@redhat.com>
Reviewed-by: Christoph Hellwig <hch@lst.de>
Reviewed-by: Darrick J. Wong <djwong@kernel.org>
Signed-off-by: Christian Brauner <brauner@kernel.org>
---
libxfs/xfs_errortag.h | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/libxfs/xfs_errortag.h b/libxfs/xfs_errortag.h
index de840abc0bcd44..57e47077c75a2a 100644
--- a/libxfs/xfs_errortag.h
+++ b/libxfs/xfs_errortag.h
@@ -73,7 +73,8 @@
#define XFS_ERRTAG_WRITE_DELAY_MS 43
#define XFS_ERRTAG_EXCHMAPS_FINISH_ONE 44
#define XFS_ERRTAG_METAFILE_RESV_CRITICAL 45
-#define XFS_ERRTAG_MAX 46
+#define XFS_ERRTAG_FORCE_ZERO_RANGE 46
+#define XFS_ERRTAG_MAX 47
/*
* Random factors for above tags, 1 means always, 2 means 1/2 time, etc.
@@ -133,7 +134,8 @@ XFS_ERRTAG(ATTR_LEAF_TO_NODE, attr_leaf_to_node, 1) \
XFS_ERRTAG(WB_DELAY_MS, wb_delay_ms, 3000) \
XFS_ERRTAG(WRITE_DELAY_MS, write_delay_ms, 3000) \
XFS_ERRTAG(EXCHMAPS_FINISH_ONE, exchmaps_finish_one, 1) \
-XFS_ERRTAG(METAFILE_RESV_CRITICAL, metafile_resv_crit, 4)
+XFS_ERRTAG(METAFILE_RESV_CRITICAL, metafile_resv_crit, 4) \
+XFS_ERRTAG(FORCE_ZERO_RANGE, force_zero_range, 4)
#endif /* XFS_ERRTAG */
#endif /* __XFS_ERRORTAG_H_ */
^ permalink raw reply related [flat|nested] 16+ messages in thread
* [PATCH 02/12] xfs: use blkdev_report_zones_cached()
2026-02-19 23:43 [PATCHSET 1/2] xfsprogs: new libxfs code from kernel 6.19 Darrick J. Wong
2026-02-19 23:43 ` [PATCH 01/12] xfs: error tag to force zeroing on debug kernels Darrick J. Wong
@ 2026-02-19 23:44 ` Darrick J. Wong
2026-02-20 15:36 ` Christoph Hellwig
2026-02-19 23:44 ` [PATCH 03/12] xfs: add a xfs_groups_to_rfsbs helper Darrick J. Wong
` (9 subsequent siblings)
11 siblings, 1 reply; 16+ messages in thread
From: Darrick J. Wong @ 2026-02-19 23:44 UTC (permalink / raw)
To: djwong, aalbersh; +Cc: axboe, dlemoal, martin.petersen, linux-xfs
From: Damien Le Moal <dlemoal@kernel.org>
Source kernel commit: e04ccfc28252f181ea8d469d834b48e7dece65b2
Modify xfs_mount_zones() to replace the call to blkdev_report_zones()
with blkdev_report_zones_cached() to speed-up mount operations.
Since this causes xfs_zone_validate_seq() to see zones with the
BLK_ZONE_COND_ACTIVE condition, this function is also modified to acept
this condition as valid.
With this change, mounting a freshly formatted large capacity (30 TB)
SMR HDD completes under 2s compared to over 4.7s before.
Signed-off-by: Damien Le Moal <dlemoal@kernel.org>
Reviewed-by: Martin K. Petersen <martin.petersen@oracle.com>
Signed-off-by: Jens Axboe <axboe@kernel.dk>
---
configure.ac | 1 +
include/builddefs.in | 1 +
libxfs/Makefile | 4 ++++
libxfs/xfs_zones.c | 1 +
m4/package_libcdev.m4 | 18 ++++++++++++++++++
5 files changed, 25 insertions(+)
diff --git a/configure.ac b/configure.ac
index a8b8f7d5066fb6..076098ae025093 100644
--- a/configure.ac
+++ b/configure.ac
@@ -182,6 +182,7 @@ AC_CONFIG_UDEV_RULE_DIR
AC_HAVE_BLKID_TOPO
AC_HAVE_TRIVIAL_AUTO_VAR_INIT
AC_STRERROR_R_RETURNS_STRING
+AC_HAVE_BLK_ZONE_COND_ACTIVE
if test "$enable_ubsan" = "yes" || test "$enable_ubsan" = "probe"; then
AC_PACKAGE_CHECK_UBSAN
diff --git a/include/builddefs.in b/include/builddefs.in
index b38a099b7d525a..f598343abb50b4 100644
--- a/include/builddefs.in
+++ b/include/builddefs.in
@@ -118,6 +118,7 @@ HAVE_UDEV = @have_udev@
UDEV_RULE_DIR = @udev_rule_dir@
HAVE_LIBURCU_ATOMIC64 = @have_liburcu_atomic64@
STRERROR_R_RETURNS_STRING = @strerror_r_returns_string@
+HAVE_BLK_ZONE_COND_ACTIVE = @have_blk_zone_cond_active@
GCCFLAGS = -funsigned-char -fno-strict-aliasing -Wall
# -Wbitwise -Wno-transparent-union -Wno-old-initializer -Wno-decl
diff --git a/libxfs/Makefile b/libxfs/Makefile
index 61c43529b532b6..eed37a21be24ed 100644
--- a/libxfs/Makefile
+++ b/libxfs/Makefile
@@ -167,6 +167,10 @@ ifeq ($(HAVE_GETRANDOM_NONBLOCK),yes)
LCFLAGS += -DHAVE_GETRANDOM_NONBLOCK
endif
+ifneq ($(HAVE_BLK_ZONE_COND_ACTIVE),yes)
+LCFLAGS += -DBLK_ZONE_COND_ACTIVE=0xff
+endif
+
FCFLAGS = -I.
LTLIBS = $(LIBPTHREAD) $(LIBRT)
diff --git a/libxfs/xfs_zones.c b/libxfs/xfs_zones.c
index 7a81d83f5b3ef7..99ae05ce7473e3 100644
--- a/libxfs/xfs_zones.c
+++ b/libxfs/xfs_zones.c
@@ -97,6 +97,7 @@ xfs_zone_validate_seq(
case BLK_ZONE_COND_IMP_OPEN:
case BLK_ZONE_COND_EXP_OPEN:
case BLK_ZONE_COND_CLOSED:
+ case BLK_ZONE_COND_ACTIVE:
return xfs_zone_validate_wp(zone, rtg, write_pointer);
case BLK_ZONE_COND_FULL:
return xfs_zone_validate_full(zone, rtg, write_pointer);
diff --git a/m4/package_libcdev.m4 b/m4/package_libcdev.m4
index c5538c30d2518a..83233ec2ad4d5e 100644
--- a/m4/package_libcdev.m4
+++ b/m4/package_libcdev.m4
@@ -347,3 +347,21 @@ puts(strerror_r(0, buf, sizeof(buf)));
CFLAGS="$OLD_CFLAGS"
AC_SUBST(strerror_r_returns_string)
])
+
+#
+# Check if blkzoned.h defines BLK_ZONE_COND_ACTIVE
+#
+AC_DEFUN([AC_HAVE_BLK_ZONE_COND_ACTIVE],
+ [AC_MSG_CHECKING([for BLK_ZONE_COND_ACTIVE])
+ AC_LINK_IFELSE(
+ [AC_LANG_PROGRAM([[
+#define _GNU_SOURCE
+#include <linux/blkzoned.h>
+ ]], [[
+int foo = BLK_ZONE_COND_ACTIVE;
+ ]])
+ ], have_blk_zone_cond_active=yes
+ AC_MSG_RESULT(yes),
+ AC_MSG_RESULT(no))
+ AC_SUBST(have_blk_zone_cond_active)
+ ])
^ permalink raw reply related [flat|nested] 16+ messages in thread
* [PATCH 03/12] xfs: add a xfs_groups_to_rfsbs helper
2026-02-19 23:43 [PATCHSET 1/2] xfsprogs: new libxfs code from kernel 6.19 Darrick J. Wong
2026-02-19 23:43 ` [PATCH 01/12] xfs: error tag to force zeroing on debug kernels Darrick J. Wong
2026-02-19 23:44 ` [PATCH 02/12] xfs: use blkdev_report_zones_cached() Darrick J. Wong
@ 2026-02-19 23:44 ` Darrick J. Wong
2026-02-19 23:44 ` [PATCH 04/12] xfs: use a lockref for the xfs_dquot reference count Darrick J. Wong
` (8 subsequent siblings)
11 siblings, 0 replies; 16+ messages in thread
From: Darrick J. Wong @ 2026-02-19 23:44 UTC (permalink / raw)
To: djwong, aalbersh; +Cc: cem, hch, linux-xfs
From: Christoph Hellwig <hch@lst.de>
Source kernel commit: 0ec73eb3f12350799c4b3fb764225f6e38b42d1e
Plus a rtgroup wrapper and use that to avoid overflows when converting
zone/rtg counts to block counts.
Signed-off-by: Christoph Hellwig <hch@lst.de>
Reviewed-by: Darrick J. Wong <djwong@kernel.org>
Signed-off-by: Carlos Maiolino <cem@kernel.org>
---
libxfs/xfs_group.h | 9 +++++++++
libxfs/xfs_rtgroup.h | 8 ++++++++
2 files changed, 17 insertions(+)
diff --git a/libxfs/xfs_group.h b/libxfs/xfs_group.h
index 4423932a231300..4ae638f1c2c519 100644
--- a/libxfs/xfs_group.h
+++ b/libxfs/xfs_group.h
@@ -98,6 +98,15 @@ xfs_group_max_blocks(
return xg->xg_mount->m_groups[xg->xg_type].blocks;
}
+static inline xfs_rfsblock_t
+xfs_groups_to_rfsbs(
+ struct xfs_mount *mp,
+ uint32_t nr_groups,
+ enum xfs_group_type type)
+{
+ return (xfs_rfsblock_t)mp->m_groups[type].blocks * nr_groups;
+}
+
static inline xfs_fsblock_t
xfs_group_start_fsb(
struct xfs_group *xg)
diff --git a/libxfs/xfs_rtgroup.h b/libxfs/xfs_rtgroup.h
index d4fcf591e63d08..a94e925ae67cb6 100644
--- a/libxfs/xfs_rtgroup.h
+++ b/libxfs/xfs_rtgroup.h
@@ -371,4 +371,12 @@ static inline int xfs_initialize_rtgroups(struct xfs_mount *mp,
# define xfs_rtgroup_get_geometry(rtg, rgeo) (-EOPNOTSUPP)
#endif /* CONFIG_XFS_RT */
+static inline xfs_rfsblock_t
+xfs_rtgs_to_rfsbs(
+ struct xfs_mount *mp,
+ uint32_t nr_groups)
+{
+ return xfs_groups_to_rfsbs(mp, nr_groups, XG_TYPE_RTG);
+}
+
#endif /* __LIBXFS_RTGROUP_H */
^ permalink raw reply related [flat|nested] 16+ messages in thread
* [PATCH 04/12] xfs: use a lockref for the xfs_dquot reference count
2026-02-19 23:43 [PATCHSET 1/2] xfsprogs: new libxfs code from kernel 6.19 Darrick J. Wong
` (2 preceding siblings ...)
2026-02-19 23:44 ` [PATCH 03/12] xfs: add a xfs_groups_to_rfsbs helper Darrick J. Wong
@ 2026-02-19 23:44 ` Darrick J. Wong
2026-02-19 23:44 ` [PATCH 05/12] xfs: add a XLOG_CYCLE_DATA_SIZE constant Darrick J. Wong
` (7 subsequent siblings)
11 siblings, 0 replies; 16+ messages in thread
From: Darrick J. Wong @ 2026-02-19 23:44 UTC (permalink / raw)
To: djwong, aalbersh; +Cc: cem, hch, linux-xfs
From: Christoph Hellwig <hch@lst.de>
Source kernel commit: 0c5e80bd579f7bec3704bad6c1f72b13b0d73b53
The xfs_dquot structure currently uses the anti-pattern of using the
in-object lock that protects the content to also serialize reference
count updates for the structure, leading to a cumbersome free path.
This is partially papered over by the fact that we never free the dquot
directly but always through the LRU. Switch to use a lockref instead and
move the reference counter manipulations out of q_qlock.
To make this work, xfs_qm_flush_one and xfs_qm_flush_one are converted to
acquire a dquot reference while flushing to integrate with the lockref
"get if not dead" scheme.
Signed-off-by: Christoph Hellwig <hch@lst.de>
Reviewed-by: Darrick J. Wong <djwong@kernel.org>
Signed-off-by: Carlos Maiolino <cem@kernel.org>
---
libxfs/xfs_quota_defs.h | 4 +---
1 file changed, 1 insertion(+), 3 deletions(-)
diff --git a/libxfs/xfs_quota_defs.h b/libxfs/xfs_quota_defs.h
index 763d941a8420c5..551d7ae46c5c21 100644
--- a/libxfs/xfs_quota_defs.h
+++ b/libxfs/xfs_quota_defs.h
@@ -29,11 +29,9 @@ typedef uint8_t xfs_dqtype_t;
* flags for q_flags field in the dquot.
*/
#define XFS_DQFLAG_DIRTY (1u << 0) /* dquot is dirty */
-#define XFS_DQFLAG_FREEING (1u << 1) /* dquot is being torn down */
#define XFS_DQFLAG_STRINGS \
- { XFS_DQFLAG_DIRTY, "DIRTY" }, \
- { XFS_DQFLAG_FREEING, "FREEING" }
+ { XFS_DQFLAG_DIRTY, "DIRTY" }
/*
* We have the possibility of all three quota types being active at once, and
^ permalink raw reply related [flat|nested] 16+ messages in thread
* [PATCH 05/12] xfs: add a XLOG_CYCLE_DATA_SIZE constant
2026-02-19 23:43 [PATCHSET 1/2] xfsprogs: new libxfs code from kernel 6.19 Darrick J. Wong
` (3 preceding siblings ...)
2026-02-19 23:44 ` [PATCH 04/12] xfs: use a lockref for the xfs_dquot reference count Darrick J. Wong
@ 2026-02-19 23:44 ` Darrick J. Wong
2026-02-19 23:45 ` [PATCH 06/12] xfs: remove xlog_in_core_2_t Darrick J. Wong
` (6 subsequent siblings)
11 siblings, 0 replies; 16+ messages in thread
From: Darrick J. Wong @ 2026-02-19 23:44 UTC (permalink / raw)
To: djwong, aalbersh; +Cc: cem, cmaiolino, hch, linux-xfs
From: Christoph Hellwig <hch@lst.de>
Source kernel commit: 74d975ed6c9f8ba44179502a8ad5a839b38e8630
The XLOG_HEADER_CYCLE_SIZE / BBSIZE expression is used a lot
in the log code, give it a symbolic name.
Signed-off-by: Christoph Hellwig <hch@lst.de>
Reviewed-by: Darrick J. Wong <djwong@kernel.org>
Reviewed-by: Carlos Maiolino <cmaiolino@redhat.com>
Signed-off-by: Carlos Maiolino <cem@kernel.org>
---
libxfs/xfs_log_format.h | 5 +++--
libxlog/xfs_log_recover.c | 6 +++---
2 files changed, 6 insertions(+), 5 deletions(-)
diff --git a/libxfs/xfs_log_format.h b/libxfs/xfs_log_format.h
index 6c50cb2ece1972..91a841ea5bb36d 100644
--- a/libxfs/xfs_log_format.h
+++ b/libxfs/xfs_log_format.h
@@ -31,6 +31,7 @@ typedef uint32_t xlog_tid_t;
#define XLOG_BIG_RECORD_BSIZE (32*1024) /* 32k buffers */
#define XLOG_MAX_RECORD_BSIZE (256*1024)
#define XLOG_HEADER_CYCLE_SIZE (32*1024) /* cycle data in header */
+#define XLOG_CYCLE_DATA_SIZE (XLOG_HEADER_CYCLE_SIZE / BBSIZE)
#define XLOG_MIN_RECORD_BSHIFT 14 /* 16384 == 1 << 14 */
#define XLOG_BIG_RECORD_BSHIFT 15 /* 32k == 1 << 15 */
#define XLOG_MAX_RECORD_BSHIFT 18 /* 256k == 1 << 18 */
@@ -135,7 +136,7 @@ typedef struct xlog_rec_header {
__le32 h_crc; /* crc of log record : 4 */
__be32 h_prev_block; /* block number to previous LR : 4 */
__be32 h_num_logops; /* number of log operations in this LR : 4 */
- __be32 h_cycle_data[XLOG_HEADER_CYCLE_SIZE / BBSIZE];
+ __be32 h_cycle_data[XLOG_CYCLE_DATA_SIZE];
/* fields added by the Linux port: */
__be32 h_fmt; /* format of log record : 4 */
@@ -172,7 +173,7 @@ typedef struct xlog_rec_header {
typedef struct xlog_rec_ext_header {
__be32 xh_cycle; /* write cycle of log : 4 */
- __be32 xh_cycle_data[XLOG_HEADER_CYCLE_SIZE / BBSIZE]; /* : 256 */
+ __be32 xh_cycle_data[XLOG_CYCLE_DATA_SIZE]; /* : 256 */
} xlog_rec_ext_header_t;
/*
diff --git a/libxlog/xfs_log_recover.c b/libxlog/xfs_log_recover.c
index 3e7bbf08af1f40..6ab8b8b0635c7b 100644
--- a/libxlog/xfs_log_recover.c
+++ b/libxlog/xfs_log_recover.c
@@ -1338,7 +1338,7 @@ xlog_unpack_data(
return error;
for (i = 0; i < BTOBB(be32_to_cpu(rhead->h_len)) &&
- i < (XLOG_HEADER_CYCLE_SIZE / BBSIZE); i++) {
+ i < XLOG_CYCLE_DATA_SIZE; i++) {
*(__be32 *)dp = *(__be32 *)&rhead->h_cycle_data[i];
dp += BBSIZE;
}
@@ -1346,8 +1346,8 @@ xlog_unpack_data(
if (xfs_has_logv2(log->l_mp)) {
xlog_in_core_2_t *xhdr = (xlog_in_core_2_t *)rhead;
for ( ; i < BTOBB(be32_to_cpu(rhead->h_len)); i++) {
- j = i / (XLOG_HEADER_CYCLE_SIZE / BBSIZE);
- k = i % (XLOG_HEADER_CYCLE_SIZE / BBSIZE);
+ j = i / XLOG_CYCLE_DATA_SIZE;
+ k = i % XLOG_CYCLE_DATA_SIZE;
*(__be32 *)dp = xhdr[j].hic_xheader.xh_cycle_data[k];
dp += BBSIZE;
}
^ permalink raw reply related [flat|nested] 16+ messages in thread
* [PATCH 06/12] xfs: remove xlog_in_core_2_t
2026-02-19 23:43 [PATCHSET 1/2] xfsprogs: new libxfs code from kernel 6.19 Darrick J. Wong
` (4 preceding siblings ...)
2026-02-19 23:44 ` [PATCH 05/12] xfs: add a XLOG_CYCLE_DATA_SIZE constant Darrick J. Wong
@ 2026-02-19 23:45 ` Darrick J. Wong
2026-02-20 15:39 ` Christoph Hellwig
2026-02-19 23:45 ` [PATCH 07/12] xfs: remove the xlog_rec_header_t typedef Darrick J. Wong
` (5 subsequent siblings)
11 siblings, 1 reply; 16+ messages in thread
From: Darrick J. Wong @ 2026-02-19 23:45 UTC (permalink / raw)
To: djwong, aalbersh; +Cc: cem, cmaiolino, hch, linux-xfs
From: Christoph Hellwig <hch@lst.de>
Source kernel commit: fe985b910e03fd91193f399a1aca9d1ea22c2557
xlog_in_core_2_t is a really odd type, not only is it grossly
misnamed because it actually is an on-disk structure, but it also
reprents the actual on-disk structure in a rather odd way.
A v1 or small v2 log header look like:
+-----------------------+
| xlog_record |
+-----------------------+
while larger v2 log headers look like:
+-----------------------+
| xlog_record |
+-----------------------+
| xlog_rec_ext_header |
+-------------------+---+
| ..... |
+-----------------------+
| xlog_rec_ext_header |
+-----------------------+
I.e., the ext headers are a variable sized array at the end of the
header. So instead of declaring a union of xlog_rec_header,
xlog_rec_ext_header and padding to BBSIZE, add the proper padding to
struct struct xlog_rec_header and struct xlog_rec_ext_header, and
add a variable sized array of the latter to the former. This also
exposes the somewhat unusual scope of the log checksums, which is
made explicitly now by adding proper padding and macro designating
the actual payload length.
Signed-off-by: Christoph Hellwig <hch@lst.de>
Reviewed-by: Darrick J. Wong <djwong@kernel.org>
Reviewed-by: Carlos Maiolino <cmaiolino@redhat.com>
Signed-off-by: Carlos Maiolino <cem@kernel.org>
---
libxfs/xfs_log_format.h | 31 +++++++++++++++----------------
libxfs/xfs_ondisk.h | 6 ++++--
libxlog/xfs_log_recover.c | 34 ++++++++++++++++++++--------------
3 files changed, 39 insertions(+), 32 deletions(-)
diff --git a/libxfs/xfs_log_format.h b/libxfs/xfs_log_format.h
index 91a841ea5bb36d..4cb69bd285ca13 100644
--- a/libxfs/xfs_log_format.h
+++ b/libxfs/xfs_log_format.h
@@ -126,6 +126,16 @@ struct xlog_op_header {
#define XLOG_FMT XLOG_FMT_LINUX_LE
#endif
+struct xlog_rec_ext_header {
+ __be32 xh_cycle; /* write cycle of log */
+ __be32 xh_cycle_data[XLOG_CYCLE_DATA_SIZE];
+ __u8 xh_reserved[252];
+};
+
+/* actual ext header payload size for checksumming */
+#define XLOG_REC_EXT_SIZE \
+ offsetofend(struct xlog_rec_ext_header, xh_cycle_data)
+
typedef struct xlog_rec_header {
__be32 h_magicno; /* log record (LR) identifier : 4 */
__be32 h_cycle; /* write cycle of log : 4 */
@@ -161,30 +171,19 @@ typedef struct xlog_rec_header {
* (little-endian) architectures.
*/
__u32 h_pad0;
+
+ __u8 h_reserved[184];
+ struct xlog_rec_ext_header h_ext[];
} xlog_rec_header_t;
#ifdef __i386__
#define XLOG_REC_SIZE offsetofend(struct xlog_rec_header, h_size)
-#define XLOG_REC_SIZE_OTHER sizeof(struct xlog_rec_header)
+#define XLOG_REC_SIZE_OTHER offsetofend(struct xlog_rec_header, h_pad0)
#else
-#define XLOG_REC_SIZE sizeof(struct xlog_rec_header)
+#define XLOG_REC_SIZE offsetofend(struct xlog_rec_header, h_pad0)
#define XLOG_REC_SIZE_OTHER offsetofend(struct xlog_rec_header, h_size)
#endif /* __i386__ */
-typedef struct xlog_rec_ext_header {
- __be32 xh_cycle; /* write cycle of log : 4 */
- __be32 xh_cycle_data[XLOG_CYCLE_DATA_SIZE]; /* : 256 */
-} xlog_rec_ext_header_t;
-
-/*
- * Quite misnamed, because this union lays out the actual on-disk log buffer.
- */
-typedef union xlog_in_core2 {
- xlog_rec_header_t hic_header;
- xlog_rec_ext_header_t hic_xheader;
- char hic_sector[XLOG_HEADER_SIZE];
-} xlog_in_core_2_t;
-
/* not an on-disk structure, but needed by log recovery in userspace */
struct xfs_log_iovec {
void *i_addr; /* beginning address of region */
diff --git a/libxfs/xfs_ondisk.h b/libxfs/xfs_ondisk.h
index 7bfa3242e2c536..2e9715cc1641df 100644
--- a/libxfs/xfs_ondisk.h
+++ b/libxfs/xfs_ondisk.h
@@ -174,9 +174,11 @@ xfs_check_ondisk_structs(void)
XFS_CHECK_STRUCT_SIZE(struct xfs_rud_log_format, 16);
XFS_CHECK_STRUCT_SIZE(struct xfs_map_extent, 32);
XFS_CHECK_STRUCT_SIZE(struct xfs_phys_extent, 16);
- XFS_CHECK_STRUCT_SIZE(struct xlog_rec_header, 328);
- XFS_CHECK_STRUCT_SIZE(struct xlog_rec_ext_header, 260);
+ XFS_CHECK_STRUCT_SIZE(struct xlog_rec_header, 512);
+ XFS_CHECK_STRUCT_SIZE(struct xlog_rec_ext_header, 512);
+ XFS_CHECK_OFFSET(struct xlog_rec_header, h_reserved, 328);
+ XFS_CHECK_OFFSET(struct xlog_rec_ext_header, xh_reserved, 260);
XFS_CHECK_OFFSET(struct xfs_bui_log_format, bui_extents, 16);
XFS_CHECK_OFFSET(struct xfs_cui_log_format, cui_extents, 16);
XFS_CHECK_OFFSET(struct xfs_rui_log_format, rui_extents, 16);
diff --git a/libxlog/xfs_log_recover.c b/libxlog/xfs_log_recover.c
index 6ab8b8b0635c7b..843b8e9c47a455 100644
--- a/libxlog/xfs_log_recover.c
+++ b/libxlog/xfs_log_recover.c
@@ -1324,35 +1324,41 @@ xlog_unpack_data_crc(
return 0;
}
+/*
+ * Cycles over XLOG_CYCLE_DATA_SIZE overflow into the extended header that was
+ * added for v2 logs. Addressing for the cycles array there is off by one,
+ * because the first batch of cycles is in the original header.
+ */
+static inline __be32 *xlog_cycle_data(struct xlog_rec_header *rhead, unsigned i)
+{
+ if (i >= XLOG_CYCLE_DATA_SIZE) {
+ unsigned j = i / XLOG_CYCLE_DATA_SIZE;
+ unsigned k = i % XLOG_CYCLE_DATA_SIZE;
+
+ return &rhead->h_ext[j - 1].xh_cycle_data[k];
+ }
+
+ return &rhead->h_cycle_data[i];
+}
+
STATIC int
xlog_unpack_data(
struct xlog_rec_header *rhead,
char *dp,
struct xlog *log)
{
- int i, j, k;
+ int i;
int error;
error = xlog_unpack_data_crc(rhead, dp, log);
if (error)
return error;
- for (i = 0; i < BTOBB(be32_to_cpu(rhead->h_len)) &&
- i < XLOG_CYCLE_DATA_SIZE; i++) {
- *(__be32 *)dp = *(__be32 *)&rhead->h_cycle_data[i];
+ for (i = 0; i < BTOBB(be32_to_cpu(rhead->h_len)); i++) {
+ *(__be32 *)dp = *xlog_cycle_data(rhead, i);
dp += BBSIZE;
}
- if (xfs_has_logv2(log->l_mp)) {
- xlog_in_core_2_t *xhdr = (xlog_in_core_2_t *)rhead;
- for ( ; i < BTOBB(be32_to_cpu(rhead->h_len)); i++) {
- j = i / XLOG_CYCLE_DATA_SIZE;
- k = i % XLOG_CYCLE_DATA_SIZE;
- *(__be32 *)dp = xhdr[j].hic_xheader.xh_cycle_data[k];
- dp += BBSIZE;
- }
- }
-
return 0;
}
^ permalink raw reply related [flat|nested] 16+ messages in thread
* [PATCH 07/12] xfs: remove the xlog_rec_header_t typedef
2026-02-19 23:43 [PATCHSET 1/2] xfsprogs: new libxfs code from kernel 6.19 Darrick J. Wong
` (5 preceding siblings ...)
2026-02-19 23:45 ` [PATCH 06/12] xfs: remove xlog_in_core_2_t Darrick J. Wong
@ 2026-02-19 23:45 ` Darrick J. Wong
2026-02-19 23:45 ` [PATCH 08/12] xfs: remove xarray mark for reclaimable zones Darrick J. Wong
` (4 subsequent siblings)
11 siblings, 0 replies; 16+ messages in thread
From: Darrick J. Wong @ 2026-02-19 23:45 UTC (permalink / raw)
To: djwong, aalbersh; +Cc: cem, cmaiolino, hch, linux-xfs
From: Christoph Hellwig <hch@lst.de>
Source kernel commit: ef1e275638fe6f6d54c18a770c138e4d5972b280
There are almost no users of the typedef left, kill it and switch the
remaining users to use the underlying struct.
Signed-off-by: Christoph Hellwig <hch@lst.de>
Reviewed-by: Darrick J. Wong <djwong@kernel.org>
Reviewed-by: Carlos Maiolino <cmaiolino@redhat.com>
Signed-off-by: Carlos Maiolino <cem@kernel.org>
---
include/libxlog.h | 4 ++--
libxfs/xfs_log_format.h | 4 ++--
libxfs/rdwr.c | 2 +-
libxlog/util.c | 6 +++---
libxlog/xfs_log_recover.c | 18 +++++++++---------
logprint/log_dump.c | 4 ++--
6 files changed, 19 insertions(+), 19 deletions(-)
diff --git a/include/libxlog.h b/include/libxlog.h
index 3948c0b8d19b1d..cf39e7402d1378 100644
--- a/include/libxlog.h
+++ b/include/libxlog.h
@@ -99,9 +99,9 @@ extern int xlog_do_recovery_pass(struct xlog *log, xfs_daddr_t head_blk,
extern int xlog_recover_do_trans(struct xlog *log, struct xlog_recover *trans,
int pass);
extern int xlog_header_check_recover(xfs_mount_t *mp,
- xlog_rec_header_t *head);
+ struct xlog_rec_header *head);
extern int xlog_header_check_mount(xfs_mount_t *mp,
- xlog_rec_header_t *head);
+ struct xlog_rec_header *head);
#define xlog_assign_atomic_lsn(l,a,b) ((void) 0)
#define xlog_assign_grant_head(l,a,b) ((void) 0)
diff --git a/libxfs/xfs_log_format.h b/libxfs/xfs_log_format.h
index 4cb69bd285ca13..908e7060428ccb 100644
--- a/libxfs/xfs_log_format.h
+++ b/libxfs/xfs_log_format.h
@@ -136,7 +136,7 @@ struct xlog_rec_ext_header {
#define XLOG_REC_EXT_SIZE \
offsetofend(struct xlog_rec_ext_header, xh_cycle_data)
-typedef struct xlog_rec_header {
+struct xlog_rec_header {
__be32 h_magicno; /* log record (LR) identifier : 4 */
__be32 h_cycle; /* write cycle of log : 4 */
__be32 h_version; /* LR version : 4 */
@@ -174,7 +174,7 @@ typedef struct xlog_rec_header {
__u8 h_reserved[184];
struct xlog_rec_ext_header h_ext[];
-} xlog_rec_header_t;
+};
#ifdef __i386__
#define XLOG_REC_SIZE offsetofend(struct xlog_rec_header, h_size)
diff --git a/libxfs/rdwr.c b/libxfs/rdwr.c
index 500a8d81549209..3419e821ef0a29 100644
--- a/libxfs/rdwr.c
+++ b/libxfs/rdwr.c
@@ -1297,7 +1297,7 @@ libxfs_log_header(
libxfs_get_block_t *nextfunc,
void *private)
{
- xlog_rec_header_t *head = (xlog_rec_header_t *)caddr;
+ struct xlog_rec_header *head = (struct xlog_rec_header *)caddr;
char *p = caddr;
__be32 cycle_lsn;
int i, len;
diff --git a/libxlog/util.c b/libxlog/util.c
index 6e21f1a895d30a..3cfaeb511adaa4 100644
--- a/libxlog/util.c
+++ b/libxlog/util.c
@@ -67,7 +67,7 @@ xlog_is_dirty(
}
static int
-header_check_uuid(xfs_mount_t *mp, xlog_rec_header_t *head)
+header_check_uuid(xfs_mount_t *mp, struct xlog_rec_header *head)
{
char uu_log[64], uu_sb[64];
@@ -89,7 +89,7 @@ header_check_uuid(xfs_mount_t *mp, xlog_rec_header_t *head)
}
int
-xlog_header_check_recover(xfs_mount_t *mp, xlog_rec_header_t *head)
+xlog_header_check_recover(xfs_mount_t *mp, struct xlog_rec_header *head)
{
if (print_record_header)
printf(_("\nLOG REC AT LSN cycle %d block %d (0x%x, 0x%x)\n"),
@@ -125,7 +125,7 @@ xlog_header_check_recover(xfs_mount_t *mp, xlog_rec_header_t *head)
}
int
-xlog_header_check_mount(xfs_mount_t *mp, xlog_rec_header_t *head)
+xlog_header_check_mount(xfs_mount_t *mp, struct xlog_rec_header *head)
{
if (platform_uuid_is_null(&head->h_fs_uuid)) return 0;
if (header_check_uuid(mp, head)) {
diff --git a/libxlog/xfs_log_recover.c b/libxlog/xfs_log_recover.c
index 843b8e9c47a455..65e3c782d59674 100644
--- a/libxlog/xfs_log_recover.c
+++ b/libxlog/xfs_log_recover.c
@@ -296,7 +296,7 @@ xlog_find_verify_log_record(
xfs_daddr_t i;
struct xfs_buf *bp;
char *offset = NULL;
- xlog_rec_header_t *head = NULL;
+ struct xlog_rec_header *head = NULL;
int error = 0;
int smallmem = 0;
int num_blks = *last_blk - start_blk;
@@ -331,7 +331,7 @@ xlog_find_verify_log_record(
goto out;
}
- head = (xlog_rec_header_t *)offset;
+ head = (struct xlog_rec_header *)offset;
if (head->h_magicno == cpu_to_be32(XLOG_HEADER_MAGIC_NUM))
break;
@@ -673,7 +673,7 @@ xlog_find_tail(
xfs_daddr_t *head_blk,
xfs_daddr_t *tail_blk)
{
- xlog_rec_header_t *rhead;
+ struct xlog_rec_header *rhead;
struct xlog_op_header *op_head;
char *offset = NULL;
struct xfs_buf *bp;
@@ -747,7 +747,7 @@ xlog_find_tail(
}
/* find blk_no of tail of log */
- rhead = (xlog_rec_header_t *)offset;
+ rhead = (struct xlog_rec_header *)offset;
*tail_blk = BLOCK_LSN(be64_to_cpu(rhead->h_tail_lsn));
/*
@@ -1413,7 +1413,7 @@ xlog_do_recovery_pass(
xfs_daddr_t tail_blk,
int pass)
{
- xlog_rec_header_t *rhead;
+ struct xlog_rec_header *rhead;
xfs_daddr_t blk_no;
char *offset;
struct xfs_buf *hbp, *dbp;
@@ -1442,7 +1442,7 @@ xlog_do_recovery_pass(
if (error)
goto bread_err1;
- rhead = (xlog_rec_header_t *)offset;
+ rhead = (struct xlog_rec_header *)offset;
error = xlog_valid_rec_header(log, rhead, tail_blk);
if (error)
goto bread_err1;
@@ -1479,7 +1479,7 @@ xlog_do_recovery_pass(
if (error)
goto bread_err2;
- rhead = (xlog_rec_header_t *)offset;
+ rhead = (struct xlog_rec_header *)offset;
error = xlog_valid_rec_header(log, rhead, blk_no);
if (error)
goto bread_err2;
@@ -1554,7 +1554,7 @@ xlog_do_recovery_pass(
if (error)
goto bread_err2;
}
- rhead = (xlog_rec_header_t *)offset;
+ rhead = (struct xlog_rec_header *)offset;
error = xlog_valid_rec_header(log, rhead,
split_hblks ? blk_no : 0);
if (error)
@@ -1628,7 +1628,7 @@ xlog_do_recovery_pass(
if (error)
goto bread_err2;
- rhead = (xlog_rec_header_t *)offset;
+ rhead = (struct xlog_rec_header *)offset;
error = xlog_valid_rec_header(log, rhead, blk_no);
if (error)
goto bread_err2;
diff --git a/logprint/log_dump.c b/logprint/log_dump.c
index 1de0206af94a9e..b403c01e99e839 100644
--- a/logprint/log_dump.c
+++ b/logprint/log_dump.c
@@ -21,11 +21,11 @@ xfs_log_dump(
int r;
uint last_cycle = -1;
xfs_daddr_t blkno, dupblkno;
- xlog_rec_header_t *hdr;
+ struct xlog_rec_header *hdr;
char buf[XLOG_HEADER_SIZE];
dupblkno = 0;
- hdr = (xlog_rec_header_t *)buf;
+ hdr = (struct xlog_rec_header *)buf;
xlog_print_lseek(log, fd, 0, SEEK_SET);
for (blkno = 0; blkno < log->l_logBBsize; blkno++) {
r = read(fd, buf, sizeof(buf));
^ permalink raw reply related [flat|nested] 16+ messages in thread
* [PATCH 08/12] xfs: remove xarray mark for reclaimable zones
2026-02-19 23:43 [PATCHSET 1/2] xfsprogs: new libxfs code from kernel 6.19 Darrick J. Wong
` (6 preceding siblings ...)
2026-02-19 23:45 ` [PATCH 07/12] xfs: remove the xlog_rec_header_t typedef Darrick J. Wong
@ 2026-02-19 23:45 ` Darrick J. Wong
2026-02-19 23:45 ` [PATCH 09/12] xfs: validate that zoned RT devices are zone aligned Darrick J. Wong
` (3 subsequent siblings)
11 siblings, 0 replies; 16+ messages in thread
From: Darrick J. Wong @ 2026-02-19 23:45 UTC (permalink / raw)
To: djwong, aalbersh; +Cc: cem, hans.holmberg, hch, linux-xfs
From: Hans Holmberg <hans.holmberg@wdc.com>
Source kernel commit: bf3b8e915215ef78319b896c0ccc14dc57dac80f
We can easily check if there are any reclaimble zones by just looking
at the used counters in the reclaim buckets, so do that to free up the
xarray mark we currently use for this purpose.
Signed-off-by: Hans Holmberg <hans.holmberg@wdc.com>
Reviewed-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Carlos Maiolino <cem@kernel.org>
---
libxfs/xfs_rtgroup.h | 6 ------
1 file changed, 6 deletions(-)
diff --git a/libxfs/xfs_rtgroup.h b/libxfs/xfs_rtgroup.h
index a94e925ae67cb6..03f1e2493334f3 100644
--- a/libxfs/xfs_rtgroup.h
+++ b/libxfs/xfs_rtgroup.h
@@ -64,12 +64,6 @@ struct xfs_rtgroup {
*/
#define XFS_RTG_FREE XA_MARK_0
-/*
- * For zoned RT devices this is set on groups that are fully written and that
- * have unused blocks. Used by the garbage collection to pick targets.
- */
-#define XFS_RTG_RECLAIMABLE XA_MARK_1
-
static inline struct xfs_rtgroup *to_rtg(struct xfs_group *xg)
{
return container_of(xg, struct xfs_rtgroup, rtg_group);
^ permalink raw reply related [flat|nested] 16+ messages in thread
* [PATCH 09/12] xfs: validate that zoned RT devices are zone aligned
2026-02-19 23:43 [PATCHSET 1/2] xfsprogs: new libxfs code from kernel 6.19 Darrick J. Wong
` (7 preceding siblings ...)
2026-02-19 23:45 ` [PATCH 08/12] xfs: remove xarray mark for reclaimable zones Darrick J. Wong
@ 2026-02-19 23:45 ` Darrick J. Wong
2026-02-19 23:46 ` [PATCH 10/12] xfs: mark __xfs_rtgroup_extents static Darrick J. Wong
` (2 subsequent siblings)
11 siblings, 0 replies; 16+ messages in thread
From: Darrick J. Wong @ 2026-02-19 23:45 UTC (permalink / raw)
To: djwong, aalbersh; +Cc: cem, hch, linux-xfs
From: Christoph Hellwig <hch@lst.de>
Source kernel commit: 982d2616a2906113e433fdc0cfcc122f8d1bb60a
Garbage collection assumes all zones contain the full amount of blocks.
Mkfs already ensures this happens, but make the kernel check it as well
to avoid getting into trouble due to fuzzers or mkfs bugs.
Fixes: 2167eaabe2fa ("xfs: define the zoned on-disk format")
Signed-off-by: Christoph Hellwig <hch@lst.de>
Reviewed-by: Darrick J. Wong <djwong@kernel.org>
Signed-off-by: Carlos Maiolino <cem@kernel.org>
---
libxfs/xfs_sb.c | 15 +++++++++++++++
1 file changed, 15 insertions(+)
diff --git a/libxfs/xfs_sb.c b/libxfs/xfs_sb.c
index dd14c3ab3b59e3..3e2d3c6da19631 100644
--- a/libxfs/xfs_sb.c
+++ b/libxfs/xfs_sb.c
@@ -299,6 +299,21 @@ xfs_validate_rt_geometry(
sbp->sb_rbmblocks != xfs_expected_rbmblocks(sbp))
return false;
+ if (xfs_sb_is_v5(sbp) &&
+ (sbp->sb_features_incompat & XFS_SB_FEAT_INCOMPAT_ZONED)) {
+ uint32_t mod;
+
+ /*
+ * Zoned RT devices must be aligned to the RT group size,
+ * because garbage collection assumes that all zones have the
+ * same size to avoid insane complexity if that weren't the
+ * case.
+ */
+ div_u64_rem(sbp->sb_rextents, sbp->sb_rgextents, &mod);
+ if (mod)
+ return false;
+ }
+
return true;
}
^ permalink raw reply related [flat|nested] 16+ messages in thread
* [PATCH 10/12] xfs: mark __xfs_rtgroup_extents static
2026-02-19 23:43 [PATCHSET 1/2] xfsprogs: new libxfs code from kernel 6.19 Darrick J. Wong
` (8 preceding siblings ...)
2026-02-19 23:45 ` [PATCH 09/12] xfs: validate that zoned RT devices are zone aligned Darrick J. Wong
@ 2026-02-19 23:46 ` Darrick J. Wong
2026-02-19 23:46 ` [PATCH 11/12] xfs: fix an overly long line in xfs_rtgroup_calc_geometry Darrick J. Wong
2026-02-19 23:46 ` [PATCH 12/12] xfs: set max_agbno to allow sparse alloc of last full inode chunk Darrick J. Wong
11 siblings, 0 replies; 16+ messages in thread
From: Darrick J. Wong @ 2026-02-19 23:46 UTC (permalink / raw)
To: djwong, aalbersh; +Cc: cem, hch, linux-xfs
From: Christoph Hellwig <hch@lst.de>
Source kernel commit: e0aea42a32984a6fd13410aed7afd3bd0caeb1c1
__xfs_rtgroup_extents is not used outside of xfs_rtgroup.c, so mark it
static. Move it and xfs_rtgroup_extents up in the file to avoid forward
declarations.
Signed-off-by: Christoph Hellwig <hch@lst.de>
Reviewed-by: Darrick J. Wong <djwong@kernel.org>
Signed-off-by: Carlos Maiolino <cem@kernel.org>
---
libxfs/xfs_rtgroup.h | 2 --
libxfs/xfs_rtgroup.c | 50 +++++++++++++++++++++++++-------------------------
2 files changed, 25 insertions(+), 27 deletions(-)
diff --git a/libxfs/xfs_rtgroup.h b/libxfs/xfs_rtgroup.h
index 03f1e2493334f3..73cace4d25c791 100644
--- a/libxfs/xfs_rtgroup.h
+++ b/libxfs/xfs_rtgroup.h
@@ -285,8 +285,6 @@ void xfs_free_rtgroups(struct xfs_mount *mp, xfs_rgnumber_t first_rgno,
int xfs_initialize_rtgroups(struct xfs_mount *mp, xfs_rgnumber_t first_rgno,
xfs_rgnumber_t end_rgno, xfs_rtbxlen_t rextents);
-xfs_rtxnum_t __xfs_rtgroup_extents(struct xfs_mount *mp, xfs_rgnumber_t rgno,
- xfs_rgnumber_t rgcount, xfs_rtbxlen_t rextents);
xfs_rtxnum_t xfs_rtgroup_extents(struct xfs_mount *mp, xfs_rgnumber_t rgno);
void xfs_rtgroup_calc_geometry(struct xfs_mount *mp, struct xfs_rtgroup *rtg,
xfs_rgnumber_t rgno, xfs_rgnumber_t rgcount,
diff --git a/libxfs/xfs_rtgroup.c b/libxfs/xfs_rtgroup.c
index e58968286f3232..1e6629ee03253d 100644
--- a/libxfs/xfs_rtgroup.c
+++ b/libxfs/xfs_rtgroup.c
@@ -45,6 +45,31 @@ xfs_rtgroup_min_block(
return 0;
}
+/* Compute the number of rt extents in this realtime group. */
+static xfs_rtxnum_t
+__xfs_rtgroup_extents(
+ struct xfs_mount *mp,
+ xfs_rgnumber_t rgno,
+ xfs_rgnumber_t rgcount,
+ xfs_rtbxlen_t rextents)
+{
+ ASSERT(rgno < rgcount);
+ if (rgno == rgcount - 1)
+ return rextents - ((xfs_rtxnum_t)rgno * mp->m_sb.sb_rgextents);
+
+ ASSERT(xfs_has_rtgroups(mp));
+ return mp->m_sb.sb_rgextents;
+}
+
+xfs_rtxnum_t
+xfs_rtgroup_extents(
+ struct xfs_mount *mp,
+ xfs_rgnumber_t rgno)
+{
+ return __xfs_rtgroup_extents(mp, rgno, mp->m_sb.sb_rgcount,
+ mp->m_sb.sb_rextents);
+}
+
/* Precompute this group's geometry */
void
xfs_rtgroup_calc_geometry(
@@ -133,31 +158,6 @@ xfs_initialize_rtgroups(
return error;
}
-/* Compute the number of rt extents in this realtime group. */
-xfs_rtxnum_t
-__xfs_rtgroup_extents(
- struct xfs_mount *mp,
- xfs_rgnumber_t rgno,
- xfs_rgnumber_t rgcount,
- xfs_rtbxlen_t rextents)
-{
- ASSERT(rgno < rgcount);
- if (rgno == rgcount - 1)
- return rextents - ((xfs_rtxnum_t)rgno * mp->m_sb.sb_rgextents);
-
- ASSERT(xfs_has_rtgroups(mp));
- return mp->m_sb.sb_rgextents;
-}
-
-xfs_rtxnum_t
-xfs_rtgroup_extents(
- struct xfs_mount *mp,
- xfs_rgnumber_t rgno)
-{
- return __xfs_rtgroup_extents(mp, rgno, mp->m_sb.sb_rgcount,
- mp->m_sb.sb_rextents);
-}
-
/*
* Update the rt extent count of the previous tail rtgroup if it changed during
* recovery (i.e. recovery of a growfs).
^ permalink raw reply related [flat|nested] 16+ messages in thread
* [PATCH 11/12] xfs: fix an overly long line in xfs_rtgroup_calc_geometry
2026-02-19 23:43 [PATCHSET 1/2] xfsprogs: new libxfs code from kernel 6.19 Darrick J. Wong
` (9 preceding siblings ...)
2026-02-19 23:46 ` [PATCH 10/12] xfs: mark __xfs_rtgroup_extents static Darrick J. Wong
@ 2026-02-19 23:46 ` Darrick J. Wong
2026-02-19 23:46 ` [PATCH 12/12] xfs: set max_agbno to allow sparse alloc of last full inode chunk Darrick J. Wong
11 siblings, 0 replies; 16+ messages in thread
From: Darrick J. Wong @ 2026-02-19 23:46 UTC (permalink / raw)
To: djwong, aalbersh; +Cc: cem, hch, linux-xfs
From: Christoph Hellwig <hch@lst.de>
Source kernel commit: baed03efe223b1649320e835d7e0c03b3dde0b0c
Signed-off-by: Christoph Hellwig <hch@lst.de>
Reviewed-by: Darrick J. Wong <djwong@kernel.org>
Signed-off-by: Carlos Maiolino <cem@kernel.org>
---
libxfs/xfs_rtgroup.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/libxfs/xfs_rtgroup.c b/libxfs/xfs_rtgroup.c
index 1e6629ee03253d..d012ca73000d86 100644
--- a/libxfs/xfs_rtgroup.c
+++ b/libxfs/xfs_rtgroup.c
@@ -80,7 +80,8 @@ xfs_rtgroup_calc_geometry(
xfs_rtbxlen_t rextents)
{
rtg->rtg_extents = __xfs_rtgroup_extents(mp, rgno, rgcount, rextents);
- rtg_group(rtg)->xg_block_count = rtg->rtg_extents * mp->m_sb.sb_rextsize;
+ rtg_group(rtg)->xg_block_count =
+ rtg->rtg_extents * mp->m_sb.sb_rextsize;
rtg_group(rtg)->xg_min_gbno = xfs_rtgroup_min_block(mp, rgno);
}
^ permalink raw reply related [flat|nested] 16+ messages in thread
* [PATCH 12/12] xfs: set max_agbno to allow sparse alloc of last full inode chunk
2026-02-19 23:43 [PATCHSET 1/2] xfsprogs: new libxfs code from kernel 6.19 Darrick J. Wong
` (10 preceding siblings ...)
2026-02-19 23:46 ` [PATCH 11/12] xfs: fix an overly long line in xfs_rtgroup_calc_geometry Darrick J. Wong
@ 2026-02-19 23:46 ` Darrick J. Wong
11 siblings, 0 replies; 16+ messages in thread
From: Darrick J. Wong @ 2026-02-19 23:46 UTC (permalink / raw)
To: djwong, aalbersh; +Cc: bfoster, cem, linux-xfs
From: Brian Foster <bfoster@redhat.com>
Source kernel commit: c360004c0160dbe345870f59f24595519008926f
Sparse inode cluster allocation sets min/max agbno values to avoid
allocating an inode cluster that might map to an invalid inode
chunk. For example, we can't have an inode record mapped to agbno 0
or that extends past the end of a runt AG of misaligned size.
The initial calculation of max_agbno is unnecessarily conservative,
however. This has triggered a corner case allocation failure where a
small runt AG (i.e. 2063 blocks) is mostly full save for an extent
to the EOFS boundary: [2050,13]. max_agbno is set to 2048 in this
case, which happens to be the offset of the last possible valid
inode chunk in the AG. In practice, we should be able to allocate
the 4-block cluster at agbno 2052 to map to the parent inode record
at agbno 2048, but the max_agbno value precludes it.
Note that this can result in filesystem shutdown via dirty trans
cancel on stable kernels prior to commit 9eb775968b68 ("xfs: walk
all AGs if TRYLOCK passed to xfs_alloc_vextent_iterate_ags") because
the tail AG selection by the allocator sets t_highest_agno on the
transaction. If the inode allocator spins around and finds an inode
chunk with free inodes in an earlier AG, the subsequent dir name
creation path may still fail to allocate due to the AG restriction
and cancel.
To avoid this problem, update the max_agbno calculation to the agbno
prior to the last chunk aligned agbno in the AG. This is not
necessarily the last valid allocation target for a sparse chunk, but
since inode chunks (i.e. records) are chunk aligned and sparse
allocs are cluster sized/aligned, this allows the sb_spino_align
alignment restriction to take over and round down the max effective
agbno to within the last valid inode chunk in the AG.
Note that even though the allocator improvements in the
aforementioned commit seem to avoid this particular dirty trans
cancel situation, the max_agbno logic improvement still applies as
we should be able to allocate from an AG that has been appropriately
selected. The more important target for this patch however are
older/stable kernels prior to this allocator rework/improvement.
Fixes: 56d1115c9bc7 ("xfs: allocate sparse inode chunks on full chunk allocation failure")
Signed-off-by: Brian Foster <bfoster@redhat.com>
Reviewed-by: Darrick J. Wong <djwong@kernel.org>
Signed-off-by: Carlos Maiolino <cem@kernel.org>
---
libxfs/xfs_ialloc.c | 11 ++++++-----
1 file changed, 6 insertions(+), 5 deletions(-)
diff --git a/libxfs/xfs_ialloc.c b/libxfs/xfs_ialloc.c
index 9f4ec7bbc02531..1da6f07fa030d0 100644
--- a/libxfs/xfs_ialloc.c
+++ b/libxfs/xfs_ialloc.c
@@ -843,15 +843,16 @@ xfs_ialloc_ag_alloc(
* invalid inode records, such as records that start at agbno 0
* or extend beyond the AG.
*
- * Set min agbno to the first aligned, non-zero agbno and max to
- * the last aligned agbno that is at least one full chunk from
- * the end of the AG.
+ * Set min agbno to the first chunk aligned, non-zero agbno and
+ * max to one less than the last chunk aligned agbno from the
+ * end of the AG. We subtract 1 from max so that the cluster
+ * allocation alignment takes over and allows allocation within
+ * the last full inode chunk in the AG.
*/
args.min_agbno = args.mp->m_sb.sb_inoalignmt;
args.max_agbno = round_down(xfs_ag_block_count(args.mp,
pag_agno(pag)),
- args.mp->m_sb.sb_inoalignmt) -
- igeo->ialloc_blks;
+ args.mp->m_sb.sb_inoalignmt) - 1;
error = xfs_alloc_vextent_near_bno(&args,
xfs_agbno_to_fsb(pag,
^ permalink raw reply related [flat|nested] 16+ messages in thread
* Re: [PATCH 02/12] xfs: use blkdev_report_zones_cached()
2026-02-19 23:44 ` [PATCH 02/12] xfs: use blkdev_report_zones_cached() Darrick J. Wong
@ 2026-02-20 15:36 ` Christoph Hellwig
2026-02-20 16:43 ` Darrick J. Wong
0 siblings, 1 reply; 16+ messages in thread
From: Christoph Hellwig @ 2026-02-20 15:36 UTC (permalink / raw)
To: Darrick J. Wong; +Cc: aalbersh, axboe, dlemoal, martin.petersen, linux-xfs
A different userspace port of this already is in xfsprogs for-next.
I'm a little biassed as I did it, but I prefer not having to deal
with autoconf :)
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [PATCH 06/12] xfs: remove xlog_in_core_2_t
2026-02-19 23:45 ` [PATCH 06/12] xfs: remove xlog_in_core_2_t Darrick J. Wong
@ 2026-02-20 15:39 ` Christoph Hellwig
0 siblings, 0 replies; 16+ messages in thread
From: Christoph Hellwig @ 2026-02-20 15:39 UTC (permalink / raw)
To: Darrick J. Wong; +Cc: aalbersh, cem, cmaiolino, hch, linux-xfs
The libxlog part looks good. I actually had a local version, but
you keep beating me on submitting these ports..
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [PATCH 02/12] xfs: use blkdev_report_zones_cached()
2026-02-20 15:36 ` Christoph Hellwig
@ 2026-02-20 16:43 ` Darrick J. Wong
0 siblings, 0 replies; 16+ messages in thread
From: Darrick J. Wong @ 2026-02-20 16:43 UTC (permalink / raw)
To: Christoph Hellwig; +Cc: aalbersh, axboe, dlemoal, martin.petersen, linux-xfs
On Fri, Feb 20, 2026 at 07:36:51AM -0800, Christoph Hellwig wrote:
> A different userspace port of this already is in xfsprogs for-next.
>
> I'm a little biassed as I did it, but I prefer not having to deal
> with autoconf :)
Aha, I see commit f5f2bad67a45cd ("block: make the new blkzoned UAPI
constants discoverable") makes it so we don't need the autoconf junk
at all! That's far less annoying than adding more autoconf.
This patch should be dropped, but the rest of the libxfs 6.19 port still
looks good.
--D
^ permalink raw reply [flat|nested] 16+ messages in thread
end of thread, other threads:[~2026-02-20 16:43 UTC | newest]
Thread overview: 16+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-02-19 23:43 [PATCHSET 1/2] xfsprogs: new libxfs code from kernel 6.19 Darrick J. Wong
2026-02-19 23:43 ` [PATCH 01/12] xfs: error tag to force zeroing on debug kernels Darrick J. Wong
2026-02-19 23:44 ` [PATCH 02/12] xfs: use blkdev_report_zones_cached() Darrick J. Wong
2026-02-20 15:36 ` Christoph Hellwig
2026-02-20 16:43 ` Darrick J. Wong
2026-02-19 23:44 ` [PATCH 03/12] xfs: add a xfs_groups_to_rfsbs helper Darrick J. Wong
2026-02-19 23:44 ` [PATCH 04/12] xfs: use a lockref for the xfs_dquot reference count Darrick J. Wong
2026-02-19 23:44 ` [PATCH 05/12] xfs: add a XLOG_CYCLE_DATA_SIZE constant Darrick J. Wong
2026-02-19 23:45 ` [PATCH 06/12] xfs: remove xlog_in_core_2_t Darrick J. Wong
2026-02-20 15:39 ` Christoph Hellwig
2026-02-19 23:45 ` [PATCH 07/12] xfs: remove the xlog_rec_header_t typedef Darrick J. Wong
2026-02-19 23:45 ` [PATCH 08/12] xfs: remove xarray mark for reclaimable zones Darrick J. Wong
2026-02-19 23:45 ` [PATCH 09/12] xfs: validate that zoned RT devices are zone aligned Darrick J. Wong
2026-02-19 23:46 ` [PATCH 10/12] xfs: mark __xfs_rtgroup_extents static Darrick J. Wong
2026-02-19 23:46 ` [PATCH 11/12] xfs: fix an overly long line in xfs_rtgroup_calc_geometry Darrick J. Wong
2026-02-19 23:46 ` [PATCH 12/12] xfs: set max_agbno to allow sparse alloc of last full inode chunk Darrick J. Wong
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox