Re: [PATCH 1/1] md: skip discard on unsupported member devices

From: wale zhang

Date: Fri Aug 07 2026 - 04:43:43 EST


Hello song and kuai,

This patch is to fix the following problem. Please help to review how
to fix this issue.

kernel log:
[768337.449125] bcache: bch_count_backing_io_errors() dm-3: IO error
on backing device, unrecoverable
[768337.449149] bcache: bch_cached_dev_error() stop bcache0: too many
IO errors on backing device dm-3
[768337.451175] BTRFS error (device bcache0): bdev /dev/bcache0 errs:
wr 1, rd 0, flush 0, corrupt 0, gen 0
[768337.452326] BTRFS error (device bcache0): bdev /dev/bcache0 errs:
wr 2, rd 0, flush 0, corrupt 0, gen 0
[768337.453512] BTRFS error (device bcache0): bdev /dev/bcache0 errs:
wr 3, rd 0, flush 0, corrupt 0, gen 0
[768337.454287] BTRFS error (device bcache0): bdev /dev/bcache0 errs:
wr 4, rd 0, flush 0, corrupt 0, gen 0
[768337.454993] BTRFS error (device bcache0): bdev /dev/bcache0 errs:
wr 5, rd 0, flush 0, corrupt 0, gen 0
[768337.455869] BTRFS error (device bcache0): bdev /dev/bcache0 errs:
wr 6, rd 0, flush 0, corrupt 0, gen 0
[768337.456643] BTRFS error (device bcache0): bdev /dev/bcache0 errs:
wr 7, rd 0, flush 0, corrupt 0, gen 0
[768337.457336] BTRFS error (device bcache0): bdev /dev/bcache0 errs:
wr 8, rd 0, flush 0, corrupt 0, gen 0
[768337.458014] BTRFS error (device bcache0): bdev /dev/bcache0 errs:
wr 9, rd 0, flush 0, corrupt 0, gen 0
[768337.458658] BTRFS error (device bcache0): bdev /dev/bcache0 errs:
wr 10, rd 0, flush 0, corrupt 0, gen 0
[768337.562394] BTRFS error (device bcache0 state A): Transaction
aborted (error -5)
[768337.562406] BTRFS: error (device bcache0 state A) in
btrfs_create_new_inode:6715: errno=-5 IO failure
[768337.562410] BTRFS info (device bcache0 state EA): forced readonly
[768346.923384] btrfs_dev_stat_inc_and_print: 1643 callbacks suppressed
[768346.923388] BTRFS error (device bcache0 state EA): bdev
/dev/bcache0 errs: wr 1653, rd 1, flush 0, corrupt 0, gen 0

storage stack is:
Btrfs
-> bcache
-> device-mapper
-> RAID0
-> disk A, discard unsupported
-> disk B, discard supported

The failing bio completion was:
kworker/u16:12-741243 [001] 768345.120068: block_bio_complete:
dev=64771 sector=20097083408 nr_sector=640 error=-95 rwbs=DS

error -95 is -EOPNOTSUPP and rwbs=DS identifies a synchronous discard
request. Repeated failures were counted by bcache as backing device
I/O errors, eventually causing bcache to stop after reaching its error
limit.

Thanks.


On Fri, Jul 31, 2026 at 3:47 PM Wale Zhang <wale.zhang.ftd@xxxxxxxxx> wrote:
>
> blk_stack_limits() uses min_not_zero() when stacking discard limits.
> Thus an array containing devices with different discard capabilities can
> expose discard support as long as at least one member has a non-zero
> discard limit.
>
> raid0 and raid10 use md_submit_discard_bio() to submit a discard bio to
> each member covered by the request. The helper currently also submits
> bios to members whose max_discard_sectors is zero. The block layer
> completes these bios with BLK_STS_NOTSUPP, and bio chaining propagates
> that status to the original discard request.
>
> Discard is optional, so skip members which do not support it. Members that
> do support discard continue to receive their portion of the request.
>
> Signed-off-by: Wale Zhang <wale.zhang.ftd@xxxxxxxxx>
> ---
> drivers/md/md.c | 4 ++++
> 1 file changed, 4 insertions(+)
>
> diff --git a/drivers/md/md.c b/drivers/md/md.c
> index d1465bcd86c8..77e6e6bd5460 100644
> --- a/drivers/md/md.c
> +++ b/drivers/md/md.c
> @@ -9350,6 +9350,10 @@ void md_submit_discard_bio(struct mddev *mddev, struct md_rdev *rdev,
> {
> struct bio *discard_bio = NULL;
>
> + /* Discard is optional, so silently skip members that do not support it. */
> + if (unlikely(!bdev_max_discard_sectors(rdev->bdev)))
> + return;
> +
> __blkdev_issue_discard(rdev->bdev, start, size, GFP_NOIO, &discard_bio);
> if (!discard_bio)
> return;
> --
> 2.47.3
>