public inbox for linux-xfs@vger.kernel.org
 help / color / mirror / Atom feed
* [PATCHBOMB] xfsprogs: rollup of libxfs-7.0-sync patches
@ 2026-03-23 18:39 Darrick J. Wong
  2026-03-23 18:40 ` [PATCHSET 1/2] xfsprogs: various bug fixes for 7.0 Darrick J. Wong
  2026-03-23 18:41 ` [PATCHSET 2/2] xfsprogs: new libxfs code from kernel 7.0 Darrick J. Wong
  0 siblings, 2 replies; 50+ messages in thread
From: Darrick J. Wong @ 2026-03-23 18:39 UTC (permalink / raw)
  To: Andrey Albershteyn; +Cc: xfs, hch

Hi folks,

Now that xfsprogs 6.19 has been released, here's a rollup of a couple of
pending bugfixes, a pre-cleanup of the kmalloc API wrappers from the
kernel, and all the libxfs ports patches, with new review tags.

Unreviewed patches:

[PATCHSET 2/2] xfsprogs: new libxfs code from kernel 7.0
  [PATCH 01/38] libxfs: fix XFS_STATS_DEC
  [PATCH 02/38] libxfs: port various kernel apis from 7.0

--D

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

* [PATCHSET 1/2] xfsprogs: various bug fixes for 7.0
  2026-03-23 18:39 [PATCHBOMB] xfsprogs: rollup of libxfs-7.0-sync patches Darrick J. Wong
@ 2026-03-23 18:40 ` Darrick J. Wong
  2026-03-23 18:41   ` [PATCH 1/1] xfs_repair: don't fail on INCOMPLETE attrs in leaf blocks Darrick J. Wong
  2026-03-23 18:41 ` [PATCHSET 2/2] xfsprogs: new libxfs code from kernel 7.0 Darrick J. Wong
  1 sibling, 1 reply; 50+ messages in thread
From: Darrick J. Wong @ 2026-03-23 18:40 UTC (permalink / raw)
  To: djwong, aalbersh; +Cc: hch, linux-xfs

Hi all,

This series contains miscellaneous bugfixes.

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=random-fixes

xfsprogs git tree:
https://git.kernel.org/cgit/linux/kernel/git/djwong/xfsprogs-dev.git/log/?h=random-fixes

fstests git tree:
https://git.kernel.org/cgit/linux/kernel/git/djwong/xfstests-dev.git/log/?h=random-fixes
---
Commits in this patchset:
 * xfs_repair: don't fail on INCOMPLETE attrs in leaf blocks
---
 repair/attr_repair.c |   22 +++++++++++++++++-----
 1 file changed, 17 insertions(+), 5 deletions(-)


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

* [PATCHSET 2/2] xfsprogs: new libxfs code from kernel 7.0
  2026-03-23 18:39 [PATCHBOMB] xfsprogs: rollup of libxfs-7.0-sync patches Darrick J. Wong
  2026-03-23 18:40 ` [PATCHSET 1/2] xfsprogs: various bug fixes for 7.0 Darrick J. Wong
@ 2026-03-23 18:41 ` Darrick J. Wong
  2026-03-23 18:41   ` [PATCH 01/40] libxfs: fix XFS_STATS_DEC Darrick J. Wong
                     ` (39 more replies)
  1 sibling, 40 replies; 50+ messages in thread
From: Darrick J. Wong @ 2026-03-23 18:41 UTC (permalink / raw)
  To: djwong, aalbersh
  Cc: kees, hch, cem, cmaiolino, mark.tinguely, nirjhar.roy.lists,
	wilfred.mallawa, dlemoal, shinsj4653, torvalds, hongao,
	souptick.joarder, linux-xfs, hans.holmberg, linux-xfs

Hi all,

This series ports kernel libxfs code to userspace from 7.0-rc5.

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-7.0-sync
---
Commits in this patchset:
 * libxfs: fix XFS_STATS_DEC
 * libxfs: port various kernel apis from 7.0
 * libfrog: hoist some utilities from libxfs
 * libfrog: fix missing gettext call in current_fixed_time
 * xfs: start creating infrastructure for health monitoring
 * xfs: create event queuing, formatting, and discovery infrastructure
 * xfs: convey filesystem unmount events to the health monitor
 * xfs: convey metadata health events to the health monitor
 * xfs: convey filesystem shutdown events to the health monitor
 * xfs: convey externally discovered fsdax media errors to the health monitor
 * xfs: convey file I/O errors to the health monitor
 * xfs: check if an open file is on the health monitored fs
 * xfs: add media verification ioctl
 * xfs: move struct xfs_log_iovec to xfs_log_priv.h
 * xfs: directly include xfs_platform.h
 * xfs: remove xfs_attr_leaf_hasname
 * xfs: add missing forward declaration in xfs_zones.h
 * xfs: add a xfs_rtgroup_raw_size helper
 * xfs: split and refactor zone validation
 * xfs: delete attr leaf freemap entries when empty
 * xfs: fix freemap adjustments when adding xattrs to leaf blocks
 * xfs: refactor attr3 leaf table size computation
 * xfs: strengthen attr leaf block freemap checking
 * xfs: reduce xfs_attr_try_sf_addname parameters
 * xfs: speed up parent pointer operations when possible
 * xfs: add a method to replace shortform attrs
 * xfs: fix spacing style issues in xfs_alloc.c
 * xfs: don't validate error tags in the I/O path
 * xfs: add zone reset error injection
 * xfs: give the defer_relog stat a xs_ prefix
 * treewide: Replace kmalloc with kmalloc_obj for non-scalar types
 * Convert 'alloc_obj' family to use the new default GFP_KERNEL argument
 * xfs: Refactoring the nagcount and delta calculation
 * xfs: fix code alignment issues in xfs_ondisk.c
 * xfs: remove metafile inodes from the active inode stat
 * xfs: Add a comment in xfs_log_sb()
 * xfs: remove duplicate static size checks
 * xfs: add static size checks for ioctl UABI
 * xfs: Remove redundant NULL check after __GFP_NOFAIL
 * xfs: fix returned valued from xfs_defer_can_append
---
 include/kmem.h                |   50 ++++++++++
 include/libxfs.h              |    7 -
 include/platform_defs.h       |    8 ++
 include/xfs_fs_compat.h       |    8 --
 include/xfs_trace.h           |    1 
 libfrog/util.h                |   21 ++++
 libxfs/libxfs_api_defs.h      |    2 
 libxfs/xfs_ag.h               |    3 +
 libxfs/xfs_attr.h             |    6 +
 libxfs/xfs_attr_leaf.h        |    1 
 libxfs/xfs_da_format.h        |    2 
 libxfs/xfs_errortag.h         |    8 +-
 libxfs/xfs_fs.h               |  189 +++++++++++++++++++++++++++++++++++++++
 libxfs/xfs_health.h           |    5 +
 libxfs/xfs_log_format.h       |    7 -
 libxfs/xfs_ondisk.h           |   52 +++++++----
 libxfs/xfs_platform.h         |   25 +----
 libxfs/xfs_rtgroup.h          |   15 +++
 libxfs/xfs_zones.h            |    6 +
 libfrog/Makefile              |    4 +
 libfrog/util.c                |  166 +++++++++++++++++++++++++++++++++++
 libxfs/Makefile               |    4 -
 libxfs/buf_mem.c              |    2 
 libxfs/cache.c                |    2 
 libxfs/defer_item.c           |    2 
 libxfs/init.c                 |    2 
 libxfs/inode.c                |    2 
 libxfs/iunlink.c              |    2 
 libxfs/kmem.c                 |    2 
 libxfs/logitem.c              |    2 
 libxfs/rdwr.c                 |    2 
 libxfs/topology.c             |    2 
 libxfs/trans.c                |    2 
 libxfs/util.c                 |  162 ----------------------------------
 libxfs/xfblob.c               |    2 
 libxfs/xfile.c                |    2 
 libxfs/xfs_ag.c               |   32 ++++++-
 libxfs/xfs_ag_resv.c          |    2 
 libxfs/xfs_alloc.c            |   10 +-
 libxfs/xfs_alloc_btree.c      |    2 
 libxfs/xfs_attr.c             |  191 +++++++++++++++++++++++++++-------------
 libxfs/xfs_attr_leaf.c        |  197 ++++++++++++++++++++++++++++++++++-------
 libxfs/xfs_attr_remote.c      |    2 
 libxfs/xfs_bit.c              |    2 
 libxfs/xfs_bmap.c             |    2 
 libxfs/xfs_bmap_btree.c       |    2 
 libxfs/xfs_btree.c            |    2 
 libxfs/xfs_btree_mem.c        |    2 
 libxfs/xfs_btree_staging.c    |    2 
 libxfs/xfs_da_btree.c         |   10 +-
 libxfs/xfs_defer.c            |    8 +-
 libxfs/xfs_dir2.c             |   21 ++--
 libxfs/xfs_dir2_block.c       |    2 
 libxfs/xfs_dir2_data.c        |    2 
 libxfs/xfs_dir2_leaf.c        |    2 
 libxfs/xfs_dir2_node.c        |    2 
 libxfs/xfs_dir2_sf.c          |    2 
 libxfs/xfs_dquot_buf.c        |    2 
 libxfs/xfs_exchmaps.c         |    2 
 libxfs/xfs_group.c            |    2 
 libxfs/xfs_ialloc.c           |    2 
 libxfs/xfs_ialloc_btree.c     |    2 
 libxfs/xfs_iext_tree.c        |    2 
 libxfs/xfs_inode_buf.c        |    6 +
 libxfs/xfs_inode_fork.c       |    2 
 libxfs/xfs_inode_util.c       |    2 
 libxfs/xfs_log_rlimit.c       |    2 
 libxfs/xfs_metadir.c          |    2 
 libxfs/xfs_metafile.c         |    7 +
 libxfs/xfs_parent.c           |   16 ++-
 libxfs/xfs_refcount.c         |    6 +
 libxfs/xfs_refcount_btree.c   |    2 
 libxfs/xfs_rmap.c             |    2 
 libxfs/xfs_rmap_btree.c       |    2 
 libxfs/xfs_rtbitmap.c         |    2 
 libxfs/xfs_rtgroup.c          |    4 -
 libxfs/xfs_rtrefcount_btree.c |    2 
 libxfs/xfs_rtrmap_btree.c     |    2 
 libxfs/xfs_sb.c               |    5 +
 libxfs/xfs_symlink_remote.c   |    2 
 libxfs/xfs_trans_inode.c      |    2 
 libxfs/xfs_trans_resv.c       |    2 
 libxfs/xfs_trans_space.c      |    2 
 libxfs/xfs_types.c            |    2 
 libxfs/xfs_zones.c            |  151 ++++++++-----------------------
 libxlog/xfs_log_recover.c     |    4 -
 repair/zoned.c                |    7 +
 87 files changed, 990 insertions(+), 533 deletions(-)
 rename libxfs/{libxfs_priv.h => xfs_platform.h} (96%)


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

* [PATCH 1/1] xfs_repair: don't fail on INCOMPLETE attrs in leaf blocks
  2026-03-23 18:40 ` [PATCHSET 1/2] xfsprogs: various bug fixes for 7.0 Darrick J. Wong
@ 2026-03-23 18:41   ` Darrick J. Wong
  0 siblings, 0 replies; 50+ messages in thread
From: Darrick J. Wong @ 2026-03-23 18:41 UTC (permalink / raw)
  To: djwong, aalbersh; +Cc: hch, linux-xfs

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

While trying to fix problems in generic/753, I noticed test failures on
account of xfs_repair:

 attribute entry #4 in attr block 0, inode 131 is INCOMPLETE
 problem with attribute contents in inode 131
 would clear attr fork
 bad nblocks 4 for inode 131, would reset to 0
 bad anextents 1 for inode 131, would reset to 0

Looking at the dumped filesystem, inode 131 is a linked file, and the
"incomplete" xattr was clearly part of an xfs_attr_set operation that
failed midway through because the induced log shutdown prevented xfs
from finishing the creation of a remote xattr.  This kind of thing is
expected, but instead xfs_repair deletes the entire attr fork!

It's far too drastic to delete every xattr because doing that destroys
things like security labels.  The kernel won't show incomplete attrs so
it's not a big deal to leave them attached to the file.  Note that
xfs_scrub can fix such things.

Signed-off-by: "Darrick J. Wong" <djwong@kernel.org>
Reviewed-by: Christoph Hellwig <hch@lst.de>
---
 repair/attr_repair.c |   22 +++++++++++++++++-----
 1 file changed, 17 insertions(+), 5 deletions(-)


diff --git a/repair/attr_repair.c b/repair/attr_repair.c
index 50159b9a533875..fe4089026cae74 100644
--- a/repair/attr_repair.c
+++ b/repair/attr_repair.c
@@ -571,7 +571,13 @@ process_leaf_attr_remote(
 	    !libxfs_attr_namecheck(entry->flags, remotep->name,
 				   remotep->namelen) ||
 	    be32_to_cpu(entry->hashval) != computed ||
-	    be32_to_cpu(entry->hashval) < last_hashval ||
+	    be32_to_cpu(entry->hashval) < last_hashval) {
+		do_warn(
+	_("inconsistent remote attribute entry %d in attr block %u, ino %" PRIu64 "\n"), i, da_bno, ino);
+		return -1;
+	}
+
+	if (!(entry->flags & XFS_ATTR_INCOMPLETE) &&
 	    be32_to_cpu(remotep->valueblk) == 0) {
 		do_warn(
 	_("inconsistent remote attribute entry %d in attr block %u, ino %" PRIu64 "\n"), i, da_bno, ino);
@@ -592,6 +598,9 @@ process_leaf_attr_remote(
 		return -1;
 	}
 
+	if (entry->flags & XFS_ATTR_INCOMPLETE)
+		goto out;
+
 	value = malloc(be32_to_cpu(remotep->valuelen));
 	if (value == NULL) {
 		do_warn(
@@ -708,12 +717,15 @@ process_leaf_attr_block(
 		}
 
 		if (entry->flags & XFS_ATTR_INCOMPLETE) {
-			/* we are inconsistent state. get rid of us */
-			do_warn(
+			/*
+			 * Warn about incomplete xattrs but don't zap the
+			 * entire attr fork because that causes loss of
+			 * security labels.  The kernel can handle stray
+			 * incomplete attr entries.
+			 */
+			do_log(
 	_("attribute entry #%d in attr block %u, inode %" PRIu64 " is INCOMPLETE\n"),
 				i, da_bno, ino);
-			clearit = 1;
-			break;
 		}
 
 		/* mark the entry used */


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

* [PATCH 01/40] libxfs: fix XFS_STATS_DEC
  2026-03-23 18:41 ` [PATCHSET 2/2] xfsprogs: new libxfs code from kernel 7.0 Darrick J. Wong
@ 2026-03-23 18:41   ` Darrick J. Wong
  2026-03-24  6:15     ` Christoph Hellwig
  2026-03-25 16:32     ` [PATCH v1.1 " Darrick J. Wong
  2026-03-23 18:41   ` [PATCH 02/40] libxfs: port various kernel apis from 7.0 Darrick J. Wong
                     ` (38 subsequent siblings)
  39 siblings, 2 replies; 50+ messages in thread
From: Darrick J. Wong @ 2026-03-23 18:41 UTC (permalink / raw)
  To: djwong, aalbersh; +Cc: linux-xfs, linux-xfs

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

This macro only takes two arguments in the kernel, so fix the definition
here too.  All existing callsites #if 0 it into oblivion which is why
we've never noticed, but an upcoming patch in the libxfs sync will not
be so lucky.

Cc: <linux-xfs@vger.kernel.org> # v4.9.0
Fixes: ece930fa14a343 ("xfs: refactor xfs_bunmapi_cow")
Signed-off-by: "Darrick J. Wong" <djwong@kernel.org>
---
 libxfs/libxfs_priv.h |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)


diff --git a/libxfs/libxfs_priv.h b/libxfs/libxfs_priv.h
index 5474865a673e9a..f72f07fabdf21e 100644
--- a/libxfs/libxfs_priv.h
+++ b/libxfs/libxfs_priv.h
@@ -183,7 +183,7 @@ enum ce { CE_DEBUG, CE_CONT, CE_NOTE, CE_WARN, CE_ALERT, CE_PANIC };
 #define XFS_ILOCK_SHARED		0
 #define XFS_IOLOCK_EXCL			0
 #define XFS_STATS_INC(mp, count)	do { (mp) = (mp); } while (0)
-#define XFS_STATS_DEC(mp, count, x)	do { (mp) = (mp); } while (0)
+#define XFS_STATS_DEC(mp, count)	do { (mp) = (mp); } while (0)
 #define XFS_STATS_ADD(mp, count, x)	do { (mp) = (mp); } while (0)
 #define XFS_TEST_ERROR(a,b)		(false)
 


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

* [PATCH 02/40] libxfs: port various kernel apis from 7.0
  2026-03-23 18:41 ` [PATCHSET 2/2] xfsprogs: new libxfs code from kernel 7.0 Darrick J. Wong
  2026-03-23 18:41   ` [PATCH 01/40] libxfs: fix XFS_STATS_DEC Darrick J. Wong
@ 2026-03-23 18:41   ` Darrick J. Wong
  2026-03-24  6:16     ` Christoph Hellwig
  2026-03-25 16:33     ` [PATCH v1.1 " Darrick J. Wong
  2026-03-23 18:42   ` [PATCH 03/40] libfrog: hoist some utilities from libxfs Darrick J. Wong
                     ` (37 subsequent siblings)
  39 siblings, 2 replies; 50+ messages in thread
From: Darrick J. Wong @ 2026-03-23 18:41 UTC (permalink / raw)
  To: djwong, aalbersh; +Cc: linux-xfs

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

Port more kernel APIs from Linux 7.0.

Signed-off-by: "Darrick J. Wong" <djwong@kernel.org>
---
 include/kmem.h |   50 ++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 50 insertions(+)


diff --git a/include/kmem.h b/include/kmem.h
index 66f8b1fbea8fdf..2c276e929c4808 100644
--- a/include/kmem.h
+++ b/include/kmem.h
@@ -61,6 +61,56 @@ static inline void *kmalloc(size_t size, gfp_t flags)
 #define kzalloc(size, gfp)	kvmalloc((size), (gfp) | __GFP_ZERO)
 #define kvzalloc(size, gfp)	kzalloc((size), (gfp))
 
+/**
+ * kmalloc_array - allocate memory for an array.
+ * @n: number of elements.
+ * @size: element size.
+ * @flags: the type of memory to allocate (see kmalloc).
+ */
+static inline void *kmalloc_array(size_t n, size_t size, gfp_t flags)
+{
+	size_t bytes;
+
+	if (unlikely(check_mul_overflow(n, size, &bytes)))
+		return NULL;
+	return kmalloc(bytes, flags);
+}
+#define kcalloc(n, size, gfp)	kmalloc_array((n), (size), (gfp) | __GFP_ZERO)
+
+/**
+ * size_mul() - Calculate size_t multiplication with saturation at SIZE_MAX
+ * @factor1: first factor
+ * @factor2: second factor
+ *
+ * Returns: calculate @factor1 * @factor2, both promoted to size_t,
+ * with any overflow causing the return value to be SIZE_MAX. The
+ * lvalue must be size_t to avoid implicit type conversion.
+ */
+static inline size_t __must_check size_mul(size_t factor1, size_t factor2)
+{
+	size_t bytes;
+
+	if (check_mul_overflow(factor1, factor2, &bytes))
+		return SIZE_MAX;
+
+	return bytes;
+}
+
+#define __alloc_objs(KMALLOC, GFP, TYPE, COUNT)				\
+({									\
+	const size_t __obj_size = size_mul(sizeof(TYPE), COUNT);	\
+	(TYPE *)KMALLOC(__obj_size, GFP);				\
+})
+
+/* Helper macro to avoid gfp flags if they are the default one */
+#define __default_gfp(a,b,...) b
+#define default_gfp(...) __default_gfp(,##__VA_ARGS__,GFP_KERNEL)
+
+#define kzalloc_obj(P, ...) \
+	__alloc_objs(kzalloc, default_gfp(__VA_ARGS__), typeof(P), 1)
+#define kmalloc_obj(VAR_OR_TYPE, ...) \
+	__alloc_objs(kmalloc, default_gfp(__VA_ARGS__), typeof(VAR_OR_TYPE), 1)
+
 static inline void kfree(const void *ptr)
 {
 	free((void *)ptr);


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

* [PATCH 03/40] libfrog: hoist some utilities from libxfs
  2026-03-23 18:41 ` [PATCHSET 2/2] xfsprogs: new libxfs code from kernel 7.0 Darrick J. Wong
  2026-03-23 18:41   ` [PATCH 01/40] libxfs: fix XFS_STATS_DEC Darrick J. Wong
  2026-03-23 18:41   ` [PATCH 02/40] libxfs: port various kernel apis from 7.0 Darrick J. Wong
@ 2026-03-23 18:42   ` Darrick J. Wong
  2026-03-23 18:42   ` [PATCH 04/40] libfrog: fix missing gettext call in current_fixed_time Darrick J. Wong
                     ` (36 subsequent siblings)
  39 siblings, 0 replies; 50+ messages in thread
From: Darrick J. Wong @ 2026-03-23 18:42 UTC (permalink / raw)
  To: djwong, aalbersh; +Cc: hch, linux-xfs

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

This started with a desire to move the duplicate cmn_err declarations in
libxfs into libfrog/util.h ahead of the patch that renames libxfs_priv.h
to xfs_platform.h.

Then this patch expanded in scope when I realized that there were
several other utility functions that weren't specific to xfs; those go
in libfrog.

Signed-off-by: "Darrick J. Wong" <djwong@kernel.org>
Reviewed-by: Christoph Hellwig <hch@lst.de>
---
 include/libxfs.h        |    7 --
 include/platform_defs.h |    8 ++
 include/xfs_fs_compat.h |    8 --
 libfrog/util.h          |   21 ++++++
 libxfs/libxfs_priv.h    |   17 -----
 libfrog/Makefile        |    4 +
 libfrog/util.c          |  166 +++++++++++++++++++++++++++++++++++++++++++++++
 libxfs/Makefile         |    2 -
 libxfs/util.c           |  160 ---------------------------------------------
 9 files changed, 201 insertions(+), 192 deletions(-)


diff --git a/include/libxfs.h b/include/libxfs.h
index 1e0d1a48fbb698..68d1f351f70093 100644
--- a/include/libxfs.h
+++ b/include/libxfs.h
@@ -26,6 +26,7 @@
 #include "libfrog/radix-tree.h"
 #include "libfrog/bitmask.h"
 #include "libfrog/div64.h"
+#include "libfrog/util.h"
 #include "atomic.h"
 #include "spinlock.h"
 
@@ -187,12 +188,6 @@ int	libxfs_alloc_file_space(struct xfs_inode *ip, xfs_off_t offset,
 int	libxfs_file_write(struct xfs_inode *ip, void *buf, off_t pos,
 		size_t len);
 
-/* XXX: this is messy and needs fixing */
-#ifndef __LIBXFS_INTERNAL_XFS_H__
-extern void cmn_err(int, char *, ...);
-enum ce { CE_DEBUG, CE_CONT, CE_NOTE, CE_WARN, CE_ALERT, CE_PANIC };
-#endif
-
 #include "xfs_ialloc.h"
 
 #include "xfs_attr_leaf.h"
diff --git a/include/platform_defs.h b/include/platform_defs.h
index 09129e0f22dcba..b2d80597a83aa4 100644
--- a/include/platform_defs.h
+++ b/include/platform_defs.h
@@ -74,6 +74,14 @@ typedef unsigned short umode_t;
 
 extern int	platform_nproc(void);
 
+/* 64-bit seconds counter that works independently of the C library time_t. */
+typedef long long int time64_t;
+
+struct timespec64 {
+	time64_t	tv_sec;			/* seconds */
+	long		tv_nsec;		/* nanoseconds */
+};
+
 #define NSEC_PER_SEC	(1000000000ULL)
 #define NSEC_PER_USEC	(1000ULL)
 
diff --git a/include/xfs_fs_compat.h b/include/xfs_fs_compat.h
index 0077f00cb94904..ccf00424b1b85a 100644
--- a/include/xfs_fs_compat.h
+++ b/include/xfs_fs_compat.h
@@ -85,14 +85,6 @@ struct xfs_extent_data {
 #define XFS_IOC_CLONE_RANGE	 _IOW (0x94, 13, struct xfs_clone_args)
 #define XFS_IOC_FILE_EXTENT_SAME _IOWR(0x94, 54, struct xfs_extent_data)
 
-/* 64-bit seconds counter that works independently of the C library time_t. */
-typedef long long int time64_t;
-
-struct timespec64 {
-	time64_t	tv_sec;			/* seconds */
-	long		tv_nsec;		/* nanoseconds */
-};
-
 #define U32_MAX		((uint32_t)~0U)
 #define S32_MAX		((int32_t)(U32_MAX >> 1))
 #define S32_MIN		((int32_t)(-S32_MAX - 1))
diff --git a/libfrog/util.h b/libfrog/util.h
index d1c4dd40fc926c..48df6a691a8f6d 100644
--- a/libfrog/util.h
+++ b/libfrog/util.h
@@ -7,6 +7,8 @@
 #define __LIBFROG_UTIL_H__
 
 #include <sys/types.h>
+#include <stdint.h>
+#include <stdbool.h>
 
 unsigned int	log2_roundup(unsigned int i);
 unsigned int	log2_rounddown(unsigned long long i);
@@ -18,4 +20,23 @@ unsigned int	log2_rounddown(unsigned long long i);
 
 void *memchr_inv(const void *start, int c, size_t bytes);
 
+struct timespec64;
+
+bool current_fixed_time(struct timespec64 *tv);
+bool get_deterministic_seed(uint32_t *result);
+
+#ifdef HAVE_GETRANDOM_NONBLOCK
+uint32_t get_random_u32(void);
+#else
+#define get_random_u32()	(0)
+#endif
+
+extern void cmn_err(int, char *, ...);
+enum ce { CE_DEBUG, CE_CONT, CE_NOTE, CE_WARN, CE_ALERT, CE_PANIC };
+
+typedef unsigned char u8;
+unsigned int hweight8(unsigned int w);
+unsigned int hweight32(unsigned int w);
+unsigned int hweight64(uint64_t w);
+
 #endif /* __LIBFROG_UTIL_H__ */
diff --git a/libxfs/libxfs_priv.h b/libxfs/libxfs_priv.h
index f72f07fabdf21e..32b86b1df677c2 100644
--- a/libxfs/libxfs_priv.h
+++ b/libxfs/libxfs_priv.h
@@ -65,9 +65,6 @@
 #include "libfrog/crc32c.h"
 
 #include <sys/xattr.h>
-#ifdef HAVE_GETRANDOM_NONBLOCK
-#include <sys/random.h>
-#endif
 
 /* Zones used in libxfs allocations that aren't in shared header files */
 extern struct kmem_cache *xfs_buf_item_cache;
@@ -133,9 +130,6 @@ extern char    *progname;
 #define XFS_IGET_CREATE			0x1
 #define XFS_IGET_UNTRUSTED		0x2
 
-extern void cmn_err(int, char *, ...);
-enum ce { CE_DEBUG, CE_CONT, CE_NOTE, CE_WARN, CE_ALERT, CE_PANIC };
-
 #define xfs_info(mp,fmt,args...)	cmn_err(CE_CONT, _(fmt), ## args)
 #define xfs_info_ratelimited(mp,fmt,args...) cmn_err(CE_CONT, _(fmt), ## args)
 #define xfs_notice(mp,fmt,args...)	cmn_err(CE_NOTE, _(fmt), ## args)
@@ -214,12 +208,6 @@ static inline bool WARN_ON(bool expr) {
 #define percpu_counter_read_positive(x)	((*x) > 0 ? (*x) : 0)
 #define percpu_counter_sum_positive(x)	((*x) > 0 ? (*x) : 0)
 
-#ifdef HAVE_GETRANDOM_NONBLOCK
-uint32_t get_random_u32(void);
-#else
-#define get_random_u32()	(0)
-#endif
-
 #define PAGE_SIZE		getpagesize()
 extern unsigned int PAGE_SHIFT;
 
@@ -567,11 +555,6 @@ void xfs_log_item_init(struct xfs_mount *mp, struct xfs_log_item *lip, int type,
 #define XFS_STATS_INC_OFF(mp, off)
 #define XFS_STATS_ADD_OFF(mp, off, val)
 
-typedef unsigned char u8;
-unsigned int hweight8(unsigned int w);
-unsigned int hweight32(unsigned int w);
-unsigned int hweight64(__u64 w);
-
 #define xfs_buf_cache_init(bch)		(0)
 #define xfs_buf_cache_destroy(bch)	((void)0)
 
diff --git a/libfrog/Makefile b/libfrog/Makefile
index 9f405ffe347566..927bd8d0957fab 100644
--- a/libfrog/Makefile
+++ b/libfrog/Makefile
@@ -82,6 +82,10 @@ else
 HAVE_GETTEXT = False
 endif
 
+ifeq ($(HAVE_GETRANDOM_NONBLOCK),yes)
+LCFLAGS += -DHAVE_GETRANDOM_NONBLOCK
+endif
+
 default: ltdepend $(LTLIBRARY) $(GETTEXT_PY)
 
 crc32table.h: gen_crc32table.c crc32defs.h
diff --git a/libfrog/util.c b/libfrog/util.c
index 4e130c884c17a2..d49cf72426f6c8 100644
--- a/libfrog/util.c
+++ b/libfrog/util.c
@@ -6,6 +6,12 @@
 #include "platform_defs.h"
 #include "util.h"
 
+#ifdef HAVE_GETRANDOM_NONBLOCK
+#include <sys/random.h>
+#endif
+
+extern char *progname;
+
 /*
  * libfrog is a collection of miscellaneous userspace utilities.
  * It's a library of Funny Random Oddball Gunk <cough>.
@@ -48,3 +54,163 @@ log2_rounddown(unsigned long long i)
 	}
 	return rval;
 }
+
+/*
+ * current_fixed_time() tries to detect if SOURCE_DATE_EPOCH is in our
+ * environment, and set input timespec's timestamp to that value.
+ *
+ * Returns true on success, fail otherwise.
+ */
+bool
+current_fixed_time(
+	struct timespec64	*tv)
+{
+	/*
+	 * To avoid many getenv() we'll use an initialization static flag, so
+	 * we only read once.
+	 */
+	static bool		enabled = false;
+	static bool		read_env = false;
+	static time64_t		epoch;
+	char			*endp;
+	char			*source_date_epoch;
+
+	if (!read_env) {
+		read_env = true;
+		source_date_epoch = getenv("SOURCE_DATE_EPOCH");
+		if (source_date_epoch && source_date_epoch[0] != '\0') {
+			errno = 0;
+			epoch = strtoll(source_date_epoch, &endp, 10);
+			if (errno != 0 || *endp != '\0') {
+				fprintf(stderr,
+			"%s: SOURCE_DATE_EPOCH '%s' invalid timestamp, ignoring.\n",
+				progname, source_date_epoch);
+
+				return false;
+			}
+
+			enabled = true;
+		}
+	}
+
+	/*
+	 * This will happen only if we successfully read a valid
+	 * SOURCE_DATE_EPOCH and properly initiated the epoch value.
+	 */
+	if (read_env && enabled) {
+		tv->tv_sec = epoch;
+		tv->tv_nsec = 0;
+		return true;
+	}
+
+	/*
+	 * We initialized but had no valid SOURCE_DATE_EPOCH so we fall back
+	 * to regular behaviour.
+	 */
+	return false;
+}
+
+void
+cmn_err(int level, char *fmt, ...)
+{
+	va_list	ap;
+
+	va_start(ap, fmt);
+	vfprintf(stderr, fmt, ap);
+	fputs("\n", stderr);
+	va_end(ap);
+}
+
+unsigned int
+hweight8(unsigned int w)
+{
+	unsigned int res = w - ((w >> 1) & 0x55);
+	res = (res & 0x33) + ((res >> 2) & 0x33);
+	return (res + (res >> 4)) & 0x0F;
+}
+
+unsigned int
+hweight32(unsigned int w)
+{
+	unsigned int res = w - ((w >> 1) & 0x55555555);
+	res = (res & 0x33333333) + ((res >> 2) & 0x33333333);
+	res = (res + (res >> 4)) & 0x0F0F0F0F;
+	res = res + (res >> 8);
+	return (res + (res >> 16)) & 0x000000FF;
+}
+
+unsigned int
+hweight64(uint64_t w)
+{
+	return hweight32((unsigned int)w) +
+	       hweight32((unsigned int)(w >> 32));
+}
+
+/*
+ * get_deterministic_seed() tries to detect if DETERMINISTIC_SEED=1 is in our
+ * environment, and set our result to 0x53454544 (SEED) instead of
+ * extracting from getrandom().
+ *
+ * Returns true on success, fail otherwise.
+ */
+bool
+get_deterministic_seed(
+	uint32_t	*result)
+{
+	/*
+	 * To avoid many getenv() we'll use an initialization static flag, so
+	 * we only read once.
+	 */
+	static bool	enabled = false;
+	static bool	read_env = false;
+	static uint32_t	deterministic_seed = 0x53454544; /* SEED */
+	char		*seed_env;
+
+	if (!read_env) {
+		read_env = true;
+		seed_env = getenv("DETERMINISTIC_SEED");
+		if (seed_env && strcmp(seed_env, "1") == 0)
+			enabled = true;
+	}
+
+	/*
+	 * This will happen only if we successfully read DETERMINISTIC_SEED=1.
+	 */
+	if (read_env && enabled) {
+		*result = deterministic_seed;
+
+		return true;
+	}
+
+	/*
+	 * We initialized but had no DETERMINISTIC_SEED=1 in env so we fall
+	 * back to regular behaviour.
+	 */
+	return false;
+}
+
+#ifdef HAVE_GETRANDOM_NONBLOCK
+uint32_t
+get_random_u32(void)
+{
+	uint32_t	ret;
+	ssize_t		sz;
+
+	/*
+	 * Check for DETERMINISTIC_SEED in environment, it means we're
+	 * creating a reproducible filesystem.
+	 * If it fails, fall back to returning getrandom() like we used to do.
+	 */
+	if (get_deterministic_seed(&ret))
+		return ret;
+	/*
+	 * Try to extract a u32 of randomness from /dev/urandom.  If that
+	 * fails, fall back to returning zero like we used to do.
+	 */
+	sz = getrandom(&ret, sizeof(ret), GRND_NONBLOCK);
+	if (sz != sizeof(ret))
+		return 0;
+
+	return ret;
+}
+#endif
diff --git a/libxfs/Makefile b/libxfs/Makefile
index 61c43529b532b6..c5e2161c33096a 100644
--- a/libxfs/Makefile
+++ b/libxfs/Makefile
@@ -169,7 +169,7 @@ endif
 
 FCFLAGS = -I.
 
-LTLIBS = $(LIBPTHREAD) $(LIBRT)
+LTLIBS = $(LIBPTHREAD) $(LIBRT) $(LIBFROG)
 
 # don't try linking xfs_repair with a debug libxfs.
 DEBUG = -DNDEBUG
diff --git a/libxfs/util.c b/libxfs/util.c
index 2b1c32efc4709a..14b746ec705092 100644
--- a/libxfs/util.c
+++ b/libxfs/util.c
@@ -137,61 +137,6 @@ xfs_log_calc_unit_res(
 	return unit_bytes;
 }
 
-/*
- * current_fixed_time() tries to detect if SOURCE_DATE_EPOCH is in our
- * environment, and set input timespec's timestamp to that value.
- *
- * Returns true on success, fail otherwise.
- */
-static bool
-current_fixed_time(
-	struct			timespec64 *tv)
-{
-	/*
-	 * To avoid many getenv() we'll use an initialization static flag, so
-	 * we only read once.
-	 */
-	static bool		enabled = false;
-	static bool		read_env = false;
-	static time64_t		epoch;
-	char			*endp;
-	char			*source_date_epoch;
-
-	if (!read_env) {
-		read_env = true;
-		source_date_epoch = getenv("SOURCE_DATE_EPOCH");
-		if (source_date_epoch && source_date_epoch[0] != '\0') {
-			errno = 0;
-			epoch = strtoll(source_date_epoch, &endp, 10);
-			if (errno != 0 || *endp != '\0') {
-				fprintf(stderr,
-			"%s: SOURCE_DATE_EPOCH '%s' invalid timestamp, ignoring.\n",
-				progname, source_date_epoch);
-
-				return false;
-			}
-
-			enabled = true;
-		}
-	}
-
-	/*
-	 * This will happen only if we successfully read a valid
-	 * SOURCE_DATE_EPOCH and properly initiated the epoch value.
-	 */
-	if (read_env && enabled) {
-		tv->tv_sec = epoch;
-		tv->tv_nsec = 0;
-		return true;
-	}
-
-	/*
-	 * We initialized but had no valid SOURCE_DATE_EPOCH so we fall back
-	 * to regular behaviour.
-	 */
-	return false;
-}
-
 struct timespec64
 current_time(struct inode *inode)
 {
@@ -364,17 +309,6 @@ libxfs_alloc_file_space(
 	return error;
 }
 
-void
-cmn_err(int level, char *fmt, ...)
-{
-	va_list	ap;
-
-	va_start(ap, fmt);
-	vfprintf(stderr, fmt, ap);
-	fputs("\n", stderr);
-	va_end(ap);
-}
-
 /*
  * Warnings specifically for verifier errors.  Differentiate CRC vs. invalid
  * values, and omit the stack trace unless the error level is tuned high.
@@ -513,31 +447,6 @@ libxfs_zero_extent(
 	return libxfs_device_zero(xfs_find_bdev_for_inode(ip), sector, size);
 }
 
-unsigned int
-hweight8(unsigned int w)
-{
-	unsigned int res = w - ((w >> 1) & 0x55);
-	res = (res & 0x33) + ((res >> 2) & 0x33);
-	return (res + (res >> 4)) & 0x0F;
-}
-
-unsigned int
-hweight32(unsigned int w)
-{
-	unsigned int res = w - ((w >> 1) & 0x55555555);
-	res = (res & 0x33333333) + ((res >> 2) & 0x33333333);
-	res = (res + (res >> 4)) & 0x0F0F0F0F;
-	res = res + (res >> 8);
-	return (res + (res >> 16)) & 0x000000FF;
-}
-
-unsigned int
-hweight64(__u64 w)
-{
-	return hweight32((unsigned int)w) +
-	       hweight32((unsigned int)(w >> 32));
-}
-
 /* xfs_health.c */
 
 /* Mark a per-fs metadata healed. */
@@ -579,75 +488,6 @@ void xfs_dirattr_mark_sick(struct xfs_inode *ip, int whichfork) { }
 void xfs_da_mark_sick(struct xfs_da_args *args) { }
 void xfs_inode_mark_sick(struct xfs_inode *ip, unsigned int mask) { }
 
-/*
- * get_deterministic_seed() tries to detect if DETERMINISTIC_SEED=1 is in our
- * environment, and set our result to 0x53454544 (SEED) instead of
- * extracting from getrandom().
- *
- * Returns true on success, fail otherwise.
- */
-static bool
-get_deterministic_seed(
-	uint32_t	*result)
-{
-	/*
-	 * To avoid many getenv() we'll use an initialization static flag, so
-	 * we only read once.
-	 */
-	static bool	enabled = false;
-	static bool	read_env = false;
-	static uint32_t	deterministic_seed = 0x53454544; /* SEED */
-	char		*seed_env;
-
-	if (!read_env) {
-		read_env = true;
-		seed_env = getenv("DETERMINISTIC_SEED");
-		if (seed_env && strcmp(seed_env, "1") == 0)
-			enabled = true;
-	}
-
-	/*
-	 * This will happen only if we successfully read DETERMINISTIC_SEED=1.
-	 */
-	if (read_env && enabled) {
-		*result = deterministic_seed;
-
-		return true;
-	}
-
-	/*
-	 * We initialized but had no DETERMINISTIC_SEED=1 in env so we fall
-	 * back to regular behaviour.
-	 */
-	return false;
-}
-
-#ifdef HAVE_GETRANDOM_NONBLOCK
-uint32_t
-get_random_u32(void)
-{
-	uint32_t	ret;
-	ssize_t		sz;
-
-	/*
-	 * Check for DETERMINISTIC_SEED in environment, it means we're
-	 * creating a reproducible filesystem.
-	 * If it fails, fall back to returning getrandom() like we used to do.
-	 */
-	if (get_deterministic_seed(&ret))
-		return ret;
-	/*
-	 * Try to extract a u32 of randomness from /dev/urandom.  If that
-	 * fails, fall back to returning zero like we used to do.
-	 */
-	sz = getrandom(&ret, sizeof(ret), GRND_NONBLOCK);
-	if (sz != sizeof(ret))
-		return 0;
-
-	return ret;
-}
-#endif
-
 /*
  * Write a buffer to a file on the data device.  There must not be sparse holes
  * or unwritten extents, and the blocks underneath the file range will be


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

* [PATCH 04/40] libfrog: fix missing gettext call in current_fixed_time
  2026-03-23 18:41 ` [PATCHSET 2/2] xfsprogs: new libxfs code from kernel 7.0 Darrick J. Wong
                     ` (2 preceding siblings ...)
  2026-03-23 18:42   ` [PATCH 03/40] libfrog: hoist some utilities from libxfs Darrick J. Wong
@ 2026-03-23 18:42   ` Darrick J. Wong
  2026-03-23 18:42   ` [PATCH 05/40] xfs: start creating infrastructure for health monitoring Darrick J. Wong
                     ` (35 subsequent siblings)
  39 siblings, 0 replies; 50+ messages in thread
From: Darrick J. Wong @ 2026-03-23 18:42 UTC (permalink / raw)
  To: djwong, aalbersh; +Cc: hch, linux-xfs

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

This error message can be seen by regular users, so it should be looked
up in the internationalization catalogue with gettext.

Signed-off-by: "Darrick J. Wong" <djwong@kernel.org>
Reviewed-by: Christoph Hellwig <hch@lst.de>
---
 libfrog/util.c |    4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)


diff --git a/libfrog/util.c b/libfrog/util.c
index d49cf72426f6c8..5bae5bab46f91d 100644
--- a/libfrog/util.c
+++ b/libfrog/util.c
@@ -83,8 +83,8 @@ current_fixed_time(
 			epoch = strtoll(source_date_epoch, &endp, 10);
 			if (errno != 0 || *endp != '\0') {
 				fprintf(stderr,
-			"%s: SOURCE_DATE_EPOCH '%s' invalid timestamp, ignoring.\n",
-				progname, source_date_epoch);
+ _("%s: SOURCE_DATE_EPOCH '%s' invalid timestamp, ignoring.\n"),
+						progname, source_date_epoch);
 
 				return false;
 			}


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

* [PATCH 05/40] xfs: start creating infrastructure for health monitoring
  2026-03-23 18:41 ` [PATCHSET 2/2] xfsprogs: new libxfs code from kernel 7.0 Darrick J. Wong
                     ` (3 preceding siblings ...)
  2026-03-23 18:42   ` [PATCH 04/40] libfrog: fix missing gettext call in current_fixed_time Darrick J. Wong
@ 2026-03-23 18:42   ` Darrick J. Wong
  2026-03-23 18:42   ` [PATCH 06/40] xfs: create event queuing, formatting, and discovery infrastructure Darrick J. Wong
                     ` (34 subsequent siblings)
  39 siblings, 0 replies; 50+ messages in thread
From: Darrick J. Wong @ 2026-03-23 18:42 UTC (permalink / raw)
  To: djwong, aalbersh; +Cc: hch, linux-xfs

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

Source kernel commit: a48373e7d35a89f6f9b39f0d0da9bf158af054ee

Start creating helper functions and infrastructure to pass filesystem
health events to a health monitoring file.  Since this is an
administrative interface, we only support a single health monitor
process per filesystem, so we don't need to use anything fancy such as
notifier chains (== tons of indirect calls).

Signed-off-by: "Darrick J. Wong" <djwong@kernel.org>
Reviewed-by: Christoph Hellwig <hch@lst.de>
---
 libxfs/xfs_fs.h |    7 +++++++
 1 file changed, 7 insertions(+)


diff --git a/libxfs/xfs_fs.h b/libxfs/xfs_fs.h
index 12463ba766da05..c58e55b3df4099 100644
--- a/libxfs/xfs_fs.h
+++ b/libxfs/xfs_fs.h
@@ -1003,6 +1003,12 @@ struct xfs_rtgroup_geometry {
 #define XFS_RTGROUP_GEOM_SICK_RMAPBT	(1U << 3)  /* reverse mappings */
 #define XFS_RTGROUP_GEOM_SICK_REFCNTBT	(1U << 4)  /* reference counts */
 
+struct xfs_health_monitor {
+	__u64	flags;		/* flags */
+	__u8	format;		/* output format */
+	__u8	pad[23];	/* zeroes */
+};
+
 /*
  * ioctl commands that are used by Linux filesystems
  */
@@ -1042,6 +1048,7 @@ struct xfs_rtgroup_geometry {
 #define XFS_IOC_GETPARENTS_BY_HANDLE _IOWR('X', 63, struct xfs_getparents_by_handle)
 #define XFS_IOC_SCRUBV_METADATA	_IOWR('X', 64, struct xfs_scrub_vec_head)
 #define XFS_IOC_RTGROUP_GEOMETRY _IOWR('X', 65, struct xfs_rtgroup_geometry)
+#define XFS_IOC_HEALTH_MONITOR	_IOW ('X', 68, struct xfs_health_monitor)
 
 /*
  * ioctl commands that replace IRIX syssgi()'s


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

* [PATCH 06/40] xfs: create event queuing, formatting, and discovery infrastructure
  2026-03-23 18:41 ` [PATCHSET 2/2] xfsprogs: new libxfs code from kernel 7.0 Darrick J. Wong
                     ` (4 preceding siblings ...)
  2026-03-23 18:42   ` [PATCH 05/40] xfs: start creating infrastructure for health monitoring Darrick J. Wong
@ 2026-03-23 18:42   ` Darrick J. Wong
  2026-03-23 18:43   ` [PATCH 07/40] xfs: convey filesystem unmount events to the health monitor Darrick J. Wong
                     ` (33 subsequent siblings)
  39 siblings, 0 replies; 50+ messages in thread
From: Darrick J. Wong @ 2026-03-23 18:42 UTC (permalink / raw)
  To: djwong, aalbersh; +Cc: hch, linux-xfs

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

Source kernel commit: b3a289a2a9397b2e731f334d7d36623a0f9192c5

Create the basic infrastructure that we need to report health events to
userspace.  We need a compact form for recording critical information
about an event and queueing them; a means to notice that we've lost some
events; and a means to format the events into something that userspace
can handle.  Make the kernel export C structures via read().

In a previous iteration of this new subsystem, I wanted to explore data
exchange formats that are more flexible and easier for humans to read
than C structures.  The thought being that when we want to rev (or
worse, enlarge) the event format, it ought to be trivially easy to do
that in a way that doesn't break old userspace.

I looked at formats such as protobufs and capnproto.  These look really
nice in that extending the wire format is fairly easy, you can give it a
data schema and it generates the serialization code for you, handles
endianness problems, etc.  The huge downside is that neither support C
all that well.

Too hard, and didn't want to port either of those huge sprawling
libraries first to the kernel and then again to xfsprogs.  Then I
thought, how about JSON?  Javascript objects are human readable, the
kernel can emit json without much fuss (it's all just strings!) and
there are plenty of interpreters for python/rust/c/etc.

There's a proposed schema format for json, which means that xfs can
publish a description of the events that kernel will emit.  Userspace
consumers (e.g. xfsprogs/xfs_healer) can embed the same schema document
and use it to validate the incoming events from the kernel, which means
it can discard events that it doesn't understand, or garbage being
emitted due to bugs.

However, json has a huge crutch -- javascript is well known for its
vague definitions of what are numbers.  This makes expressing a large
number rather fraught, because the runtime is free to represent a number
in nearly any way it wants.  Stupider ones will truncate values to word
size, others will roll out doubles for uint52_t (yes, fifty-two) with
the resulting loss of precision.  Not good when you're dealing with
discrete units.

It just so happens that python's json library is smart enough to see a
sequence of digits and put them in a u64 (at least on x86_64/aarch64)
but an actual javascript interpreter (pasting into Firefox) isn't
necessarily so clever.

It turns out that none of the proposed json schemas were ever ratified
even in an open-consensus way, so json blobs are still just loosely
structured blobs.  The parsing in userspace was also noticeably slow and
memory-consumptive.

Hence only the C interface survives.

Signed-off-by: "Darrick J. Wong" <djwong@kernel.org>
Reviewed-by: Christoph Hellwig <hch@lst.de>
---
 libxfs/xfs_fs.h |   47 +++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 47 insertions(+)


diff --git a/libxfs/xfs_fs.h b/libxfs/xfs_fs.h
index c58e55b3df4099..22b86bc888de5a 100644
--- a/libxfs/xfs_fs.h
+++ b/libxfs/xfs_fs.h
@@ -1003,12 +1003,59 @@ struct xfs_rtgroup_geometry {
 #define XFS_RTGROUP_GEOM_SICK_RMAPBT	(1U << 3)  /* reverse mappings */
 #define XFS_RTGROUP_GEOM_SICK_REFCNTBT	(1U << 4)  /* reference counts */
 
+/* Health monitor event domains */
+
+/* affects the whole fs */
+#define XFS_HEALTH_MONITOR_DOMAIN_MOUNT		(0)
+
+/* Health monitor event types */
+
+/* status of the monitor itself */
+#define XFS_HEALTH_MONITOR_TYPE_RUNNING		(0)
+#define XFS_HEALTH_MONITOR_TYPE_LOST		(1)
+
+/* lost events */
+struct xfs_health_monitor_lost {
+	__u64	count;
+};
+
+struct xfs_health_monitor_event {
+	/* XFS_HEALTH_MONITOR_DOMAIN_* */
+	__u32	domain;
+
+	/* XFS_HEALTH_MONITOR_TYPE_* */
+	__u32	type;
+
+	/* Timestamp of the event, in nanoseconds since the Unix epoch */
+	__u64	time_ns;
+
+	/*
+	 * Details of the event.  The primary clients are written in python
+	 * and rust, so break this up because bindgen hates anonymous structs
+	 * and unions.
+	 */
+	union {
+		struct xfs_health_monitor_lost lost;
+	} e;
+
+	/* zeroes */
+	__u64	pad[2];
+};
+
 struct xfs_health_monitor {
 	__u64	flags;		/* flags */
 	__u8	format;		/* output format */
 	__u8	pad[23];	/* zeroes */
 };
 
+/* Return all health status events, not just deltas */
+#define XFS_HEALTH_MONITOR_VERBOSE	(1ULL << 0)
+
+#define XFS_HEALTH_MONITOR_ALL		(XFS_HEALTH_MONITOR_VERBOSE)
+
+/* Initial return format version */
+#define XFS_HEALTH_MONITOR_FMT_V0	(0)
+
 /*
  * ioctl commands that are used by Linux filesystems
  */


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

* [PATCH 07/40] xfs: convey filesystem unmount events to the health monitor
  2026-03-23 18:41 ` [PATCHSET 2/2] xfsprogs: new libxfs code from kernel 7.0 Darrick J. Wong
                     ` (5 preceding siblings ...)
  2026-03-23 18:42   ` [PATCH 06/40] xfs: create event queuing, formatting, and discovery infrastructure Darrick J. Wong
@ 2026-03-23 18:43   ` Darrick J. Wong
  2026-03-23 18:43   ` [PATCH 08/40] xfs: convey metadata health " Darrick J. Wong
                     ` (32 subsequent siblings)
  39 siblings, 0 replies; 50+ messages in thread
From: Darrick J. Wong @ 2026-03-23 18:43 UTC (permalink / raw)
  To: djwong, aalbersh; +Cc: hch, linux-xfs

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

Source kernel commit: 25ca57fa3624cae9c6b5c6d3fc7f38318ca1402e

In xfs_healthmon_unmount, send events to xfs_healer so that it knows
that nothing further can be done for the filesystem.

Signed-off-by: "Darrick J. Wong" <djwong@kernel.org>
Reviewed-by: Christoph Hellwig <hch@lst.de>
---
 libxfs/xfs_fs.h |    3 +++
 1 file changed, 3 insertions(+)


diff --git a/libxfs/xfs_fs.h b/libxfs/xfs_fs.h
index 22b86bc888de5a..59de6ab69fb319 100644
--- a/libxfs/xfs_fs.h
+++ b/libxfs/xfs_fs.h
@@ -1014,6 +1014,9 @@ struct xfs_rtgroup_geometry {
 #define XFS_HEALTH_MONITOR_TYPE_RUNNING		(0)
 #define XFS_HEALTH_MONITOR_TYPE_LOST		(1)
 
+/* filesystem was unmounted */
+#define XFS_HEALTH_MONITOR_TYPE_UNMOUNT		(2)
+
 /* lost events */
 struct xfs_health_monitor_lost {
 	__u64	count;


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

* [PATCH 08/40] xfs: convey metadata health events to the health monitor
  2026-03-23 18:41 ` [PATCHSET 2/2] xfsprogs: new libxfs code from kernel 7.0 Darrick J. Wong
                     ` (6 preceding siblings ...)
  2026-03-23 18:43   ` [PATCH 07/40] xfs: convey filesystem unmount events to the health monitor Darrick J. Wong
@ 2026-03-23 18:43   ` Darrick J. Wong
  2026-03-23 18:43   ` [PATCH 09/40] xfs: convey filesystem shutdown " Darrick J. Wong
                     ` (31 subsequent siblings)
  39 siblings, 0 replies; 50+ messages in thread
From: Darrick J. Wong @ 2026-03-23 18:43 UTC (permalink / raw)
  To: djwong, aalbersh; +Cc: hch, linux-xfs

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

Source kernel commit: 5eb4cb18e445d09f64ef4b7c8fdc3b2296cb0702

Connect the filesystem metadata health event collection system to the
health monitor so that xfs can send events to xfs_healer as it collects
information.

Signed-off-by: "Darrick J. Wong" <djwong@kernel.org>
Reviewed-by: Christoph Hellwig <hch@lst.de>
---
 libxfs/xfs_fs.h     |   35 +++++++++++++++++++++++++++++++++++
 libxfs/xfs_health.h |    5 +++++
 2 files changed, 40 insertions(+)


diff --git a/libxfs/xfs_fs.h b/libxfs/xfs_fs.h
index 59de6ab69fb319..04e1dcf61257d0 100644
--- a/libxfs/xfs_fs.h
+++ b/libxfs/xfs_fs.h
@@ -1008,6 +1008,12 @@ struct xfs_rtgroup_geometry {
 /* affects the whole fs */
 #define XFS_HEALTH_MONITOR_DOMAIN_MOUNT		(0)
 
+/* metadata health events */
+#define XFS_HEALTH_MONITOR_DOMAIN_FS		(1)
+#define XFS_HEALTH_MONITOR_DOMAIN_AG		(2)
+#define XFS_HEALTH_MONITOR_DOMAIN_INODE		(3)
+#define XFS_HEALTH_MONITOR_DOMAIN_RTGROUP	(4)
+
 /* Health monitor event types */
 
 /* status of the monitor itself */
@@ -1017,11 +1023,37 @@ struct xfs_rtgroup_geometry {
 /* filesystem was unmounted */
 #define XFS_HEALTH_MONITOR_TYPE_UNMOUNT		(2)
 
+/* metadata health events */
+#define XFS_HEALTH_MONITOR_TYPE_SICK		(3)
+#define XFS_HEALTH_MONITOR_TYPE_CORRUPT		(4)
+#define XFS_HEALTH_MONITOR_TYPE_HEALTHY		(5)
+
 /* lost events */
 struct xfs_health_monitor_lost {
 	__u64	count;
 };
 
+/* fs/rt metadata */
+struct xfs_health_monitor_fs {
+	/* XFS_FSOP_GEOM_SICK_* flags */
+	__u32	mask;
+};
+
+/* ag/rtgroup metadata */
+struct xfs_health_monitor_group {
+	/* XFS_{AG,RTGROUP}_SICK_* flags */
+	__u32	mask;
+	__u32	gno;
+};
+
+/* inode metadata */
+struct xfs_health_monitor_inode {
+	/* XFS_BS_SICK_* flags */
+	__u32	mask;
+	__u32	gen;
+	__u64	ino;
+};
+
 struct xfs_health_monitor_event {
 	/* XFS_HEALTH_MONITOR_DOMAIN_* */
 	__u32	domain;
@@ -1039,6 +1071,9 @@ struct xfs_health_monitor_event {
 	 */
 	union {
 		struct xfs_health_monitor_lost lost;
+		struct xfs_health_monitor_fs fs;
+		struct xfs_health_monitor_group group;
+		struct xfs_health_monitor_inode inode;
 	} e;
 
 	/* zeroes */
diff --git a/libxfs/xfs_health.h b/libxfs/xfs_health.h
index b31000f7190ce5..1d45cf5789e864 100644
--- a/libxfs/xfs_health.h
+++ b/libxfs/xfs_health.h
@@ -289,4 +289,9 @@ void xfs_bulkstat_health(struct xfs_inode *ip, struct xfs_bulkstat *bs);
 #define xfs_metadata_is_sick(error) \
 	(unlikely((error) == -EFSCORRUPTED || (error) == -EFSBADCRC))
 
+unsigned int xfs_healthmon_inode_mask(unsigned int sick_mask);
+unsigned int xfs_healthmon_rtgroup_mask(unsigned int sick_mask);
+unsigned int xfs_healthmon_perag_mask(unsigned int sick_mask);
+unsigned int xfs_healthmon_fs_mask(unsigned int sick_mask);
+
 #endif	/* __XFS_HEALTH_H__ */


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

* [PATCH 09/40] xfs: convey filesystem shutdown events to the health monitor
  2026-03-23 18:41 ` [PATCHSET 2/2] xfsprogs: new libxfs code from kernel 7.0 Darrick J. Wong
                     ` (7 preceding siblings ...)
  2026-03-23 18:43   ` [PATCH 08/40] xfs: convey metadata health " Darrick J. Wong
@ 2026-03-23 18:43   ` Darrick J. Wong
  2026-03-23 18:43   ` [PATCH 10/40] xfs: convey externally discovered fsdax media errors " Darrick J. Wong
                     ` (30 subsequent siblings)
  39 siblings, 0 replies; 50+ messages in thread
From: Darrick J. Wong @ 2026-03-23 18:43 UTC (permalink / raw)
  To: djwong, aalbersh; +Cc: hch, linux-xfs

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

Source kernel commit: 74c4795e50f816dbf5cf094691fc4f95bbc729ad

Connect the filesystem shutdown code to the health monitor so that xfs
can send events about that to the xfs_healer daemon.

Signed-off-by: "Darrick J. Wong" <djwong@kernel.org>
Reviewed-by: Christoph Hellwig <hch@lst.de>
---
 libxfs/xfs_fs.h |   18 ++++++++++++++++++
 1 file changed, 18 insertions(+)


diff --git a/libxfs/xfs_fs.h b/libxfs/xfs_fs.h
index 04e1dcf61257d0..c8f7011a7ef8ef 100644
--- a/libxfs/xfs_fs.h
+++ b/libxfs/xfs_fs.h
@@ -1028,6 +1028,9 @@ struct xfs_rtgroup_geometry {
 #define XFS_HEALTH_MONITOR_TYPE_CORRUPT		(4)
 #define XFS_HEALTH_MONITOR_TYPE_HEALTHY		(5)
 
+/* filesystem shutdown */
+#define XFS_HEALTH_MONITOR_TYPE_SHUTDOWN	(6)
+
 /* lost events */
 struct xfs_health_monitor_lost {
 	__u64	count;
@@ -1054,6 +1057,20 @@ struct xfs_health_monitor_inode {
 	__u64	ino;
 };
 
+/* shutdown reasons */
+#define XFS_HEALTH_SHUTDOWN_META_IO_ERROR	(1u << 0)
+#define XFS_HEALTH_SHUTDOWN_LOG_IO_ERROR	(1u << 1)
+#define XFS_HEALTH_SHUTDOWN_FORCE_UMOUNT	(1u << 2)
+#define XFS_HEALTH_SHUTDOWN_CORRUPT_INCORE	(1u << 3)
+#define XFS_HEALTH_SHUTDOWN_CORRUPT_ONDISK	(1u << 4)
+#define XFS_HEALTH_SHUTDOWN_DEVICE_REMOVED	(1u << 5)
+
+/* shutdown */
+struct xfs_health_monitor_shutdown {
+	/* XFS_HEALTH_SHUTDOWN_* flags */
+	__u32	reasons;
+};
+
 struct xfs_health_monitor_event {
 	/* XFS_HEALTH_MONITOR_DOMAIN_* */
 	__u32	domain;
@@ -1074,6 +1091,7 @@ struct xfs_health_monitor_event {
 		struct xfs_health_monitor_fs fs;
 		struct xfs_health_monitor_group group;
 		struct xfs_health_monitor_inode inode;
+		struct xfs_health_monitor_shutdown shutdown;
 	} e;
 
 	/* zeroes */


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

* [PATCH 10/40] xfs: convey externally discovered fsdax media errors to the health monitor
  2026-03-23 18:41 ` [PATCHSET 2/2] xfsprogs: new libxfs code from kernel 7.0 Darrick J. Wong
                     ` (8 preceding siblings ...)
  2026-03-23 18:43   ` [PATCH 09/40] xfs: convey filesystem shutdown " Darrick J. Wong
@ 2026-03-23 18:43   ` Darrick J. Wong
  2026-03-23 18:44   ` [PATCH 11/40] xfs: convey file I/O " Darrick J. Wong
                     ` (29 subsequent siblings)
  39 siblings, 0 replies; 50+ messages in thread
From: Darrick J. Wong @ 2026-03-23 18:43 UTC (permalink / raw)
  To: djwong, aalbersh; +Cc: hch, linux-xfs

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

Source kernel commit: e76e0e3fc9957a5183ddc51dc84c3e471125ab06

Connect the fsdax media failure notification code to the health monitor
so that xfs can send events about that to the xfs_healer daemon.

Later on we'll add the ability for the xfs_scrub media scan (phase 6) to
report the errors that it finds to the kernel so that those are also
logged by xfs_healer.

Signed-off-by: "Darrick J. Wong" <djwong@kernel.org>
Reviewed-by: Christoph Hellwig <hch@lst.de>
---
 libxfs/xfs_fs.h |   15 +++++++++++++++
 1 file changed, 15 insertions(+)


diff --git a/libxfs/xfs_fs.h b/libxfs/xfs_fs.h
index c8f7011a7ef8ef..38aeb1b0d87b5e 100644
--- a/libxfs/xfs_fs.h
+++ b/libxfs/xfs_fs.h
@@ -1014,6 +1014,11 @@ struct xfs_rtgroup_geometry {
 #define XFS_HEALTH_MONITOR_DOMAIN_INODE		(3)
 #define XFS_HEALTH_MONITOR_DOMAIN_RTGROUP	(4)
 
+/* disk events */
+#define XFS_HEALTH_MONITOR_DOMAIN_DATADEV	(5)
+#define XFS_HEALTH_MONITOR_DOMAIN_RTDEV		(6)
+#define XFS_HEALTH_MONITOR_DOMAIN_LOGDEV	(7)
+
 /* Health monitor event types */
 
 /* status of the monitor itself */
@@ -1031,6 +1036,9 @@ struct xfs_rtgroup_geometry {
 /* filesystem shutdown */
 #define XFS_HEALTH_MONITOR_TYPE_SHUTDOWN	(6)
 
+/* media errors */
+#define XFS_HEALTH_MONITOR_TYPE_MEDIA_ERROR	(7)
+
 /* lost events */
 struct xfs_health_monitor_lost {
 	__u64	count;
@@ -1071,6 +1079,12 @@ struct xfs_health_monitor_shutdown {
 	__u32	reasons;
 };
 
+/* disk media errors */
+struct xfs_health_monitor_media {
+	__u64	daddr;
+	__u64	bbcount;
+};
+
 struct xfs_health_monitor_event {
 	/* XFS_HEALTH_MONITOR_DOMAIN_* */
 	__u32	domain;
@@ -1092,6 +1106,7 @@ struct xfs_health_monitor_event {
 		struct xfs_health_monitor_group group;
 		struct xfs_health_monitor_inode inode;
 		struct xfs_health_monitor_shutdown shutdown;
+		struct xfs_health_monitor_media media;
 	} e;
 
 	/* zeroes */


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

* [PATCH 11/40] xfs: convey file I/O errors to the health monitor
  2026-03-23 18:41 ` [PATCHSET 2/2] xfsprogs: new libxfs code from kernel 7.0 Darrick J. Wong
                     ` (9 preceding siblings ...)
  2026-03-23 18:43   ` [PATCH 10/40] xfs: convey externally discovered fsdax media errors " Darrick J. Wong
@ 2026-03-23 18:44   ` Darrick J. Wong
  2026-03-23 18:44   ` [PATCH 12/40] xfs: check if an open file is on the health monitored fs Darrick J. Wong
                     ` (28 subsequent siblings)
  39 siblings, 0 replies; 50+ messages in thread
From: Darrick J. Wong @ 2026-03-23 18:44 UTC (permalink / raw)
  To: djwong, aalbersh; +Cc: hch, linux-xfs

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

Source kernel commit: dfa8bad3a8796ce1ca4f1d15158e2ecfb9c5c014

Connect the fserror reporting to the health monitor so that xfs can send
events about file I/O errors to the xfs_healer daemon.  These events are
entirely informational because xfs cannot regenerate user data, so
hopefully the fsnotify I/O error event gets noticed by the relevant
management systems.

Signed-off-by: "Darrick J. Wong" <djwong@kernel.org>
Reviewed-by: Christoph Hellwig <hch@lst.de>
---
 libxfs/xfs_fs.h |   24 ++++++++++++++++++++++++
 1 file changed, 24 insertions(+)


diff --git a/libxfs/xfs_fs.h b/libxfs/xfs_fs.h
index 38aeb1b0d87b5e..4ec1b2aede976f 100644
--- a/libxfs/xfs_fs.h
+++ b/libxfs/xfs_fs.h
@@ -1019,6 +1019,9 @@ struct xfs_rtgroup_geometry {
 #define XFS_HEALTH_MONITOR_DOMAIN_RTDEV		(6)
 #define XFS_HEALTH_MONITOR_DOMAIN_LOGDEV	(7)
 
+/* file range events */
+#define XFS_HEALTH_MONITOR_DOMAIN_FILERANGE	(8)
+
 /* Health monitor event types */
 
 /* status of the monitor itself */
@@ -1039,6 +1042,17 @@ struct xfs_rtgroup_geometry {
 /* media errors */
 #define XFS_HEALTH_MONITOR_TYPE_MEDIA_ERROR	(7)
 
+/* pagecache I/O to a file range failed */
+#define XFS_HEALTH_MONITOR_TYPE_BUFREAD		(8)
+#define XFS_HEALTH_MONITOR_TYPE_BUFWRITE	(9)
+
+/* direct I/O to a file range failed */
+#define XFS_HEALTH_MONITOR_TYPE_DIOREAD		(10)
+#define XFS_HEALTH_MONITOR_TYPE_DIOWRITE	(11)
+
+/* out of band media error reported for a file range */
+#define XFS_HEALTH_MONITOR_TYPE_DATALOST	(12)
+
 /* lost events */
 struct xfs_health_monitor_lost {
 	__u64	count;
@@ -1079,6 +1093,15 @@ struct xfs_health_monitor_shutdown {
 	__u32	reasons;
 };
 
+/* file range events */
+struct xfs_health_monitor_filerange {
+	__u64	pos;
+	__u64	len;
+	__u64	ino;
+	__u32	gen;
+	__u32	error;
+};
+
 /* disk media errors */
 struct xfs_health_monitor_media {
 	__u64	daddr;
@@ -1107,6 +1130,7 @@ struct xfs_health_monitor_event {
 		struct xfs_health_monitor_inode inode;
 		struct xfs_health_monitor_shutdown shutdown;
 		struct xfs_health_monitor_media media;
+		struct xfs_health_monitor_filerange filerange;
 	} e;
 
 	/* zeroes */


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

* [PATCH 12/40] xfs: check if an open file is on the health monitored fs
  2026-03-23 18:41 ` [PATCHSET 2/2] xfsprogs: new libxfs code from kernel 7.0 Darrick J. Wong
                     ` (10 preceding siblings ...)
  2026-03-23 18:44   ` [PATCH 11/40] xfs: convey file I/O " Darrick J. Wong
@ 2026-03-23 18:44   ` Darrick J. Wong
  2026-03-23 18:44   ` [PATCH 13/40] xfs: add media verification ioctl Darrick J. Wong
                     ` (27 subsequent siblings)
  39 siblings, 0 replies; 50+ messages in thread
From: Darrick J. Wong @ 2026-03-23 18:44 UTC (permalink / raw)
  To: djwong, aalbersh; +Cc: hch, linux-xfs

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

Source kernel commit: 8b85dc4090e1c72c6d42acd823514cce67cd54fc

Create a new ioctl for the healthmon file that checks that a given fd
points to the same filesystem that the healthmon file is monitoring.
This allows xfs_healer to check that when it reopens a mountpoint to
perform repairs, the file that it gets matches the filesystem that
generated the corruption report.

(Note that xfs_healer doesn't maintain an open fd to a filesystem that
it's monitoring so that it doesn't pin the mount.)

Signed-off-by: "Darrick J. Wong" <djwong@kernel.org>
Reviewed-by: Christoph Hellwig <hch@lst.de>
---
 libxfs/xfs_fs.h |   12 +++++++++++-
 1 file changed, 11 insertions(+), 1 deletion(-)


diff --git a/libxfs/xfs_fs.h b/libxfs/xfs_fs.h
index 4ec1b2aede976f..a01303c5de6ce6 100644
--- a/libxfs/xfs_fs.h
+++ b/libxfs/xfs_fs.h
@@ -1151,6 +1151,15 @@ struct xfs_health_monitor {
 /* Initial return format version */
 #define XFS_HEALTH_MONITOR_FMT_V0	(0)
 
+/*
+ * Check that a given fd points to the same filesystem that the health monitor
+ * is monitoring.
+ */
+struct xfs_health_file_on_monitored_fs {
+	__s32		fd;
+	__u32		flags;	/* zero for now */
+};
+
 /*
  * ioctl commands that are used by Linux filesystems
  */
@@ -1191,7 +1200,8 @@ struct xfs_health_monitor {
 #define XFS_IOC_SCRUBV_METADATA	_IOWR('X', 64, struct xfs_scrub_vec_head)
 #define XFS_IOC_RTGROUP_GEOMETRY _IOWR('X', 65, struct xfs_rtgroup_geometry)
 #define XFS_IOC_HEALTH_MONITOR	_IOW ('X', 68, struct xfs_health_monitor)
-
+#define XFS_IOC_HEALTH_FD_ON_MONITORED_FS \
+				_IOW ('X', 69, struct xfs_health_file_on_monitored_fs)
 /*
  * ioctl commands that replace IRIX syssgi()'s
  */


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

* [PATCH 13/40] xfs: add media verification ioctl
  2026-03-23 18:41 ` [PATCHSET 2/2] xfsprogs: new libxfs code from kernel 7.0 Darrick J. Wong
                     ` (11 preceding siblings ...)
  2026-03-23 18:44   ` [PATCH 12/40] xfs: check if an open file is on the health monitored fs Darrick J. Wong
@ 2026-03-23 18:44   ` Darrick J. Wong
  2026-03-23 18:44   ` [PATCH 14/40] xfs: move struct xfs_log_iovec to xfs_log_priv.h Darrick J. Wong
                     ` (26 subsequent siblings)
  39 siblings, 0 replies; 50+ messages in thread
From: Darrick J. Wong @ 2026-03-23 18:44 UTC (permalink / raw)
  To: djwong, aalbersh; +Cc: hch, linux-xfs

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

Source kernel commit: b8accfd65d31f25b9df15ec2419179b6fa0b21d5

Add a new privileged ioctl so that xfs_scrub can ask the kernel to
verify the media of the devices backing an xfs filesystem, and have any
resulting media errors reported to fsnotify and xfs_healer.

To accomplish this, the kernel allocates a folio between the base page
size and 1MB, and issues read IOs to a gradually incrementing range of
one of the storage devices underlying an xfs filesystem.  If any error
occurs, that raw error is reported to the calling process.  If the error
happens to be one of the ones that the kernel considers indicative of
data loss, then it will also be reported to xfs_healthmon and fsnotify.

Driving the verification from the kernel enables xfs (and by extension
xfs_scrub) to have precise control over the size and error handling of
IOs that are issued to the underlying block device, and to emit
notifications about problems to other relevant kernel subsystems
immediately.

Note that the caller is also allowed to reduce the size of the IO and
to ask for a relaxation period after each IO.

Signed-off-by: "Darrick J. Wong" <djwong@kernel.org>
Reviewed-by: Christoph Hellwig <hch@lst.de>
---
 libxfs/xfs_fs.h |   30 ++++++++++++++++++++++++++++++
 1 file changed, 30 insertions(+)


diff --git a/libxfs/xfs_fs.h b/libxfs/xfs_fs.h
index a01303c5de6ce6..d165de607d179e 100644
--- a/libxfs/xfs_fs.h
+++ b/libxfs/xfs_fs.h
@@ -1160,6 +1160,34 @@ struct xfs_health_file_on_monitored_fs {
 	__u32		flags;	/* zero for now */
 };
 
+/* Verify the media of the underlying devices */
+struct xfs_verify_media {
+	__u32	me_dev;		/* I: XFS_DEV_{DATA,LOG,RT} */
+	__u32	me_flags;	/* I: XFS_VERIFY_MEDIA_* */
+
+	/*
+	 * IO: inclusive start of disk range to verify, in 512b blocks.
+	 * Will be adjusted upwards as media verification succeeds.
+	 */
+	__u64	me_start_daddr;
+
+	/*
+	 * IO: exclusive end of the disk range to verify, in 512b blocks.
+	 * Can be adjusted downwards to match device size.
+	 */
+	__u64	me_end_daddr;
+
+	__u32	me_ioerror;	/* O: I/O error (positive) */
+	__u32	me_max_io_size;	/* I: maximum IO size in bytes */
+
+	__u32	me_rest_us;	/* I: rest time between IOs, usecs */
+	__u32	me_pad;		/* zero */
+};
+
+#define XFS_VERIFY_MEDIA_REPORT	(1 << 0)	/* report to fsnotify */
+
+#define XFS_VERIFY_MEDIA_FLAGS	(XFS_VERIFY_MEDIA_REPORT)
+
 /*
  * ioctl commands that are used by Linux filesystems
  */
@@ -1202,6 +1230,8 @@ struct xfs_health_file_on_monitored_fs {
 #define XFS_IOC_HEALTH_MONITOR	_IOW ('X', 68, struct xfs_health_monitor)
 #define XFS_IOC_HEALTH_FD_ON_MONITORED_FS \
 				_IOW ('X', 69, struct xfs_health_file_on_monitored_fs)
+#define XFS_IOC_VERIFY_MEDIA	_IOWR('X', 70, struct xfs_verify_media)
+
 /*
  * ioctl commands that replace IRIX syssgi()'s
  */


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

* [PATCH 14/40] xfs: move struct xfs_log_iovec to xfs_log_priv.h
  2026-03-23 18:41 ` [PATCHSET 2/2] xfsprogs: new libxfs code from kernel 7.0 Darrick J. Wong
                     ` (12 preceding siblings ...)
  2026-03-23 18:44   ` [PATCH 13/40] xfs: add media verification ioctl Darrick J. Wong
@ 2026-03-23 18:44   ` Darrick J. Wong
  2026-03-23 18:45   ` [PATCH 15/40] xfs: directly include xfs_platform.h Darrick J. Wong
                     ` (25 subsequent siblings)
  39 siblings, 0 replies; 50+ messages in thread
From: Darrick J. Wong @ 2026-03-23 18:44 UTC (permalink / raw)
  To: djwong, aalbersh; +Cc: cem, hch, linux-xfs

From: Christoph Hellwig <hch@lst.de>

Source kernel commit: 027410591418bded6ba6051151d88fc6fb8a7614

This structure is now only used by the core logging and CIL code.

Also remove the unused typedef.

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_log_format.h   |    7 -------
 libxlog/xfs_log_recover.c |    4 ++--
 2 files changed, 2 insertions(+), 9 deletions(-)


diff --git a/libxfs/xfs_log_format.h b/libxfs/xfs_log_format.h
index 908e7060428ccb..3f5a24dda90701 100644
--- a/libxfs/xfs_log_format.h
+++ b/libxfs/xfs_log_format.h
@@ -184,13 +184,6 @@ struct xlog_rec_header {
 #define XLOG_REC_SIZE_OTHER	offsetofend(struct xlog_rec_header, h_size)
 #endif /* __i386__ */
 
-/* not an on-disk structure, but needed by log recovery in userspace */
-struct xfs_log_iovec {
-	void		*i_addr;	/* beginning address of region */
-	int		i_len;		/* length in bytes of region */
-	uint		i_type;		/* type of region */
-};
-
 /*
  * Transaction Header definitions.
  *
diff --git a/libxlog/xfs_log_recover.c b/libxlog/xfs_log_recover.c
index 65e3c782d59674..af72b97d150b75 100644
--- a/libxlog/xfs_log_recover.c
+++ b/libxlog/xfs_log_recover.c
@@ -1112,8 +1112,8 @@ xlog_recover_add_to_trans(
 		}
 
 		item->ri_total = in_f->ilf_size;
-		item->ri_buf = kzalloc(
-			item->ri_total * sizeof(struct xfs_log_iovec), 0);
+		item->ri_buf = kcalloc(item->ri_total, sizeof(*item->ri_buf),
+				0);
 	}
 	ASSERT(item->ri_total > item->ri_cnt);
 	/* Description region is ri_buf[0] */


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

* [PATCH 15/40] xfs: directly include xfs_platform.h
  2026-03-23 18:41 ` [PATCHSET 2/2] xfsprogs: new libxfs code from kernel 7.0 Darrick J. Wong
                     ` (13 preceding siblings ...)
  2026-03-23 18:44   ` [PATCH 14/40] xfs: move struct xfs_log_iovec to xfs_log_priv.h Darrick J. Wong
@ 2026-03-23 18:45   ` Darrick J. Wong
  2026-03-23 18:45   ` [PATCH 16/40] xfs: remove xfs_attr_leaf_hasname Darrick J. Wong
                     ` (24 subsequent siblings)
  39 siblings, 0 replies; 50+ messages in thread
From: Darrick J. Wong @ 2026-03-23 18:45 UTC (permalink / raw)
  To: djwong, aalbersh; +Cc: cem, hch, linux-xfs

From: Christoph Hellwig <hch@lst.de>

Source kernel commit: cf9b52fa7d65362b648927d1d752ec99659f5c43

The xfs.h header conflicts with the public xfs.h in xfsprogs, leading
to a spurious difference in all shared libxfs files that have to
include libxfs_priv.h in userspace.  Directly include xfs_platform.h so
that we can add a header of the same name to xfsprogs and remove this
major annoyance for the shared code.

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_platform.h         |    6 +++---
 libxfs/Makefile               |    2 +-
 libxfs/buf_mem.c              |    2 +-
 libxfs/cache.c                |    2 +-
 libxfs/defer_item.c           |    2 +-
 libxfs/init.c                 |    2 +-
 libxfs/inode.c                |    2 +-
 libxfs/iunlink.c              |    2 +-
 libxfs/kmem.c                 |    2 +-
 libxfs/logitem.c              |    2 +-
 libxfs/rdwr.c                 |    2 +-
 libxfs/topology.c             |    2 +-
 libxfs/trans.c                |    2 +-
 libxfs/util.c                 |    2 +-
 libxfs/xfblob.c               |    2 +-
 libxfs/xfile.c                |    2 +-
 libxfs/xfs_ag.c               |    2 +-
 libxfs/xfs_ag_resv.c          |    2 +-
 libxfs/xfs_alloc.c            |    2 +-
 libxfs/xfs_alloc_btree.c      |    2 +-
 libxfs/xfs_attr.c             |    2 +-
 libxfs/xfs_attr_leaf.c        |    2 +-
 libxfs/xfs_attr_remote.c      |    2 +-
 libxfs/xfs_bit.c              |    2 +-
 libxfs/xfs_bmap.c             |    2 +-
 libxfs/xfs_bmap_btree.c       |    2 +-
 libxfs/xfs_btree.c            |    2 +-
 libxfs/xfs_btree_mem.c        |    2 +-
 libxfs/xfs_btree_staging.c    |    2 +-
 libxfs/xfs_da_btree.c         |    2 +-
 libxfs/xfs_defer.c            |    2 +-
 libxfs/xfs_dir2.c             |    2 +-
 libxfs/xfs_dir2_block.c       |    2 +-
 libxfs/xfs_dir2_data.c        |    2 +-
 libxfs/xfs_dir2_leaf.c        |    2 +-
 libxfs/xfs_dir2_node.c        |    2 +-
 libxfs/xfs_dir2_sf.c          |    2 +-
 libxfs/xfs_dquot_buf.c        |    2 +-
 libxfs/xfs_exchmaps.c         |    2 +-
 libxfs/xfs_group.c            |    2 +-
 libxfs/xfs_ialloc.c           |    2 +-
 libxfs/xfs_ialloc_btree.c     |    2 +-
 libxfs/xfs_iext_tree.c        |    2 +-
 libxfs/xfs_inode_buf.c        |    2 +-
 libxfs/xfs_inode_fork.c       |    2 +-
 libxfs/xfs_inode_util.c       |    2 +-
 libxfs/xfs_log_rlimit.c       |    2 +-
 libxfs/xfs_metadir.c          |    2 +-
 libxfs/xfs_metafile.c         |    2 +-
 libxfs/xfs_parent.c           |    2 +-
 libxfs/xfs_refcount.c         |    2 +-
 libxfs/xfs_refcount_btree.c   |    2 +-
 libxfs/xfs_rmap.c             |    2 +-
 libxfs/xfs_rmap_btree.c       |    2 +-
 libxfs/xfs_rtbitmap.c         |    2 +-
 libxfs/xfs_rtgroup.c          |    2 +-
 libxfs/xfs_rtrefcount_btree.c |    2 +-
 libxfs/xfs_rtrmap_btree.c     |    2 +-
 libxfs/xfs_sb.c               |    2 +-
 libxfs/xfs_symlink_remote.c   |    2 +-
 libxfs/xfs_trans_inode.c      |    2 +-
 libxfs/xfs_trans_resv.c       |    2 +-
 libxfs/xfs_trans_space.c      |    2 +-
 libxfs/xfs_types.c            |    2 +-
 libxfs/xfs_zones.c            |    2 +-
 repair/zoned.c                |    2 +-
 66 files changed, 68 insertions(+), 68 deletions(-)
 rename libxfs/{libxfs_priv.h => xfs_platform.h} (99%)


diff --git a/libxfs/libxfs_priv.h b/libxfs/xfs_platform.h
similarity index 99%
rename from libxfs/libxfs_priv.h
rename to libxfs/xfs_platform.h
index 32b86b1df677c2..5cddfbb82cc88c 100644
--- a/libxfs/libxfs_priv.h
+++ b/libxfs/xfs_platform.h
@@ -34,8 +34,8 @@
  * define a guard and something we can check to determine what include context
  * we are running from.
  */
-#ifndef __LIBXFS_INTERNAL_XFS_H__
-#define __LIBXFS_INTERNAL_XFS_H__
+#ifndef _XFS_PLATFORM_H
+#define _XFS_PLATFORM_H
 
 /* CONFIG_XFS_* must be defined to 1 to work with IS_ENABLED() */
 #define CONFIG_XFS_RT 1
@@ -604,4 +604,4 @@ int xfs_bmap_last_extent(struct xfs_trans *tp, struct xfs_inode *ip,
 #define irix_sgid_inherit		(false)
 #define vfsgid_in_group_p(...)		(false)
 
-#endif	/* __LIBXFS_INTERNAL_XFS_H__ */
+#endif	/* _XFS_PLATFORM_H */
diff --git a/libxfs/Makefile b/libxfs/Makefile
index c5e2161c33096a..83c8592e5fe536 100644
--- a/libxfs/Makefile
+++ b/libxfs/Makefile
@@ -26,7 +26,7 @@ HFILES = \
 	listxattr.h \
 	init.h \
 	iunlink.h \
-	libxfs_priv.h \
+	xfs_platform.h \
 	linux-err.h \
 	topology.h \
 	buf_mem.h \
diff --git a/libxfs/buf_mem.c b/libxfs/buf_mem.c
index 77396fa95b4138..15c61966db4384 100644
--- a/libxfs/buf_mem.c
+++ b/libxfs/buf_mem.c
@@ -3,7 +3,7 @@
  * Copyright (c) 2023-2024 Oracle.  All Rights Reserved.
  * Author: Darrick J. Wong <djwong@kernel.org>
  */
-#include "libxfs_priv.h"
+#include "xfs_platform.h"
 #include "libxfs.h"
 #include "libxfs/xfile.h"
 #include "libxfs/buf_mem.h"
diff --git a/libxfs/cache.c b/libxfs/cache.c
index af20f3854df93e..389afeff4a1f16 100644
--- a/libxfs/cache.c
+++ b/libxfs/cache.c
@@ -10,7 +10,7 @@
 #include <unistd.h>
 #include <pthread.h>
 
-#include "libxfs_priv.h"
+#include "xfs_platform.h"
 #include "xfs_fs.h"
 #include "xfs_shared.h"
 #include "xfs_format.h"
diff --git a/libxfs/defer_item.c b/libxfs/defer_item.c
index 3dc938d514e65e..4fc2c74a548c91 100644
--- a/libxfs/defer_item.c
+++ b/libxfs/defer_item.c
@@ -3,7 +3,7 @@
  * Copyright (C) 2016 Oracle.  All Rights Reserved.
  * Author: Darrick J. Wong <darrick.wong@oracle.com>
  */
-#include "libxfs_priv.h"
+#include "xfs_platform.h"
 #include "xfs_fs.h"
 #include "xfs_shared.h"
 #include "xfs_format.h"
diff --git a/libxfs/init.c b/libxfs/init.c
index a5e898539c9eb2..5d8b4a153e28da 100644
--- a/libxfs/init.c
+++ b/libxfs/init.c
@@ -7,7 +7,7 @@
 #include <sys/stat.h>
 #include "init.h"
 
-#include "libxfs_priv.h"
+#include "xfs_platform.h"
 #include "xfs_fs.h"
 #include "xfs_shared.h"
 #include "xfs_format.h"
diff --git a/libxfs/inode.c b/libxfs/inode.c
index 1ce159fcc9d61a..dc7e227e8ee92f 100644
--- a/libxfs/inode.c
+++ b/libxfs/inode.c
@@ -4,7 +4,7 @@
  * All Rights Reserved.
  */
 
-#include "libxfs_priv.h"
+#include "xfs_platform.h"
 #include "libxfs.h"
 #include "libxfs_io.h"
 #include "init.h"
diff --git a/libxfs/iunlink.c b/libxfs/iunlink.c
index 53e36cdc3439b2..2d4dd0aee0b87b 100644
--- a/libxfs/iunlink.c
+++ b/libxfs/iunlink.c
@@ -4,7 +4,7 @@
  * All Rights Reserved.
  */
 
-#include "libxfs_priv.h"
+#include "xfs_platform.h"
 #include "libxfs.h"
 #include "libxfs_io.h"
 #include "init.h"
diff --git a/libxfs/kmem.c b/libxfs/kmem.c
index 2e293518024fe3..718b190ad54607 100644
--- a/libxfs/kmem.c
+++ b/libxfs/kmem.c
@@ -1,7 +1,7 @@
 // SPDX-License-Identifier: GPL-2.0
 
 
-#include "libxfs_priv.h"
+#include "xfs_platform.h"
 
 /*
  * Simple memory interface
diff --git a/libxfs/logitem.c b/libxfs/logitem.c
index 062d6311b942ae..d8d86d919cf4d7 100644
--- a/libxfs/logitem.c
+++ b/libxfs/logitem.c
@@ -4,7 +4,7 @@
  * All Rights Reserved.
  */
 
-#include "libxfs_priv.h"
+#include "xfs_platform.h"
 #include "xfs_fs.h"
 #include "xfs_shared.h"
 #include "xfs_format.h"
diff --git a/libxfs/rdwr.c b/libxfs/rdwr.c
index 3419e821ef0a29..6c57bedef54852 100644
--- a/libxfs/rdwr.c
+++ b/libxfs/rdwr.c
@@ -5,7 +5,7 @@
  */
 
 
-#include "libxfs_priv.h"
+#include "xfs_platform.h"
 #include "init.h"
 #include "xfs_fs.h"
 #include "xfs_shared.h"
diff --git a/libxfs/topology.c b/libxfs/topology.c
index 366165719c84ed..dc2aaa17ab3bda 100644
--- a/libxfs/topology.c
+++ b/libxfs/topology.c
@@ -10,7 +10,7 @@
 #include <fcntl.h>
 #include <sys/stat.h>
 
-#include "libxfs_priv.h"
+#include "xfs_platform.h"
 #include "libxcmd.h"
 #include <blkid/blkid.h>
 #include "xfs_multidisk.h"
diff --git a/libxfs/trans.c b/libxfs/trans.c
index 64457d1710bbd6..c89b035ffeaf10 100644
--- a/libxfs/trans.c
+++ b/libxfs/trans.c
@@ -5,7 +5,7 @@
  * All Rights Reserved.
  */
 
-#include "libxfs_priv.h"
+#include "xfs_platform.h"
 #include "xfs_fs.h"
 #include "xfs_shared.h"
 #include "xfs_format.h"
diff --git a/libxfs/util.c b/libxfs/util.c
index 14b746ec705092..143d011ac60ddd 100644
--- a/libxfs/util.c
+++ b/libxfs/util.c
@@ -4,7 +4,7 @@
  * All Rights Reserved.
  */
 
-#include "libxfs_priv.h"
+#include "xfs_platform.h"
 #include "libxfs.h"
 #include "libxfs_io.h"
 #include "init.h"
diff --git a/libxfs/xfblob.c b/libxfs/xfblob.c
index 00f8ed5e5a7bef..597aeb75641641 100644
--- a/libxfs/xfblob.c
+++ b/libxfs/xfblob.c
@@ -3,7 +3,7 @@
  * Copyright (c) 2022-2024 Oracle.  All Rights Reserved.
  * Author: Darrick J. Wong <djwong@kernel.org>
  */
-#include "libxfs_priv.h"
+#include "xfs_platform.h"
 #include "libxfs.h"
 #include "libxfs/xfile.h"
 #include "libxfs/xfblob.h"
diff --git a/libxfs/xfile.c b/libxfs/xfile.c
index b83797751b87ba..6532197ce6ab29 100644
--- a/libxfs/xfile.c
+++ b/libxfs/xfile.c
@@ -3,7 +3,7 @@
  * Copyright (c) 2021-2024 Oracle.  All Rights Reserved.
  * Author: Darrick J. Wong <djwong@kernel.org>
  */
-#include "libxfs_priv.h"
+#include "xfs_platform.h"
 #include "libxfs.h"
 #include "libxfs/xfile.h"
 #include <linux/memfd.h>
diff --git a/libxfs/xfs_ag.c b/libxfs/xfs_ag.c
index ea64e9eac58945..8ccd67672b4e00 100644
--- a/libxfs/xfs_ag.c
+++ b/libxfs/xfs_ag.c
@@ -5,7 +5,7 @@
  * All rights reserved.
  */
 
-#include "libxfs_priv.h"
+#include "xfs_platform.h"
 #include "xfs_fs.h"
 #include "xfs_shared.h"
 #include "xfs_format.h"
diff --git a/libxfs/xfs_ag_resv.c b/libxfs/xfs_ag_resv.c
index 842e797b2f9c68..052d187330460e 100644
--- a/libxfs/xfs_ag_resv.c
+++ b/libxfs/xfs_ag_resv.c
@@ -3,7 +3,7 @@
  * Copyright (C) 2016 Oracle.  All Rights Reserved.
  * Author: Darrick J. Wong <darrick.wong@oracle.com>
  */
-#include "libxfs_priv.h"
+#include "xfs_platform.h"
 #include "xfs_fs.h"
 #include "xfs_shared.h"
 #include "xfs_format.h"
diff --git a/libxfs/xfs_alloc.c b/libxfs/xfs_alloc.c
index 311f5342d6e982..9f92bd77fad76c 100644
--- a/libxfs/xfs_alloc.c
+++ b/libxfs/xfs_alloc.c
@@ -3,7 +3,7 @@
  * Copyright (c) 2000-2002,2005 Silicon Graphics, Inc.
  * All Rights Reserved.
  */
-#include "libxfs_priv.h"
+#include "xfs_platform.h"
 #include "xfs_fs.h"
 #include "xfs_format.h"
 #include "xfs_log_format.h"
diff --git a/libxfs/xfs_alloc_btree.c b/libxfs/xfs_alloc_btree.c
index 1604e1bb625116..54f0ff75a23805 100644
--- a/libxfs/xfs_alloc_btree.c
+++ b/libxfs/xfs_alloc_btree.c
@@ -3,7 +3,7 @@
  * Copyright (c) 2000-2001,2005 Silicon Graphics, Inc.
  * All Rights Reserved.
  */
-#include "libxfs_priv.h"
+#include "xfs_platform.h"
 #include "xfs_fs.h"
 #include "xfs_shared.h"
 #include "xfs_format.h"
diff --git a/libxfs/xfs_attr.c b/libxfs/xfs_attr.c
index 4b985e054ff84c..72b701f1b6dcae 100644
--- a/libxfs/xfs_attr.c
+++ b/libxfs/xfs_attr.c
@@ -3,7 +3,7 @@
  * Copyright (c) 2000-2005 Silicon Graphics, Inc.
  * All Rights Reserved.
  */
-#include "libxfs_priv.h"
+#include "xfs_platform.h"
 #include "xfs_fs.h"
 #include "xfs_shared.h"
 #include "xfs_format.h"
diff --git a/libxfs/xfs_attr_leaf.c b/libxfs/xfs_attr_leaf.c
index 29e9a419d07c8b..ff1085f0b3afe4 100644
--- a/libxfs/xfs_attr_leaf.c
+++ b/libxfs/xfs_attr_leaf.c
@@ -4,7 +4,7 @@
  * Copyright (c) 2013 Red Hat, Inc.
  * All Rights Reserved.
  */
-#include "libxfs_priv.h"
+#include "xfs_platform.h"
 #include "xfs_fs.h"
 #include "xfs_shared.h"
 #include "xfs_format.h"
diff --git a/libxfs/xfs_attr_remote.c b/libxfs/xfs_attr_remote.c
index 82217baf405bc1..89d01aa7b051e8 100644
--- a/libxfs/xfs_attr_remote.c
+++ b/libxfs/xfs_attr_remote.c
@@ -4,7 +4,7 @@
  * Copyright (c) 2013 Red Hat, Inc.
  * All Rights Reserved.
  */
-#include "libxfs_priv.h"
+#include "xfs_platform.h"
 #include "xfs_fs.h"
 #include "xfs_shared.h"
 #include "xfs_format.h"
diff --git a/libxfs/xfs_bit.c b/libxfs/xfs_bit.c
index 3f97fa3e725686..f05a07c0f75da3 100644
--- a/libxfs/xfs_bit.c
+++ b/libxfs/xfs_bit.c
@@ -3,7 +3,7 @@
  * Copyright (c) 2000-2005 Silicon Graphics, Inc.
  * All Rights Reserved.
  */
-#include "libxfs_priv.h"
+#include "xfs_platform.h"
 #include "xfs_log_format.h"
 #include "xfs_bit.h"
 
diff --git a/libxfs/xfs_bmap.c b/libxfs/xfs_bmap.c
index f2f616e521759e..96975f88497add 100644
--- a/libxfs/xfs_bmap.c
+++ b/libxfs/xfs_bmap.c
@@ -3,7 +3,7 @@
  * Copyright (c) 2000-2006 Silicon Graphics, Inc.
  * All Rights Reserved.
  */
-#include "libxfs_priv.h"
+#include "xfs_platform.h"
 #include "xfs_fs.h"
 #include "xfs_shared.h"
 #include "xfs_format.h"
diff --git a/libxfs/xfs_bmap_btree.c b/libxfs/xfs_bmap_btree.c
index 252da347b06e15..6038c45674557b 100644
--- a/libxfs/xfs_bmap_btree.c
+++ b/libxfs/xfs_bmap_btree.c
@@ -3,7 +3,7 @@
  * Copyright (c) 2000-2003,2005 Silicon Graphics, Inc.
  * All Rights Reserved.
  */
-#include "libxfs_priv.h"
+#include "xfs_platform.h"
 #include "xfs_fs.h"
 #include "xfs_shared.h"
 #include "xfs_format.h"
diff --git a/libxfs/xfs_btree.c b/libxfs/xfs_btree.c
index 1404d86fb96394..4ab0d8d3789b18 100644
--- a/libxfs/xfs_btree.c
+++ b/libxfs/xfs_btree.c
@@ -3,7 +3,7 @@
  * Copyright (c) 2000-2002,2005 Silicon Graphics, Inc.
  * All Rights Reserved.
  */
-#include "libxfs_priv.h"
+#include "xfs_platform.h"
 #include "xfs_fs.h"
 #include "xfs_shared.h"
 #include "xfs_format.h"
diff --git a/libxfs/xfs_btree_mem.c b/libxfs/xfs_btree_mem.c
index 2b98b8d01dce0d..5fa4a9787c99ab 100644
--- a/libxfs/xfs_btree_mem.c
+++ b/libxfs/xfs_btree_mem.c
@@ -3,7 +3,7 @@
  * Copyright (c) 2021-2024 Oracle.  All Rights Reserved.
  * Author: Darrick J. Wong <djwong@kernel.org>
  */
-#include "libxfs_priv.h"
+#include "xfs_platform.h"
 #include "xfs_fs.h"
 #include "xfs_shared.h"
 #include "xfs_format.h"
diff --git a/libxfs/xfs_btree_staging.c b/libxfs/xfs_btree_staging.c
index d82665ef78398e..4300c058807ba5 100644
--- a/libxfs/xfs_btree_staging.c
+++ b/libxfs/xfs_btree_staging.c
@@ -3,7 +3,7 @@
  * Copyright (C) 2020 Oracle.  All Rights Reserved.
  * Author: Darrick J. Wong <darrick.wong@oracle.com>
  */
-#include "libxfs_priv.h"
+#include "xfs_platform.h"
 #include "xfs_fs.h"
 #include "xfs_shared.h"
 #include "xfs_format.h"
diff --git a/libxfs/xfs_da_btree.c b/libxfs/xfs_da_btree.c
index 37be99bd54c772..969bfc9dee909d 100644
--- a/libxfs/xfs_da_btree.c
+++ b/libxfs/xfs_da_btree.c
@@ -4,7 +4,7 @@
  * Copyright (c) 2013 Red Hat, Inc.
  * All Rights Reserved.
  */
-#include "libxfs_priv.h"
+#include "xfs_platform.h"
 #include "xfs_fs.h"
 #include "xfs_shared.h"
 #include "xfs_format.h"
diff --git a/libxfs/xfs_defer.c b/libxfs/xfs_defer.c
index 8f6708c0f3bfcd..5bd3cbe4cfa1a3 100644
--- a/libxfs/xfs_defer.c
+++ b/libxfs/xfs_defer.c
@@ -3,7 +3,7 @@
  * Copyright (C) 2016 Oracle.  All Rights Reserved.
  * Author: Darrick J. Wong <darrick.wong@oracle.com>
  */
-#include "libxfs_priv.h"
+#include "xfs_platform.h"
 #include "xfs_fs.h"
 #include "xfs_shared.h"
 #include "xfs_format.h"
diff --git a/libxfs/xfs_dir2.c b/libxfs/xfs_dir2.c
index d5f2e516e5bfea..2ca6bf198ba54f 100644
--- a/libxfs/xfs_dir2.c
+++ b/libxfs/xfs_dir2.c
@@ -3,7 +3,7 @@
  * Copyright (c) 2000-2001,2005 Silicon Graphics, Inc.
  * All Rights Reserved.
  */
-#include "libxfs_priv.h"
+#include "xfs_platform.h"
 #include "xfs_fs.h"
 #include "xfs_shared.h"
 #include "xfs_format.h"
diff --git a/libxfs/xfs_dir2_block.c b/libxfs/xfs_dir2_block.c
index 82da0d3275e366..29b5b158c80d1f 100644
--- a/libxfs/xfs_dir2_block.c
+++ b/libxfs/xfs_dir2_block.c
@@ -4,7 +4,7 @@
  * Copyright (c) 2013 Red Hat, Inc.
  * All Rights Reserved.
  */
-#include "libxfs_priv.h"
+#include "xfs_platform.h"
 #include "xfs_fs.h"
 #include "xfs_shared.h"
 #include "xfs_format.h"
diff --git a/libxfs/xfs_dir2_data.c b/libxfs/xfs_dir2_data.c
index 65e6ed8791ed9f..1fb43cdfdd6d04 100644
--- a/libxfs/xfs_dir2_data.c
+++ b/libxfs/xfs_dir2_data.c
@@ -4,7 +4,7 @@
  * Copyright (c) 2013 Red Hat, Inc.
  * All Rights Reserved.
  */
-#include "libxfs_priv.h"
+#include "xfs_platform.h"
 #include "xfs_fs.h"
 #include "xfs_shared.h"
 #include "xfs_format.h"
diff --git a/libxfs/xfs_dir2_leaf.c b/libxfs/xfs_dir2_leaf.c
index 7c0bba51288142..b89350b03b8724 100644
--- a/libxfs/xfs_dir2_leaf.c
+++ b/libxfs/xfs_dir2_leaf.c
@@ -4,7 +4,7 @@
  * Copyright (c) 2013 Red Hat, Inc.
  * All Rights Reserved.
  */
-#include "libxfs_priv.h"
+#include "xfs_platform.h"
 #include "xfs_fs.h"
 #include "xfs_shared.h"
 #include "xfs_format.h"
diff --git a/libxfs/xfs_dir2_node.c b/libxfs/xfs_dir2_node.c
index c94d00eb99c874..9d8bb27f716fe4 100644
--- a/libxfs/xfs_dir2_node.c
+++ b/libxfs/xfs_dir2_node.c
@@ -4,7 +4,7 @@
  * Copyright (c) 2013 Red Hat, Inc.
  * All Rights Reserved.
  */
-#include "libxfs_priv.h"
+#include "xfs_platform.h"
 #include "xfs_fs.h"
 #include "xfs_shared.h"
 #include "xfs_format.h"
diff --git a/libxfs/xfs_dir2_sf.c b/libxfs/xfs_dir2_sf.c
index aaf73cd35ca753..1a67cdd6a70706 100644
--- a/libxfs/xfs_dir2_sf.c
+++ b/libxfs/xfs_dir2_sf.c
@@ -3,7 +3,7 @@
  * Copyright (c) 2000-2003,2005 Silicon Graphics, Inc.
  * All Rights Reserved.
  */
-#include "libxfs_priv.h"
+#include "xfs_platform.h"
 #include "xfs_fs.h"
 #include "xfs_shared.h"
 #include "xfs_format.h"
diff --git a/libxfs/xfs_dquot_buf.c b/libxfs/xfs_dquot_buf.c
index 599d03ac960b7b..329aceca005db7 100644
--- a/libxfs/xfs_dquot_buf.c
+++ b/libxfs/xfs_dquot_buf.c
@@ -4,7 +4,7 @@
  * Copyright (c) 2013 Red Hat, Inc.
  * All Rights Reserved.
  */
-#include "libxfs_priv.h"
+#include "xfs_platform.h"
 #include "xfs_fs.h"
 #include "xfs_shared.h"
 #include "xfs_format.h"
diff --git a/libxfs/xfs_exchmaps.c b/libxfs/xfs_exchmaps.c
index 8e39324d42ca25..5566f9faf45612 100644
--- a/libxfs/xfs_exchmaps.c
+++ b/libxfs/xfs_exchmaps.c
@@ -3,7 +3,7 @@
  * Copyright (c) 2020-2024 Oracle.  All Rights Reserved.
  * Author: Darrick J. Wong <djwong@kernel.org>
  */
-#include "libxfs_priv.h"
+#include "xfs_platform.h"
 #include "xfs_fs.h"
 #include "xfs_shared.h"
 #include "xfs_format.h"
diff --git a/libxfs/xfs_group.c b/libxfs/xfs_group.c
index 03c508242d52f6..cb841514750978 100644
--- a/libxfs/xfs_group.c
+++ b/libxfs/xfs_group.c
@@ -3,7 +3,7 @@
  * Copyright (c) 2018 Red Hat, Inc.
  */
 
-#include "libxfs_priv.h"
+#include "xfs_platform.h"
 #include "xfs_shared.h"
 #include "xfs_format.h"
 #include "xfs_trans_resv.h"
diff --git a/libxfs/xfs_ialloc.c b/libxfs/xfs_ialloc.c
index 1da6f07fa030d0..31c818f9870f8d 100644
--- a/libxfs/xfs_ialloc.c
+++ b/libxfs/xfs_ialloc.c
@@ -3,7 +3,7 @@
  * Copyright (c) 2000-2002,2005 Silicon Graphics, Inc.
  * All Rights Reserved.
  */
-#include "libxfs_priv.h"
+#include "xfs_platform.h"
 #include "xfs_fs.h"
 #include "xfs_shared.h"
 #include "xfs_format.h"
diff --git a/libxfs/xfs_ialloc_btree.c b/libxfs/xfs_ialloc_btree.c
index dab9b61bd2006f..e0d886f324d89c 100644
--- a/libxfs/xfs_ialloc_btree.c
+++ b/libxfs/xfs_ialloc_btree.c
@@ -3,7 +3,7 @@
  * Copyright (c) 2000-2001,2005 Silicon Graphics, Inc.
  * All Rights Reserved.
  */
-#include "libxfs_priv.h"
+#include "xfs_platform.h"
 #include "xfs_fs.h"
 #include "xfs_shared.h"
 #include "xfs_format.h"
diff --git a/libxfs/xfs_iext_tree.c b/libxfs/xfs_iext_tree.c
index cdbb72d6387823..5b2b926ab2285f 100644
--- a/libxfs/xfs_iext_tree.c
+++ b/libxfs/xfs_iext_tree.c
@@ -3,7 +3,7 @@
  * Copyright (c) 2017 Christoph Hellwig.
  */
 
-#include "libxfs_priv.h"
+#include "xfs_platform.h"
 #include "xfs_shared.h"
 #include "xfs_format.h"
 #include "xfs_bit.h"
diff --git a/libxfs/xfs_inode_buf.c b/libxfs/xfs_inode_buf.c
index e2c87ca03cc39b..0802bc376073d8 100644
--- a/libxfs/xfs_inode_buf.c
+++ b/libxfs/xfs_inode_buf.c
@@ -3,7 +3,7 @@
  * Copyright (c) 2000-2006 Silicon Graphics, Inc.
  * All Rights Reserved.
  */
-#include "libxfs_priv.h"
+#include "xfs_platform.h"
 #include "xfs_fs.h"
 #include "xfs_shared.h"
 #include "xfs_format.h"
diff --git a/libxfs/xfs_inode_fork.c b/libxfs/xfs_inode_fork.c
index 329d52cc524a16..87afe671886ede 100644
--- a/libxfs/xfs_inode_fork.c
+++ b/libxfs/xfs_inode_fork.c
@@ -4,7 +4,7 @@
  * All Rights Reserved.
  */
 
-#include "libxfs_priv.h"
+#include "xfs_platform.h"
 #include "xfs_fs.h"
 #include "xfs_shared.h"
 #include "xfs_format.h"
diff --git a/libxfs/xfs_inode_util.c b/libxfs/xfs_inode_util.c
index 85d4af41d56de5..ccd38f18c3ed55 100644
--- a/libxfs/xfs_inode_util.c
+++ b/libxfs/xfs_inode_util.c
@@ -3,7 +3,7 @@
  * Copyright (c) 2000-2006 Silicon Graphics, Inc.
  * All Rights Reserved.
  */
-#include "libxfs_priv.h"
+#include "xfs_platform.h"
 #include "xfs_fs.h"
 #include "xfs_shared.h"
 #include "xfs_format.h"
diff --git a/libxfs/xfs_log_rlimit.c b/libxfs/xfs_log_rlimit.c
index 2b9047f5ffb58b..37712b2f87572e 100644
--- a/libxfs/xfs_log_rlimit.c
+++ b/libxfs/xfs_log_rlimit.c
@@ -3,7 +3,7 @@
  * Copyright (c) 2013 Jie Liu.
  * All Rights Reserved.
  */
-#include "libxfs_priv.h"
+#include "xfs_platform.h"
 #include "xfs_fs.h"
 #include "xfs_shared.h"
 #include "xfs_format.h"
diff --git a/libxfs/xfs_metadir.c b/libxfs/xfs_metadir.c
index 253fbf48e170e0..bffe9ba9129002 100644
--- a/libxfs/xfs_metadir.c
+++ b/libxfs/xfs_metadir.c
@@ -3,7 +3,7 @@
  * Copyright (c) 2018-2024 Oracle.  All Rights Reserved.
  * Author: Darrick J. Wong <djwong@kernel.org>
  */
-#include "libxfs_priv.h"
+#include "xfs_platform.h"
 #include "xfs_fs.h"
 #include "xfs_shared.h"
 #include "xfs_format.h"
diff --git a/libxfs/xfs_metafile.c b/libxfs/xfs_metafile.c
index 9c3751f58161e0..8d98989349d086 100644
--- a/libxfs/xfs_metafile.c
+++ b/libxfs/xfs_metafile.c
@@ -3,7 +3,7 @@
  * Copyright (c) 2018-2024 Oracle.  All Rights Reserved.
  * Author: Darrick J. Wong <djwong@kernel.org>
  */
-#include "libxfs_priv.h"
+#include "xfs_platform.h"
 #include "xfs_fs.h"
 #include "xfs_shared.h"
 #include "xfs_format.h"
diff --git a/libxfs/xfs_parent.c b/libxfs/xfs_parent.c
index 84220f10a1f409..12e4299840b8ef 100644
--- a/libxfs/xfs_parent.c
+++ b/libxfs/xfs_parent.c
@@ -3,7 +3,7 @@
  * Copyright (c) 2022-2024 Oracle.
  * All rights reserved.
  */
-#include "libxfs_priv.h"
+#include "xfs_platform.h"
 #include "xfs_fs.h"
 #include "xfs_format.h"
 #include "xfs_da_format.h"
diff --git a/libxfs/xfs_refcount.c b/libxfs/xfs_refcount.c
index f9714acd9a5a1b..5c362e0e901124 100644
--- a/libxfs/xfs_refcount.c
+++ b/libxfs/xfs_refcount.c
@@ -3,7 +3,7 @@
  * Copyright (C) 2016 Oracle.  All Rights Reserved.
  * Author: Darrick J. Wong <darrick.wong@oracle.com>
  */
-#include "libxfs_priv.h"
+#include "xfs_platform.h"
 #include "xfs_fs.h"
 #include "xfs_shared.h"
 #include "xfs_format.h"
diff --git a/libxfs/xfs_refcount_btree.c b/libxfs/xfs_refcount_btree.c
index 44d942e9d098e1..5a39dbbc635ca4 100644
--- a/libxfs/xfs_refcount_btree.c
+++ b/libxfs/xfs_refcount_btree.c
@@ -3,7 +3,7 @@
  * Copyright (C) 2016 Oracle.  All Rights Reserved.
  * Author: Darrick J. Wong <darrick.wong@oracle.com>
  */
-#include "libxfs_priv.h"
+#include "xfs_platform.h"
 #include "xfs_fs.h"
 #include "xfs_shared.h"
 #include "xfs_format.h"
diff --git a/libxfs/xfs_rmap.c b/libxfs/xfs_rmap.c
index 33e856875db419..9da10afe3578b5 100644
--- a/libxfs/xfs_rmap.c
+++ b/libxfs/xfs_rmap.c
@@ -3,7 +3,7 @@
  * Copyright (c) 2014 Red Hat, Inc.
  * All Rights Reserved.
  */
-#include "libxfs_priv.h"
+#include "xfs_platform.h"
 #include "xfs_fs.h"
 #include "xfs_shared.h"
 #include "xfs_format.h"
diff --git a/libxfs/xfs_rmap_btree.c b/libxfs/xfs_rmap_btree.c
index d7b9fccc3a0f5d..c39faa4aac6c2b 100644
--- a/libxfs/xfs_rmap_btree.c
+++ b/libxfs/xfs_rmap_btree.c
@@ -3,7 +3,7 @@
  * Copyright (c) 2014 Red Hat, Inc.
  * All Rights Reserved.
  */
-#include "libxfs_priv.h"
+#include "xfs_platform.h"
 #include "xfs_fs.h"
 #include "xfs_shared.h"
 #include "xfs_format.h"
diff --git a/libxfs/xfs_rtbitmap.c b/libxfs/xfs_rtbitmap.c
index 354ebb8d066e09..7a06305b4e11dd 100644
--- a/libxfs/xfs_rtbitmap.c
+++ b/libxfs/xfs_rtbitmap.c
@@ -3,7 +3,7 @@
  * Copyright (c) 2000-2005 Silicon Graphics, Inc.
  * All Rights Reserved.
  */
-#include "libxfs_priv.h"
+#include "xfs_platform.h"
 #include "xfs_fs.h"
 #include "xfs_shared.h"
 #include "xfs_format.h"
diff --git a/libxfs/xfs_rtgroup.c b/libxfs/xfs_rtgroup.c
index d012ca73000d86..af4eafb20bc138 100644
--- a/libxfs/xfs_rtgroup.c
+++ b/libxfs/xfs_rtgroup.c
@@ -3,7 +3,7 @@
  * Copyright (c) 2022-2024 Oracle.  All Rights Reserved.
  * Author: Darrick J. Wong <djwong@kernel.org>
  */
-#include "libxfs_priv.h"
+#include "xfs_platform.h"
 #include "xfs_fs.h"
 #include "xfs_shared.h"
 #include "xfs_format.h"
diff --git a/libxfs/xfs_rtrefcount_btree.c b/libxfs/xfs_rtrefcount_btree.c
index 77191f073a10bb..f893677e0fcd32 100644
--- a/libxfs/xfs_rtrefcount_btree.c
+++ b/libxfs/xfs_rtrefcount_btree.c
@@ -3,7 +3,7 @@
  * Copyright (c) 2021-2024 Oracle.  All Rights Reserved.
  * Author: Darrick J. Wong <djwong@kernel.org>
  */
-#include "libxfs_priv.h"
+#include "xfs_platform.h"
 #include "xfs_fs.h"
 #include "xfs_shared.h"
 #include "xfs_format.h"
diff --git a/libxfs/xfs_rtrmap_btree.c b/libxfs/xfs_rtrmap_btree.c
index 633dca0333f4e7..7191bf445c399b 100644
--- a/libxfs/xfs_rtrmap_btree.c
+++ b/libxfs/xfs_rtrmap_btree.c
@@ -3,7 +3,7 @@
  * Copyright (c) 2018-2024 Oracle.  All Rights Reserved.
  * Author: Darrick J. Wong <djwong@kernel.org>
  */
-#include "libxfs_priv.h"
+#include "xfs_platform.h"
 #include "xfs_fs.h"
 #include "xfs_shared.h"
 #include "xfs_format.h"
diff --git a/libxfs/xfs_sb.c b/libxfs/xfs_sb.c
index 3e2d3c6da19631..b29077dcd0aed7 100644
--- a/libxfs/xfs_sb.c
+++ b/libxfs/xfs_sb.c
@@ -3,7 +3,7 @@
  * Copyright (c) 2000-2005 Silicon Graphics, Inc.
  * All Rights Reserved.
  */
-#include "libxfs_priv.h"
+#include "xfs_platform.h"
 #include "xfs_fs.h"
 #include "xfs_shared.h"
 #include "xfs_format.h"
diff --git a/libxfs/xfs_symlink_remote.c b/libxfs/xfs_symlink_remote.c
index 1c355f751e1cc7..d29eae498c493e 100644
--- a/libxfs/xfs_symlink_remote.c
+++ b/libxfs/xfs_symlink_remote.c
@@ -4,7 +4,7 @@
  * Copyright (c) 2012-2013 Red Hat, Inc.
  * All rights reserved.
  */
-#include "libxfs_priv.h"
+#include "xfs_platform.h"
 #include "xfs_fs.h"
 #include "xfs_format.h"
 #include "xfs_log_format.h"
diff --git a/libxfs/xfs_trans_inode.c b/libxfs/xfs_trans_inode.c
index 90eec4d3592dea..ef404e7f0f6e91 100644
--- a/libxfs/xfs_trans_inode.c
+++ b/libxfs/xfs_trans_inode.c
@@ -3,7 +3,7 @@
  * Copyright (c) 2000,2005 Silicon Graphics, Inc.
  * All Rights Reserved.
  */
-#include "libxfs_priv.h"
+#include "xfs_platform.h"
 #include "xfs_fs.h"
 #include "xfs_shared.h"
 #include "xfs_format.h"
diff --git a/libxfs/xfs_trans_resv.c b/libxfs/xfs_trans_resv.c
index b3b9d22b54515d..9294b72e61b77e 100644
--- a/libxfs/xfs_trans_resv.c
+++ b/libxfs/xfs_trans_resv.c
@@ -4,7 +4,7 @@
  * Copyright (C) 2010 Red Hat, Inc.
  * All Rights Reserved.
  */
-#include "libxfs_priv.h"
+#include "xfs_platform.h"
 #include "xfs_fs.h"
 #include "xfs_shared.h"
 #include "xfs_format.h"
diff --git a/libxfs/xfs_trans_space.c b/libxfs/xfs_trans_space.c
index 373f5cc24977a8..9b8f495c9049cc 100644
--- a/libxfs/xfs_trans_space.c
+++ b/libxfs/xfs_trans_space.c
@@ -3,7 +3,7 @@
  * Copyright (c) 2000,2005 Silicon Graphics, Inc.
  * All Rights Reserved.
  */
-#include "libxfs_priv.h"
+#include "xfs_platform.h"
 #include "xfs_fs.h"
 #include "xfs_shared.h"
 #include "xfs_format.h"
diff --git a/libxfs/xfs_types.c b/libxfs/xfs_types.c
index 4e24599c369397..67c947a47f1478 100644
--- a/libxfs/xfs_types.c
+++ b/libxfs/xfs_types.c
@@ -4,7 +4,7 @@
  * Copyright (C) 2017 Oracle.
  * All Rights Reserved.
  */
-#include "libxfs_priv.h"
+#include "xfs_platform.h"
 #include "xfs_fs.h"
 #include "xfs_format.h"
 #include "xfs_shared.h"
diff --git a/libxfs/xfs_zones.c b/libxfs/xfs_zones.c
index 90e2ba0908be5d..e31e1dc0913efe 100644
--- a/libxfs/xfs_zones.c
+++ b/libxfs/xfs_zones.c
@@ -3,7 +3,7 @@
  * Copyright (c) 2023-2025 Christoph Hellwig.
  * Copyright (c) 2024-2025, Western Digital Corporation or its affiliates.
  */
-#include "libxfs_priv.h"
+#include "xfs_platform.h"
 #include "xfs.h"
 #include "xfs_fs.h"
 #include "xfs_shared.h"
diff --git a/repair/zoned.c b/repair/zoned.c
index 07e676ac7fd3f6..c721709d137064 100644
--- a/repair/zoned.c
+++ b/repair/zoned.c
@@ -3,7 +3,7 @@
  * Copyright (c) 2024 Christoph Hellwig.
  */
 #include <ctype.h>
-#include "libxfs_priv.h"
+#include "xfs_platform.h"
 #include "libxfs.h"
 #include "xfs_zones.h"
 #include "libfrog/zones.h"


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

* [PATCH 16/40] xfs: remove xfs_attr_leaf_hasname
  2026-03-23 18:41 ` [PATCHSET 2/2] xfsprogs: new libxfs code from kernel 7.0 Darrick J. Wong
                     ` (14 preceding siblings ...)
  2026-03-23 18:45   ` [PATCH 15/40] xfs: directly include xfs_platform.h Darrick J. Wong
@ 2026-03-23 18:45   ` Darrick J. Wong
  2026-03-23 18:45   ` [PATCH 17/40] xfs: add missing forward declaration in xfs_zones.h Darrick J. Wong
                     ` (23 subsequent siblings)
  39 siblings, 0 replies; 50+ messages in thread
From: Darrick J. Wong @ 2026-03-23 18:45 UTC (permalink / raw)
  To: djwong, aalbersh; +Cc: cem, hch, mark.tinguely, linux-xfs

From: Christoph Hellwig <hch@lst.de>

Source kernel commit: 3a65ea768b8094e4699e72f9ab420eb9e0f3f568

The calling convention of xfs_attr_leaf_hasname() is problematic, because
it returns a NULL buffer when xfs_attr3_leaf_read fails, a valid buffer
when xfs_attr3_leaf_lookup_int returns -ENOATTR or -EEXIST, and a
non-NULL buffer pointer for an already released buffer when
xfs_attr3_leaf_lookup_int fails with other error values.

Fix this by simply open coding xfs_attr_leaf_hasname in the callers, so
that the buffer release code is done by each caller of
xfs_attr3_leaf_read.

Fixes: 07120f1abdff ("xfs: Add xfs_has_attr and subroutines")
Reported-by: Mark Tinguely <mark.tinguely@oracle.com>
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_attr.c |   75 +++++++++++++++++------------------------------------
 1 file changed, 24 insertions(+), 51 deletions(-)


diff --git a/libxfs/xfs_attr.c b/libxfs/xfs_attr.c
index 72b701f1b6dcae..baf617cfeabe00 100644
--- a/libxfs/xfs_attr.c
+++ b/libxfs/xfs_attr.c
@@ -49,7 +49,6 @@ STATIC int xfs_attr_shortform_addname(xfs_da_args_t *args);
  */
 STATIC int xfs_attr_leaf_get(xfs_da_args_t *args);
 STATIC int xfs_attr_leaf_removename(xfs_da_args_t *args);
-STATIC int xfs_attr_leaf_hasname(struct xfs_da_args *args, struct xfs_buf **bp);
 
 /*
  * Internal routines when attribute list is more than one block.
@@ -978,11 +977,12 @@ xfs_attr_lookup(
 		return error;
 
 	if (xfs_attr_is_leaf(dp)) {
-		error = xfs_attr_leaf_hasname(args, &bp);
-
-		if (bp)
-			xfs_trans_brelse(args->trans, bp);
-
+		error = xfs_attr3_leaf_read(args->trans, args->dp, args->owner,
+				0, &bp);
+		if (error)
+			return error;
+		error = xfs_attr3_leaf_lookup_int(bp, args);
+		xfs_trans_brelse(args->trans, bp);
 		return error;
 	}
 
@@ -1221,27 +1221,6 @@ xfs_attr_shortform_addname(
  * External routines when attribute list is one block
  *========================================================================*/
 
-/*
- * Return EEXIST if attr is found, or ENOATTR if not
- */
-STATIC int
-xfs_attr_leaf_hasname(
-	struct xfs_da_args	*args,
-	struct xfs_buf		**bp)
-{
-	int                     error = 0;
-
-	error = xfs_attr3_leaf_read(args->trans, args->dp, args->owner, 0, bp);
-	if (error)
-		return error;
-
-	error = xfs_attr3_leaf_lookup_int(*bp, args);
-	if (error != -ENOATTR && error != -EEXIST)
-		xfs_trans_brelse(args->trans, *bp);
-
-	return error;
-}
-
 /*
  * Remove a name from the leaf attribute list structure
  *
@@ -1252,25 +1231,22 @@ STATIC int
 xfs_attr_leaf_removename(
 	struct xfs_da_args	*args)
 {
-	struct xfs_inode	*dp;
-	struct xfs_buf		*bp;
+	struct xfs_inode	*dp = args->dp;
 	int			error, forkoff;
+	struct xfs_buf		*bp;
 
 	trace_xfs_attr_leaf_removename(args);
 
-	/*
-	 * Remove the attribute.
-	 */
-	dp = args->dp;
-
-	error = xfs_attr_leaf_hasname(args, &bp);
-	if (error == -ENOATTR) {
+	error = xfs_attr3_leaf_read(args->trans, args->dp, args->owner, 0, &bp);
+	if (error)
+		return error;
+	error = xfs_attr3_leaf_lookup_int(bp, args);
+	if (error != -EEXIST) {
 		xfs_trans_brelse(args->trans, bp);
-		if (args->op_flags & XFS_DA_OP_RECOVERY)
+		if (error == -ENOATTR && (args->op_flags & XFS_DA_OP_RECOVERY))
 			return 0;
 		return error;
-	} else if (error != -EEXIST)
-		return error;
+	}
 
 	xfs_attr3_leaf_remove(bp, args);
 
@@ -1294,23 +1270,20 @@ xfs_attr_leaf_removename(
  * Returns 0 on successful retrieval, otherwise an error.
  */
 STATIC int
-xfs_attr_leaf_get(xfs_da_args_t *args)
+xfs_attr_leaf_get(
+	struct xfs_da_args	*args)
 {
-	struct xfs_buf *bp;
-	int error;
+	struct xfs_buf		*bp;
+	int			error;
 
 	trace_xfs_attr_leaf_get(args);
 
-	error = xfs_attr_leaf_hasname(args, &bp);
-
-	if (error == -ENOATTR)  {
-		xfs_trans_brelse(args->trans, bp);
+	error = xfs_attr3_leaf_read(args->trans, args->dp, args->owner, 0, &bp);
+	if (error)
 		return error;
-	} else if (error != -EEXIST)
-		return error;
-
-
-	error = xfs_attr3_leaf_getvalue(bp, args);
+	error = xfs_attr3_leaf_lookup_int(bp, args);
+	if (error == -EEXIST)
+		error = xfs_attr3_leaf_getvalue(bp, args);
 	xfs_trans_brelse(args->trans, bp);
 	return error;
 }


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

* [PATCH 17/40] xfs: add missing forward declaration in xfs_zones.h
  2026-03-23 18:41 ` [PATCHSET 2/2] xfsprogs: new libxfs code from kernel 7.0 Darrick J. Wong
                     ` (15 preceding siblings ...)
  2026-03-23 18:45   ` [PATCH 16/40] xfs: remove xfs_attr_leaf_hasname Darrick J. Wong
@ 2026-03-23 18:45   ` Darrick J. Wong
  2026-03-23 18:45   ` [PATCH 18/40] xfs: add a xfs_rtgroup_raw_size helper Darrick J. Wong
                     ` (22 subsequent siblings)
  39 siblings, 0 replies; 50+ messages in thread
From: Darrick J. Wong @ 2026-03-23 18:45 UTC (permalink / raw)
  To: djwong, aalbersh; +Cc: cem, cmaiolino, dlemoal, hch, linux-xfs

From: Damien Le Moal <dlemoal@kernel.org>

Source kernel commit: 41263267ef26d315b1425eb9c8a8d7092f9db7c8

Add the missing forward declaration for struct blk_zone in xfs_zones.h.
This avoids headaches with the order of header file inclusion to avoid
compilation errors.

Signed-off-by: Damien Le Moal <dlemoal@kernel.org>
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_zones.h |    1 +
 1 file changed, 1 insertion(+)


diff --git a/libxfs/xfs_zones.h b/libxfs/xfs_zones.h
index 5fefd132e002ee..df10a34da71d64 100644
--- a/libxfs/xfs_zones.h
+++ b/libxfs/xfs_zones.h
@@ -3,6 +3,7 @@
 #define _LIBXFS_ZONES_H
 
 struct xfs_rtgroup;
+struct blk_zone;
 
 /*
  * In order to guarantee forward progress for GC we need to reserve at least


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

* [PATCH 18/40] xfs: add a xfs_rtgroup_raw_size helper
  2026-03-23 18:41 ` [PATCHSET 2/2] xfsprogs: new libxfs code from kernel 7.0 Darrick J. Wong
                     ` (16 preceding siblings ...)
  2026-03-23 18:45   ` [PATCH 17/40] xfs: add missing forward declaration in xfs_zones.h Darrick J. Wong
@ 2026-03-23 18:45   ` Darrick J. Wong
  2026-03-23 18:46   ` [PATCH 19/40] xfs: split and refactor zone validation Darrick J. Wong
                     ` (21 subsequent siblings)
  39 siblings, 0 replies; 50+ messages in thread
From: Darrick J. Wong @ 2026-03-23 18:45 UTC (permalink / raw)
  To: djwong, aalbersh; +Cc: cem, cmaiolino, dlemoal, hch, linux-xfs

From: Christoph Hellwig <hch@lst.de>

Source kernel commit: fc633b5c5b80c1d840b7a8bc2828be96582c6b55

Add a helper to figure the on-disk size of a group, accounting for the
XFS_SB_FEAT_INCOMPAT_ZONE_GAPS feature if needed.

Signed-off-by: Christoph Hellwig <hch@lst.de>
Reviewed-by: Darrick J. Wong <djwong@kernel.org>
Reviewed-by: Carlos Maiolino <cmaiolino@redhat.com>
Reviewed-by: Damien Le Moal <dlemoal@kernel.org>
Signed-off-by: Carlos Maiolino <cem@kernel.org>
---
 libxfs/xfs_rtgroup.h |   15 +++++++++++++++
 1 file changed, 15 insertions(+)


diff --git a/libxfs/xfs_rtgroup.h b/libxfs/xfs_rtgroup.h
index 73cace4d25c791..c0b9f9f2c4131b 100644
--- a/libxfs/xfs_rtgroup.h
+++ b/libxfs/xfs_rtgroup.h
@@ -371,4 +371,19 @@ xfs_rtgs_to_rfsbs(
 	return xfs_groups_to_rfsbs(mp, nr_groups, XG_TYPE_RTG);
 }
 
+/*
+ * Return the "raw" size of a group on the hardware device.  This includes the
+ * daddr gaps present for XFS_SB_FEAT_INCOMPAT_ZONE_GAPS file systems.
+ */
+static inline xfs_rgblock_t
+xfs_rtgroup_raw_size(
+	struct xfs_mount	*mp)
+{
+	struct xfs_groups	*g = &mp->m_groups[XG_TYPE_RTG];
+
+	if (g->has_daddr_gaps)
+		return 1U << g->blklog;
+	return g->blocks;
+}
+
 #endif /* __LIBXFS_RTGROUP_H */


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

* [PATCH 19/40] xfs: split and refactor zone validation
  2026-03-23 18:41 ` [PATCHSET 2/2] xfsprogs: new libxfs code from kernel 7.0 Darrick J. Wong
                     ` (17 preceding siblings ...)
  2026-03-23 18:45   ` [PATCH 18/40] xfs: add a xfs_rtgroup_raw_size helper Darrick J. Wong
@ 2026-03-23 18:46   ` Darrick J. Wong
  2026-03-23 18:46   ` [PATCH 20/40] xfs: delete attr leaf freemap entries when empty Darrick J. Wong
                     ` (20 subsequent siblings)
  39 siblings, 0 replies; 50+ messages in thread
From: Darrick J. Wong @ 2026-03-23 18:46 UTC (permalink / raw)
  To: djwong, aalbersh; +Cc: cem, dlemoal, hch, linux-xfs

From: Christoph Hellwig <hch@lst.de>

Source kernel commit: 19c5b6051ed62d8c4b1cf92e463c1bcf629107f4

Currently xfs_zone_validate mixes validating the software zone state in
the XFS realtime group with validating the hardware state reported in
struct blk_zone and deriving the write pointer from that.

Move all code that works on the realtime group to xfs_init_zone, and only
keep the hardware state validation in xfs_zone_validate.  This makes the
code more clear, and allows for better reuse in userspace.

Signed-off-by: Christoph Hellwig <hch@lst.de>
Reviewed-by: Darrick J. Wong <djwong@kernel.org>
Reviewed-by: Damien Le Moal <dlemoal@kernel.org>
Signed-off-by: Carlos Maiolino <cem@kernel.org>
---
 libxfs/libxfs_api_defs.h |    2 -
 libxfs/xfs_zones.h       |    5 +-
 libxfs/xfs_zones.c       |  149 ++++++++++++----------------------------------
 repair/zoned.c           |    5 +-
 4 files changed, 47 insertions(+), 114 deletions(-)


diff --git a/libxfs/libxfs_api_defs.h b/libxfs/libxfs_api_defs.h
index fe00e19bada9d8..d7c912e778799c 100644
--- a/libxfs/libxfs_api_defs.h
+++ b/libxfs/libxfs_api_defs.h
@@ -412,7 +412,7 @@
 #define xfs_verify_rgbno		libxfs_verify_rgbno
 #define xfs_verify_rtbno		libxfs_verify_rtbno
 #define xfs_zero_extent			libxfs_zero_extent
-#define xfs_zone_validate		libxfs_zone_validate
+#define xfs_validate_blk_zone		libxfs_validate_blk_zone
 
 /* Please keep this list alphabetized. */
 
diff --git a/libxfs/xfs_zones.h b/libxfs/xfs_zones.h
index df10a34da71d64..c16089c9a652da 100644
--- a/libxfs/xfs_zones.h
+++ b/libxfs/xfs_zones.h
@@ -37,7 +37,8 @@ struct blk_zone;
  */
 #define XFS_DEFAULT_MAX_OPEN_ZONES	128
 
-bool xfs_zone_validate(struct blk_zone *zone, struct xfs_rtgroup *rtg,
-	xfs_rgblock_t *write_pointer);
+bool xfs_validate_blk_zone(struct xfs_mount *mp, struct blk_zone *zone,
+	unsigned int zone_no, uint32_t expected_size,
+	uint32_t expected_capacity, xfs_rgblock_t *write_pointer);
 
 #endif /* _LIBXFS_ZONES_H */
diff --git a/libxfs/xfs_zones.c b/libxfs/xfs_zones.c
index e31e1dc0913efe..4f9820dc54197e 100644
--- a/libxfs/xfs_zones.c
+++ b/libxfs/xfs_zones.c
@@ -16,173 +16,102 @@
 #include "xfs_zones.h"
 
 static bool
-xfs_zone_validate_empty(
+xfs_validate_blk_zone_seq(
+	struct xfs_mount	*mp,
 	struct blk_zone		*zone,
-	struct xfs_rtgroup	*rtg,
+	unsigned int		zone_no,
 	xfs_rgblock_t		*write_pointer)
 {
-	struct xfs_mount	*mp = rtg_mount(rtg);
-
-	if (rtg_rmap(rtg)->i_used_blocks > 0) {
-		xfs_warn(mp, "empty zone %u has non-zero used counter (0x%x).",
-			 rtg_rgno(rtg), rtg_rmap(rtg)->i_used_blocks);
-		return false;
-	}
-
-	*write_pointer = 0;
-	return true;
-}
-
-static bool
-xfs_zone_validate_wp(
-	struct blk_zone		*zone,
-	struct xfs_rtgroup	*rtg,
-	xfs_rgblock_t		*write_pointer)
-{
-	struct xfs_mount	*mp = rtg_mount(rtg);
-	xfs_rtblock_t		wp_fsb = xfs_daddr_to_rtb(mp, zone->wp);
-
-	if (rtg_rmap(rtg)->i_used_blocks > rtg->rtg_extents) {
-		xfs_warn(mp, "zone %u has too large used counter (0x%x).",
-			 rtg_rgno(rtg), rtg_rmap(rtg)->i_used_blocks);
-		return false;
-	}
-
-	if (xfs_rtb_to_rgno(mp, wp_fsb) != rtg_rgno(rtg)) {
-		xfs_warn(mp, "zone %u write pointer (0x%llx) outside of zone.",
-			 rtg_rgno(rtg), wp_fsb);
-		return false;
-	}
-
-	*write_pointer = xfs_rtb_to_rgbno(mp, wp_fsb);
-	if (*write_pointer >= rtg->rtg_extents) {
-		xfs_warn(mp, "zone %u has invalid write pointer (0x%x).",
-			 rtg_rgno(rtg), *write_pointer);
-		return false;
-	}
-
-	return true;
-}
-
-static bool
-xfs_zone_validate_full(
-	struct blk_zone		*zone,
-	struct xfs_rtgroup	*rtg,
-	xfs_rgblock_t		*write_pointer)
-{
-	struct xfs_mount	*mp = rtg_mount(rtg);
-
-	if (rtg_rmap(rtg)->i_used_blocks > rtg->rtg_extents) {
-		xfs_warn(mp, "zone %u has too large used counter (0x%x).",
-			 rtg_rgno(rtg), rtg_rmap(rtg)->i_used_blocks);
-		return false;
-	}
-
-	*write_pointer = rtg->rtg_extents;
-	return true;
-}
-
-static bool
-xfs_zone_validate_seq(
-	struct blk_zone		*zone,
-	struct xfs_rtgroup	*rtg,
-	xfs_rgblock_t		*write_pointer)
-{
-	struct xfs_mount	*mp = rtg_mount(rtg);
-
 	switch (zone->cond) {
 	case BLK_ZONE_COND_EMPTY:
-		return xfs_zone_validate_empty(zone, rtg, write_pointer);
+		*write_pointer = 0;
+		return true;
 	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);
+		if (zone->wp < zone->start ||
+		    zone->wp >= zone->start + zone->capacity) {
+			xfs_warn(mp,
+	"zone %u write pointer (%llu) outside of zone.",
+				zone_no, zone->wp);
+			return false;
+		}
+
+		*write_pointer = XFS_BB_TO_FSB(mp, zone->wp - zone->start);
+		return true;
 	case BLK_ZONE_COND_FULL:
-		return xfs_zone_validate_full(zone, rtg, write_pointer);
+		*write_pointer = XFS_BB_TO_FSB(mp, zone->capacity);
+		return true;
 	case BLK_ZONE_COND_NOT_WP:
 	case BLK_ZONE_COND_OFFLINE:
 	case BLK_ZONE_COND_READONLY:
 		xfs_warn(mp, "zone %u has unsupported zone condition 0x%x.",
-			rtg_rgno(rtg), zone->cond);
+			zone_no, zone->cond);
 		return false;
 	default:
 		xfs_warn(mp, "zone %u has unknown zone condition 0x%x.",
-			rtg_rgno(rtg), zone->cond);
+			zone_no, zone->cond);
 		return false;
 	}
 }
 
 static bool
-xfs_zone_validate_conv(
+xfs_validate_blk_zone_conv(
+	struct xfs_mount	*mp,
 	struct blk_zone		*zone,
-	struct xfs_rtgroup	*rtg)
+	unsigned int		zone_no)
 {
-	struct xfs_mount	*mp = rtg_mount(rtg);
-
 	switch (zone->cond) {
 	case BLK_ZONE_COND_NOT_WP:
 		return true;
 	default:
 		xfs_warn(mp,
 "conventional zone %u has unsupported zone condition 0x%x.",
-			 rtg_rgno(rtg), zone->cond);
+			 zone_no, zone->cond);
 		return false;
 	}
 }
 
 bool
-xfs_zone_validate(
+xfs_validate_blk_zone(
+	struct xfs_mount	*mp,
 	struct blk_zone		*zone,
-	struct xfs_rtgroup	*rtg,
+	unsigned int		zone_no,
+	uint32_t		expected_size,
+	uint32_t		expected_capacity,
 	xfs_rgblock_t		*write_pointer)
 {
-	struct xfs_mount	*mp = rtg_mount(rtg);
-	struct xfs_groups	*g = &mp->m_groups[XG_TYPE_RTG];
-	uint32_t		expected_size;
-
 	/*
 	 * Check that the zone capacity matches the rtgroup size stored in the
 	 * superblock.  Note that all zones including the last one must have a
 	 * uniform capacity.
 	 */
-	if (XFS_BB_TO_FSB(mp, zone->capacity) != g->blocks) {
+	if (XFS_BB_TO_FSB(mp, zone->capacity) != expected_capacity) {
 		xfs_warn(mp,
-"zone %u capacity (0x%llx) does not match RT group size (0x%x).",
-			rtg_rgno(rtg), XFS_BB_TO_FSB(mp, zone->capacity),
-			g->blocks);
+"zone %u capacity (%llu) does not match RT group size (%u).",
+			zone_no, XFS_BB_TO_FSB(mp, zone->capacity),
+			expected_capacity);
 		return false;
 	}
 
-	if (g->has_daddr_gaps) {
-		expected_size = 1 << g->blklog;
-	} else {
-		if (zone->len != zone->capacity) {
-			xfs_warn(mp,
-"zone %u has capacity != size ((0x%llx vs 0x%llx)",
-				rtg_rgno(rtg),
-				XFS_BB_TO_FSB(mp, zone->len),
-				XFS_BB_TO_FSB(mp, zone->capacity));
-			return false;
-		}
-		expected_size = g->blocks;
-	}
-
 	if (XFS_BB_TO_FSB(mp, zone->len) != expected_size) {
 		xfs_warn(mp,
-"zone %u length (0x%llx) does match geometry (0x%x).",
-			rtg_rgno(rtg), XFS_BB_TO_FSB(mp, zone->len),
+"zone %u length (%llu) does not match geometry (%u).",
+			zone_no, XFS_BB_TO_FSB(mp, zone->len),
 			expected_size);
+		return false;
 	}
 
 	switch (zone->type) {
 	case BLK_ZONE_TYPE_CONVENTIONAL:
-		return xfs_zone_validate_conv(zone, rtg);
+		return xfs_validate_blk_zone_conv(mp, zone, zone_no);
 	case BLK_ZONE_TYPE_SEQWRITE_REQ:
-		return xfs_zone_validate_seq(zone, rtg, write_pointer);
+		return xfs_validate_blk_zone_seq(mp, zone, zone_no,
+				write_pointer);
 	default:
 		xfs_warn(mp, "zoned %u has unsupported type 0x%x.",
-			rtg_rgno(rtg), zone->type);
+			zone_no, zone->type);
 		return false;
 	}
 }
diff --git a/repair/zoned.c b/repair/zoned.c
index c721709d137064..6ab91371d95af6 100644
--- a/repair/zoned.c
+++ b/repair/zoned.c
@@ -39,7 +39,10 @@ report_zones_cb(
 	if (!rtg_rmap(rtg))
 		do_warn(_("no rmap inode for zone %u."), rgno);
 	else
-		libxfs_zone_validate(zone, rtg, &write_pointer);
+		libxfs_validate_blk_zone(mp, zone, rtg_rgno(rtg),
+				xfs_rtgroup_raw_size(mp),
+				mp->m_groups[XG_TYPE_RTG].blocks,
+				&write_pointer);
 	libxfs_rtgroup_rele(rtg);
 }
 


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

* [PATCH 20/40] xfs: delete attr leaf freemap entries when empty
  2026-03-23 18:41 ` [PATCHSET 2/2] xfsprogs: new libxfs code from kernel 7.0 Darrick J. Wong
                     ` (18 preceding siblings ...)
  2026-03-23 18:46   ` [PATCH 19/40] xfs: split and refactor zone validation Darrick J. Wong
@ 2026-03-23 18:46   ` Darrick J. Wong
  2026-03-23 18:46   ` [PATCH 21/40] xfs: fix freemap adjustments when adding xattrs to leaf blocks Darrick J. Wong
                     ` (19 subsequent siblings)
  39 siblings, 0 replies; 50+ messages in thread
From: Darrick J. Wong @ 2026-03-23 18:46 UTC (permalink / raw)
  To: djwong, aalbersh; +Cc: hch, linux-xfs

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

Source kernel commit: 6f13c1d2a6271c2e73226864a0e83de2770b6f34

Back in commit 2a2b5932db6758 ("xfs: fix attr leaf header freemap.size
underflow"), Brian Foster observed that it's possible for a small
freemap at the end of the end of the xattr entries array to experience
a size underflow when subtracting the space consumed by an expansion of
the entries array.  There are only three freemap entries, which means
that it is not a complete index of all free space in the leaf block.

This code can leave behind a zero-length freemap entry with a nonzero
base.  Subsequent setxattr operations can increase the base up to the
point that it overlaps with another freemap entry.  This isn't in and of
itself a problem because the code in _leaf_add that finds free space
ignores any freemap entry with zero size.

However, there's another bug in the freemap update code in _leaf_add,
which is that it fails to update a freemap entry that begins midway
through the xattr entry that was just appended to the array.  That can
result in the freemap containing two entries with the same base but
different sizes (0 for the "pushed-up" entry, nonzero for the entry
that's actually tracking free space).  A subsequent _leaf_add can then
allocate xattr namevalue entries on top of the entries array, leading to
data loss.  But fixing that is for later.

For now, eliminate the possibility of confusion by zeroing out the base
of any freemap entry that has zero size.  Because the freemap is not
intended to be a complete index of free space, a subsequent failure to
find any free space for a new xattr will trigger block compaction, which
regenerates the freemap.

It looks like this bug has been in the codebase for quite a long time.

Fixes: 1da177e4c3f415 ("Linux-2.6.12-rc2")
Signed-off-by: "Darrick J. Wong" <djwong@kernel.org>
Reviewed-by: Christoph Hellwig <hch@lst.de>
---
 libxfs/xfs_attr_leaf.c |   13 +++++++++++++
 1 file changed, 13 insertions(+)


diff --git a/libxfs/xfs_attr_leaf.c b/libxfs/xfs_attr_leaf.c
index ff1085f0b3afe4..f5ea39abf04a35 100644
--- a/libxfs/xfs_attr_leaf.c
+++ b/libxfs/xfs_attr_leaf.c
@@ -1577,6 +1577,19 @@ xfs_attr3_leaf_add_work(
 				min_t(uint16_t, ichdr->freemap[i].size,
 						sizeof(xfs_attr_leaf_entry_t));
 		}
+
+		/*
+		 * Don't leave zero-length freemaps with nonzero base lying
+		 * around, because we don't want the code in _remove that
+		 * matches on base address to get confused and create
+		 * overlapping freemaps.  If we end up with no freemap entries
+		 * then the next _add will compact the leaf block and
+		 * regenerate the freemaps.
+		 */
+		if (ichdr->freemap[i].size == 0 && ichdr->freemap[i].base > 0) {
+			ichdr->freemap[i].base = 0;
+			ichdr->holes = 1;
+		}
 	}
 	ichdr->usedbytes += xfs_attr_leaf_entsize(leaf, args->index);
 }


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

* [PATCH 21/40] xfs: fix freemap adjustments when adding xattrs to leaf blocks
  2026-03-23 18:41 ` [PATCHSET 2/2] xfsprogs: new libxfs code from kernel 7.0 Darrick J. Wong
                     ` (19 preceding siblings ...)
  2026-03-23 18:46   ` [PATCH 20/40] xfs: delete attr leaf freemap entries when empty Darrick J. Wong
@ 2026-03-23 18:46   ` Darrick J. Wong
  2026-03-23 18:47   ` [PATCH 22/40] xfs: refactor attr3 leaf table size computation Darrick J. Wong
                     ` (18 subsequent siblings)
  39 siblings, 0 replies; 50+ messages in thread
From: Darrick J. Wong @ 2026-03-23 18:46 UTC (permalink / raw)
  To: djwong, aalbersh; +Cc: hch, linux-xfs

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

Source kernel commit: 3eefc0c2b78444b64feeb3783c017d6adc3cd3ce

xfs/592 and xfs/794 both trip this assertion in the leaf block freemap
adjustment code after ~20 minutes of running on my test VMs:

ASSERT(ichdr->firstused >= ichdr->count * sizeof(xfs_attr_leaf_entry_t)
+ xfs_attr3_leaf_hdr_size(leaf));

Upon enabling quite a lot more debugging code, I narrowed this down to
fsstress trying to set a local extended attribute with namelen=3 and
valuelen=71.  This results in an entry size of 80 bytes.

At the start of xfs_attr3_leaf_add_work, the freemap looks like this:

i 0 base 448 size 0 rhs 448 count 46
i 1 base 388 size 132 rhs 448 count 46
i 2 base 2120 size 4 rhs 448 count 46
firstused = 520

where "rhs" is the first byte past the end of the leaf entry array.
This is inconsistent -- the entries array ends at byte 448, but
freemap[1] says there's free space starting at byte 388!

By the end of the function, the freemap is in worse shape:

i 0 base 456 size 0 rhs 456 count 47
i 1 base 388 size 52 rhs 456 count 47
i 2 base 2120 size 4 rhs 456 count 47
firstused = 440

Important note: 388 is not aligned with the entries array element size
of 8 bytes.

Based on the incorrect freemap, the name area starts at byte 440, which
is below the end of the entries array!  That's why the assertion
triggers and the filesystem shuts down.

How did we end up here?  First, recall from the previous patch that the
freemap array in an xattr leaf block is not intended to be a
comprehensive map of all free space in the leaf block.  In other words,
it's perfectly legal to have a leaf block with:

* 376 bytes in use by the entries array
* freemap[0] has [base = 376, size = 8]
* freemap[1] has [base = 388, size = 1500]
* the space between 376 and 388 is free, but the freemap stopped
tracking that some time ago

If we add one xattr, the entries array grows to 384 bytes, and
freemap[0] becomes [base = 384, size = 0].  So far, so good.  But if we
add a second xattr, the entries array grows to 392 bytes, and freemap[0]
gets pushed up to [base = 392, size = 0].  This is bad, because
freemap[1] hasn't been updated, and now the entries array and the free
space claim the same space.

The fix here is to adjust all freemap entries so that none of them
collide with the entries array.  Note that this fix relies on commit
2a2b5932db6758 ("xfs: fix attr leaf header freemap.size underflow") and
the previous patch that resets zero length freemap entries to have
base = 0.

Fixes: 1da177e4c3f415 ("Linux-2.6.12-rc2")
Signed-off-by: "Darrick J. Wong" <djwong@kernel.org>
Reviewed-by: Christoph Hellwig <hch@lst.de>
---
 libxfs/xfs_attr_leaf.c |   36 ++++++++++++++++++++++++++++--------
 1 file changed, 28 insertions(+), 8 deletions(-)


diff --git a/libxfs/xfs_attr_leaf.c b/libxfs/xfs_attr_leaf.c
index f5ea39abf04a35..b8aea9d73c0e4e 100644
--- a/libxfs/xfs_attr_leaf.c
+++ b/libxfs/xfs_attr_leaf.c
@@ -1473,6 +1473,7 @@ xfs_attr3_leaf_add_work(
 	struct xfs_attr_leaf_name_local *name_loc;
 	struct xfs_attr_leaf_name_remote *name_rmt;
 	struct xfs_mount	*mp;
+	int			old_end, new_end;
 	int			tmp;
 	int			i;
 
@@ -1565,17 +1566,36 @@ xfs_attr3_leaf_add_work(
 	if (be16_to_cpu(entry->nameidx) < ichdr->firstused)
 		ichdr->firstused = be16_to_cpu(entry->nameidx);
 
-	ASSERT(ichdr->firstused >= ichdr->count * sizeof(xfs_attr_leaf_entry_t)
-					+ xfs_attr3_leaf_hdr_size(leaf));
-	tmp = (ichdr->count - 1) * sizeof(xfs_attr_leaf_entry_t)
-					+ xfs_attr3_leaf_hdr_size(leaf);
+	new_end = ichdr->count * sizeof(struct xfs_attr_leaf_entry) +
+					xfs_attr3_leaf_hdr_size(leaf);
+	old_end = new_end - sizeof(struct xfs_attr_leaf_entry);
+
+	ASSERT(ichdr->firstused >= new_end);
 
 	for (i = 0; i < XFS_ATTR_LEAF_MAPSIZE; i++) {
-		if (ichdr->freemap[i].base == tmp) {
-			ichdr->freemap[i].base += sizeof(xfs_attr_leaf_entry_t);
+		int		diff = 0;
+
+		if (ichdr->freemap[i].base == old_end) {
+			/*
+			 * This freemap entry starts at the old end of the
+			 * leaf entry array, so we need to adjust its base
+			 * upward to accomodate the larger array.
+			 */
+			diff = sizeof(struct xfs_attr_leaf_entry);
+		} else if (ichdr->freemap[i].size > 0 &&
+			   ichdr->freemap[i].base < new_end) {
+			/*
+			 * This freemap entry starts in the space claimed by
+			 * the new leaf entry.  Adjust its base upward to
+			 * reflect that.
+			 */
+			diff = new_end - ichdr->freemap[i].base;
+		}
+
+		if (diff) {
+			ichdr->freemap[i].base += diff;
 			ichdr->freemap[i].size -=
-				min_t(uint16_t, ichdr->freemap[i].size,
-						sizeof(xfs_attr_leaf_entry_t));
+				min_t(uint16_t, ichdr->freemap[i].size, diff);
 		}
 
 		/*


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

* [PATCH 22/40] xfs: refactor attr3 leaf table size computation
  2026-03-23 18:41 ` [PATCHSET 2/2] xfsprogs: new libxfs code from kernel 7.0 Darrick J. Wong
                     ` (20 preceding siblings ...)
  2026-03-23 18:46   ` [PATCH 21/40] xfs: fix freemap adjustments when adding xattrs to leaf blocks Darrick J. Wong
@ 2026-03-23 18:47   ` Darrick J. Wong
  2026-03-23 18:47   ` [PATCH 23/40] xfs: strengthen attr leaf block freemap checking Darrick J. Wong
                     ` (17 subsequent siblings)
  39 siblings, 0 replies; 50+ messages in thread
From: Darrick J. Wong @ 2026-03-23 18:47 UTC (permalink / raw)
  To: djwong, aalbersh; +Cc: hch, linux-xfs

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

Source kernel commit: a165f7e7633ee0d83926d29e7909fdd8dd4dfadc

Replace all the open-coded callsites with a single static inline helper.

Signed-off-by: "Darrick J. Wong" <djwong@kernel.org>
Reviewed-by: Christoph Hellwig <hch@lst.de>
---
 libxfs/xfs_da_format.h |    2 +-
 libxfs/xfs_attr_leaf.c |   57 ++++++++++++++++++++++++------------------------
 2 files changed, 30 insertions(+), 29 deletions(-)


diff --git a/libxfs/xfs_da_format.h b/libxfs/xfs_da_format.h
index 86de99e2f75707..7d55307e619fe9 100644
--- a/libxfs/xfs_da_format.h
+++ b/libxfs/xfs_da_format.h
@@ -746,7 +746,7 @@ struct xfs_attr3_leafblock {
 #define	XFS_ATTR_LEAF_NAME_ALIGN	((uint)sizeof(xfs_dablk_t))
 
 static inline int
-xfs_attr3_leaf_hdr_size(struct xfs_attr_leafblock *leafp)
+xfs_attr3_leaf_hdr_size(const struct xfs_attr_leafblock *leafp)
 {
 	if (leafp->hdr.info.magic == cpu_to_be16(XFS_ATTR3_LEAF_MAGIC))
 		return sizeof(struct xfs_attr3_leaf_hdr);
diff --git a/libxfs/xfs_attr_leaf.c b/libxfs/xfs_attr_leaf.c
index b8aea9d73c0e4e..158864249c8888 100644
--- a/libxfs/xfs_attr_leaf.c
+++ b/libxfs/xfs_attr_leaf.c
@@ -72,6 +72,16 @@ STATIC void xfs_attr3_leaf_moveents(struct xfs_da_args *args,
 			int move_count);
 STATIC int xfs_attr_leaf_entsize(xfs_attr_leafblock_t *leaf, int index);
 
+/* Compute the byte offset of the end of the leaf entry array. */
+static inline int
+xfs_attr_leaf_entries_end(
+	unsigned int			hdrcount,
+	const struct xfs_attr_leafblock	*leaf)
+{
+	return hdrcount * sizeof(struct xfs_attr_leaf_entry) +
+			xfs_attr3_leaf_hdr_size(leaf);
+}
+
 /*
  * attr3 block 'firstused' conversion helpers.
  *
@@ -1406,8 +1416,7 @@ xfs_attr3_leaf_add(
 	 * Search through freemap for first-fit on new name length.
 	 * (may need to figure in size of entry struct too)
 	 */
-	tablesize = (ichdr.count + 1) * sizeof(xfs_attr_leaf_entry_t)
-					+ xfs_attr3_leaf_hdr_size(leaf);
+	tablesize = xfs_attr_leaf_entries_end(ichdr.count + 1, leaf);
 	for (sum = 0, i = XFS_ATTR_LEAF_MAPSIZE - 1; i >= 0; i--) {
 		if (tablesize > ichdr.firstused) {
 			sum += ichdr.freemap[i].size;
@@ -1566,8 +1575,7 @@ xfs_attr3_leaf_add_work(
 	if (be16_to_cpu(entry->nameidx) < ichdr->firstused)
 		ichdr->firstused = be16_to_cpu(entry->nameidx);
 
-	new_end = ichdr->count * sizeof(struct xfs_attr_leaf_entry) +
-					xfs_attr3_leaf_hdr_size(leaf);
+	new_end = xfs_attr_leaf_entries_end(ichdr->count, leaf);
 	old_end = new_end - sizeof(struct xfs_attr_leaf_entry);
 
 	ASSERT(ichdr->firstused >= new_end);
@@ -1804,8 +1812,8 @@ xfs_attr3_leaf_rebalance(
 		/*
 		 * leaf2 is the destination, compact it if it looks tight.
 		 */
-		max  = ichdr2.firstused - xfs_attr3_leaf_hdr_size(leaf1);
-		max -= ichdr2.count * sizeof(xfs_attr_leaf_entry_t);
+		max = ichdr2.firstused -
+				xfs_attr_leaf_entries_end(ichdr2.count, leaf1);
 		if (space > max)
 			xfs_attr3_leaf_compact(args, &ichdr2, blk2->bp);
 
@@ -1833,8 +1841,8 @@ xfs_attr3_leaf_rebalance(
 		/*
 		 * leaf1 is the destination, compact it if it looks tight.
 		 */
-		max  = ichdr1.firstused - xfs_attr3_leaf_hdr_size(leaf1);
-		max -= ichdr1.count * sizeof(xfs_attr_leaf_entry_t);
+		max = ichdr1.firstused -
+				xfs_attr_leaf_entries_end(ichdr1.count, leaf1);
 		if (space > max)
 			xfs_attr3_leaf_compact(args, &ichdr1, blk1->bp);
 
@@ -2040,9 +2048,7 @@ xfs_attr3_leaf_toosmall(
 	blk = &state->path.blk[ state->path.active-1 ];
 	leaf = blk->bp->b_addr;
 	xfs_attr3_leaf_hdr_from_disk(state->args->geo, &ichdr, leaf);
-	bytes = xfs_attr3_leaf_hdr_size(leaf) +
-		ichdr.count * sizeof(xfs_attr_leaf_entry_t) +
-		ichdr.usedbytes;
+	bytes = xfs_attr_leaf_entries_end(ichdr.count, leaf) + ichdr.usedbytes;
 	if (bytes > (state->args->geo->blksize >> 1)) {
 		*action = 0;	/* blk over 50%, don't try to join */
 		return 0;
@@ -2100,9 +2106,8 @@ xfs_attr3_leaf_toosmall(
 		bytes = state->args->geo->blksize -
 			(state->args->geo->blksize >> 2) -
 			ichdr.usedbytes - ichdr2.usedbytes -
-			((ichdr.count + ichdr2.count) *
-					sizeof(xfs_attr_leaf_entry_t)) -
-			xfs_attr3_leaf_hdr_size(leaf);
+			xfs_attr_leaf_entries_end(ichdr.count + ichdr2.count,
+					leaf);
 
 		xfs_trans_brelse(state->args->trans, bp);
 		if (bytes >= 0)
@@ -2164,8 +2169,7 @@ xfs_attr3_leaf_remove(
 
 	ASSERT(ichdr.count > 0 && ichdr.count < args->geo->blksize / 8);
 	ASSERT(args->index >= 0 && args->index < ichdr.count);
-	ASSERT(ichdr.firstused >= ichdr.count * sizeof(*entry) +
-					xfs_attr3_leaf_hdr_size(leaf));
+	ASSERT(ichdr.firstused >= xfs_attr_leaf_entries_end(ichdr.count, leaf));
 
 	entry = &xfs_attr3_leaf_entryp(leaf)[args->index];
 
@@ -2178,8 +2182,7 @@ xfs_attr3_leaf_remove(
 	 *    find smallest free region in case we need to replace it,
 	 *    adjust any map that borders the entry table,
 	 */
-	tablesize = ichdr.count * sizeof(xfs_attr_leaf_entry_t)
-					+ xfs_attr3_leaf_hdr_size(leaf);
+	tablesize = xfs_attr_leaf_entries_end(ichdr.count, leaf);
 	tmp = ichdr.freemap[0].size;
 	before = after = -1;
 	smallest = XFS_ATTR_LEAF_MAPSIZE - 1;
@@ -2286,8 +2289,7 @@ xfs_attr3_leaf_remove(
 	 * Check if leaf is less than 50% full, caller may want to
 	 * "join" the leaf with a sibling if so.
 	 */
-	tmp = ichdr.usedbytes + xfs_attr3_leaf_hdr_size(leaf) +
-	      ichdr.count * sizeof(xfs_attr_leaf_entry_t);
+	tmp = ichdr.usedbytes + xfs_attr_leaf_entries_end(ichdr.count, leaf);
 
 	return tmp < args->geo->magicpct; /* leaf is < 37% full */
 }
@@ -2610,11 +2612,11 @@ xfs_attr3_leaf_moveents(
 	       ichdr_s->magic == XFS_ATTR3_LEAF_MAGIC);
 	ASSERT(ichdr_s->magic == ichdr_d->magic);
 	ASSERT(ichdr_s->count > 0 && ichdr_s->count < args->geo->blksize / 8);
-	ASSERT(ichdr_s->firstused >= (ichdr_s->count * sizeof(*entry_s))
-					+ xfs_attr3_leaf_hdr_size(leaf_s));
+	ASSERT(ichdr_s->firstused >=
+			xfs_attr_leaf_entries_end(ichdr_s->count, leaf_s));
 	ASSERT(ichdr_d->count < args->geo->blksize / 8);
-	ASSERT(ichdr_d->firstused >= (ichdr_d->count * sizeof(*entry_d))
-					+ xfs_attr3_leaf_hdr_size(leaf_d));
+	ASSERT(ichdr_d->firstused >=
+			xfs_attr_leaf_entries_end(ichdr_d->count, leaf_d));
 
 	ASSERT(start_s < ichdr_s->count);
 	ASSERT(start_d <= ichdr_d->count);
@@ -2674,8 +2676,7 @@ xfs_attr3_leaf_moveents(
 			ichdr_d->usedbytes += tmp;
 			ichdr_s->count -= 1;
 			ichdr_d->count += 1;
-			tmp = ichdr_d->count * sizeof(xfs_attr_leaf_entry_t)
-					+ xfs_attr3_leaf_hdr_size(leaf_d);
+			tmp = xfs_attr_leaf_entries_end(ichdr_d->count, leaf_d);
 			ASSERT(ichdr_d->firstused >= tmp);
 #ifdef GROT
 		}
@@ -2711,8 +2712,8 @@ xfs_attr3_leaf_moveents(
 	/*
 	 * Fill in the freemap information
 	 */
-	ichdr_d->freemap[0].base = xfs_attr3_leaf_hdr_size(leaf_d);
-	ichdr_d->freemap[0].base += ichdr_d->count * sizeof(xfs_attr_leaf_entry_t);
+	ichdr_d->freemap[0].base =
+		xfs_attr_leaf_entries_end(ichdr_d->count, leaf_d);
 	ichdr_d->freemap[0].size = ichdr_d->firstused - ichdr_d->freemap[0].base;
 	ichdr_d->freemap[1].base = 0;
 	ichdr_d->freemap[2].base = 0;


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

* [PATCH 23/40] xfs: strengthen attr leaf block freemap checking
  2026-03-23 18:41 ` [PATCHSET 2/2] xfsprogs: new libxfs code from kernel 7.0 Darrick J. Wong
                     ` (21 preceding siblings ...)
  2026-03-23 18:47   ` [PATCH 22/40] xfs: refactor attr3 leaf table size computation Darrick J. Wong
@ 2026-03-23 18:47   ` Darrick J. Wong
  2026-03-23 18:47   ` [PATCH 24/40] xfs: reduce xfs_attr_try_sf_addname parameters Darrick J. Wong
                     ` (16 subsequent siblings)
  39 siblings, 0 replies; 50+ messages in thread
From: Darrick J. Wong @ 2026-03-23 18:47 UTC (permalink / raw)
  To: djwong, aalbersh; +Cc: hch, linux-xfs

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

Source kernel commit: 27a0c41f33d8d31558d334b07eb58701aab0b3dd

Check for erroneous overlapping freemap regions and collisions between
freemap regions and the xattr leaf entry array.

Note that we must explicitly zero out the extra freemaps in
xfs_attr3_leaf_compact so that the in-memory buffer has a correctly
initialized freemap array to satisfy the new verification code, even if
subsequent code changes the contents before unlocking the buffer.

Signed-off-by: "Darrick J. Wong" <djwong@kernel.org>
Reviewed-by: Christoph Hellwig <hch@lst.de>
---
 libxfs/xfs_attr_leaf.c |   55 ++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 55 insertions(+)


diff --git a/libxfs/xfs_attr_leaf.c b/libxfs/xfs_attr_leaf.c
index 158864249c8888..f591984c3748ff 100644
--- a/libxfs/xfs_attr_leaf.c
+++ b/libxfs/xfs_attr_leaf.c
@@ -82,6 +82,49 @@ xfs_attr_leaf_entries_end(
 			xfs_attr3_leaf_hdr_size(leaf);
 }
 
+static inline bool
+ichdr_freemaps_overlap(
+	const struct xfs_attr3_icleaf_hdr	*ichdr,
+	unsigned int				x,
+	unsigned int				y)
+{
+	const unsigned int			xend =
+		ichdr->freemap[x].base + ichdr->freemap[x].size;
+	const unsigned int			yend =
+		ichdr->freemap[y].base + ichdr->freemap[y].size;
+
+	/* empty slots do not overlap */
+	if (!ichdr->freemap[x].size || !ichdr->freemap[y].size)
+		return false;
+
+	return ichdr->freemap[x].base < yend && xend > ichdr->freemap[y].base;
+}
+
+static inline xfs_failaddr_t
+xfs_attr_leaf_ichdr_freemaps_verify(
+	const struct xfs_attr3_icleaf_hdr	*ichdr,
+	const struct xfs_attr_leafblock		*leaf)
+{
+	unsigned int				entries_end =
+		xfs_attr_leaf_entries_end(ichdr->count, leaf);
+	int					i;
+
+	if (ichdr_freemaps_overlap(ichdr, 0, 1))
+		return __this_address;
+	if (ichdr_freemaps_overlap(ichdr, 0, 2))
+		return __this_address;
+	if (ichdr_freemaps_overlap(ichdr, 1, 2))
+		return __this_address;
+
+	for (i = 0; i < XFS_ATTR_LEAF_MAPSIZE; i++) {
+		if (ichdr->freemap[i].size > 0 &&
+		    ichdr->freemap[i].base < entries_end)
+			return __this_address;
+	}
+
+	return NULL;
+}
+
 /*
  * attr3 block 'firstused' conversion helpers.
  *
@@ -225,6 +268,8 @@ xfs_attr3_leaf_hdr_to_disk(
 			hdr3->freemap[i].base = cpu_to_be16(from->freemap[i].base);
 			hdr3->freemap[i].size = cpu_to_be16(from->freemap[i].size);
 		}
+
+		ASSERT(xfs_attr_leaf_ichdr_freemaps_verify(from, to) == NULL);
 		return;
 	}
 	to->hdr.info.forw = cpu_to_be32(from->forw);
@@ -240,6 +285,8 @@ xfs_attr3_leaf_hdr_to_disk(
 		to->hdr.freemap[i].base = cpu_to_be16(from->freemap[i].base);
 		to->hdr.freemap[i].size = cpu_to_be16(from->freemap[i].size);
 	}
+
+	ASSERT(xfs_attr_leaf_ichdr_freemaps_verify(from, to) == NULL);
 }
 
 static xfs_failaddr_t
@@ -392,6 +439,10 @@ xfs_attr3_leaf_verify(
 			return __this_address;
 	}
 
+	fa = xfs_attr_leaf_ichdr_freemaps_verify(&ichdr, leaf);
+	if (fa)
+		return fa;
+
 	return NULL;
 }
 
@@ -1661,6 +1712,10 @@ xfs_attr3_leaf_compact(
 	ichdr_dst->freemap[0].base = xfs_attr3_leaf_hdr_size(leaf_src);
 	ichdr_dst->freemap[0].size = ichdr_dst->firstused -
 						ichdr_dst->freemap[0].base;
+	ichdr_dst->freemap[1].base = 0;
+	ichdr_dst->freemap[2].base = 0;
+	ichdr_dst->freemap[1].size = 0;
+	ichdr_dst->freemap[2].size = 0;
 
 	/* write the header back to initialise the underlying buffer */
 	xfs_attr3_leaf_hdr_to_disk(args->geo, leaf_dst, ichdr_dst);


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

* [PATCH 24/40] xfs: reduce xfs_attr_try_sf_addname parameters
  2026-03-23 18:41 ` [PATCHSET 2/2] xfsprogs: new libxfs code from kernel 7.0 Darrick J. Wong
                     ` (22 preceding siblings ...)
  2026-03-23 18:47   ` [PATCH 23/40] xfs: strengthen attr leaf block freemap checking Darrick J. Wong
@ 2026-03-23 18:47   ` Darrick J. Wong
  2026-03-23 18:47   ` [PATCH 25/40] xfs: speed up parent pointer operations when possible Darrick J. Wong
                     ` (15 subsequent siblings)
  39 siblings, 0 replies; 50+ messages in thread
From: Darrick J. Wong @ 2026-03-23 18:47 UTC (permalink / raw)
  To: djwong, aalbersh; +Cc: hch, linux-xfs

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

Source kernel commit: 1ef7729df1f0c5f7bb63a121164f54d376d35835

The dp parameter to this function is an alias of args->dp, so remove it
for clarity before we go adding new callers.

Signed-off-by: "Darrick J. Wong" <djwong@kernel.org>
Reviewed-by: Christoph Hellwig <hch@lst.de>
---
 libxfs/xfs_attr.c |   11 ++++-------
 1 file changed, 4 insertions(+), 7 deletions(-)


diff --git a/libxfs/xfs_attr.c b/libxfs/xfs_attr.c
index baf617cfeabe00..175f8572b0f930 100644
--- a/libxfs/xfs_attr.c
+++ b/libxfs/xfs_attr.c
@@ -349,16 +349,14 @@ xfs_attr_set_resv(
  */
 STATIC int
 xfs_attr_try_sf_addname(
-	struct xfs_inode	*dp,
 	struct xfs_da_args	*args)
 {
-
 	int			error;
 
 	/*
 	 * Build initial attribute list (if required).
 	 */
-	if (dp->i_af.if_format == XFS_DINODE_FMT_EXTENTS)
+	if (args->dp->i_af.if_format == XFS_DINODE_FMT_EXTENTS)
 		xfs_attr_shortform_create(args);
 
 	error = xfs_attr_shortform_addname(args);
@@ -370,9 +368,9 @@ xfs_attr_try_sf_addname(
 	 * NOTE: this is also the error path (EEXIST, etc).
 	 */
 	if (!error)
-		xfs_trans_ichgtime(args->trans, dp, XFS_ICHGTIME_CHG);
+		xfs_trans_ichgtime(args->trans, args->dp, XFS_ICHGTIME_CHG);
 
-	if (xfs_has_wsync(dp->i_mount))
+	if (xfs_has_wsync(args->dp->i_mount))
 		xfs_trans_set_sync(args->trans);
 
 	return error;
@@ -383,10 +381,9 @@ xfs_attr_sf_addname(
 	struct xfs_attr_intent		*attr)
 {
 	struct xfs_da_args		*args = attr->xattri_da_args;
-	struct xfs_inode		*dp = args->dp;
 	int				error = 0;
 
-	error = xfs_attr_try_sf_addname(dp, args);
+	error = xfs_attr_try_sf_addname(args);
 	if (error != -ENOSPC) {
 		ASSERT(!error || error == -EEXIST);
 		attr->xattri_dela_state = XFS_DAS_DONE;


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

* [PATCH 25/40] xfs: speed up parent pointer operations when possible
  2026-03-23 18:41 ` [PATCHSET 2/2] xfsprogs: new libxfs code from kernel 7.0 Darrick J. Wong
                     ` (23 preceding siblings ...)
  2026-03-23 18:47   ` [PATCH 24/40] xfs: reduce xfs_attr_try_sf_addname parameters Darrick J. Wong
@ 2026-03-23 18:47   ` Darrick J. Wong
  2026-03-23 18:48   ` [PATCH 26/40] xfs: add a method to replace shortform attrs Darrick J. Wong
                     ` (14 subsequent siblings)
  39 siblings, 0 replies; 50+ messages in thread
From: Darrick J. Wong @ 2026-03-23 18:47 UTC (permalink / raw)
  To: djwong, aalbersh; +Cc: hch, linux-xfs

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

Source kernel commit: d693534513d8dcdaafcf855986d0fe0476a47462

After a recent fsmark benchmarking run, I observed that the overhead of
parent pointers on file creation and deletion can be a bit high.  On a
machine with 20 CPUs, 128G of memory, and an NVME SSD capable of pushing
750000iops, I see the following results:

$ mkfs.xfs -f -l logdev=/dev/nvme1n1,size=1g /dev/nvme0n1 -n parent=0
meta-data=/dev/nvme0n1           isize=512    agcount=40, agsize=9767586 blks
=                       sectsz=4096  attr=2, projid32bit=1
=                       crc=1        finobt=1, sparse=1, rmapbt=1
=                       reflink=1    bigtime=1 inobtcount=1 nrext64=1
=                       exchange=0   metadir=0
data     =                       bsize=4096   blocks=390703440, imaxpct=5
=                       sunit=0      swidth=0 blks
naming   =version 2              bsize=4096   ascii-ci=0, ftype=1, parent=0
log      =/dev/nvme1n1           bsize=4096   blocks=262144, version=2
=                       sectsz=4096  sunit=1 blks, lazy-count=1
realtime =none                   extsz=4096   blocks=0, rtextents=0
=                       rgcount=0    rgsize=0 extents
=                       zoned=0      start=0 reserved=0

So we created 40 AGs, one per CPU.  Now we create 40 directories and run
fsmark:

$ time fs_mark  -D  10000  -S  0  -n  100000  -s  0  -L  8 -d ...
# Version 3.3, 40 thread(s) starting at Wed Dec 10 14:22:07 2025
# Sync method: NO SYNC: Test does not issue sync() or fsync() calls.
# Directories:  Time based hash between directories across 10000 subdirectories with 180 seconds per subdirectory.
# File names: 40 bytes long, (16 initial bytes of time stamp with 24 random bytes at end of name)
# Files info: size 0 bytes, written with an IO size of 16384 bytes per write
# App overhead is time in microseconds spent in the test not doing file writing related system calls.

parent=0               parent=1
==================     ==================
real    0m57.573s      real    1m2.934s
user    3m53.578s      user    3m53.508s
sys     19m44.440s     sys     25m14.810s

$ time rm -rf ...

parent=0               parent=1
==================     ==================
real    0m59.649s      real    1m12.505s
user    0m41.196s      user    0m47.489s
sys     13m9.566s      sys     20m33.844s

Parent pointers increase the system time by 28% overhead to create 32
million files that are totally empty.  Removing them incurs a system
time increase of 56%.  Wall time increases by 9% and 22%.

For most filesystems, each file tends to have a single owner and not
that many xattrs.  If the xattr structure is shortform, then all xattr
changes are logged with the inode and do not require the the xattr
intent mechanism to persist the parent pointer.

Therefore, we can speed up parent pointer operations by calling the
shortform xattr functions directly if the child's xattr is in short
format.  Now the overhead looks like:

$ time fs_mark  -D  10000  -S  0  -n  100000  -s  0  -L  8 -d ...

parent=0               parent=1
==================     ==================
real    0m58.030s      real    1m0.983s
user    3m54.141s      user    3m53.758s
sys     19m57.003s     sys     21m30.605s

$ time rm -rf ...

parent=0               parent=1
==================     ==================
real    0m58.911s      real    1m4.420s
user    0m41.329s      user    0m45.169s
sys     13m27.857s     sys     15m58.564s

Now parent pointers only increase the system time by 8% for creation and
19% for deletion.  Wall time increases by 5% and 9% now.

Close the performance gap by creating helpers for the attr set, remove,
and replace operations that will try to make direct shortform updates,
and fall back to the attr intent machinery if that doesn't work.  This
works for regular xattrs and for parent pointers.

Signed-off-by: "Darrick J. Wong" <djwong@kernel.org>
Reviewed-by: Christoph Hellwig <hch@lst.de>
---
 libxfs/xfs_attr.h   |    6 +++
 libxfs/xfs_attr.c   |   99 +++++++++++++++++++++++++++++++++++++++++++++++++--
 libxfs/xfs_parent.c |   14 ++++---
 3 files changed, 109 insertions(+), 10 deletions(-)


diff --git a/libxfs/xfs_attr.h b/libxfs/xfs_attr.h
index 0e51d0723f9aa3..8244305949deb9 100644
--- a/libxfs/xfs_attr.h
+++ b/libxfs/xfs_attr.h
@@ -573,7 +573,7 @@ struct xfs_trans_res xfs_attr_set_resv(const struct xfs_da_args *args);
  */
 static inline bool
 xfs_attr_is_shortform(
-	struct xfs_inode    *ip)
+	const struct xfs_inode    *ip)
 {
 	return ip->i_af.if_format == XFS_DINODE_FMT_LOCAL ||
 	       (ip->i_af.if_format == XFS_DINODE_FMT_EXTENTS &&
@@ -649,4 +649,8 @@ void xfs_attr_intent_destroy_cache(void);
 int xfs_attr_sf_totsize(struct xfs_inode *dp);
 int xfs_attr_add_fork(struct xfs_inode *ip, int size, int rsvd);
 
+int xfs_attr_setname(struct xfs_da_args *args, int rmt_blks);
+int xfs_attr_removename(struct xfs_da_args *args);
+int xfs_attr_replacename(struct xfs_da_args *args, int rmt_blks);
+
 #endif	/* __XFS_ATTR_H__ */
diff --git a/libxfs/xfs_attr.c b/libxfs/xfs_attr.c
index 175f8572b0f930..0b45e72b5478b4 100644
--- a/libxfs/xfs_attr.c
+++ b/libxfs/xfs_attr.c
@@ -1027,6 +1027,91 @@ xfs_attr_add_fork(
 	return error;
 }
 
+/*
+ * Decide if it is theoretically possible to try to bypass the attr intent
+ * mechanism for better performance.  Other constraints (e.g. available space
+ * in the existing structure) are not considered here.
+ */
+static inline bool
+xfs_attr_can_shortcut(
+	const struct xfs_inode	*ip)
+{
+	return xfs_inode_has_attr_fork(ip) && xfs_attr_is_shortform(ip);
+}
+
+/* Try to set an attr in one transaction or fall back to attr intents. */
+int
+xfs_attr_setname(
+	struct xfs_da_args	*args,
+	int			rmt_blks)
+{
+	int			error;
+
+	if (!rmt_blks && xfs_attr_can_shortcut(args->dp)) {
+		args->op_flags |= XFS_DA_OP_ADDNAME;
+
+		error = xfs_attr_try_sf_addname(args);
+		if (error != -ENOSPC)
+			return error;
+	}
+
+	xfs_attr_defer_add(args, XFS_ATTR_DEFER_SET);
+	return 0;
+}
+
+/* Try to remove an attr in one transaction or fall back to attr intents. */
+int
+xfs_attr_removename(
+	struct xfs_da_args	*args)
+{
+	if (xfs_attr_can_shortcut(args->dp))
+		return xfs_attr_sf_removename(args);
+
+	xfs_attr_defer_add(args, XFS_ATTR_DEFER_REMOVE);
+	return 0;
+}
+
+/* Try to replace an attr in one transaction or fall back to attr intents. */
+int
+xfs_attr_replacename(
+	struct xfs_da_args	*args,
+	int			rmt_blks)
+{
+	int			error;
+
+	if (rmt_blks || !xfs_attr_can_shortcut(args->dp)) {
+		xfs_attr_defer_add(args, XFS_ATTR_DEFER_REPLACE);
+		return 0;
+	}
+
+	args->op_flags |= XFS_DA_OP_ADDNAME | XFS_DA_OP_REPLACE;
+
+	error = xfs_attr_sf_removename(args);
+	if (error)
+		return error;
+
+	if (args->attr_filter & XFS_ATTR_PARENT) {
+		/*
+		 * Move the new name/value to the regular name/value slots and
+		 * zero out the new name/value slots because we don't need to
+		 * log them for a PPTR_SET operation.
+		 */
+		xfs_attr_update_pptr_replace_args(args);
+		args->new_name = NULL;
+		args->new_namelen = 0;
+		args->new_value = NULL;
+		args->new_valuelen = 0;
+	}
+	args->op_flags &= ~XFS_DA_OP_REPLACE;
+
+	error = xfs_attr_try_sf_addname(args);
+	if (error != -ENOSPC)
+		return error;
+
+	xfs_attr_defer_add(args, XFS_ATTR_DEFER_SET);
+	return 0;
+}
+
 /*
  * Make a change to the xattr structure.
  *
@@ -1107,14 +1192,19 @@ xfs_attr_set(
 	case -EEXIST:
 		if (op == XFS_ATTRUPDATE_REMOVE) {
 			/* if no value, we are performing a remove operation */
-			xfs_attr_defer_add(args, XFS_ATTR_DEFER_REMOVE);
+			error = xfs_attr_removename(args);
+			if (error)
+				goto out_trans_cancel;
 			break;
 		}
 
 		/* Pure create fails if the attr already exists */
 		if (op == XFS_ATTRUPDATE_CREATE)
 			goto out_trans_cancel;
-		xfs_attr_defer_add(args, XFS_ATTR_DEFER_REPLACE);
+
+		error = xfs_attr_replacename(args, rmt_blks);
+		if (error)
+			goto out_trans_cancel;
 		break;
 	case -ENOATTR:
 		/* Can't remove what isn't there. */
@@ -1124,7 +1214,10 @@ xfs_attr_set(
 		/* Pure replace fails if no existing attr to replace. */
 		if (op == XFS_ATTRUPDATE_REPLACE)
 			goto out_trans_cancel;
-		xfs_attr_defer_add(args, XFS_ATTR_DEFER_SET);
+
+		error = xfs_attr_setname(args, rmt_blks);
+		if (error)
+			goto out_trans_cancel;
 		break;
 	default:
 		goto out_trans_cancel;
diff --git a/libxfs/xfs_parent.c b/libxfs/xfs_parent.c
index 12e4299840b8ef..d82c38197f4696 100644
--- a/libxfs/xfs_parent.c
+++ b/libxfs/xfs_parent.c
@@ -26,6 +26,7 @@
 #include "xfs_trans_space.h"
 #include "defer_item.h"
 #include "xfs_health.h"
+#include "xfs_attr_leaf.h"
 
 struct kmem_cache		*xfs_parent_args_cache;
 
@@ -199,8 +200,8 @@ xfs_parent_addname(
 	xfs_inode_to_parent_rec(&ppargs->rec, dp);
 	xfs_parent_da_args_init(&ppargs->args, tp, &ppargs->rec, child,
 			child->i_ino, parent_name);
-	xfs_attr_defer_add(&ppargs->args, XFS_ATTR_DEFER_SET);
-	return 0;
+
+	return xfs_attr_setname(&ppargs->args, 0);
 }
 
 /* Remove a parent pointer to reflect a dirent removal. */
@@ -221,8 +222,8 @@ xfs_parent_removename(
 	xfs_inode_to_parent_rec(&ppargs->rec, dp);
 	xfs_parent_da_args_init(&ppargs->args, tp, &ppargs->rec, child,
 			child->i_ino, parent_name);
-	xfs_attr_defer_add(&ppargs->args, XFS_ATTR_DEFER_REMOVE);
-	return 0;
+
+	return xfs_attr_removename(&ppargs->args);
 }
 
 /* Replace one parent pointer with another to reflect a rename. */
@@ -247,12 +248,13 @@ xfs_parent_replacename(
 			child->i_ino, old_name);
 
 	xfs_inode_to_parent_rec(&ppargs->new_rec, new_dp);
+
 	ppargs->args.new_name = new_name->name;
 	ppargs->args.new_namelen = new_name->len;
 	ppargs->args.new_value = &ppargs->new_rec;
 	ppargs->args.new_valuelen = sizeof(struct xfs_parent_rec);
-	xfs_attr_defer_add(&ppargs->args, XFS_ATTR_DEFER_REPLACE);
-	return 0;
+
+	return xfs_attr_replacename(&ppargs->args, 0);
 }
 
 /*


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

* [PATCH 26/40] xfs: add a method to replace shortform attrs
  2026-03-23 18:41 ` [PATCHSET 2/2] xfsprogs: new libxfs code from kernel 7.0 Darrick J. Wong
                     ` (24 preceding siblings ...)
  2026-03-23 18:47   ` [PATCH 25/40] xfs: speed up parent pointer operations when possible Darrick J. Wong
@ 2026-03-23 18:48   ` Darrick J. Wong
  2026-03-23 18:48   ` [PATCH 27/40] xfs: fix spacing style issues in xfs_alloc.c Darrick J. Wong
                     ` (13 subsequent siblings)
  39 siblings, 0 replies; 50+ messages in thread
From: Darrick J. Wong @ 2026-03-23 18:48 UTC (permalink / raw)
  To: djwong, aalbersh; +Cc: hch, linux-xfs

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

Source kernel commit: eaec8aeff31d0679eadb27a13a62942ddbfd7b87

If we're trying to replace an xattr in a shortform attr structure and
the old entry fits the new entry, we can just memcpy and exit without
having to delete, compact, and re-add the entry (or worse use the attr
intent machinery).  For parent pointers this only advantages renaming
where the filename length stays the same (e.g. mv autoexec.bat
scandisk.exe) but for regular xattrs it might be useful for updating
security labels and the like.

Signed-off-by: "Darrick J. Wong" <djwong@kernel.org>
Reviewed-by: Christoph Hellwig <hch@lst.de>
---
 include/xfs_trace.h    |    1 +
 libxfs/xfs_attr_leaf.h |    1 +
 libxfs/xfs_attr.c      |    4 ++++
 libxfs/xfs_attr_leaf.c |   38 ++++++++++++++++++++++++++++++++++++++
 4 files changed, 44 insertions(+)


diff --git a/include/xfs_trace.h b/include/xfs_trace.h
index 6bbf4007cbbbd9..be9183fc33ad90 100644
--- a/include/xfs_trace.h
+++ b/include/xfs_trace.h
@@ -57,6 +57,7 @@
 #define trace_xfs_attr_defer_replace(...)	((void) 0)
 #define trace_xfs_attr_defer_remove(...)	((void) 0)
 #define trace_xfs_attr_sf_addname_return(...)	((void) 0)
+#define trace_xfs_attr_sf_replace(...)		((void) 0)
 #define trace_xfs_attr_set_iter_return(...)	((void) 0)
 #define trace_xfs_attr_leaf_addname_return(...)	((void) 0)
 #define trace_xfs_attr_node_addname_return(...)	((void) 0)
diff --git a/libxfs/xfs_attr_leaf.h b/libxfs/xfs_attr_leaf.h
index 589f810eedc0d8..aca46da2bc502e 100644
--- a/libxfs/xfs_attr_leaf.h
+++ b/libxfs/xfs_attr_leaf.h
@@ -46,6 +46,7 @@ struct xfs_attr3_icleaf_hdr {
  * Internal routines when attribute fork size < XFS_LITINO(mp).
  */
 void	xfs_attr_shortform_create(struct xfs_da_args *args);
+int	xfs_attr_shortform_replace(struct xfs_da_args *args);
 void	xfs_attr_shortform_add(struct xfs_da_args *args, int forkoff);
 int	xfs_attr_shortform_getvalue(struct xfs_da_args *args);
 int	xfs_attr_shortform_to_leaf(struct xfs_da_args *args);
diff --git a/libxfs/xfs_attr.c b/libxfs/xfs_attr.c
index 0b45e72b5478b4..a2611aace8190f 100644
--- a/libxfs/xfs_attr.c
+++ b/libxfs/xfs_attr.c
@@ -1084,6 +1084,10 @@ xfs_attr_replacename(
 		return 0;
 	}
 
+	error = xfs_attr_shortform_replace(args);
+	if (error != -ENOSPC)
+		return error;
+
 	args->op_flags |= XFS_DA_OP_ADDNAME | XFS_DA_OP_REPLACE;
 
 	error = xfs_attr_sf_removename(args);
diff --git a/libxfs/xfs_attr_leaf.c b/libxfs/xfs_attr_leaf.c
index f591984c3748ff..90be21a3887642 100644
--- a/libxfs/xfs_attr_leaf.c
+++ b/libxfs/xfs_attr_leaf.c
@@ -839,6 +839,44 @@ xfs_attr_sf_findname(
 	return NULL;
 }
 
+/*
+ * Replace a shortform xattr if it's the right length.  Returns 0 on success,
+ * -ENOSPC if the length is wrong, or -ENOATTR if the attr was not found.
+ */
+int
+xfs_attr_shortform_replace(
+	struct xfs_da_args		*args)
+{
+	struct xfs_attr_sf_entry	*sfe;
+
+	ASSERT(args->dp->i_af.if_format == XFS_DINODE_FMT_LOCAL);
+
+	trace_xfs_attr_sf_replace(args);
+
+	sfe = xfs_attr_sf_findname(args);
+	if (!sfe)
+		return -ENOATTR;
+
+	if (args->attr_filter & XFS_ATTR_PARENT) {
+		if (sfe->namelen != args->new_namelen ||
+		    sfe->valuelen != args->new_valuelen)
+			return -ENOSPC;
+
+		memcpy(sfe->nameval, args->new_name, sfe->namelen);
+		memcpy(&sfe->nameval[sfe->namelen], args->new_value,
+				sfe->valuelen);
+	} else {
+		if (sfe->valuelen != args->valuelen)
+			return -ENOSPC;
+		memcpy(&sfe->nameval[sfe->namelen], args->value,
+				sfe->valuelen);
+	}
+
+	xfs_trans_log_inode(args->trans, args->dp,
+			XFS_ILOG_CORE | XFS_ILOG_ADATA);
+	return 0;
+}
+
 /*
  * Add a name/value pair to the shortform attribute list.
  * Overflow from the inode has already been checked for.


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

* [PATCH 27/40] xfs: fix spacing style issues in xfs_alloc.c
  2026-03-23 18:41 ` [PATCHSET 2/2] xfsprogs: new libxfs code from kernel 7.0 Darrick J. Wong
                     ` (25 preceding siblings ...)
  2026-03-23 18:48   ` [PATCH 26/40] xfs: add a method to replace shortform attrs Darrick J. Wong
@ 2026-03-23 18:48   ` Darrick J. Wong
  2026-03-23 18:48   ` [PATCH 28/40] xfs: don't validate error tags in the I/O path Darrick J. Wong
                     ` (12 subsequent siblings)
  39 siblings, 0 replies; 50+ messages in thread
From: Darrick J. Wong @ 2026-03-23 18:48 UTC (permalink / raw)
  To: djwong, aalbersh; +Cc: cem, shinsj4653, linux-xfs

From: Shin Seong-jun <shinsj4653@gmail.com>

Source kernel commit: 0ead3b72469e52ca02946b2e5b35fff38bfa061f

Fix checkpatch.pl errors regarding missing spaces around assignment
operators in xfs_alloc_compute_diff() and xfs_alloc_fixup_trees().

Adhere to the Linux kernel coding style by ensuring spaces are placed
around the assignment operator '='.

Signed-off-by: Shin Seong-jun <shinsj4653@gmail.com>
Reviewed-by: Darrick J. Wong <djwong@kernel.org>
Signed-off-by: Carlos Maiolino <cem@kernel.org>
---
 libxfs/xfs_alloc.c |    8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)


diff --git a/libxfs/xfs_alloc.c b/libxfs/xfs_alloc.c
index 9f92bd77fad76c..695ed830d139fe 100644
--- a/libxfs/xfs_alloc.c
+++ b/libxfs/xfs_alloc.c
@@ -372,8 +372,8 @@ xfs_alloc_compute_diff(
 	xfs_agblock_t	freeend;	/* end of freespace extent */
 	xfs_agblock_t	newbno1;	/* return block number */
 	xfs_agblock_t	newbno2;	/* other new block number */
-	xfs_extlen_t	newlen1=0;	/* length with newbno1 */
-	xfs_extlen_t	newlen2=0;	/* length with newbno2 */
+	xfs_extlen_t	newlen1 = 0;	/* length with newbno1 */
+	xfs_extlen_t	newlen2 = 0;	/* length with newbno2 */
 	xfs_agblock_t	wantend;	/* end of target extent */
 	bool		userdata = datatype & XFS_ALLOC_USERDATA;
 
@@ -573,8 +573,8 @@ xfs_alloc_fixup_trees(
 	int		i;		/* operation results */
 	xfs_agblock_t	nfbno1;		/* first new free startblock */
 	xfs_agblock_t	nfbno2;		/* second new free startblock */
-	xfs_extlen_t	nflen1=0;	/* first new free length */
-	xfs_extlen_t	nflen2=0;	/* second new free length */
+	xfs_extlen_t	nflen1 = 0;	/* first new free length */
+	xfs_extlen_t	nflen2 = 0;	/* second new free length */
 	struct xfs_mount *mp;
 	bool		fixup_longest = false;
 


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

* [PATCH 28/40] xfs: don't validate error tags in the I/O path
  2026-03-23 18:41 ` [PATCHSET 2/2] xfsprogs: new libxfs code from kernel 7.0 Darrick J. Wong
                     ` (26 preceding siblings ...)
  2026-03-23 18:48   ` [PATCH 27/40] xfs: fix spacing style issues in xfs_alloc.c Darrick J. Wong
@ 2026-03-23 18:48   ` Darrick J. Wong
  2026-03-23 18:48   ` [PATCH 29/40] xfs: add zone reset error injection Darrick J. Wong
                     ` (11 subsequent siblings)
  39 siblings, 0 replies; 50+ messages in thread
From: Darrick J. Wong @ 2026-03-23 18:48 UTC (permalink / raw)
  To: djwong, aalbersh; +Cc: cem, cmaiolino, hans.holmberg, hch, linux-xfs

From: Christoph Hellwig <hch@lst.de>

Source kernel commit: b8862a09d8256a9037293f1da3b4617b21de26f1

We can trust XFS developers enough to not pass random stuff to
XFS_ERROR_TEST/DELAY.  Open code the validity check in xfs_errortag_add,
which is the only place that receives unvalidated error tag values from
user space, and drop the now pointless xfs_errortag_enabled helper.

Signed-off-by: Christoph Hellwig <hch@lst.de>
Reviewed-by: Hans Holmberg <hans.holmberg@wdc.com>
Reviewed-by: Carlos Maiolino <cmaiolino@redhat.com>
Reviewed-by: Darrick J. Wong <djwong@kernel.org>
Signed-off-by: Carlos Maiolino <cem@kernel.org>
---
 libxfs/xfs_errortag.h |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)


diff --git a/libxfs/xfs_errortag.h b/libxfs/xfs_errortag.h
index 57e47077c75a2a..b7d98471684bf1 100644
--- a/libxfs/xfs_errortag.h
+++ b/libxfs/xfs_errortag.h
@@ -53,7 +53,7 @@
  * Drop-writes support removed because write error handling cannot trash
  * pre-existing delalloc extents in any useful way anymore. We retain the
  * definition so that we can reject it as an invalid value in
- * xfs_errortag_valid().
+ * xfs_errortag_add().
  */
 #define XFS_ERRTAG_DROP_WRITES				28
 #define XFS_ERRTAG_LOG_BAD_CRC				29


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

* [PATCH 29/40] xfs: add zone reset error injection
  2026-03-23 18:41 ` [PATCHSET 2/2] xfsprogs: new libxfs code from kernel 7.0 Darrick J. Wong
                     ` (27 preceding siblings ...)
  2026-03-23 18:48   ` [PATCH 28/40] xfs: don't validate error tags in the I/O path Darrick J. Wong
@ 2026-03-23 18:48   ` Darrick J. Wong
  2026-03-23 18:49   ` [PATCH 30/40] xfs: give the defer_relog stat a xs_ prefix Darrick J. Wong
                     ` (10 subsequent siblings)
  39 siblings, 0 replies; 50+ messages in thread
From: Darrick J. Wong @ 2026-03-23 18:48 UTC (permalink / raw)
  To: djwong, aalbersh; +Cc: cem, cmaiolino, hans.holmberg, hch, linux-xfs

From: Christoph Hellwig <hch@lst.de>

Source kernel commit: 41374ae69ec3a910950d3888f444f80678c6f308

Add a new errortag to test that zone reset errors are handled correctly.

Signed-off-by: Christoph Hellwig <hch@lst.de>
Reviewed-by: Carlos Maiolino <cmaiolino@redhat.com>
Reviewed-by: Hans Holmberg <hans.holmberg@wdc.com>
Reviewed-by: Darrick J. Wong <djwong@kernel.org>
Signed-off-by: Carlos Maiolino <cem@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 b7d98471684bf1..6de207fed2d892 100644
--- a/libxfs/xfs_errortag.h
+++ b/libxfs/xfs_errortag.h
@@ -74,7 +74,8 @@
 #define XFS_ERRTAG_EXCHMAPS_FINISH_ONE			44
 #define XFS_ERRTAG_METAFILE_RESV_CRITICAL		45
 #define XFS_ERRTAG_FORCE_ZERO_RANGE			46
-#define XFS_ERRTAG_MAX					47
+#define XFS_ERRTAG_ZONE_RESET				47
+#define XFS_ERRTAG_MAX					48
 
 /*
  * Random factors for above tags, 1 means always, 2 means 1/2 time, etc.
@@ -135,7 +136,8 @@ 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(FORCE_ZERO_RANGE,	force_zero_range,	4)
+XFS_ERRTAG(FORCE_ZERO_RANGE,	force_zero_range,	4) \
+XFS_ERRTAG(ZONE_RESET,		zone_reset,		1)
 #endif /* XFS_ERRTAG */
 
 #endif /* __XFS_ERRORTAG_H_ */


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

* [PATCH 30/40] xfs: give the defer_relog stat a xs_ prefix
  2026-03-23 18:41 ` [PATCHSET 2/2] xfsprogs: new libxfs code from kernel 7.0 Darrick J. Wong
                     ` (28 preceding siblings ...)
  2026-03-23 18:48   ` [PATCH 29/40] xfs: add zone reset error injection Darrick J. Wong
@ 2026-03-23 18:49   ` Darrick J. Wong
  2026-03-23 18:49   ` [PATCH 31/40] treewide: Replace kmalloc with kmalloc_obj for non-scalar types Darrick J. Wong
                     ` (9 subsequent siblings)
  39 siblings, 0 replies; 50+ messages in thread
From: Darrick J. Wong @ 2026-03-23 18:49 UTC (permalink / raw)
  To: djwong, aalbersh; +Cc: cem, dlemoal, hch, linux-xfs

From: Christoph Hellwig <hch@lst.de>

Source kernel commit: edf6078212c366459d3c70833290579b200128b1

Make this counter naming consistent with all the others.

Signed-off-by: Christoph Hellwig <hch@lst.de>
Reviewed-by: Damien Le Moal <dlemoal@kernel.org>
Signed-off-by: Carlos Maiolino <cem@kernel.org>
---
 libxfs/xfs_defer.c |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)


diff --git a/libxfs/xfs_defer.c b/libxfs/xfs_defer.c
index 5bd3cbe4cfa1a3..c0d3aa401cbab5 100644
--- a/libxfs/xfs_defer.c
+++ b/libxfs/xfs_defer.c
@@ -558,7 +558,7 @@ xfs_defer_relog(
 			continue;
 
 		trace_xfs_defer_relog_intent((*tpp)->t_mountp, dfp);
-		XFS_STATS_INC((*tpp)->t_mountp, defer_relog);
+		XFS_STATS_INC((*tpp)->t_mountp, xs_defer_relog);
 
 		xfs_defer_relog_intent(*tpp, dfp);
 	}


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

* [PATCH 31/40] treewide: Replace kmalloc with kmalloc_obj for non-scalar types
  2026-03-23 18:41 ` [PATCHSET 2/2] xfsprogs: new libxfs code from kernel 7.0 Darrick J. Wong
                     ` (29 preceding siblings ...)
  2026-03-23 18:49   ` [PATCH 30/40] xfs: give the defer_relog stat a xs_ prefix Darrick J. Wong
@ 2026-03-23 18:49   ` Darrick J. Wong
  2026-03-23 18:49   ` [PATCH 32/40] Convert 'alloc_obj' family to use the new default GFP_KERNEL argument Darrick J. Wong
                     ` (8 subsequent siblings)
  39 siblings, 0 replies; 50+ messages in thread
From: Darrick J. Wong @ 2026-03-23 18:49 UTC (permalink / raw)
  To: djwong, aalbersh; +Cc: kees, linux-xfs

From: Kees Cook <kees@kernel.org>

Source kernel commit: 69050f8d6d075dc01af7a5f2f550a8067510366f

This is the result of running the Coccinelle script from
scripts/coccinelle/api/kmalloc_objs.cocci. The script is designed to
avoid scalar types (which need careful case-by-case checking), and
instead replace kmalloc-family calls that allocate struct or union
object instances:

Single allocations:     kmalloc(sizeof(TYPE), ...)
are replaced with:      kmalloc_obj(TYPE, ...)

Array allocations:      kmalloc_array(COUNT, sizeof(TYPE), ...)
are replaced with:      kmalloc_objs(TYPE, COUNT, ...)

Flex array allocations: kmalloc(struct_size(PTR, FAM, COUNT), ...)
are replaced with:      kmalloc_flex(*PTR, FAM, COUNT, ...)

(where TYPE may also be *VAR)

The resulting allocations no longer return "void *", instead returning
"TYPE *".

Signed-off-by: Kees Cook <kees@kernel.org>
---
 libxfs/xfs_ag.c       |    2 +-
 libxfs/xfs_defer.c    |    2 +-
 libxfs/xfs_dir2.c     |   19 +++++++++----------
 libxfs/xfs_refcount.c |    4 ++--
 libxfs/xfs_rtgroup.c  |    2 +-
 5 files changed, 14 insertions(+), 15 deletions(-)


diff --git a/libxfs/xfs_ag.c b/libxfs/xfs_ag.c
index 8ccd67672b4e00..0f1eaf5d6e39b8 100644
--- a/libxfs/xfs_ag.c
+++ b/libxfs/xfs_ag.c
@@ -222,7 +222,7 @@ xfs_perag_alloc(
 	struct xfs_perag	*pag;
 	int			error;
 
-	pag = kzalloc(sizeof(*pag), GFP_KERNEL);
+	pag = kzalloc_obj(*pag, GFP_KERNEL);
 	if (!pag)
 		return -ENOMEM;
 
diff --git a/libxfs/xfs_defer.c b/libxfs/xfs_defer.c
index c0d3aa401cbab5..e4d17177f67faf 100644
--- a/libxfs/xfs_defer.c
+++ b/libxfs/xfs_defer.c
@@ -975,7 +975,7 @@ xfs_defer_ops_capture(
 		return ERR_PTR(error);
 
 	/* Create an object to capture the defer ops. */
-	dfc = kzalloc(sizeof(*dfc), GFP_KERNEL | __GFP_NOFAIL);
+	dfc = kzalloc_obj(*dfc, GFP_KERNEL | __GFP_NOFAIL);
 	INIT_LIST_HEAD(&dfc->dfc_list);
 	INIT_LIST_HEAD(&dfc->dfc_dfops);
 
diff --git a/libxfs/xfs_dir2.c b/libxfs/xfs_dir2.c
index 2ca6bf198ba54f..1a13fec25e15b3 100644
--- a/libxfs/xfs_dir2.c
+++ b/libxfs/xfs_dir2.c
@@ -115,10 +115,10 @@ xfs_da_mount(
 	ASSERT(mp->m_sb.sb_versionnum & XFS_SB_VERSION_DIRV2BIT);
 	ASSERT(xfs_dir2_dirblock_bytes(&mp->m_sb) <= XFS_MAX_BLOCKSIZE);
 
-	mp->m_dir_geo = kzalloc(sizeof(struct xfs_da_geometry),
-				GFP_KERNEL | __GFP_RETRY_MAYFAIL);
-	mp->m_attr_geo = kzalloc(sizeof(struct xfs_da_geometry),
-				GFP_KERNEL | __GFP_RETRY_MAYFAIL);
+	mp->m_dir_geo = kzalloc_obj(struct xfs_da_geometry,
+				    GFP_KERNEL | __GFP_RETRY_MAYFAIL);
+	mp->m_attr_geo = kzalloc_obj(struct xfs_da_geometry,
+				     GFP_KERNEL | __GFP_RETRY_MAYFAIL);
 	if (!mp->m_dir_geo || !mp->m_attr_geo) {
 		kfree(mp->m_dir_geo);
 		kfree(mp->m_attr_geo);
@@ -247,7 +247,7 @@ xfs_dir_init(
 	if (error)
 		return error;
 
-	args = kzalloc(sizeof(*args), GFP_KERNEL | __GFP_NOFAIL);
+	args = kzalloc_obj(*args, GFP_KERNEL | __GFP_NOFAIL);
 	if (!args)
 		return -ENOMEM;
 
@@ -340,7 +340,7 @@ xfs_dir_createname(
 		XFS_STATS_INC(dp->i_mount, xs_dir_create);
 	}
 
-	args = kzalloc(sizeof(*args), GFP_KERNEL | __GFP_NOFAIL);
+	args = kzalloc_obj(*args, GFP_KERNEL | __GFP_NOFAIL);
 	if (!args)
 		return -ENOMEM;
 
@@ -436,8 +436,7 @@ xfs_dir_lookup(
 	ASSERT(S_ISDIR(VFS_I(dp)->i_mode));
 	XFS_STATS_INC(dp->i_mount, xs_dir_lookup);
 
-	args = kzalloc(sizeof(*args),
-			GFP_KERNEL | __GFP_NOLOCKDEP | __GFP_NOFAIL);
+	args = kzalloc_obj(*args, GFP_KERNEL | __GFP_NOLOCKDEP | __GFP_NOFAIL);
 	args->geo = dp->i_mount->m_dir_geo;
 	args->name = name->name;
 	args->namelen = name->len;
@@ -502,7 +501,7 @@ xfs_dir_removename(
 	ASSERT(S_ISDIR(VFS_I(dp)->i_mode));
 	XFS_STATS_INC(dp->i_mount, xs_dir_remove);
 
-	args = kzalloc(sizeof(*args), GFP_KERNEL | __GFP_NOFAIL);
+	args = kzalloc_obj(*args, GFP_KERNEL | __GFP_NOFAIL);
 	if (!args)
 		return -ENOMEM;
 
@@ -562,7 +561,7 @@ xfs_dir_replace(
 	if (rval)
 		return rval;
 
-	args = kzalloc(sizeof(*args), GFP_KERNEL | __GFP_NOFAIL);
+	args = kzalloc_obj(*args, GFP_KERNEL | __GFP_NOFAIL);
 	if (!args)
 		return -ENOMEM;
 
diff --git a/libxfs/xfs_refcount.c b/libxfs/xfs_refcount.c
index 5c362e0e901124..036497dbb22b70 100644
--- a/libxfs/xfs_refcount.c
+++ b/libxfs/xfs_refcount.c
@@ -2031,8 +2031,8 @@ xfs_refcount_recover_extent(
 		return -EFSCORRUPTED;
 	}
 
-	rr = kmalloc(sizeof(struct xfs_refcount_recovery),
-			GFP_KERNEL | __GFP_NOFAIL);
+	rr = kmalloc_obj(struct xfs_refcount_recovery,
+			 GFP_KERNEL | __GFP_NOFAIL);
 	INIT_LIST_HEAD(&rr->rr_list);
 	xfs_refcount_btrec_to_irec(rec, &rr->rr_rrec);
 
diff --git a/libxfs/xfs_rtgroup.c b/libxfs/xfs_rtgroup.c
index af4eafb20bc138..69e71494057a1e 100644
--- a/libxfs/xfs_rtgroup.c
+++ b/libxfs/xfs_rtgroup.c
@@ -95,7 +95,7 @@ xfs_rtgroup_alloc(
 	struct xfs_rtgroup	*rtg;
 	int			error;
 
-	rtg = kzalloc(sizeof(struct xfs_rtgroup), GFP_KERNEL);
+	rtg = kzalloc_obj(struct xfs_rtgroup, GFP_KERNEL);
 	if (!rtg)
 		return -ENOMEM;
 


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

* [PATCH 32/40] Convert 'alloc_obj' family to use the new default GFP_KERNEL argument
  2026-03-23 18:41 ` [PATCHSET 2/2] xfsprogs: new libxfs code from kernel 7.0 Darrick J. Wong
                     ` (30 preceding siblings ...)
  2026-03-23 18:49   ` [PATCH 31/40] treewide: Replace kmalloc with kmalloc_obj for non-scalar types Darrick J. Wong
@ 2026-03-23 18:49   ` Darrick J. Wong
  2026-03-23 18:49   ` [PATCH 33/40] xfs: Refactoring the nagcount and delta calculation Darrick J. Wong
                     ` (7 subsequent siblings)
  39 siblings, 0 replies; 50+ messages in thread
From: Darrick J. Wong @ 2026-03-23 18:49 UTC (permalink / raw)
  To: djwong, aalbersh; +Cc: torvalds, linux-xfs

From: Linus Torvalds <torvalds@linux-foundation.org>

Source kernel commit: bf4afc53b77aeaa48b5409da5c8da6bb4eff7f43

This was done entirely with mindless brute force, using

git grep -l '\<k[vmz]*alloc_objs*(.*, GFP_KERNEL)' |
xargs sed -i 's/\(alloc_objs*(.*\), GFP_KERNEL)/\1)/'

to convert the new alloc_obj() users that had a simple GFP_KERNEL
argument to just drop that argument.

Note that due to the extreme simplicity of the scripting, any slightly
more complex cases spread over multiple lines would not be triggered:
they definitely exist, but this covers the vast bulk of the cases, and
the resulting diff is also then easier to check automatically.

For the same reason the 'flex' versions will be done as a separate
conversion.

Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
---
 libxfs/xfs_ag.c      |    2 +-
 libxfs/xfs_rtgroup.c |    2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)


diff --git a/libxfs/xfs_ag.c b/libxfs/xfs_ag.c
index 0f1eaf5d6e39b8..5742d59a2659da 100644
--- a/libxfs/xfs_ag.c
+++ b/libxfs/xfs_ag.c
@@ -222,7 +222,7 @@ xfs_perag_alloc(
 	struct xfs_perag	*pag;
 	int			error;
 
-	pag = kzalloc_obj(*pag, GFP_KERNEL);
+	pag = kzalloc_obj(*pag);
 	if (!pag)
 		return -ENOMEM;
 
diff --git a/libxfs/xfs_rtgroup.c b/libxfs/xfs_rtgroup.c
index 69e71494057a1e..d127ac0d611026 100644
--- a/libxfs/xfs_rtgroup.c
+++ b/libxfs/xfs_rtgroup.c
@@ -95,7 +95,7 @@ xfs_rtgroup_alloc(
 	struct xfs_rtgroup	*rtg;
 	int			error;
 
-	rtg = kzalloc_obj(struct xfs_rtgroup, GFP_KERNEL);
+	rtg = kzalloc_obj(struct xfs_rtgroup);
 	if (!rtg)
 		return -ENOMEM;
 


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

* [PATCH 33/40] xfs: Refactoring the nagcount and delta calculation
  2026-03-23 18:41 ` [PATCHSET 2/2] xfsprogs: new libxfs code from kernel 7.0 Darrick J. Wong
                     ` (31 preceding siblings ...)
  2026-03-23 18:49   ` [PATCH 32/40] Convert 'alloc_obj' family to use the new default GFP_KERNEL argument Darrick J. Wong
@ 2026-03-23 18:49   ` Darrick J. Wong
  2026-03-23 18:50   ` [PATCH 34/40] xfs: fix code alignment issues in xfs_ondisk.c Darrick J. Wong
                     ` (6 subsequent siblings)
  39 siblings, 0 replies; 50+ messages in thread
From: Darrick J. Wong @ 2026-03-23 18:49 UTC (permalink / raw)
  To: djwong, aalbersh; +Cc: cem, hch, nirjhar.roy.lists, linux-xfs

From: Nirjhar Roy (IBM) <nirjhar.roy.lists@gmail.com>

Source kernel commit: a49b7ff63f98ba1c4503869c568c99ecffa478f2

Introduce xfs_growfs_compute_delta() to calculate the nagcount
and delta blocks and refactor the code from xfs_growfs_data_private().
No functional changes.

Reviewed-by: Darrick J. Wong <djwong@kernel.org>
Reviewed-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Nirjhar Roy (IBM) <nirjhar.roy.lists@gmail.com>
Signed-off-by: Carlos Maiolino <cem@kernel.org>
---
 libxfs/xfs_ag.h |    3 +++
 libxfs/xfs_ag.c |   28 ++++++++++++++++++++++++++++
 2 files changed, 31 insertions(+)


diff --git a/libxfs/xfs_ag.h b/libxfs/xfs_ag.h
index 1f24cfa2732172..3cd4790768ff91 100644
--- a/libxfs/xfs_ag.h
+++ b/libxfs/xfs_ag.h
@@ -331,6 +331,9 @@ struct aghdr_init_data {
 int xfs_ag_init_headers(struct xfs_mount *mp, struct aghdr_init_data *id);
 int xfs_ag_shrink_space(struct xfs_perag *pag, struct xfs_trans **tpp,
 			xfs_extlen_t delta);
+void
+xfs_growfs_compute_deltas(struct xfs_mount *mp, xfs_rfsblock_t nb,
+			int64_t *deltap, xfs_agnumber_t *nagcountp);
 int xfs_ag_extend_space(struct xfs_perag *pag, struct xfs_trans *tp,
 			xfs_extlen_t len);
 int xfs_ag_get_geometry(struct xfs_perag *pag, struct xfs_ag_geometry *ageo);
diff --git a/libxfs/xfs_ag.c b/libxfs/xfs_ag.c
index 5742d59a2659da..fd5f902b052435 100644
--- a/libxfs/xfs_ag.c
+++ b/libxfs/xfs_ag.c
@@ -870,6 +870,34 @@ xfs_ag_shrink_space(
 	return err2;
 }
 
+void
+xfs_growfs_compute_deltas(
+	struct xfs_mount	*mp,
+	xfs_rfsblock_t		nb,
+	int64_t			*deltap,
+	xfs_agnumber_t		*nagcountp)
+{
+	xfs_rfsblock_t	nb_div, nb_mod;
+	int64_t		delta;
+	xfs_agnumber_t	nagcount;
+
+	nb_div = nb;
+	nb_mod = do_div(nb_div, mp->m_sb.sb_agblocks);
+	if (nb_mod && nb_mod >= XFS_MIN_AG_BLOCKS)
+		nb_div++;
+	else if (nb_mod)
+		nb = nb_div * mp->m_sb.sb_agblocks;
+
+	if (nb_div > XFS_MAX_AGNUMBER + 1) {
+		nb_div = XFS_MAX_AGNUMBER + 1;
+		nb = nb_div * mp->m_sb.sb_agblocks;
+	}
+	nagcount = nb_div;
+	delta = nb - mp->m_sb.sb_dblocks;
+	*deltap = delta;
+	*nagcountp = nagcount;
+}
+
 /*
  * Extent the AG indicated by the @id by the length passed in
  */


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

* [PATCH 34/40] xfs: fix code alignment issues in xfs_ondisk.c
  2026-03-23 18:41 ` [PATCHSET 2/2] xfsprogs: new libxfs code from kernel 7.0 Darrick J. Wong
                     ` (32 preceding siblings ...)
  2026-03-23 18:49   ` [PATCH 33/40] xfs: Refactoring the nagcount and delta calculation Darrick J. Wong
@ 2026-03-23 18:50   ` Darrick J. Wong
  2026-03-23 18:50   ` [PATCH 35/40] xfs: remove metafile inodes from the active inode stat Darrick J. Wong
                     ` (5 subsequent siblings)
  39 siblings, 0 replies; 50+ messages in thread
From: Darrick J. Wong @ 2026-03-23 18:50 UTC (permalink / raw)
  To: djwong, aalbersh; +Cc: cem, hch, wilfred.mallawa, linux-xfs

From: Wilfred Mallawa <wilfred.mallawa@wdc.com>

Source kernel commit: fd81d3fd01a5ee4bd26a7dc440e7a2209277d14b

Fixup some code alignment issues in xfs_ondisk.c

Signed-off-by: Wilfred Mallawa <wilfred.mallawa@wdc.com>
Reviewed-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Carlos Maiolino <cem@kernel.org>
---
 libxfs/xfs_ondisk.h |    4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)


diff --git a/libxfs/xfs_ondisk.h b/libxfs/xfs_ondisk.h
index 2e9715cc1641df..70605019383c32 100644
--- a/libxfs/xfs_ondisk.h
+++ b/libxfs/xfs_ondisk.h
@@ -73,7 +73,7 @@ xfs_check_ondisk_structs(void)
 	XFS_CHECK_STRUCT_SIZE(struct xfs_dir3_free_hdr,		64);
 	XFS_CHECK_STRUCT_SIZE(struct xfs_dir3_leaf,		64);
 	XFS_CHECK_STRUCT_SIZE(struct xfs_dir3_leaf_hdr,		64);
-	XFS_CHECK_STRUCT_SIZE(struct xfs_attr_leaf_entry,		8);
+	XFS_CHECK_STRUCT_SIZE(struct xfs_attr_leaf_entry,	8);
 	XFS_CHECK_STRUCT_SIZE(struct xfs_attr_leaf_hdr,		32);
 	XFS_CHECK_STRUCT_SIZE(struct xfs_attr_leaf_map,		4);
 	XFS_CHECK_STRUCT_SIZE(struct xfs_attr_leaf_name_local,	4);
@@ -116,7 +116,7 @@ xfs_check_ondisk_structs(void)
 	XFS_CHECK_STRUCT_SIZE(struct xfs_da_intnode,		16);
 	XFS_CHECK_STRUCT_SIZE(struct xfs_da_node_entry,		8);
 	XFS_CHECK_STRUCT_SIZE(struct xfs_da_node_hdr,		16);
-	XFS_CHECK_STRUCT_SIZE(struct xfs_dir2_data_free,		4);
+	XFS_CHECK_STRUCT_SIZE(struct xfs_dir2_data_free,	4);
 	XFS_CHECK_STRUCT_SIZE(struct xfs_dir2_data_hdr,		16);
 	XFS_CHECK_OFFSET(struct xfs_dir2_data_unused, freetag,	0);
 	XFS_CHECK_OFFSET(struct xfs_dir2_data_unused, length,	2);


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

* [PATCH 35/40] xfs: remove metafile inodes from the active inode stat
  2026-03-23 18:41 ` [PATCHSET 2/2] xfsprogs: new libxfs code from kernel 7.0 Darrick J. Wong
                     ` (33 preceding siblings ...)
  2026-03-23 18:50   ` [PATCH 34/40] xfs: fix code alignment issues in xfs_ondisk.c Darrick J. Wong
@ 2026-03-23 18:50   ` Darrick J. Wong
  2026-03-23 18:50   ` [PATCH 36/40] xfs: Add a comment in xfs_log_sb() Darrick J. Wong
                     ` (4 subsequent siblings)
  39 siblings, 0 replies; 50+ messages in thread
From: Darrick J. Wong @ 2026-03-23 18:50 UTC (permalink / raw)
  To: djwong, aalbersh; +Cc: cem, hch, linux-xfs

From: Christoph Hellwig <hch@lst.de>

Source kernel commit: 47553dd60b1da88df2354f841a4f71dd4de6478a

The active inode (or active vnode until recently) stat can get much larger
than expected on file systems with a lot of metafile inodes like zoned
file systems on SMR hard disks with 10.000s of rtg rmap inodes.

Remove all metafile inodes from the active counter to make it more useful
to track actual workloads and add a separate counter for active metafile
inodes.

This fixes xfs/177 on SMR hard drives.

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_inode_buf.c |    4 ++++
 libxfs/xfs_metafile.c  |    5 +++++
 2 files changed, 9 insertions(+)


diff --git a/libxfs/xfs_inode_buf.c b/libxfs/xfs_inode_buf.c
index 0802bc376073d8..f56aef0dbb3db9 100644
--- a/libxfs/xfs_inode_buf.c
+++ b/libxfs/xfs_inode_buf.c
@@ -265,6 +265,10 @@ xfs_inode_from_disk(
 	}
 	if (xfs_is_reflink_inode(ip))
 		xfs_ifork_init_cow(ip);
+	if (xfs_is_metadir_inode(ip)) {
+		XFS_STATS_DEC(ip->i_mount, xs_inodes_active);
+		XFS_STATS_INC(ip->i_mount, xs_inodes_meta);
+	}
 	return 0;
 
 out_destroy_data_fork:
diff --git a/libxfs/xfs_metafile.c b/libxfs/xfs_metafile.c
index 8d98989349d086..bab5d7e29ae9a7 100644
--- a/libxfs/xfs_metafile.c
+++ b/libxfs/xfs_metafile.c
@@ -59,6 +59,9 @@ xfs_metafile_set_iflag(
 	ip->i_diflags2 |= XFS_DIFLAG2_METADATA;
 	ip->i_metatype = metafile_type;
 	xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE);
+
+	XFS_STATS_DEC(ip->i_mount, xs_inodes_active);
+	XFS_STATS_INC(ip->i_mount, xs_inodes_meta);
 }
 
 /* Clear the metadata directory inode flag. */
@@ -72,6 +75,8 @@ xfs_metafile_clear_iflag(
 
 	ip->i_diflags2 &= ~XFS_DIFLAG2_METADATA;
 	xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE);
+	XFS_STATS_INC(ip->i_mount, xs_inodes_active);
+	XFS_STATS_DEC(ip->i_mount, xs_inodes_meta);
 }
 
 /*


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

* [PATCH 36/40] xfs: Add a comment in xfs_log_sb()
  2026-03-23 18:41 ` [PATCHSET 2/2] xfsprogs: new libxfs code from kernel 7.0 Darrick J. Wong
                     ` (34 preceding siblings ...)
  2026-03-23 18:50   ` [PATCH 35/40] xfs: remove metafile inodes from the active inode stat Darrick J. Wong
@ 2026-03-23 18:50   ` Darrick J. Wong
  2026-03-23 18:50   ` [PATCH 37/40] xfs: remove duplicate static size checks Darrick J. Wong
                     ` (3 subsequent siblings)
  39 siblings, 0 replies; 50+ messages in thread
From: Darrick J. Wong @ 2026-03-23 18:50 UTC (permalink / raw)
  To: djwong, aalbersh; +Cc: cem, hch, nirjhar.roy.lists, linux-xfs

From: Nirjhar Roy (IBM) <nirjhar.roy.lists@gmail.com>

Source kernel commit: ac1d977096a17d56c55bd7f90be48e81ac4cec3f

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: Darrick J. Wong <djwong@kernel.org>
Reviewed-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Nirjhar Roy (IBM) <nirjhar.roy.lists@gmail.com>
Signed-off-by: Carlos Maiolino <cem@kernel.org>
---
 libxfs/xfs_sb.c |    3 +++
 1 file changed, 3 insertions(+)


diff --git a/libxfs/xfs_sb.c b/libxfs/xfs_sb.c
index b29077dcd0aed7..7a1d85b86e59ea 100644
--- a/libxfs/xfs_sb.c
+++ b/libxfs/xfs_sb.c
@@ -1345,6 +1345,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 =


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

* [PATCH 37/40] xfs: remove duplicate static size checks
  2026-03-23 18:41 ` [PATCHSET 2/2] xfsprogs: new libxfs code from kernel 7.0 Darrick J. Wong
                     ` (35 preceding siblings ...)
  2026-03-23 18:50   ` [PATCH 36/40] xfs: Add a comment in xfs_log_sb() Darrick J. Wong
@ 2026-03-23 18:50   ` Darrick J. Wong
  2026-03-23 18:51   ` [PATCH 38/40] xfs: add static size checks for ioctl UABI Darrick J. Wong
                     ` (2 subsequent siblings)
  39 siblings, 0 replies; 50+ messages in thread
From: Darrick J. Wong @ 2026-03-23 18:50 UTC (permalink / raw)
  To: djwong, aalbersh; +Cc: cem, hch, wilfred.mallawa, linux-xfs

From: Wilfred Mallawa <wilfred.mallawa@wdc.com>

Source kernel commit: e97cbf863d8918452c9f81bebdade8d04e2e7b60

In libxfs/xfs_ondisk.h, remove some duplicate entries of
XFS_CHECK_STRUCT_SIZE().

Signed-off-by: Wilfred Mallawa <wilfred.mallawa@wdc.com>
Reviewed-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Carlos Maiolino <cem@kernel.org>
---
 libxfs/xfs_ondisk.h |    9 ---------
 1 file changed, 9 deletions(-)


diff --git a/libxfs/xfs_ondisk.h b/libxfs/xfs_ondisk.h
index 70605019383c32..7bccfa7b695c95 100644
--- a/libxfs/xfs_ondisk.h
+++ b/libxfs/xfs_ondisk.h
@@ -136,16 +136,7 @@ xfs_check_ondisk_structs(void)
 	/* ondisk dir/attr structures from xfs/122 */
 	XFS_CHECK_STRUCT_SIZE(struct xfs_attr_sf_entry,		3);
 	XFS_CHECK_STRUCT_SIZE(struct xfs_dir2_data_free,	4);
-	XFS_CHECK_STRUCT_SIZE(struct xfs_dir2_data_hdr,		16);
 	XFS_CHECK_STRUCT_SIZE(struct xfs_dir2_data_unused,	6);
-	XFS_CHECK_STRUCT_SIZE(struct xfs_dir2_free,		16);
-	XFS_CHECK_STRUCT_SIZE(struct xfs_dir2_free_hdr,		16);
-	XFS_CHECK_STRUCT_SIZE(struct xfs_dir2_leaf,		16);
-	XFS_CHECK_STRUCT_SIZE(struct xfs_dir2_leaf_entry,	8);
-	XFS_CHECK_STRUCT_SIZE(struct xfs_dir2_leaf_hdr,		16);
-	XFS_CHECK_STRUCT_SIZE(struct xfs_dir2_leaf_tail,	4);
-	XFS_CHECK_STRUCT_SIZE(struct xfs_dir2_sf_entry,		3);
-	XFS_CHECK_STRUCT_SIZE(struct xfs_dir2_sf_hdr,		10);
 
 	/* log structures */
 	XFS_CHECK_STRUCT_SIZE(struct xfs_buf_log_format,	88);


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

* [PATCH 38/40] xfs: add static size checks for ioctl UABI
  2026-03-23 18:41 ` [PATCHSET 2/2] xfsprogs: new libxfs code from kernel 7.0 Darrick J. Wong
                     ` (36 preceding siblings ...)
  2026-03-23 18:50   ` [PATCH 37/40] xfs: remove duplicate static size checks Darrick J. Wong
@ 2026-03-23 18:51   ` Darrick J. Wong
  2026-03-23 18:51   ` [PATCH 39/40] xfs: Remove redundant NULL check after __GFP_NOFAIL Darrick J. Wong
  2026-03-23 18:51   ` [PATCH 40/40] xfs: fix returned valued from xfs_defer_can_append Darrick J. Wong
  39 siblings, 0 replies; 50+ messages in thread
From: Darrick J. Wong @ 2026-03-23 18:51 UTC (permalink / raw)
  To: djwong, aalbersh; +Cc: cem, hch, wilfred.mallawa, linux-xfs

From: Wilfred Mallawa <wilfred.mallawa@wdc.com>

Source kernel commit: 650b774cf94495465d6a38c31bb1a6ce697b6b37

The ioctl structures in libxfs/xfs_fs.h are missing static size checks.
It is useful to have static size checks for these structures as adding
new fields to them could cause issues (e.g. extra padding that may be
inserted by the compiler). So add these checks to xfs/xfs_ondisk.h.

Due to different padding/alignment requirements across different
architectures, to avoid build failures, some structures are ommited from
the size checks. For example, structures with "compat_" definitions in
xfs/xfs_ioctl32.h are ommited.

Signed-off-by: Wilfred Mallawa <wilfred.mallawa@wdc.com>
Reviewed-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Carlos Maiolino <cem@kernel.org>
---
 libxfs/xfs_ondisk.h |   39 ++++++++++++++++++++++++++++++++++-----
 1 file changed, 34 insertions(+), 5 deletions(-)


diff --git a/libxfs/xfs_ondisk.h b/libxfs/xfs_ondisk.h
index 7bccfa7b695c95..23cde1248f019f 100644
--- a/libxfs/xfs_ondisk.h
+++ b/libxfs/xfs_ondisk.h
@@ -208,11 +208,6 @@ xfs_check_ondisk_structs(void)
 	XFS_CHECK_OFFSET(struct xfs_dir3_free, hdr.hdr.magic,	0);
 	XFS_CHECK_OFFSET(struct xfs_attr3_leafblock, hdr.info.hdr, 0);
 
-	XFS_CHECK_STRUCT_SIZE(struct xfs_bulkstat,		192);
-	XFS_CHECK_STRUCT_SIZE(struct xfs_inumbers,		24);
-	XFS_CHECK_STRUCT_SIZE(struct xfs_bulkstat_req,		64);
-	XFS_CHECK_STRUCT_SIZE(struct xfs_inumbers_req,		64);
-
 	/*
 	 * Make sure the incore inode timestamp range corresponds to hand
 	 * converted values based on the ondisk format specification.
@@ -292,6 +287,40 @@ xfs_check_ondisk_structs(void)
 	XFS_CHECK_SB_OFFSET(sb_pad,			281);
 	XFS_CHECK_SB_OFFSET(sb_rtstart,			288);
 	XFS_CHECK_SB_OFFSET(sb_rtreserved,		296);
+
+	/*
+	 * ioctl UABI
+	 *
+	 * Due to different padding/alignment requirements across
+	 * different architectures, some structures are ommited from
+	 * the size checks. In addition, structures with architecture
+	 * dependent size fields are also ommited (e.g. __kernel_long_t).
+	 */
+	XFS_CHECK_STRUCT_SIZE(struct xfs_bulkstat,		192);
+	XFS_CHECK_STRUCT_SIZE(struct xfs_inumbers,		24);
+	XFS_CHECK_STRUCT_SIZE(struct xfs_bulkstat_req,		64);
+	XFS_CHECK_STRUCT_SIZE(struct xfs_inumbers_req,		64);
+	XFS_CHECK_STRUCT_SIZE(struct dioattr,			12);
+	XFS_CHECK_STRUCT_SIZE(struct getbmap,			32);
+	XFS_CHECK_STRUCT_SIZE(struct getbmapx,			48);
+	XFS_CHECK_STRUCT_SIZE(struct xfs_attrlist_cursor,	16);
+	XFS_CHECK_STRUCT_SIZE(struct xfs_attrlist,		8);
+	XFS_CHECK_STRUCT_SIZE(struct xfs_attrlist,		8);
+	XFS_CHECK_STRUCT_SIZE(struct xfs_attrlist_ent,		4);
+	XFS_CHECK_STRUCT_SIZE(struct xfs_ag_geometry,		128);
+	XFS_CHECK_STRUCT_SIZE(struct xfs_rtgroup_geometry,	128);
+	XFS_CHECK_STRUCT_SIZE(struct xfs_error_injection,	8);
+	XFS_CHECK_STRUCT_SIZE(struct xfs_fsop_geom,		256);
+	XFS_CHECK_STRUCT_SIZE(struct xfs_fsop_geom_v4,		112);
+	XFS_CHECK_STRUCT_SIZE(struct xfs_fsop_counts,		32);
+	XFS_CHECK_STRUCT_SIZE(struct xfs_fsop_resblks,		16);
+	XFS_CHECK_STRUCT_SIZE(struct xfs_growfs_log,		8);
+	XFS_CHECK_STRUCT_SIZE(struct xfs_bulk_ireq,		64);
+	XFS_CHECK_STRUCT_SIZE(struct xfs_fs_eofblocks,		128);
+	XFS_CHECK_STRUCT_SIZE(struct xfs_fsid,			8);
+	XFS_CHECK_STRUCT_SIZE(struct xfs_scrub_metadata,	64);
+	XFS_CHECK_STRUCT_SIZE(struct xfs_scrub_vec,		16);
+	XFS_CHECK_STRUCT_SIZE(struct xfs_scrub_vec_head,	40);
 }
 
 #endif /* __XFS_ONDISK_H */


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

* [PATCH 39/40] xfs: Remove redundant NULL check after __GFP_NOFAIL
  2026-03-23 18:41 ` [PATCHSET 2/2] xfsprogs: new libxfs code from kernel 7.0 Darrick J. Wong
                     ` (37 preceding siblings ...)
  2026-03-23 18:51   ` [PATCH 38/40] xfs: add static size checks for ioctl UABI Darrick J. Wong
@ 2026-03-23 18:51   ` Darrick J. Wong
  2026-03-23 18:51   ` [PATCH 40/40] xfs: fix returned valued from xfs_defer_can_append Darrick J. Wong
  39 siblings, 0 replies; 50+ messages in thread
From: Darrick J. Wong @ 2026-03-23 18:51 UTC (permalink / raw)
  To: djwong, aalbersh; +Cc: cem, hch, hongao, linux-xfs

From: hongao <hongao@uniontech.com>

Source kernel commit: 281cb17787d4284a7790b9cbd80fded826ca7739

kzalloc() is called with __GFP_NOFAIL, so a NULL return is not expected.
Drop the redundant !map check in xfs_dabuf_map().
Also switch the nirecs-sized allocation to kcalloc().

Signed-off-by: hongao <hongao@uniontech.com>
Reviewed-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Carlos Maiolino <cem@kernel.org>
---
 libxfs/xfs_da_btree.c |    8 ++------
 1 file changed, 2 insertions(+), 6 deletions(-)


diff --git a/libxfs/xfs_da_btree.c b/libxfs/xfs_da_btree.c
index 969bfc9dee909d..2fce657af5d0b6 100644
--- a/libxfs/xfs_da_btree.c
+++ b/libxfs/xfs_da_btree.c
@@ -2712,12 +2712,8 @@ xfs_dabuf_map(
 	 * larger one that needs to be free by the caller.
 	 */
 	if (nirecs > 1) {
-		map = kzalloc(nirecs * sizeof(struct xfs_buf_map),
-				GFP_KERNEL | __GFP_NOLOCKDEP | __GFP_NOFAIL);
-		if (!map) {
-			error = -ENOMEM;
-			goto out_free_irecs;
-		}
+		map = kcalloc(nirecs, sizeof(struct xfs_buf_map),
+			      GFP_KERNEL | __GFP_NOLOCKDEP | __GFP_NOFAIL);
 		*mapp = map;
 	}
 


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

* [PATCH 40/40] xfs: fix returned valued from xfs_defer_can_append
  2026-03-23 18:41 ` [PATCHSET 2/2] xfsprogs: new libxfs code from kernel 7.0 Darrick J. Wong
                     ` (38 preceding siblings ...)
  2026-03-23 18:51   ` [PATCH 39/40] xfs: Remove redundant NULL check after __GFP_NOFAIL Darrick J. Wong
@ 2026-03-23 18:51   ` Darrick J. Wong
  39 siblings, 0 replies; 50+ messages in thread
From: Darrick J. Wong @ 2026-03-23 18:51 UTC (permalink / raw)
  To: djwong, aalbersh; +Cc: cem, cmaiolino, souptick.joarder, linux-xfs

From: Carlos Maiolino <cem@kernel.org>

Source kernel commit: 54fcd2f95f8d216183965a370ec69e1aab14f5da

xfs_defer_can_append returns a bool, it shouldn't be returning
a NULL.

Found by code inspection.

Fixes: 4dffb2cbb483 ("xfs: allow pausing of pending deferred work items")
Signed-off-by: Carlos Maiolino <cmaiolino@redhat.com>
Reviewed-by: Darrick J. Wong <djwong@kernel.org>
Acked-by: Souptick Joarder <souptick.joarder@hpe.com>
Signed-off-by: Carlos Maiolino <cem@kernel.org>
---
 libxfs/xfs_defer.c |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)


diff --git a/libxfs/xfs_defer.c b/libxfs/xfs_defer.c
index e4d17177f67faf..3e36865fd1279f 100644
--- a/libxfs/xfs_defer.c
+++ b/libxfs/xfs_defer.c
@@ -802,7 +802,7 @@ xfs_defer_can_append(
 
 	/* Paused items cannot absorb more work */
 	if (dfp->dfp_flags & XFS_DEFER_PAUSED)
-		return NULL;
+		return false;
 
 	/* Already full? */
 	if (ops->max_items && dfp->dfp_count >= ops->max_items)


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

* Re: [PATCH 01/40] libxfs: fix XFS_STATS_DEC
  2026-03-23 18:41   ` [PATCH 01/40] libxfs: fix XFS_STATS_DEC Darrick J. Wong
@ 2026-03-24  6:15     ` Christoph Hellwig
  2026-03-25 16:32     ` [PATCH v1.1 " Darrick J. Wong
  1 sibling, 0 replies; 50+ messages in thread
From: Christoph Hellwig @ 2026-03-24  6:15 UTC (permalink / raw)
  To: Darrick J. Wong; +Cc: aalbersh, linux-xfs

On Mon, Mar 23, 2026 at 11:41:32AM -0700, Darrick J. Wong wrote:
> From: Darrick J. Wong <djwong@kernel.org>
> 
> This macro only takes two arguments in the kernel, so fix the definition
> here too.  All existing callsites #if 0 it into oblivion which is why
> we've never noticed, but an upcoming patch in the libxfs sync will not
> be so lucky.

Looks good:

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

>  #define XFS_TEST_ERROR(a,b)		(false)
>  
> 
> 
---end quoted text---

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

* Re: [PATCH 02/40] libxfs: port various kernel apis from 7.0
  2026-03-23 18:41   ` [PATCH 02/40] libxfs: port various kernel apis from 7.0 Darrick J. Wong
@ 2026-03-24  6:16     ` Christoph Hellwig
  2026-03-24 17:18       ` Darrick J. Wong
  2026-03-25 16:33     ` [PATCH v1.1 " Darrick J. Wong
  1 sibling, 1 reply; 50+ messages in thread
From: Christoph Hellwig @ 2026-03-24  6:16 UTC (permalink / raw)
  To: Darrick J. Wong; +Cc: aalbersh, linux-xfs

On Mon, Mar 23, 2026 at 11:41:48AM -0700, Darrick J. Wong wrote:
> From: Darrick J. Wong <djwong@kernel.org>
> 
> Port more kernel APIs from Linux 7.0.

A little nitpicky, but this suggeste they were all added in Linux 7.0.
At least kmalloc_array is much older than that.

> +#define kcalloc(n, size, gfp)	kmalloc_array((n), (size), (gfp) | __GFP_ZERO)

Overly long line.

Otherwise looks good:

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

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

* Re: [PATCH 02/40] libxfs: port various kernel apis from 7.0
  2026-03-24  6:16     ` Christoph Hellwig
@ 2026-03-24 17:18       ` Darrick J. Wong
  2026-03-25  5:43         ` Christoph Hellwig
  0 siblings, 1 reply; 50+ messages in thread
From: Darrick J. Wong @ 2026-03-24 17:18 UTC (permalink / raw)
  To: Christoph Hellwig; +Cc: aalbersh, linux-xfs

On Mon, Mar 23, 2026 at 11:16:41PM -0700, Christoph Hellwig wrote:
> On Mon, Mar 23, 2026 at 11:41:48AM -0700, Darrick J. Wong wrote:
> > From: Darrick J. Wong <djwong@kernel.org>
> > 
> > Port more kernel APIs from Linux 7.0.
> 
> A little nitpicky, but this suggeste they were all added in Linux 7.0.
> At least kmalloc_array is much older than that.

I'll change it to:

"Port more kernel APIs from Linux as of 7.0."

> > +#define kcalloc(n, size, gfp)	kmalloc_array((n), (size), (gfp) | __GFP_ZERO)
> 
> Overly long line.

It is?  On my system it only hits column 78.

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

Thanks!

--D

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

* Re: [PATCH 02/40] libxfs: port various kernel apis from 7.0
  2026-03-24 17:18       ` Darrick J. Wong
@ 2026-03-25  5:43         ` Christoph Hellwig
  0 siblings, 0 replies; 50+ messages in thread
From: Christoph Hellwig @ 2026-03-25  5:43 UTC (permalink / raw)
  To: Darrick J. Wong; +Cc: Christoph Hellwig, aalbersh, linux-xfs

On Tue, Mar 24, 2026 at 10:18:43AM -0700, Darrick J. Wong wrote:
> On Mon, Mar 23, 2026 at 11:16:41PM -0700, Christoph Hellwig wrote:
> > On Mon, Mar 23, 2026 at 11:41:48AM -0700, Darrick J. Wong wrote:
> > > From: Darrick J. Wong <djwong@kernel.org>
> > > 
> > > Port more kernel APIs from Linux 7.0.
> > 
> > A little nitpicky, but this suggeste they were all added in Linux 7.0.
> > At least kmalloc_array is much older than that.
> 
> I'll change it to:
> 
> "Port more kernel APIs from Linux as of 7.0."

Sounds good.

> 
 > > +#define kcalloc(n, size, gfp)	kmalloc_array((n), (size), (gfp) | __GFP_ZERO)
> > 
> > Overly long line.
> 
> It is?  On my system it only hits column 78.

You're right, the diff messed up the mid-line tab alignment.


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

* [PATCH v1.1 01/40] libxfs: fix XFS_STATS_DEC
  2026-03-23 18:41   ` [PATCH 01/40] libxfs: fix XFS_STATS_DEC Darrick J. Wong
  2026-03-24  6:15     ` Christoph Hellwig
@ 2026-03-25 16:32     ` Darrick J. Wong
  1 sibling, 0 replies; 50+ messages in thread
From: Darrick J. Wong @ 2026-03-25 16:32 UTC (permalink / raw)
  To: aalbersh; +Cc: linux-xfs

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

This macro only takes two arguments in the kernel, so fix the definition
here too.  All existing callsites #if 0 it into oblivion which is why
we've never noticed, but an upcoming patch in the libxfs sync will not
be so lucky.

Cc: <linux-xfs@vger.kernel.org> # v4.9.0
Fixes: ece930fa14a343 ("xfs: refactor xfs_bunmapi_cow")
Signed-off-by: "Darrick J. Wong" <djwong@kernel.org>
Reviewed-by: Christoph Hellwig <hch@lst.de>
---
v1.1: add rvb tag
---
 libxfs/libxfs_priv.h |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/libxfs/libxfs_priv.h b/libxfs/libxfs_priv.h
index 5474865a673e9a..f72f07fabdf21e 100644
--- a/libxfs/libxfs_priv.h
+++ b/libxfs/libxfs_priv.h
@@ -183,7 +183,7 @@ enum ce { CE_DEBUG, CE_CONT, CE_NOTE, CE_WARN, CE_ALERT, CE_PANIC };
 #define XFS_ILOCK_SHARED		0
 #define XFS_IOLOCK_EXCL			0
 #define XFS_STATS_INC(mp, count)	do { (mp) = (mp); } while (0)
-#define XFS_STATS_DEC(mp, count, x)	do { (mp) = (mp); } while (0)
+#define XFS_STATS_DEC(mp, count)	do { (mp) = (mp); } while (0)
 #define XFS_STATS_ADD(mp, count, x)	do { (mp) = (mp); } while (0)
 #define XFS_TEST_ERROR(a,b)		(false)
 

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

* [PATCH v1.1 02/40] libxfs: port various kernel apis from 7.0
  2026-03-23 18:41   ` [PATCH 02/40] libxfs: port various kernel apis from 7.0 Darrick J. Wong
  2026-03-24  6:16     ` Christoph Hellwig
@ 2026-03-25 16:33     ` Darrick J. Wong
  1 sibling, 0 replies; 50+ messages in thread
From: Darrick J. Wong @ 2026-03-25 16:33 UTC (permalink / raw)
  To: aalbersh; +Cc: linux-xfs

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

Port more kernel APIs from Linux, as of version 7.0.

Signed-off-by: "Darrick J. Wong" <djwong@kernel.org>
Reviewed-by: Christoph Hellwig <hch@lst.de>
---
v1.1: add rvb, clarify the commit message
---
 include/kmem.h |   50 ++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 50 insertions(+)

diff --git a/include/kmem.h b/include/kmem.h
index 66f8b1fbea8fdf..2c276e929c4808 100644
--- a/include/kmem.h
+++ b/include/kmem.h
@@ -61,6 +61,56 @@ static inline void *kmalloc(size_t size, gfp_t flags)
 #define kzalloc(size, gfp)	kvmalloc((size), (gfp) | __GFP_ZERO)
 #define kvzalloc(size, gfp)	kzalloc((size), (gfp))
 
+/**
+ * kmalloc_array - allocate memory for an array.
+ * @n: number of elements.
+ * @size: element size.
+ * @flags: the type of memory to allocate (see kmalloc).
+ */
+static inline void *kmalloc_array(size_t n, size_t size, gfp_t flags)
+{
+	size_t bytes;
+
+	if (unlikely(check_mul_overflow(n, size, &bytes)))
+		return NULL;
+	return kmalloc(bytes, flags);
+}
+#define kcalloc(n, size, gfp)	kmalloc_array((n), (size), (gfp) | __GFP_ZERO)
+
+/**
+ * size_mul() - Calculate size_t multiplication with saturation at SIZE_MAX
+ * @factor1: first factor
+ * @factor2: second factor
+ *
+ * Returns: calculate @factor1 * @factor2, both promoted to size_t,
+ * with any overflow causing the return value to be SIZE_MAX. The
+ * lvalue must be size_t to avoid implicit type conversion.
+ */
+static inline size_t __must_check size_mul(size_t factor1, size_t factor2)
+{
+	size_t bytes;
+
+	if (check_mul_overflow(factor1, factor2, &bytes))
+		return SIZE_MAX;
+
+	return bytes;
+}
+
+#define __alloc_objs(KMALLOC, GFP, TYPE, COUNT)				\
+({									\
+	const size_t __obj_size = size_mul(sizeof(TYPE), COUNT);	\
+	(TYPE *)KMALLOC(__obj_size, GFP);				\
+})
+
+/* Helper macro to avoid gfp flags if they are the default one */
+#define __default_gfp(a,b,...) b
+#define default_gfp(...) __default_gfp(,##__VA_ARGS__,GFP_KERNEL)
+
+#define kzalloc_obj(P, ...) \
+	__alloc_objs(kzalloc, default_gfp(__VA_ARGS__), typeof(P), 1)
+#define kmalloc_obj(VAR_OR_TYPE, ...) \
+	__alloc_objs(kmalloc, default_gfp(__VA_ARGS__), typeof(VAR_OR_TYPE), 1)
+
 static inline void kfree(const void *ptr)
 {
 	free((void *)ptr);

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

end of thread, other threads:[~2026-03-25 16:33 UTC | newest]

Thread overview: 50+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-03-23 18:39 [PATCHBOMB] xfsprogs: rollup of libxfs-7.0-sync patches Darrick J. Wong
2026-03-23 18:40 ` [PATCHSET 1/2] xfsprogs: various bug fixes for 7.0 Darrick J. Wong
2026-03-23 18:41   ` [PATCH 1/1] xfs_repair: don't fail on INCOMPLETE attrs in leaf blocks Darrick J. Wong
2026-03-23 18:41 ` [PATCHSET 2/2] xfsprogs: new libxfs code from kernel 7.0 Darrick J. Wong
2026-03-23 18:41   ` [PATCH 01/40] libxfs: fix XFS_STATS_DEC Darrick J. Wong
2026-03-24  6:15     ` Christoph Hellwig
2026-03-25 16:32     ` [PATCH v1.1 " Darrick J. Wong
2026-03-23 18:41   ` [PATCH 02/40] libxfs: port various kernel apis from 7.0 Darrick J. Wong
2026-03-24  6:16     ` Christoph Hellwig
2026-03-24 17:18       ` Darrick J. Wong
2026-03-25  5:43         ` Christoph Hellwig
2026-03-25 16:33     ` [PATCH v1.1 " Darrick J. Wong
2026-03-23 18:42   ` [PATCH 03/40] libfrog: hoist some utilities from libxfs Darrick J. Wong
2026-03-23 18:42   ` [PATCH 04/40] libfrog: fix missing gettext call in current_fixed_time Darrick J. Wong
2026-03-23 18:42   ` [PATCH 05/40] xfs: start creating infrastructure for health monitoring Darrick J. Wong
2026-03-23 18:42   ` [PATCH 06/40] xfs: create event queuing, formatting, and discovery infrastructure Darrick J. Wong
2026-03-23 18:43   ` [PATCH 07/40] xfs: convey filesystem unmount events to the health monitor Darrick J. Wong
2026-03-23 18:43   ` [PATCH 08/40] xfs: convey metadata health " Darrick J. Wong
2026-03-23 18:43   ` [PATCH 09/40] xfs: convey filesystem shutdown " Darrick J. Wong
2026-03-23 18:43   ` [PATCH 10/40] xfs: convey externally discovered fsdax media errors " Darrick J. Wong
2026-03-23 18:44   ` [PATCH 11/40] xfs: convey file I/O " Darrick J. Wong
2026-03-23 18:44   ` [PATCH 12/40] xfs: check if an open file is on the health monitored fs Darrick J. Wong
2026-03-23 18:44   ` [PATCH 13/40] xfs: add media verification ioctl Darrick J. Wong
2026-03-23 18:44   ` [PATCH 14/40] xfs: move struct xfs_log_iovec to xfs_log_priv.h Darrick J. Wong
2026-03-23 18:45   ` [PATCH 15/40] xfs: directly include xfs_platform.h Darrick J. Wong
2026-03-23 18:45   ` [PATCH 16/40] xfs: remove xfs_attr_leaf_hasname Darrick J. Wong
2026-03-23 18:45   ` [PATCH 17/40] xfs: add missing forward declaration in xfs_zones.h Darrick J. Wong
2026-03-23 18:45   ` [PATCH 18/40] xfs: add a xfs_rtgroup_raw_size helper Darrick J. Wong
2026-03-23 18:46   ` [PATCH 19/40] xfs: split and refactor zone validation Darrick J. Wong
2026-03-23 18:46   ` [PATCH 20/40] xfs: delete attr leaf freemap entries when empty Darrick J. Wong
2026-03-23 18:46   ` [PATCH 21/40] xfs: fix freemap adjustments when adding xattrs to leaf blocks Darrick J. Wong
2026-03-23 18:47   ` [PATCH 22/40] xfs: refactor attr3 leaf table size computation Darrick J. Wong
2026-03-23 18:47   ` [PATCH 23/40] xfs: strengthen attr leaf block freemap checking Darrick J. Wong
2026-03-23 18:47   ` [PATCH 24/40] xfs: reduce xfs_attr_try_sf_addname parameters Darrick J. Wong
2026-03-23 18:47   ` [PATCH 25/40] xfs: speed up parent pointer operations when possible Darrick J. Wong
2026-03-23 18:48   ` [PATCH 26/40] xfs: add a method to replace shortform attrs Darrick J. Wong
2026-03-23 18:48   ` [PATCH 27/40] xfs: fix spacing style issues in xfs_alloc.c Darrick J. Wong
2026-03-23 18:48   ` [PATCH 28/40] xfs: don't validate error tags in the I/O path Darrick J. Wong
2026-03-23 18:48   ` [PATCH 29/40] xfs: add zone reset error injection Darrick J. Wong
2026-03-23 18:49   ` [PATCH 30/40] xfs: give the defer_relog stat a xs_ prefix Darrick J. Wong
2026-03-23 18:49   ` [PATCH 31/40] treewide: Replace kmalloc with kmalloc_obj for non-scalar types Darrick J. Wong
2026-03-23 18:49   ` [PATCH 32/40] Convert 'alloc_obj' family to use the new default GFP_KERNEL argument Darrick J. Wong
2026-03-23 18:49   ` [PATCH 33/40] xfs: Refactoring the nagcount and delta calculation Darrick J. Wong
2026-03-23 18:50   ` [PATCH 34/40] xfs: fix code alignment issues in xfs_ondisk.c Darrick J. Wong
2026-03-23 18:50   ` [PATCH 35/40] xfs: remove metafile inodes from the active inode stat Darrick J. Wong
2026-03-23 18:50   ` [PATCH 36/40] xfs: Add a comment in xfs_log_sb() Darrick J. Wong
2026-03-23 18:50   ` [PATCH 37/40] xfs: remove duplicate static size checks Darrick J. Wong
2026-03-23 18:51   ` [PATCH 38/40] xfs: add static size checks for ioctl UABI Darrick J. Wong
2026-03-23 18:51   ` [PATCH 39/40] xfs: Remove redundant NULL check after __GFP_NOFAIL Darrick J. Wong
2026-03-23 18:51   ` [PATCH 40/40] xfs: fix returned valued from xfs_defer_can_append 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