From: Eric Biggers <ebiggers@kernel.org>
To: Mikulas Patocka <mpatocka@redhat.com>
Cc: "周伟江 (Weijiang Zhou)" <weijiang.zhou@unisoc.com>,
"dm-devel@lists.linux.dev" <dm-devel@lists.linux.dev>,
"Alasdair Kergon" <agk@redhat.com>,
"Mike Snitzer" <snitzer@kernel.org>,
"Benjamin Marzinski" <bmarzins@redhat.com>,
"Sami Tolvanen" <samitolvanen@google.com>,
"金红宇 (Hongyu Jin)" <hongyu.jin@unisoc.com>,
"吴祥禄 (Xianglu Wu)" <Xianglu.Wu@unisoc.com>,
"吴周镜 (Justin Wu)" <Justin.Wu@unisoc.com>
Subject: Re: [RFC PATCH 1/2] dm-verity: don't decode FEC into a dm_bufio page that is already in the cache
Date: Thu, 12 Nov 2026 21:36:39 -0800 [thread overview]
Message-ID: <20261113053639.GA76778@sol> (raw)
In-Reply-To: <5188c1e8-c08a-2a56-7e4c-1d84aba4df35@redhat.com>
On Tue, Nov 10, 2026 at 10:08:02PM +0100, Mikulas Patocka wrote:
> On Tue, 10 Nov 2026, 周伟江 (Weijiang Zhou) wrote:
> > Commit 51ba14fb368e ("dm-verity: do forward error correction on metadata
> > I/O errors") handles a failed hash block read by allocating the block with
> > dm_bufio_new() and decoding into it with verity_fec_decode().
> >
> > dm_bufio_new() inserts the buffer into the v->bufio cache immediately, with
> > no B_READING state and no read_error, i.e. indistinguishable from a
> > successfully read block that merely has not been hash-verified yet. Its
> > contents are whatever the allocator returned (all zeroes with init_on_alloc),
> > and no I/O is ever submitted for it.
>
> I don't see why this should be a problem.
>
> If the device returns random data, FEC is supposed to correct it.
>
> If the device returns an I/O error and we create a buffer with random
> data, this is similar to the case where the device returned random data -
> and FEC should also correct it. It doesn't matter whether the random data
> came from the device or from uninitialized kernel memory.
>
> So, it seems to me that this patch is just papering over the problem.
dm-verity does use FEC to try to recover from I/O errors, but this
doesn't mean that I/O errors and corruption are interchangeable and
handled in the same way. See the difference at the end of
verity_handle_data_hash_mismatch(), for example. It calls
verity_handle_err() only on actual corruption, not an I/O error. That
triggers the corruption policy controlled by 'v->mode', which is
different from the I/O error policy controlled by 'v->error_mode'.
> > FEC then reads every other block of the RS codeword and, for blocks on the
> > data device, calls verity_hash_for_block() on them to decide whether they
> > are erasures. That walks the hash tree through the same v->bufio. If one of
> > those data blocks is covered by the hash block being recovered (or by a
> > descendant of it, when it is an upper level block), the nested
>
> This is the real problem that should be fixed. Correcting a block
> shouldn't depend on the content of the block being corrected.
There does seem to be a bug where when FEC is trying to read data block
hashes to correct a block, it can detect corruption in the hash tree and
be unable to correct it due to FEC being non-recursive. That triggers
the corruption policy, when really it shouldn't and FEC should just
consider erasure information unavailable. That is fixable.
But it is not the root cause problem here. The root cause problem is
that the call to dm_bufio_new() injects uninitialized data into the hash
block cache as if it came from a successful read. That turns an I/O
error into corruption, making the corruption policy take effect merely
due to an I/O error. This is not limited to FEC reading the data block
erasures, either; any concurrent reader can trip over this corruption.
It seems that dm_bufio_new() was designed for writers that overwrite the
full block without reading any of it while also excluding concurrent
readers, e.g. using locks. That just does not work here, unfortunately.
Using a kmalloc() buffer (this patch) kind of works but is a hack
because it doesn't actually populate the cache at all. I think the
correct solution would be to have the FEC output initially just go into
fio->output, then populate the cache atomically with the data. Seems
that dm-bufio.c will need a new function for that.
- Eric
next prev parent reply other threads:[~2026-11-13 5:36 UTC|newest]
Thread overview: 12+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-11-10 13:06 [RFC PATCH 0/2] dm-verity: don't let FEC decode into a dm_bufio page that is already in the cache 周伟江 (Weijiang Zhou)
2026-11-10 13:06 ` [RFC PATCH 1/2] dm-verity: don't decode FEC " 周伟江 (Weijiang Zhou)
2026-11-10 21:08 ` Mikulas Patocka
2026-11-11 3:14 ` 周伟江 (Weijiang Zhou)
2026-11-11 23:33 ` Mikulas Patocka
2026-11-12 0:38 ` Sami Tolvanen
2026-11-13 5:36 ` Eric Biggers [this message]
2026-11-10 13:06 ` [RFC PATCH 2/2] dm-verity: don't restart or panic on errors during system shutdown 周伟江 (Weijiang Zhou)
2026-11-10 21:13 ` Mikulas Patocka
2026-11-11 3:14 ` 周伟江 (Weijiang Zhou)
2026-11-11 22:48 ` Mikulas Patocka
2026-11-13 5:55 ` Eric Biggers
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20261113053639.GA76778@sol \
--to=ebiggers@kernel.org \
--cc=Justin.Wu@unisoc.com \
--cc=Xianglu.Wu@unisoc.com \
--cc=agk@redhat.com \
--cc=bmarzins@redhat.com \
--cc=dm-devel@lists.linux.dev \
--cc=hongyu.jin@unisoc.com \
--cc=mpatocka@redhat.com \
--cc=samitolvanen@google.com \
--cc=snitzer@kernel.org \
--cc=weijiang.zhou@unisoc.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.