Re: [PATCH 02/19] buffer: allow a buffer_head to point at memory outside the page cache
Chris S <[email protected]> Wed, 5 Aug 2026 13:42:00 -0400
| Newsgroups | org.kernel.vger.linux-ext4,dev.linux.lists.gfs2,dev.linux.lists.ocfs2-devel,org.kernel.vger.linux-fsdevel,org.kernel.vger.linux-kernel |
|---|---|
| Message-ID | <CACd_6n0hCFbEnJwKbMoR5qxdQoRoicKA8OE+Th6HshkL-NiKsA@mail.gmail.com> |
Correcting myself: it is not the kmem_cache pointer that lands at that offset. SLAB_MATCH(compound_info, slab_cache) puts slab_cache at word 1, while ->mapping is word 3, so what a slab folio has there is slab_list.prev= . Not an address_space either way, so the reason for splitting the patch stands, but I named the wrong field. Best, Chao On Tue, Aug 4, 2026 at 7:06=E2=80=AFPM Chris S <[email protected]> wrote: > > Agreed, and done - but not in this patch, which is worth flagging because= it > is not obvious. > > folio_mapping() is doing two jobs here. The one you are objecting to is = the > swap cache mapping. The other is that it returns NULL for a slab folio, = and > that is the only reason this path is safe for jbd2's shadow buffers today= - > they are the slab-backed buffers this series is getting rid of, and they = do > reach buffer_set_crypto_ctx() through __bh_submit(). > > So doing it in this patch would leave one commit where shadow buffers sti= ll > sit on slab folios, and this code reads folio->mapping directly, i.e., ha= nds > fscrypt a struct kmem_cache and dereferences ->host on it. Fine at the e= nd > of the series, broken in the middle of it. > > v2 does it as its own patch 4, after the jbd2 change. > > Chao > > On Tue, Aug 4, 2026 at 10:07=E2=80=AFAM Matthew Wilcox <[email protected]= rg> wrote: > > > > On Tue, Aug 04, 2026 at 10:07:39AM +0200, Jan Kara wrote: > > > > Yes, agreed. I think it's fine to add in some 'if (!bh->b_folio)' > > > > tests, but only where they're needed for the occasional consumer. = This > > > > really is a rare (but legitimate) case. > > > > > > Yes. If we were to write this code from scratch, I'd rather push for > > > forming and submitting the bio directly instead of trying to bend the= bh > > > layer for these temporary bhs. Eventually we might want to do this cl= eanup > > > anyway (since bhs don't really buy us much in this path) but not in t= his > > > patch set. > > > > I think that would be better, but it is out of scope. > > > > > > > > static void buffer_set_crypto_ctx(struct bio *bio, const struc= t buffer_head *bh, > > > > > > gfp_t gfp_mask) > > > > > > { > > > > > > - const struct address_space *mapping =3D folio_mapping(b= h->b_folio); > > > > > > + const struct address_space *mapping; > > > > > > > > > > > > /* > > > > > > * The ext4 journal (jbd2) can submit a buffer_head it = directly created > > > > > > - * for a non-pagecache page. fscrypt doesn't care abou= t these. > > > > > > + * for memory that is not in the page cache at all. fs= crypt doesn't > > > > > > + * care about these. > > > > > > */ > > > > > > + if (!bh->b_folio) > > > > > > + return; > > > > > > + mapping =3D folio_mapping(bh->b_folio); > > > > > > if (!mapping) > > > > > > return; > > > > > > > > Do we want to call folio_mapping() here? The only case where I can= see > > > > this being useful is if we attach a buffer_head to an anonymous fol= io, > > > > and I don't see a good reason to do that. I think this can just be > > > > > > > > mapping =3D bh->b_folio->mapping; > > > > > > For all I know yes, bh->b_folio->mapping should be enough here. But I > > > thought folio_mapping() is kind of preferred to open-coding? > > > > It rather depends on the path we're talking about. Looking at the > > implementation of folio_mapping(), it's actually mildly dangerous > > to call folio_mapping() in this path. If we were ever to point a > > buffer_head at some memory on a page in swap cache, we'd get a pointer > > to a swap_address_space. I think we'd safely crash in that case becaus= e > > mapping->host would be NULL, but in other contexts doing things to a > > swap mapping would be quite bad. > > > > So I think this should just be folio->mapping; don't risk getting a > > pointer to a swap mapping.