* [PATCH v3 1/3] xfs: zero entire directory data block header region at init
2026-04-11 14:24 [PATCH v3 0/3] xfs: clean up directory data block header padding Yuto Ohnuki
@ 2026-04-11 14:24 ` Yuto Ohnuki
2026-04-11 14:24 ` [PATCH v3 2/3] xfs: zero directory data block padding on write verification Yuto Ohnuki
2026-04-11 14:24 ` [PATCH v3 3/3] xfs: check directory data block header padding in scrub Yuto Ohnuki
2 siblings, 0 replies; 4+ messages in thread
From: Yuto Ohnuki @ 2026-04-11 14:24 UTC (permalink / raw)
To: Carlos Maiolino
Cc: Darrick J . Wong, Dave Chinner, linux-xfs, linux-kernel,
Yuto Ohnuki
xfs_dir3_data_init currently zeroes only the xfs_dir3_blk_hdr portion of
the directory data block header, then manually initializes the bestfree
entries in a loop. This leaves the pad field in xfs_dir3_data_hdr
uninitialized and requires explicit zeroing of each bestfree slot.
Zero the entire header region (geo->data_entry_offset bytes)
unconditionally before setting individual fields. This covers all
current and future header fields, all padding (implicit and explicit),
and the bestfree array, so the manual zeroing loop for bestfree can be
removed.
Suggested-by: Dave Chinner <dgc@kernel.org>
Signed-off-by: Yuto Ohnuki <ytohnuki@amazon.com>
---
fs/xfs/libxfs/xfs_dir2_data.c | 12 +++++-------
1 file changed, 5 insertions(+), 7 deletions(-)
diff --git a/fs/xfs/libxfs/xfs_dir2_data.c b/fs/xfs/libxfs/xfs_dir2_data.c
index 80ba94f51e5c..35ff119aa84b 100644
--- a/fs/xfs/libxfs/xfs_dir2_data.c
+++ b/fs/xfs/libxfs/xfs_dir2_data.c
@@ -728,7 +728,6 @@ xfs_dir3_data_init(
struct xfs_dir2_data_unused *dup;
struct xfs_dir2_data_free *bf;
int error;
- int i;
/*
* Get the buffer set up for the block.
@@ -741,13 +740,16 @@ xfs_dir3_data_init(
xfs_trans_buf_set_type(tp, bp, XFS_BLFT_DIR_DATA_BUF);
/*
- * Initialize the header.
+ * Initialize the whole directory header region to zero
+ * so that all padding, bestfree entries, and any
+ * future header fields are clean.
*/
hdr = bp->b_addr;
+ memset(hdr, 0, geo->data_entry_offset);
+
if (xfs_has_crc(mp)) {
struct xfs_dir3_blk_hdr *hdr3 = bp->b_addr;
- memset(hdr3, 0, sizeof(*hdr3));
hdr3->magic = cpu_to_be32(XFS_DIR3_DATA_MAGIC);
hdr3->blkno = cpu_to_be64(xfs_buf_daddr(bp));
hdr3->owner = cpu_to_be64(args->owner);
@@ -759,10 +761,6 @@ xfs_dir3_data_init(
bf = xfs_dir2_data_bestfree_p(mp, hdr);
bf[0].offset = cpu_to_be16(geo->data_entry_offset);
bf[0].length = cpu_to_be16(geo->blksize - geo->data_entry_offset);
- for (i = 1; i < XFS_DIR2_DATA_FD_COUNT; i++) {
- bf[i].length = 0;
- bf[i].offset = 0;
- }
/*
* Set up an unused entry for the block's body.
--
2.50.1
Amazon Web Services EMEA SARL, 38 avenue John F. Kennedy, L-1855 Luxembourg, R.C.S. Luxembourg B186284
Amazon Web Services EMEA SARL, Irish Branch, One Burlington Plaza, Burlington Road, Dublin 4, Ireland, branch registration number 908705
^ permalink raw reply related [flat|nested] 4+ messages in thread* [PATCH v3 2/3] xfs: zero directory data block padding on write verification
2026-04-11 14:24 [PATCH v3 0/3] xfs: clean up directory data block header padding Yuto Ohnuki
2026-04-11 14:24 ` [PATCH v3 1/3] xfs: zero entire directory data block header region at init Yuto Ohnuki
@ 2026-04-11 14:24 ` Yuto Ohnuki
2026-04-11 14:24 ` [PATCH v3 3/3] xfs: check directory data block header padding in scrub Yuto Ohnuki
2 siblings, 0 replies; 4+ messages in thread
From: Yuto Ohnuki @ 2026-04-11 14:24 UTC (permalink / raw)
To: Carlos Maiolino
Cc: Darrick J . Wong, Dave Chinner, linux-xfs, linux-kernel,
Yuto Ohnuki
Old kernels did not zero the pad field in xfs_dir3_data_hdr when
initializing directory data blocks, so existing filesystems may have
non-zero padding on disk.
Zero the pad field in xfs_dir3_data_write_verify alongside the existing
LSN and checksum updates. The pad field is pure alignment padding with
no runtime meaning, so zeroing it during write verification is safe and
has no additional I/O cost. This lets filesystems gradually self-heal
stale non-zero padding as directories are modified, without requiring an
explicit repair pass.
Suggested-by: Dave Chinner <dgc@kernel.org>
Signed-off-by: Yuto Ohnuki <ytohnuki@amazon.com>
---
fs/xfs/libxfs/xfs_dir2_data.c | 6 ++++++
1 file changed, 6 insertions(+)
diff --git a/fs/xfs/libxfs/xfs_dir2_data.c b/fs/xfs/libxfs/xfs_dir2_data.c
index 35ff119aa84b..aecbab61014c 100644
--- a/fs/xfs/libxfs/xfs_dir2_data.c
+++ b/fs/xfs/libxfs/xfs_dir2_data.c
@@ -382,6 +382,7 @@ xfs_dir3_data_write_verify(
struct xfs_mount *mp = bp->b_mount;
struct xfs_buf_log_item *bip = bp->b_log_item;
struct xfs_dir3_blk_hdr *hdr3 = bp->b_addr;
+ struct xfs_dir3_data_hdr *datahdr3 = bp->b_addr;
xfs_failaddr_t fa;
fa = xfs_dir3_data_verify(bp);
@@ -396,6 +397,11 @@ xfs_dir3_data_write_verify(
if (bip)
hdr3->lsn = cpu_to_be64(bip->bli_item.li_lsn);
+ /*
+ * Zero padding that may be stale from old kernels.
+ */
+ datahdr3->pad = 0;
+
xfs_buf_update_cksum(bp, XFS_DIR3_DATA_CRC_OFF);
}
--
2.50.1
Amazon Web Services EMEA SARL, 38 avenue John F. Kennedy, L-1855 Luxembourg, R.C.S. Luxembourg B186284
Amazon Web Services EMEA SARL, Irish Branch, One Burlington Plaza, Burlington Road, Dublin 4, Ireland, branch registration number 908705
^ permalink raw reply related [flat|nested] 4+ messages in thread
* [PATCH v3 3/3] xfs: check directory data block header padding in scrub
2026-04-11 14:24 [PATCH v3 0/3] xfs: clean up directory data block header padding Yuto Ohnuki
2026-04-11 14:24 ` [PATCH v3 1/3] xfs: zero entire directory data block header region at init Yuto Ohnuki
2026-04-11 14:24 ` [PATCH v3 2/3] xfs: zero directory data block padding on write verification Yuto Ohnuki
@ 2026-04-11 14:24 ` Yuto Ohnuki
2 siblings, 0 replies; 4+ messages in thread
From: Yuto Ohnuki @ 2026-04-11 14:24 UTC (permalink / raw)
To: Carlos Maiolino
Cc: Darrick J . Wong, Dave Chinner, linux-xfs, linux-kernel,
Yuto Ohnuki
Add the missing scrub check for the pad field in directory data block
headers. Old kernels may have written non-zero padding without issue,
and the write path now self-heals stale padding on modification. Flag
non-zero padding as an optimization opportunity (preen) rather than
corruption.
Add xchk_fblock_set_preen helper for reporting file fork block issues
that could be optimized. The trace event xchk_fblock_preen already
exists.
Signed-off-by: Yuto Ohnuki <ytohnuki@amazon.com>
---
fs/xfs/scrub/common.c | 11 +++++++++++
fs/xfs/scrub/common.h | 2 ++
fs/xfs/scrub/dir.c | 7 ++++++-
3 files changed, 19 insertions(+), 1 deletion(-)
diff --git a/fs/xfs/scrub/common.c b/fs/xfs/scrub/common.c
index 20e63069088b..3d40cb0b2496 100644
--- a/fs/xfs/scrub/common.c
+++ b/fs/xfs/scrub/common.c
@@ -251,6 +251,17 @@ xchk_ino_set_preen(
trace_xchk_ino_preen(sc, ino, __return_address);
}
+/* Record a block indexed by a file fork that could be optimized. */
+void
+xchk_fblock_set_preen(
+ struct xfs_scrub *sc,
+ int whichfork,
+ xfs_fileoff_t offset)
+{
+ sc->sm->sm_flags |= XFS_SCRUB_OFLAG_PREEN;
+ trace_xchk_fblock_preen(sc, whichfork, offset, __return_address);
+}
+
/* Record something being wrong with the filesystem primary superblock. */
void
xchk_set_corrupt(
diff --git a/fs/xfs/scrub/common.h b/fs/xfs/scrub/common.h
index f2ecc68538f0..b494d747c008 100644
--- a/fs/xfs/scrub/common.h
+++ b/fs/xfs/scrub/common.h
@@ -25,6 +25,8 @@ bool xchk_fblock_xref_process_error(struct xfs_scrub *sc,
void xchk_block_set_preen(struct xfs_scrub *sc,
struct xfs_buf *bp);
void xchk_ino_set_preen(struct xfs_scrub *sc, xfs_ino_t ino);
+void xchk_fblock_set_preen(struct xfs_scrub *sc,
+ int whichfork, xfs_fileoff_t offset);
void xchk_set_corrupt(struct xfs_scrub *sc);
void xchk_block_set_corrupt(struct xfs_scrub *sc,
diff --git a/fs/xfs/scrub/dir.c b/fs/xfs/scrub/dir.c
index e09724cd3725..09715a4aa154 100644
--- a/fs/xfs/scrub/dir.c
+++ b/fs/xfs/scrub/dir.c
@@ -492,7 +492,12 @@ xchk_directory_data_bestfree(
goto out;
xchk_buffer_recheck(sc, bp);
- /* XXX: Check xfs_dir3_data_hdr.pad is zero once we start setting it. */
+ if (xfs_has_crc(sc->mp)) {
+ struct xfs_dir3_data_hdr *hdr3 = bp->b_addr;
+
+ if (hdr3->pad)
+ xchk_fblock_set_preen(sc, XFS_DATA_FORK, lblk);
+ }
if (sc->sm->sm_flags & XFS_SCRUB_OFLAG_CORRUPT)
goto out_buf;
--
2.50.1
Amazon Web Services EMEA SARL, 38 avenue John F. Kennedy, L-1855 Luxembourg, R.C.S. Luxembourg B186284
Amazon Web Services EMEA SARL, Irish Branch, One Burlington Plaza, Burlington Road, Dublin 4, Ireland, branch registration number 908705
^ permalink raw reply related [flat|nested] 4+ messages in thread