--- /dev/null
+From 0193e3966ceeeef69e235975918b287ab093082b Mon Sep 17 00:00:00 2001
+From: Wu Bo <bo.wu@vivo.com>
+Date: Tue, 21 Nov 2023 20:51:50 -0700
+Subject: dm verity: don't perform FEC for failed readahead IO
+
+From: Wu Bo <bo.wu@vivo.com>
+
+commit 0193e3966ceeeef69e235975918b287ab093082b upstream.
+
+We found an issue under Android OTA scenario that many BIOs have to do
+FEC where the data under dm-verity is 100% complete and no corruption.
+
+Android OTA has many dm-block layers, from upper to lower:
+dm-verity
+dm-snapshot
+dm-origin & dm-cow
+dm-linear
+ufs
+
+DM tables have to change 2 times during Android OTA merging process.
+When doing table change, the dm-snapshot will be suspended for a while.
+During this interval, many readahead IOs are submitted to dm_verity
+from filesystem. Then the kverity works are busy doing FEC process
+which cost too much time to finish dm-verity IO. This causes needless
+delay which feels like system is hung.
+
+After adding debugging it was found that each readahead IO needed
+around 10s to finish when this situation occurred. This is due to IO
+amplification:
+
+dm-snapshot suspend
+erofs_readahead // 300+ io is submitted
+ dm_submit_bio (dm_verity)
+ dm_submit_bio (dm_snapshot)
+ bio return EIO
+ bio got nothing, it's empty
+ verity_end_io
+ verity_verify_io
+ forloop range(0, io->n_blocks) // each io->nblocks ~= 20
+ verity_fec_decode
+ fec_decode_rsb
+ fec_read_bufs
+ forloop range(0, v->fec->rsn) // v->fec->rsn = 253
+ new_read
+ submit_bio (dm_snapshot)
+ end loop
+ end loop
+dm-snapshot resume
+
+Readahead BIOs get nothing while dm-snapshot is suspended, so all of
+them will cause verity's FEC.
+Each readahead BIO needs to verify ~20 (io->nblocks) blocks.
+Each block needs to do FEC, and every block needs to do 253
+(v->fec->rsn) reads.
+So during the suspend interval(~200ms), 300 readahead BIOs trigger
+~1518000 (300*20*253) IOs to dm-snapshot.
+
+As readahead IO is not required by userspace, and to fix this issue,
+it is best to pass readahead errors to upper layer to handle it.
+
+Cc: stable@vger.kernel.org
+Fixes: a739ff3f543a ("dm verity: add support for forward error correction")
+Signed-off-by: Wu Bo <bo.wu@vivo.com>
+Reviewed-by: Mikulas Patocka <mpatocka@redhat.com>
+Signed-off-by: Mike Snitzer <snitzer@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/md/dm-verity-target.c | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+--- a/drivers/md/dm-verity-target.c
++++ b/drivers/md/dm-verity-target.c
+@@ -579,7 +579,9 @@ static void verity_end_io(struct bio *bi
+ struct dm_verity_io *io = bio->bi_private;
+
+ if (bio->bi_status &&
+- (!verity_fec_is_enabled(io->v) || verity_is_system_shutting_down())) {
++ (!verity_fec_is_enabled(io->v) ||
++ verity_is_system_shutting_down() ||
++ (bio->bi_opf & REQ_RAHEAD))) {
+ verity_finish_io(io, bio->bi_status);
+ return;
+ }