Re: [RFC PATCH 0/9] ext4: phase out inline data write paths for regular files
From: Jan Kara
Date: Wed Oct 21 2026 - 10:39:11 EST
Hi!
So I was thinking about this for unrelated reasons and I think the
following plan / design should work.
On Wed 29-07-26 11:12:17, Zhou, Yun wrote:
> On 7/27/26 23:03, Theodore Tso wrote:
> > I agree that inline_data feature has been a persistent source of bugs,
> > and is relatively minimal for data files. Howvever, the regular files
> > that are small enough to support inline data come really boring filess
> > where we're not doing the really stressful things that fsx, fstress,
> > syzbot, etc. do to punish the file system.
>
> The "boring file" argument assumes benign workloads. Under adversarial
> conditions (which CVE assignments reflect), any race window is exploitable
> regardless of how unlikely it is under normal use.
I agree we have to keep things as simple as possible. Still what Ted
suggested below should be mostly achievable with quite simple design.
> > So what if we had a mechanism where we're using delayed allocation, if
> > the are no open file descriptor, so races and deadlocks can be
> > avoided, and in that case, we can write it as an inline regular data
> > file. Otherwise, we back it using a regular block. I think this
> > would get us 95% of the benefits of inline data files, with much less
> > of the complexity cost.
>
> This is an interesting approach and could potentially work. That said, new
> mechanisms often introduce new race conditions. Do the minor gains truly
> justify the added complexity? No major distribution enables inline_data by
> default. The feature has been available for 14 years and remains opt-in,
> suggesting the benefit has never been compelling enough for general use.
>
> It's not worth introducing new complexity for a feature that has no actual
> users and keeps introducing bugs. However, I am open to investigating this
> further in the hope of finding a good balance.
So I believe following design should be simple and achieve what Ted wants.
What I'd do is that without delalloc, we'd do practically what you have
implemented - convert inline data on first write(2) (in .write_begin) or on
.page_mkwrite under the folio lock. In fact we could just prepare the write
as if inline data was not existing and just destroy the inline_data xattr
once the preparation of the write succeeded. No extra special code needed.
When delayed allocation is enabled, again both .write_begin and
.page_mkwrite would prepare the write as if inline data was not existing
(i.e., reserve delalloc blocks as normal). Then in writeback code once we
have folios locked and are mapping underlying blocks, if the data (based on
i_size) fits into the inode, we'd writeback it as inline_data xattr. If it
doesn't fit into the inode (writing xattr fails), we'd just delete the
existing inline_data xattr and continue with normal writeback. Again this
will require very little additional code.
Finally, truncate, in addition to operating as without inline data has to
also appropriately shorten inline_data xattr if it exists, but again this
should be very little code.
Thoughts?
Honza
--
Jan Kara <jack@xxxxxxxx>
SUSE Labs, CR