All of lore.kernel.org
 help / color / mirror / Atom feed
From: Chao Yu <chao@kernel.org>
To: jaegeuk@kernel.org
Cc: linux-f2fs-devel@lists.sourceforge.net,
	linux-kernel@vger.kernel.org, Chao Yu <chao@kernel.org>
Subject: [PATCH v1 00/12] f2fs: introduce metadata cache
Date: Thu, 20 Aug 2026 11:17:09 +0800	[thread overview]
Message-ID: <20260820031721.12218-1-chao@kernel.org> (raw)

This patchset introduces a self-managed metadata block cache in f2fs,
decoupling meta blocks, node blocks, and compressed data blocks from
the Linux VFS page cache and fake internal inodes.

=== 1. Background & Motivation ===

Currently, F2FS uses fake VFS inodes (meta_inode, node_inode, and
compress_inode) to manage internal block caching through the VFS page
cache. Because of this implementation, the f2fs block size was
historically coupled to the kernel page size.

We now want to unbind block size from page size to support configurations
where block size <= PAGE_SIZE (e.g., mounting a 4KB-block F2FS image on a
16KB or 64KB page system).

One possible approach is to continue using the VFS page cache to store
metadata blocks. However, doing so introduces three major architectural
issues (illustrated by a 4KB block on a 16KB page system):

1. Memory Overhead:
   Metadata access patterns are typically random and sparse. Caching a
   single 4KB metadata block inside a page cache folio forces the
   allocation of an entire 16KB folio, resulting in 4x memory waste.

2. Folio and Sub-block Conversion Complexity:
   Using larger folios requires tracking individual sub-block dirty/uptodate
   states within each folio and performing index-to-offset conversions across
   function boundaries. Because core metadata structures (e.g., f2fs_checkpoint,
   f2fs_sit_block, f2fs_nat_block, f2fs_summary_block, f2fs_node) are accessed
   extensively throughout the filesystem, this sub-block management and offset
   calculation complexity would spread across the entire F2FS codebase.

3. Lock Contention:
   Multiple independent node blocks (e.g., dnode blocks belonging to
   different files) can reside within the same folio. Concurrent fsync()
   calls on unrelated files would contend on the same folio_lock(),
   serializing metadata updates and degrading multi-threaded performance.

Decoupling metadata caching from PAGE_SIZE by allocating exact
block-sized cache entries is the critical first step toward supporting
4KB-block F2FS images on 16KB/64KB page systems.

=== 2. Metadata Cache Architecture & Design ===

This patchset introduces a dedicated, block-size-aligned caching

3. Lock Contention:
   Multiple independent node blocks (e.g., dnode blocks belonging to
   different files) can reside within the same folio. Concurrent fsync()
   calls on unrelated files would contend on the same folio_lock(),
   serializing metadata updates and degrading multi-threaded performance.

3. Lock Contention:
   Multiple independent node blocks (e.g., dnode blocks belonging to
   different files) can reside within the same folio. Concurrent fsync()
   calls on unrelated files would contend on the same folio_lock(),
   serializing metadata updates and degrading multi-threaded performance.

Decoupling metadata caching from PAGE_SIZE by allocating exact
block-sized cache entries is the critical first step toward supporting
4KB-block F2FS images on 16KB/64KB page systems.

=== 2. Metadata Cache Architecture & Design ===

This patchset introduces a dedicated, block-size-aligned caching
infrastructure with the following key components:

- Block-Size Aligned Allocation:
  Allocates memory buffers matching exactly the filesystem block size
  (4KB or 16KB) via kzalloc(), fully independent of the host
  architecture's PAGE_SIZE.

- Radix Tree Indexing with Fast Tag Scanning:
  Each cache instance (META_CACHE, NODE_CACHE, COMPRESS_CACHE) indexes
  cached blocks via a radix tree (keyed by Physical Block Address for meta/
  compress cache, and Node ID for node cache). Radix tree tags
  (F2FS_CACHE_TAG_DIRTY, F2FS_CACHE_TAG_WRITEBACK) provide O(1) batch gang
  lookups for flushing and writeback without dual-list shuffling.

- Lightweight Bit-Locking:
  Individual entries use atomic bit locks (F2FS_BLOCK_LOCKED via
  wait_on_bit_lock() / clear_and_wake_up_bit()) rather than heavyweight
  embedded mutexes/semaphores, minimizing memory footprint per entry.

- Direct BIO Read/Write & BIO Merging:
  Decouples metadata/node I/O from VFS address spaces by submitting direct
  BIOs (f2fs_submit_cache_read / f2fs_submit_cache_write) with chained
  adjacent vector merging (entry->next_entry) and dedicated completion
  handlers.

- Memory Reclamation Shrinker:
  Integrates with the kernel shrinker subsystem via a 3-phase isolation
  algorithm (isolate unreferenced clean entries -> truncate from radix tree
  under lock -> splice un-reclaimed entries back to LRU) to safely reclaim
  clean cached blocks under system memory pressure.

- Background Writeback Kthread & Checkpoint Integration:
  Provides a dedicated background kthread (f2fs_writeback-X:Y) for periodic
  dirty cache flushing, combined with synchronous flushing during checkpoint
  commit.

- Fault Injection, Tracepoints & Debugfs Observability:
  Integrates FAULT_KALLOC fault injection, tracepoints for cache state
  transitions and batch writeback, and per-cache memory breakdowns in debugfs.

=== 3. Patchset Organization ===

- Patch 01: Implement the core metadata cache infrastructure & direct BIO I/O.
- Patch 02: Initialize and teardown META_CACHE in sb_info.
- Patch 03: Integrate metadata cache into the memory shrinker subsystem.
- Patch 04: Introduce the background writeback kernel thread.
- Patch 05: Migrate metadata block caching (SIT, NAT, SSA, CP, recovery, GC)
            from meta_inode to META_CACHE.
- Patch 06: Initialize and teardown NODE_CACHE in sb_info.
- Patch 07: Migrate node and inode block caching from node_inode to NODE_CACHE.
- Patch 08: Initialize and teardown COMPRESS_CACHE in sb_info.
- Patch 09: Migrate compressed cluster caching from compress_inode to COMPRESS_CACHE.
- Patch 10: Add fault injection support for cache allocation paths.
- Patch 11: Introduce ftrace tracepoints for cache dirty and writeback events.
- Patch 12: Expose per-cache memory usage in debugfs.

Chao Yu (12):
  f2fs: cache: implement metadata cache
  f2fs: cache: initialize meta cache
  f2fs: cache: introduce shrinker
  f2fs: cache: introduce writeback thread
  f2fs: cache: use meta cache
  f2fs: cache: initialize node cache
  f2fs: cache: use node cache
  f2fs: cache: initialize compress cache
  f2fs: cache: use compress cache
  f2fs: cache: support fault injection
  f2fs: cache: introduce tracepoints
  f2fs: cache: show per-cache usage in debugfs

 fs/f2fs/Makefile            |   2 +-
 fs/f2fs/acl.c               |  26 +-
 fs/f2fs/acl.h               |   8 +-
 fs/f2fs/cache.c             | 690 +++++++++++++++++++++++++
 fs/f2fs/cache.h             | 224 ++++++++
 fs/f2fs/checkpoint.c        | 404 +++++++--------
 fs/f2fs/compress.c          | 171 +++----
 fs/f2fs/data.c              | 527 +++++++++++++------
 fs/f2fs/debug.c             |  70 ++-
 fs/f2fs/dir.c               | 168 +++---
 fs/f2fs/extent_cache.c      |  14 +-
 fs/f2fs/f2fs.h              | 333 ++++++------
 fs/f2fs/file.c              |  78 ++-
 fs/f2fs/gc.c                | 178 ++++---
 fs/f2fs/inline.c            | 284 ++++++-----
 fs/f2fs/inode.c             | 205 +++-----
 fs/f2fs/iostat.h            |  11 +
 fs/f2fs/namei.c             | 118 ++---
 fs/f2fs/node.c              | 994 +++++++++++++++++-------------------
 fs/f2fs/node.h              | 109 ++--
 fs/f2fs/recovery.c          | 253 ++++-----
 fs/f2fs/segment.c           | 263 +++++-----
 fs/f2fs/segment.h           |  39 +-
 fs/f2fs/shrinker.c          |  13 +
 fs/f2fs/super.c             | 143 +++---
 fs/f2fs/xattr.c             | 123 +++--
 fs/f2fs/xattr.h             |  12 +-
 include/linux/f2fs_fs.h     |   3 -
 include/trace/events/f2fs.h |  71 +++
 29 files changed, 3331 insertions(+), 2203 deletions(-)
 create mode 100644 fs/f2fs/cache.c
 create mode 100644 fs/f2fs/cache.h

-- 
2.49.0


WARNING: multiple messages have this Message-ID (diff)
From: Chao Yu via Linux-f2fs-devel <linux-f2fs-devel@lists.sourceforge.net>
To: jaegeuk@kernel.org
Cc: linux-kernel@vger.kernel.org, linux-f2fs-devel@lists.sourceforge.net
Subject: [f2fs-dev] [PATCH v1 00/12] f2fs: introduce metadata cache
Date: Thu, 20 Aug 2026 11:17:09 +0800	[thread overview]
Message-ID: <20260820031721.12218-1-chao@kernel.org> (raw)

This patchset introduces a self-managed metadata block cache in f2fs,
decoupling meta blocks, node blocks, and compressed data blocks from
the Linux VFS page cache and fake internal inodes.

=== 1. Background & Motivation ===

Currently, F2FS uses fake VFS inodes (meta_inode, node_inode, and
compress_inode) to manage internal block caching through the VFS page
cache. Because of this implementation, the f2fs block size was
historically coupled to the kernel page size.

We now want to unbind block size from page size to support configurations
where block size <= PAGE_SIZE (e.g., mounting a 4KB-block F2FS image on a
16KB or 64KB page system).

One possible approach is to continue using the VFS page cache to store
metadata blocks. However, doing so introduces three major architectural
issues (illustrated by a 4KB block on a 16KB page system):

1. Memory Overhead:
   Metadata access patterns are typically random and sparse. Caching a
   single 4KB metadata block inside a page cache folio forces the
   allocation of an entire 16KB folio, resulting in 4x memory waste.

2. Folio and Sub-block Conversion Complexity:
   Using larger folios requires tracking individual sub-block dirty/uptodate
   states within each folio and performing index-to-offset conversions across
   function boundaries. Because core metadata structures (e.g., f2fs_checkpoint,
   f2fs_sit_block, f2fs_nat_block, f2fs_summary_block, f2fs_node) are accessed
   extensively throughout the filesystem, this sub-block management and offset
   calculation complexity would spread across the entire F2FS codebase.

3. Lock Contention:
   Multiple independent node blocks (e.g., dnode blocks belonging to
   different files) can reside within the same folio. Concurrent fsync()
   calls on unrelated files would contend on the same folio_lock(),
   serializing metadata updates and degrading multi-threaded performance.

Decoupling metadata caching from PAGE_SIZE by allocating exact
block-sized cache entries is the critical first step toward supporting
4KB-block F2FS images on 16KB/64KB page systems.

=== 2. Metadata Cache Architecture & Design ===

This patchset introduces a dedicated, block-size-aligned caching

3. Lock Contention:
   Multiple independent node blocks (e.g., dnode blocks belonging to
   different files) can reside within the same folio. Concurrent fsync()
   calls on unrelated files would contend on the same folio_lock(),
   serializing metadata updates and degrading multi-threaded performance.

3. Lock Contention:
   Multiple independent node blocks (e.g., dnode blocks belonging to
   different files) can reside within the same folio. Concurrent fsync()
   calls on unrelated files would contend on the same folio_lock(),
   serializing metadata updates and degrading multi-threaded performance.

Decoupling metadata caching from PAGE_SIZE by allocating exact
block-sized cache entries is the critical first step toward supporting
4KB-block F2FS images on 16KB/64KB page systems.

=== 2. Metadata Cache Architecture & Design ===

This patchset introduces a dedicated, block-size-aligned caching
infrastructure with the following key components:

- Block-Size Aligned Allocation:
  Allocates memory buffers matching exactly the filesystem block size
  (4KB or 16KB) via kzalloc(), fully independent of the host
  architecture's PAGE_SIZE.

- Radix Tree Indexing with Fast Tag Scanning:
  Each cache instance (META_CACHE, NODE_CACHE, COMPRESS_CACHE) indexes
  cached blocks via a radix tree (keyed by Physical Block Address for meta/
  compress cache, and Node ID for node cache). Radix tree tags
  (F2FS_CACHE_TAG_DIRTY, F2FS_CACHE_TAG_WRITEBACK) provide O(1) batch gang
  lookups for flushing and writeback without dual-list shuffling.

- Lightweight Bit-Locking:
  Individual entries use atomic bit locks (F2FS_BLOCK_LOCKED via
  wait_on_bit_lock() / clear_and_wake_up_bit()) rather than heavyweight
  embedded mutexes/semaphores, minimizing memory footprint per entry.

- Direct BIO Read/Write & BIO Merging:
  Decouples metadata/node I/O from VFS address spaces by submitting direct
  BIOs (f2fs_submit_cache_read / f2fs_submit_cache_write) with chained
  adjacent vector merging (entry->next_entry) and dedicated completion
  handlers.

- Memory Reclamation Shrinker:
  Integrates with the kernel shrinker subsystem via a 3-phase isolation
  algorithm (isolate unreferenced clean entries -> truncate from radix tree
  under lock -> splice un-reclaimed entries back to LRU) to safely reclaim
  clean cached blocks under system memory pressure.

- Background Writeback Kthread & Checkpoint Integration:
  Provides a dedicated background kthread (f2fs_writeback-X:Y) for periodic
  dirty cache flushing, combined with synchronous flushing during checkpoint
  commit.

- Fault Injection, Tracepoints & Debugfs Observability:
  Integrates FAULT_KALLOC fault injection, tracepoints for cache state
  transitions and batch writeback, and per-cache memory breakdowns in debugfs.

=== 3. Patchset Organization ===

- Patch 01: Implement the core metadata cache infrastructure & direct BIO I/O.
- Patch 02: Initialize and teardown META_CACHE in sb_info.
- Patch 03: Integrate metadata cache into the memory shrinker subsystem.
- Patch 04: Introduce the background writeback kernel thread.
- Patch 05: Migrate metadata block caching (SIT, NAT, SSA, CP, recovery, GC)
            from meta_inode to META_CACHE.
- Patch 06: Initialize and teardown NODE_CACHE in sb_info.
- Patch 07: Migrate node and inode block caching from node_inode to NODE_CACHE.
- Patch 08: Initialize and teardown COMPRESS_CACHE in sb_info.
- Patch 09: Migrate compressed cluster caching from compress_inode to COMPRESS_CACHE.
- Patch 10: Add fault injection support for cache allocation paths.
- Patch 11: Introduce ftrace tracepoints for cache dirty and writeback events.
- Patch 12: Expose per-cache memory usage in debugfs.

Chao Yu (12):
  f2fs: cache: implement metadata cache
  f2fs: cache: initialize meta cache
  f2fs: cache: introduce shrinker
  f2fs: cache: introduce writeback thread
  f2fs: cache: use meta cache
  f2fs: cache: initialize node cache
  f2fs: cache: use node cache
  f2fs: cache: initialize compress cache
  f2fs: cache: use compress cache
  f2fs: cache: support fault injection
  f2fs: cache: introduce tracepoints
  f2fs: cache: show per-cache usage in debugfs

 fs/f2fs/Makefile            |   2 +-
 fs/f2fs/acl.c               |  26 +-
 fs/f2fs/acl.h               |   8 +-
 fs/f2fs/cache.c             | 690 +++++++++++++++++++++++++
 fs/f2fs/cache.h             | 224 ++++++++
 fs/f2fs/checkpoint.c        | 404 +++++++--------
 fs/f2fs/compress.c          | 171 +++----
 fs/f2fs/data.c              | 527 +++++++++++++------
 fs/f2fs/debug.c             |  70 ++-
 fs/f2fs/dir.c               | 168 +++---
 fs/f2fs/extent_cache.c      |  14 +-
 fs/f2fs/f2fs.h              | 333 ++++++------
 fs/f2fs/file.c              |  78 ++-
 fs/f2fs/gc.c                | 178 ++++---
 fs/f2fs/inline.c            | 284 ++++++-----
 fs/f2fs/inode.c             | 205 +++-----
 fs/f2fs/iostat.h            |  11 +
 fs/f2fs/namei.c             | 118 ++---
 fs/f2fs/node.c              | 994 +++++++++++++++++-------------------
 fs/f2fs/node.h              | 109 ++--
 fs/f2fs/recovery.c          | 253 ++++-----
 fs/f2fs/segment.c           | 263 +++++-----
 fs/f2fs/segment.h           |  39 +-
 fs/f2fs/shrinker.c          |  13 +
 fs/f2fs/super.c             | 143 +++---
 fs/f2fs/xattr.c             | 123 +++--
 fs/f2fs/xattr.h             |  12 +-
 include/linux/f2fs_fs.h     |   3 -
 include/trace/events/f2fs.h |  71 +++
 29 files changed, 3331 insertions(+), 2203 deletions(-)
 create mode 100644 fs/f2fs/cache.c
 create mode 100644 fs/f2fs/cache.h

-- 
2.49.0



_______________________________________________
Linux-f2fs-devel mailing list
Linux-f2fs-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel

             reply	other threads:[~2026-08-20  3:17 UTC|newest]

Thread overview: 34+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-08-20  3:17 Chao Yu [this message]
2026-08-20  3:17 ` [f2fs-dev] [PATCH v1 00/12] f2fs: introduce metadata cache Chao Yu via Linux-f2fs-devel
2026-08-20  3:17 ` [PATCH v1 01/12] f2fs: cache: implement " Chao Yu
2026-08-20  3:17   ` [f2fs-dev] " Chao Yu via Linux-f2fs-devel
2026-08-20  5:08   ` Jaegeuk Kim via Linux-f2fs-devel
2026-08-20  5:08     ` Jaegeuk Kim
2026-08-20  5:13     ` Chao Yu via Linux-f2fs-devel
2026-08-20  5:13       ` Chao Yu
2026-08-20  3:17 ` [PATCH v1 02/12] f2fs: cache: initialize meta cache Chao Yu
2026-08-20  3:17   ` [f2fs-dev] " Chao Yu via Linux-f2fs-devel
2026-08-20  3:17 ` [PATCH v1 03/12] f2fs: cache: introduce shrinker Chao Yu
2026-08-20  3:17   ` [f2fs-dev] " Chao Yu via Linux-f2fs-devel
2026-08-20  3:17 ` [PATCH v1 04/12] f2fs: cache: introduce writeback thread Chao Yu
2026-08-20  3:17   ` [f2fs-dev] " Chao Yu via Linux-f2fs-devel
2026-08-20  5:09   ` Jaegeuk Kim via Linux-f2fs-devel
2026-08-20  5:09     ` Jaegeuk Kim
2026-08-20  3:17 ` [f2fs-dev] [PATCH v1 05/12] f2fs: cache: use meta cache Chao Yu via Linux-f2fs-devel
2026-08-20  3:17   ` Chao Yu
2026-08-20  5:11   ` [f2fs-dev] " Jaegeuk Kim via Linux-f2fs-devel
2026-08-20  5:11     ` Jaegeuk Kim
2026-08-20  3:17 ` [PATCH v1 06/12] f2fs: cache: initialize node cache Chao Yu
2026-08-20  3:17   ` [f2fs-dev] " Chao Yu via Linux-f2fs-devel
2026-08-20  3:17 ` [f2fs-dev] [PATCH v1 07/12] f2fs: cache: use " Chao Yu via Linux-f2fs-devel
2026-08-20  3:17   ` Chao Yu
2026-08-20  3:17 ` [PATCH v1 08/12] f2fs: cache: initialize compress cache Chao Yu
2026-08-20  3:17   ` [f2fs-dev] " Chao Yu via Linux-f2fs-devel
2026-08-20  3:17 ` [PATCH v1 09/12] f2fs: cache: use " Chao Yu
2026-08-20  3:17   ` [f2fs-dev] " Chao Yu via Linux-f2fs-devel
2026-08-20  3:17 ` [PATCH v1 10/12] f2fs: cache: support fault injection Chao Yu
2026-08-20  3:17   ` [f2fs-dev] " Chao Yu via Linux-f2fs-devel
2026-08-20  3:17 ` [PATCH v1 11/12] f2fs: cache: introduce tracepoints Chao Yu
2026-08-20  3:17   ` [f2fs-dev] " Chao Yu via Linux-f2fs-devel
2026-08-20  3:17 ` [PATCH v1 12/12] f2fs: cache: show per-cache usage in debugfs Chao Yu
2026-08-20  3:17   ` [f2fs-dev] " Chao Yu via Linux-f2fs-devel

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20260820031721.12218-1-chao@kernel.org \
    --to=chao@kernel.org \
    --cc=jaegeuk@kernel.org \
    --cc=linux-f2fs-devel@lists.sourceforge.net \
    --cc=linux-kernel@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.