Re: [PATCH v2] fs/buffer: serialize set_buffer_uptodate against concurrent clears

From: Chris S

Date: Thu Jul 30 2026 - 18:09:50 EST


Yes, that works. And appreciate your reply.
I prototyped it, and it survives a journal replay.

Six sites, with bio_add_virt_nofail() covering the submit side:

bh_offset() b_page may be NULL
buffer_set_crypto_ctx() NULL guard
__bh_submit() bio_add_virt_nofail() when !b_folio, and
skip wbc_account_cgroup_owner()
jbd2_journal_write_metadata_buffer()
b_folio = NULL, b_data =
jh->b_frozen_data, not folio_set_bh()
jbd2_checksum_data(), jbd2_block_tag_csum_set() both kmap the temp bh
(fs/jbd2/commit.c:705 and :745)

4 files, +38/-12. I'll send it as the first patch of the series.

Tested: ext4 with metadata_csum, mounted data=journal,journal_checksum,
writing files whose every block starts with the JBD2 magic so escaping
forces copy-out into b_frozen_data, plus repeated modification of the same
metadata while commits run. Then sysrq-b without unmounting, reboot,
mount to replay. Journal recovery completed, md5sums of the escaped files
matched, e2fsck -fn clean, no warnings. An instrumented build confirmed
the b_folio == NULL path was actually taken rather than silently skipped.

Best,
Chao

On Thu, Jul 30, 2026 at 4:20 PM Matthew Wilcox <willy@xxxxxxxxxxxxx> wrote:
>
> On Thu, Jul 30, 2026 at 03:47:23PM -0400, Chris S wrote:
> > Hi Jan, I'm currently working on the changes we discussed. Based on
> > vfs.all now. Four things came out of writing it that I would rather
> > resolve before posting.
> >
> > 1. mark_buffer_write_io_error() is not safe for jbd2's buffers yet. It
> > dereferences bh->b_folio->mapping directly (fs/buffer.c:1057), and
> > jbd2_journal_write_metadata_buffer() points the temporary bh at
> > virt_to_folio(jh->b_frozen_data), which is slab-backed.
>
> ... yeah. That's one of the unclean things which keeps me awake at
> night. Sorry you ran into it.
>
> My longterm plan for this particular usecase (pointing a bh at slab
> memory) is to have bh->b_folio = NULL, bh->b_data = (address of data).
> Maybe we could do that now? That would make mark_buffer_write_io_error()
> work without change today.
>
> There might be a good reason I didn't do that yet, but I forget what it
> was.
>