summaryrefslogtreecommitdiffstats
path: root/fs/btrfs/extent_io.c
diff options
context:
space:
mode:
authorTavian Barnes <tavianator@tavianator.com>2024-03-18 09:56:54 -0400
committerDavid Sterba <dsterba@suse.com>2024-05-07 21:31:00 +0200
commitf32f20e2bd1f3b83925f703704840eebb56faedb (patch)
tree5e5139c315a25e56fcb98bcd10fd8aeb4b6cd907 /fs/btrfs/extent_io.c
parent1e2d1837091bf70f204802bcac48495358e75673 (diff)
downloadlinux-f32f20e2bd1f3b83925f703704840eebb56faedb.tar.gz
linux-f32f20e2bd1f3b83925f703704840eebb56faedb.tar.bz2
linux-f32f20e2bd1f3b83925f703704840eebb56faedb.zip
btrfs: warn if EXTENT_BUFFER_UPTODATE is set while reading
We recently tracked down a race condition that triggered a read for an extent buffer with EXTENT_BUFFER_UPTODATE already set. While this read was in progress, other concurrent readers would see the UPTODATE bit and return early as if the read was already complete, making accesses to the extent buffer conflict with the read operation that was overwriting it. Add a WARN_ON() to end_bbio_meta_read() for this situation to make similar races easier to spot in the future. Reviewed-by: Qu Wenruo <wqu@suse.com> Signed-off-by: Tavian Barnes <tavianator@tavianator.com> Reviewed-by: David Sterba <dsterba@suse.com> Signed-off-by: David Sterba <dsterba@suse.com>
Diffstat (limited to 'fs/btrfs/extent_io.c')
-rw-r--r--fs/btrfs/extent_io.c7
1 files changed, 7 insertions, 0 deletions
diff --git a/fs/btrfs/extent_io.c b/fs/btrfs/extent_io.c
index 23bdd05b5cec..ecb18a8db373 100644
--- a/fs/btrfs/extent_io.c
+++ b/fs/btrfs/extent_io.c
@@ -4275,6 +4275,13 @@ static void end_bbio_meta_read(struct btrfs_bio *bbio)
struct folio_iter fi;
u32 bio_offset = 0;
+ /*
+ * If the extent buffer is marked UPTODATE before the read operation
+ * completes, other calls to read_extent_buffer_pages() will return
+ * early without waiting for the read to finish, causing data races.
+ */
+ WARN_ON(test_bit(EXTENT_BUFFER_UPTODATE, &eb->bflags));
+
eb->read_mirror = bbio->mirror_num;
if (uptodate &&