Re: [PATCH v2] ext4: use fsdata to track inline data write state and fix race

From: Aditya Prakash Srivastava

Date: Thu Jul 02 2026 - 08:47:48 EST


Hi Jan,

Thought a bit more about it. Treating fsdata as
bitwise flags rather than mutually exclusive enums is a much
cleaner and more robust design. It completely decouples the
different write path states.

To implement this, I will define:

#define FALL_BACK_TO_NONDELALLOC 1
#define CONVERT_INLINE_DATA 2
#define EXT4_WRITE_DATA_INLINE 4

This ensures that the flags are fully independent and do not
overlap.

Regarding unrolling the state on exit, there is a slight
asymmetry in the VFS interface. ext4_write_begin() receives
fsdata as a pointer-to-pointer (void **fsdata), while
ext4_write_end() receives it by value (void *fsdata).

Because write_end() receives fsdata by value, modifying it in
the write_end handlers has no effect on the caller's
(generic_perform_write()) local stack variable. As a result, a
stale EXT4_WRITE_DATA_INLINE bit would remain in the VFS across
a retry.

To handle this cleanly within the constraints of the VFS
interface, I propose clearing the stale bit on entry to
ext4_write_begin():

static int ext4_write_begin(..., void **fsdata)
{
...

/* Clear any stale inline flag from a previous retry. */
*fsdata = (void *)((unsigned long)*fsdata &
~EXT4_WRITE_DATA_INLINE);

...
}

This ensures that:

any stale inline flag from a previous retry is cleared from
the VFS stack variable before the next attempt;

the FALL_BACK_TO_NONDELALLOC bit remains preserved; and

if the retry prepares an inline write, ext4_write_begin()
simply sets the bit again.

Please let me know whether this write_begin unrolling approach
looks good to you, and I'll submit the v3 series shortly.

Thanks,
Aditya