RE:(2) [RFC PATCH v3 0/2] ext4: speed up fast commit on random writes

Daejun Park <[email protected]>
Newsgroups org.kernel.vger.linux-ext4,org.kernel.vger.linux-kernel
Message-ID <20260723082515epcms2p18b33139192f8ddf493573817c2d21cc3@epcms2p1>
On Jul 22, 2026, at 01:27, Andreas Dilger <[email protected]> wrote:
> Have you looked at implementing a more dynamic structure like another
> extent status tree, rbtree, xarray or or similar instead of having a
> fixed-size array? [...] It would be useful to do some testing of how
> many separate ranges gets worse than the fallback.

Thanks -- I implemented the dynamic structure; it replaces the array and the
tunable entirely.  v4 tracks the modified ranges in a per-inode rbtree, which
answered both of your questions.

It can't be the shared extent status tree: I probed whether the shrinker
reclaims a mapped es entry for a modified-but-not-yet-committed range, and it
does (448 in one short run under mild pressure).  That "modified" mark is not
re-derivable, so marking the shared tree would silently lose modifications -- the
tracker has to own its structure.

So it is a private rbtree, reusing ext4's own machinery (generic rb_*, as the
extent status tree already does for per-inode ranges) -- idiomatic, no new
dependency.  The node is a dedicated 32-byte struct with its own slab cache, not
extent_status: extent_status carries an 8-byte es_pblk that fast commit never
uses, and its cache is SLAB_RECLAIM_ACCOUNT, which would misaccount these
non-reclaimable nodes.  The rb_root is inline in the inode, so only per-range
nodes are allocated.  (I also built and compared a maple-tree version:
behaviour-identical, within ~15% on memory, denser only at the range counts this
series already caps -- so the rbtree, with no dependency, is the choice.)

On "how many is too many": the cap is EXT4_FC_SNAPSHOT_MAX_RANGES (2048), the
limit the snapshot already enforces on emitted ranges -- reused directly, not a
new constant.  Each disjoint tracked range snapshots to at least one ADD_RANGE,
so a tracked set larger than that can never fit under the snapshot cap: the fast
commit would overrun it and fall back regardless.  That count is exactly where
tracking stops paying off, so at the cap the transaction falls back to a full
commit.  (Verified: R=4096 disjoint writes/fsync falls back there; R=1024 tracks
precisely.)

Thanks,
Daejun
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.