Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

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 <wqu@suse.com>
Reviewed-by: Johannes Thumshirn <johannes.thumshirn@wdc.com>
Reviewed-by: Mark Harmstone <mark@harmstone.com>
Signed-off-by: Michal Grzedzicki <mge@meta.com>
Signed-off-by: David Sterba <dsterba@suse.com>

authored by

Michal Grzedzicki and committed by
David Sterba
3cd181cc e0dfaebb

+2 -2
+1 -1
fs/btrfs/ordered-data.c
··· 386 386 } 387 387 388 388 if (!uptodate) 389 - set_bit(BTRFS_ORDERED_IOERR, &ordered->flags); 389 + btrfs_mark_ordered_extent_error(ordered); 390 390 391 391 if (ordered->bytes_left) 392 392 return false;
+1 -1
fs/btrfs/zoned.c
··· 2134 2134 continue; 2135 2135 } 2136 2136 if (!btrfs_zoned_split_ordered(ordered, logical, len)) { 2137 - set_bit(BTRFS_ORDERED_IOERR, &ordered->flags); 2137 + btrfs_mark_ordered_extent_error(ordered); 2138 2138 btrfs_err(fs_info, "failed to split ordered extent"); 2139 2139 goto out; 2140 2140 }