From: Michal Grzedzicki Date: Mon, 30 Mar 2026 16:06:44 +0000 (-0700) Subject: btrfs: fix silent IO error loss in encoded writes and zoned split X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=3cd181cc46d36aa7bd4af85f14639d86a25beaec;p=thirdparty%2Flinux.git btrfs: fix silent IO error loss in encoded writes and zoned split can_finish_ordered_extent() and btrfs_finish_ordered_zoned() set BTRFS_ORDERED_IOERR via bare set_bit(). Later, btrfs_mark_ordered_extent_error() in btrfs_finish_one_ordered() uses test_and_set_bit(), finds it already set, and skips mapping_set_error(). The error is never recorded on the inode's address_space, making it invisible to fsync. For encoded writes this causes btrfs receive to silently produce files with zero-filled holes. Fix: replace bare set_bit(BTRFS_ORDERED_IOERR) with btrfs_mark_ordered_extent_error() which pairs test_and_set_bit() with mapping_set_error(), guaranteeing the error is recorded exactly once. Reviewed-by: Qu Wenruo Reviewed-by: Johannes Thumshirn Reviewed-by: Mark Harmstone Signed-off-by: Michal Grzedzicki Signed-off-by: David Sterba --- diff --git a/fs/btrfs/ordered-data.c b/fs/btrfs/ordered-data.c index d39f1c49d1cf8..e5a24b3ff95e4 100644 --- a/fs/btrfs/ordered-data.c +++ b/fs/btrfs/ordered-data.c @@ -386,7 +386,7 @@ static bool can_finish_ordered_extent(struct btrfs_ordered_extent *ordered, } if (!uptodate) - set_bit(BTRFS_ORDERED_IOERR, &ordered->flags); + btrfs_mark_ordered_extent_error(ordered); if (ordered->bytes_left) return false; diff --git a/fs/btrfs/zoned.c b/fs/btrfs/zoned.c index f7ca01a32a031..16dd87aa06f20 100644 --- a/fs/btrfs/zoned.c +++ b/fs/btrfs/zoned.c @@ -2134,7 +2134,7 @@ void btrfs_finish_ordered_zoned(struct btrfs_ordered_extent *ordered) continue; } if (!btrfs_zoned_split_ordered(ordered, logical, len)) { - set_bit(BTRFS_ORDERED_IOERR, &ordered->flags); + btrfs_mark_ordered_extent_error(ordered); btrfs_err(fs_info, "failed to split ordered extent"); goto out; }