]> www.infradead.org Git - users/jedix/linux-maple.git/commitdiff
bcachefs: Fix silent short reads in data read retry path
authorKent Overstreet <kent.overstreet@linux.dev>
Mon, 24 Mar 2025 15:51:01 +0000 (11:51 -0400)
committerKent Overstreet <kent.overstreet@linux.dev>
Tue, 25 Mar 2025 15:49:16 +0000 (11:49 -0400)
__bch2_read, before calling __bch2_read_extent(), sets bvec_iter.bi_size
to "the size we can read from the current extent" with a swap, and
restores it to "the size for the total read" after the read_extent call
with another swap.

But we neglected to do the restore before the "if (ret) goto err;" -
which is a problem if we're retrying those errors.

Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
fs/bcachefs/fs-io-buffered.c
fs/bcachefs/io_read.c
fs/bcachefs/io_read.h

index 5ab1c73c8d4c9986fa3556a9362296e6b6df1b06..a03e2c780cba078bec87a0bbf6e31c11d578dc67 100644 (file)
@@ -225,11 +225,11 @@ static void bchfs_read(struct btree_trans *trans,
 
                bch2_read_extent(trans, rbio, iter.pos,
                                 data_btree, k, offset_into_extent, flags);
+               swap(rbio->bio.bi_iter.bi_size, bytes);
 
                if (flags & BCH_READ_last_fragment)
                        break;
 
-               swap(rbio->bio.bi_iter.bi_size, bytes);
                bio_advance(&rbio->bio, bytes);
 err:
                if (ret &&
index f1503df57dc71a033765d704eb07f3dd092cace7..fafd00a3d6c955b590878e1110d74651096f2cec 100644 (file)
@@ -1322,13 +1322,14 @@ int __bch2_read(struct btree_trans *trans, struct bch_read_bio *rbio,
                ret = __bch2_read_extent(trans, rbio, bvec_iter, iter.pos,
                                         data_btree, k,
                                         offset_into_extent, failed, flags, -1);
+               swap(bvec_iter.bi_size, bytes);
+
                if (ret)
                        goto err;
 
                if (flags & BCH_READ_last_fragment)
                        break;
 
-               swap(bvec_iter.bi_size, bytes);
                bio_advance_iter(&rbio->bio, &bvec_iter, bytes);
 err:
                if (ret == -BCH_ERR_data_read_retry_csum_err_maybe_userspace)
index cd21950417f6430f812b9ee61e0226be293e6da5..c78025d863e0ff37a9a49a2ac66f3e7c5546794f 100644 (file)
@@ -137,8 +137,10 @@ static inline void bch2_read_extent(struct btree_trans *trans,
                        enum btree_id data_btree, struct bkey_s_c k,
                        unsigned offset_into_extent, unsigned flags)
 {
-       __bch2_read_extent(trans, rbio, rbio->bio.bi_iter, read_pos,
-                          data_btree, k, offset_into_extent, NULL, flags, -1);
+       int ret = __bch2_read_extent(trans, rbio, rbio->bio.bi_iter, read_pos,
+                                    data_btree, k, offset_into_extent, NULL, flags, -1);
+       /* __bch2_read_extent only returns errors if BCH_READ_in_retry is set */
+       WARN(ret, "unhandled error from __bch2_read_extent()");
 }
 
 int __bch2_read(struct btree_trans *, struct bch_read_bio *, struct bvec_iter,