From 1c3fe56094dd23b3446b93247172980037229dc9 Mon Sep 17 00:00:00 2001 From: Andrea Parri Date: Mon, 28 Sep 2026 10:48:07 +0200 Subject: [PATCH] xfs: add an error tag to inject a ->writeback_submit() failure The only in-tree way for xfs_writeback_submit() to fail is a failing xfs_reflink_convert_cow(), which requires a shared (reflinked) CoW extent. There was previously no way to exercise that failure path from userspace, which made it hard to write an xfstest for it, e.g. for "iomap: don't resubmit an ioend after ->writeback_submit() failed". Add XFS_ERRTAG_WB_COW_CONVERT_ERROR to force xfs_reflink_convert_cow() to fail with -EIO, so that ->writeback_submit() failure and its callers' error handling can be exercised with error injection alone, without needing a corrupted or racy COW fork. Suggested-by: Christoph Hellwig Reviewed-by: Darrick J. Wong Reviewed-by: Christoph Hellwig Signed-off-by: Andrea Parri Link: https://patch.msgid.link/6c05aee81af9264ce6c19a436bc3503ecdab1e45.1790342457.git.parri.andrea@gmail.com Reviewed-by: "Darrick J. Wong" Signed-off-by: Christian Brauner (Amutable) --- fs/xfs/libxfs/xfs_errortag.h | 6 ++++-- fs/xfs/xfs_reflink.c | 5 +++++ 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/fs/xfs/libxfs/xfs_errortag.h b/fs/xfs/libxfs/xfs_errortag.h index 2dc441da0333..ac5abee05d80 100644 --- a/fs/xfs/libxfs/xfs_errortag.h +++ b/fs/xfs/libxfs/xfs_errortag.h @@ -76,7 +76,8 @@ #define XFS_ERRTAG_FORCE_ZERO_RANGE 46 #define XFS_ERRTAG_ZONE_RESET 47 #define XFS_ERRTAG_BOUNCE_REREAD 48 -#define XFS_ERRTAG_MAX 49 +#define XFS_ERRTAG_WB_COW_CONVERT_ERROR 49 +#define XFS_ERRTAG_MAX 50 /* * Random factors for above tags, 1 means always, 2 means 1/2 time, etc. @@ -139,7 +140,8 @@ 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(ZONE_RESET, zone_reset, 1) \ -XFS_ERRTAG(BOUNCE_REREAD, bounce_reread, XFS_RANDOM_DEFAULT) +XFS_ERRTAG(BOUNCE_REREAD, bounce_reread, XFS_RANDOM_DEFAULT) \ +XFS_ERRTAG(WB_COW_CONVERT_ERROR, wb_cow_convert_error, 1) #endif /* XFS_ERRTAG */ #endif /* __XFS_ERRORTAG_H_ */ diff --git a/fs/xfs/xfs_reflink.c b/fs/xfs/xfs_reflink.c index 480136136635..104542b10d9e 100644 --- a/fs/xfs/xfs_reflink.c +++ b/fs/xfs/xfs_reflink.c @@ -34,6 +34,8 @@ #include "xfs_rtalloc.h" #include "xfs_rtgroup.h" #include "xfs_metafile.h" +#include "xfs_errortag.h" +#include "xfs_error.h" /* * Copy on Write of Shared Blocks @@ -346,6 +348,9 @@ xfs_reflink_convert_cow( ASSERT(count != 0); + if (XFS_TEST_ERROR(mp, XFS_ERRTAG_WB_COW_CONVERT_ERROR)) + return -EIO; + xfs_ilock(ip, XFS_ILOCK_EXCL); error = xfs_reflink_convert_cow_locked(ip, offset_fsb, count_fsb); xfs_iunlock(ip, XFS_ILOCK_EXCL);