* [f2fs-dev] [PATCH v3 00/14] Remove PG_private by using page/folio->private checks instead
@ 2026-09-08 2:56 ` Zi Yan via Linux-f2fs-devel
0 siblings, 0 replies; 37+ messages in thread
From: Zi Yan via Linux-f2fs-devel @ 2026-09-08 2:56 UTC (permalink / raw)
To: David Hildenbrand, Matthew Wilcox (Oracle), Andrew Morton,
Muchun Song, Lorenzo Stoakes, Liam R. Howlett, Vlastimil Babka,
Mike Rapoport, Suren Baghdasaryan, Michal Hocko, Baolin Wang,
Nico Pache, Ryan Roberts, Dev Jain, Barry Song, Lance Yang,
Usama Arif, Gregory Price, Ying Huang, Alistair Popple,
Johannes Weiner, Qi Zheng, Shakeel Butt, Kairui Song
Cc: Mark Rutland, Ian Rogers, Jan Kara, linux-doc, Alex Markuze,
Peter Zijlstra, kexec, Dave Hansen, Dave Young, Adrian Hunter,
linux-mm, Hongbo Li, H. Peter Anvin, Chunhai Guo, Shuah Khan,
ceph-devel, Baoquan He, Matthew Brost, Anna Schumaker,
Stefano Stabellini, Yue Hu, Rakie Kim, Minchan Kim,
Richard Weinberger, x86, Eric Biggers, Alexander Shishkin,
Ingo Molnar, Viacheslav Dubeyko, Wei Xu, Zi Yan, Yu Kuai,
xen-devel, Gao Xiang, Li Nan, Masami Hiramatsu, Joshua Hahn,
Xiao Ni, Byungchul Park, James Clark, Arnaldo Carvalho de Melo,
linux-raid, linux-fscrypt, Borislav Petkov, Steven Rostedt,
linux-mtd, Axel Rasmussen, Jeffle Xu, Namhyung Kim, Jaegeuk Kim,
Yuanchu Xie, Ilya Dryomov, Oscar Salvador, Juergen Gross,
Pratyush Yadav, linux-nfs, Theodore Y. Ts'o,
Oleksandr Tyshchenko, Song Liu, Jonathan Corbet, Pasha Tatashin,
linux-kernel, linux-f2fs-devel, linux-perf-users,
Sergey Senozhatsky, Thomas Gleixner, Jiri Olsa, linux-fsdevel,
Mathieu Desnoyers, linux-trace-kernel, linux-erofs,
Trond Myklebust
Hi all,
This patchset removes PG_private to make space for upcoming PG_folio
(reserved as __PG_folio) for identifying pages from a folio (more details
in Note below). Instead of checking PG_private, all code is changed to
check page/folio->private != NULL instead.
MM people are cc'd on all patches and subsystem people are cc'd on the
cover letter and corresponding patches.
Patch 6 is picked up separately in f2fs tree, but since mm-new does not
have it yet, it is sent for MM testing.
Overview
===
Most code uses folio_attach/detach/change_private() functions, so folio
refcount is increased and decreased when folio->private is set and reset,
respectively. There is no need to change them.
Changes are needed for exceptional users:
1. zsmalloc uses PG_private to indicate first component zpdesc page and
page->private is used to store zspage in zpdesc. To remove PG_private,
is_first_zpdesc() is replaced by pointer comparison.
2. kernel/events/ring_buffer.c stores page order in page->private.
Replacing PG_private with page->private != NULL works.
3. drivers/xen/grant-table.c stores xen_page_foreign in page->private,
where on 32-bit, a pointer to xen_page_foreign is stored; on 64-bit,
page->private is used as xen_page_foreign. PG_private check is replaced
by page->private != NULL on 32-bit for xen_page_foreign deallocation.
On 64-bit, page->private is cleared unconditionally since {domid=0,
gref=0} (xen_page_foreign can be 0) is valid.
4. fs/crypto/crypto.c stores a folio pointer in page->private, PG_private
checks are replaced by page->private != NULL.
5. fs/erofs has two different uses:
5a. folio->private is used to form a reversed list of
the outputs of readahead_folio(). readahead_folio_last() is added to
output folios in reversed order, so that ->private is no longer needed.
5b. folio->private is used as an in-flight I/O counter. Convert the
code to use folio_attach/detach/get_private() and add bias==1 to the
counter to avoid folio->private being zero.
6. fs/nfs/write.c: folio refcount maintenance is in a bigger scope than
folio->private. So folio_attach/detach/get_private() is not used.
Nothing to change.
7. fs/f2fs uses attach_page_private() to first reset folio->private then
immediately sets PAGE_PRIVATE_NOT_POINTER bit on it. Change it to use
attach_page_private() to set PAGE_PRIVATE_NOT_POINTER bit directly to
avoid folio->private == NULL gap inside set_page_private_##name().
8. hugetlb uses folio_change_private(folio, NULL) without folio refcount
maintenance. Change it to folio->private = NULL.
After the above changes, PG_private ops are converted to
page/folio->private ops.
folio_test_fs_private() is added to check filesystem-only private data by
excluding swapcache and hugetlb folios, because swapcache folios overlap
swp_entry_t swap with ->private and hugetlb sets its own flags in
->private.
Note
===
1. KPF_PRIVATE is removed after PG_private is removed.
2. Documentation/mm/hugetlbfs_reserv.rst is outdated, so I did not remove
PG_private related text. It should be rewritten.
3. PG_folio is planned to be set on every page from a folio in
page_rmappable_folio(), so folios with any order (currently
PG_large_rmappable is used to identify >0 order folios, but not order-0
folios) can be identified. Then vm_insert_*() can correctly reject all
folios and rmap code will only see folios. Eventually, page_folio()
will return NULL for non-folio pages by checking PG_folio, but before
that all existing users that treat compound pages as folios will need
to be converted.
Tests
===
1. allmodconfig build passed.
2. zsmalloc is tested using ext4 on a 1GB lz4 zram:
2a. zram load + zsmalloc compaction;
2b. concurrent zspage migration via memory compaction;
2c. confirmed that multi-page zspages actually formed.
Details: https://github.com/x-y-z/linux-dev/blob/b4/remove-pg_private/test_zsmalloc.md
3. erofs is tested on images created with -C4096 and lz4hc, lzma,
deflate, and zstd algorithms:
3a. cold read of all files, verify checksums match source;
3b. readahead + reclaim/migration race.
Details: https://github.com/x-y-z/linux-dev/blob/b4/remove-pg_private/test_erofs.md
4. fscrypt is tested on software-encrypted ext4 with writes to exercise
bounce pages.
Details: https://github.com/x-y-z/linux-dev/blob/b4/remove-pg_private/test_fscrypt.md
5. f2fs is tested on an image with inline_data,compress_algorithm=lz4:
5a. INLINE_INODE — lots of tiny files;
5b. REF_RESOURCE + general writeback — buffered write churn with fsync;
5c. ONGOING_MIGRATION — force GC / page migration;
5d. ATOMIC_WRITE — atomic-write ioctl path.
Details: https://github.com/x-y-z/linux-dev/blob/b4/remove-pg_private/test_f2fs.md
(I did not run xfstests)
6. MM selftests passed.
LLM use
===
Claude was used to form a concrete plan on what code needs to be changed
and how to change them. The plan was reviewed by Codex until no issue was
spotted.
Plan is at: https://github.com/x-y-z/linux-dev/blob/b4/remove-pg_private/plan.md
I then followed the plan to make code changes. I did bounce ideas with
Claude how to change fs/erofs, since I did not like the original idea.
After each change, I asked Claude to review my code and git commit message.
I also asked Claude to give me test plans (see above).
At last, Codex was used to review all patches.
Comments and suggestions are welcome. Thanks.
Assisted-by: Claude:claude-opus-4-8
Assisted-by: Codex:gpt-5
Signed-off-by: Zi Yan <ziy@nvidia.com>
---
Changes in v3:
1. changed folio_test_fs_private() to check PG_swapbacked instead of
PG_swapcache for excluding swapcache folios. Because folio->private and
PG_swapcache are not set as a whole, making folio_test_fs_private() give
false positive, whereas PG_swapbacked is always set for swapcache
folios.
2. added __DEF_PAGEFLAG_NAME() to show __PG_folio instead of open code.
3. f2fs change is picked up at
https://git.kernel.org/jaegeuk/f2fs/c/5ad9409a9533, mm-new currently
does not have it, so the patch is sent for MM testing purpose.
- Link to v2: https://patch.msgid.link/20260831-remove-pg_private-v2-0-3668159cd9e8@nvidia.com
Changes in v2:
1. removed is_first_zpdesc() in patch 1 and open coded the checks.
2. fixed wording in patch 2's commit message and clarified page_private()
also works when ring buffer's AUX page order is 0.
3. removed the empty loop in 64-bit gnttab_pages_set_private().
4. clarified folio->private will be reset to NULL by
fscrypt_free_bounce_page() in the commit message.
5. clarified why hugetlb needs to restore hugetlb_vmemmap_optimized.
6. renamed readahead_folio_reverse() readahead_folio_last() and
reimplemented readahead_folio_last() by adding a new readahead_control
private member, _forward, and a new helper __readahead_advance().
7. added a bias, 1, to erofs I/O counter, so that folio->private stays non
NULL between folio_attach_private() and folio_detach_private().
8. converted more call sites to use folio_test_fs_private().
- Link to v1: https://lore.kernel.org/r/20260731-remove-pg_private-v1-0-142c97ba3562@nvidia.com
---
Zi Yan (14):
mm/zsmalloc: replace PG_private with pointer comparison
perf/ring_buffer: stop using PG_private as AUX page high-order marker
xen/grant-table: stop setting PG_private on pages for grant mapping
fscrypt: stop setting PG_private on bounce page
mm/hugetlb: use direct assignment instead of folio_change_private()
f2fs: stop using PG_private
erofs: mm/pagemap: add readahead_folio_last() to avoid folio->private
erofs: use folio_attach/detach_private() instead of direct assignment
mm/page-flags: check page/folio->private instead of PG_private
mm/page-flags: introduce folio_test_fs_private()
treewide: remove folio_set/clear_private()
treewide: replace PagePrivate() with page_private()
treewide: adjust comments on PagePrivate and PG_private
mm/page-flags: remove PG_private
Documentation/admin-guide/kdump/vmcoreinfo.rst | 2 +-
Documentation/filesystems/vfs.rst | 6 +--
arch/x86/events/intel/bts.c | 3 --
arch/x86/events/intel/pt.c | 6 +--
drivers/md/md-bitmap.c | 6 +--
drivers/xen/balloon.c | 5 +++
drivers/xen/grant-table.c | 11 +++--
fs/ceph/addr.c | 8 ++--
fs/crypto/crypto.c | 2 -
fs/erofs/data.c | 16 ++++---
fs/erofs/zdata.c | 13 ++----
fs/f2fs/f2fs.h | 8 ++--
fs/nfs/file.c | 4 +-
fs/nfs/write.c | 2 -
fs/proc/page.c | 1 -
fs/ubifs/file.c | 8 ++--
include/linux/buffer_head.h | 6 ---
include/linux/kernel-page-flags.h | 1 -
include/linux/mm.h | 35 +++++++++------
include/linux/mm_types.h | 4 +-
include/linux/page-flags.h | 43 +++++++++++++-----
include/linux/pagemap.h | 60 +++++++++++++++++++++-----
include/trace/events/mmflags.h | 3 +-
include/trace/events/pagemap.h | 3 +-
kernel/events/ring_buffer.c | 7 ++-
kernel/vmcore_info.c | 1 -
mm/huge_memory.c | 3 +-
mm/hugetlb.c | 6 +--
mm/migrate.c | 3 +-
mm/page-writeback.c | 3 +-
mm/vmscan.c | 2 +-
mm/zpdesc.h | 2 +-
mm/zsmalloc.c | 24 +++--------
tools/mm/page-types.c | 2 -
34 files changed, 172 insertions(+), 137 deletions(-)
---
base-commit: 5f4c0999b2bde1fbbba3c499208b415447ca4c7a
change-id: 20260728-remove-pg_private-cfe926c7f83c
Best regards,
--
Yan, Zi
_______________________________________________
Linux-f2fs-devel mailing list
Linux-f2fs-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel
^ permalink raw reply [flat|nested] 37+ messages in thread* [PATCH v3 04/14] fscrypt: stop setting PG_private on bounce page
2026-09-08 2:56 ` [f2fs-dev] " Zi Yan via Linux-f2fs-devel
(?)
@ 2026-09-08 2:56 ` Zi Yan
2026-09-08 15:16 ` David Hildenbrand (Arm)
-1 siblings, 1 reply; 37+ messages in thread
From: Zi Yan @ 2026-09-08 2:56 UTC (permalink / raw)
To: David Hildenbrand, Matthew Wilcox (Oracle), Andrew Morton,
Muchun Song, Lorenzo Stoakes, Liam R. Howlett, Vlastimil Babka,
Mike Rapoport, Suren Baghdasaryan, Michal Hocko, Baolin Wang,
Nico Pache, Ryan Roberts, Dev Jain, Barry Song, Lance Yang,
Usama Arif, Gregory Price, Ying Huang, Alistair Popple,
Johannes Weiner, Qi Zheng, Shakeel Butt, Kairui Song
Cc: linux-mm, linux-kernel, Zi Yan, Eric Biggers,
Theodore Y. Ts'o, Jaegeuk Kim, linux-fscrypt
The pointer to a plain text folio is stored in bound_page->private and
cannot be NULL until the bounce_page is freed, making PG_private redundant.
It prepares for a future commit that remove PG_private.
No functional change intended.
Assisted-by: Claude:claude-opus-4-8
Assisted-by: Codex:gpt-5
To: Eric Biggers <ebiggers@kernel.org>
To: "Theodore Y. Ts'o" <tytso@mit.edu>
To: Jaegeuk Kim <jaegeuk@kernel.org>
Cc: linux-fscrypt@vger.kernel.org
Cc: linux-kernel@vger.kernel.org
Acked-by: Eric Biggers <ebiggers@kernel.org>
Acked-by: Usama Arif <usama.arif@linux.dev>
Signed-off-by: Zi Yan <ziy@nvidia.com>
---
fs/crypto/crypto.c | 2 --
1 file changed, 2 deletions(-)
diff --git a/fs/crypto/crypto.c b/fs/crypto/crypto.c
index 5286a124b0d98..aced5c50a4601 100644
--- a/fs/crypto/crypto.c
+++ b/fs/crypto/crypto.c
@@ -65,7 +65,6 @@ void fscrypt_free_bounce_page(struct page *bounce_page)
if (!bounce_page)
return;
set_page_private(bounce_page, (unsigned long)NULL);
- ClearPagePrivate(bounce_page);
mempool_free(bounce_page, fscrypt_bounce_page_pool);
}
EXPORT_SYMBOL(fscrypt_free_bounce_page);
@@ -210,7 +209,6 @@ struct page *fscrypt_encrypt_pagecache_blocks(struct folio *folio,
return ERR_PTR(err);
}
}
- SetPagePrivate(ciphertext_page);
set_page_private(ciphertext_page, (unsigned long)folio);
return ciphertext_page;
}
--
2.53.0
^ permalink raw reply related [flat|nested] 37+ messages in thread
* Re: [PATCH v3 04/14] fscrypt: stop setting PG_private on bounce page
2026-09-08 2:56 ` [PATCH v3 04/14] fscrypt: stop setting PG_private on bounce page Zi Yan
@ 2026-09-08 15:16 ` David Hildenbrand (Arm)
0 siblings, 0 replies; 37+ messages in thread
From: David Hildenbrand (Arm) @ 2026-09-08 15:16 UTC (permalink / raw)
To: Zi Yan, Matthew Wilcox (Oracle), Andrew Morton, Muchun Song,
Lorenzo Stoakes, Liam R. Howlett, Vlastimil Babka, Mike Rapoport,
Suren Baghdasaryan, Michal Hocko, Baolin Wang, Nico Pache,
Ryan Roberts, Dev Jain, Barry Song, Lance Yang, Usama Arif,
Gregory Price, Ying Huang, Alistair Popple, Johannes Weiner,
Qi Zheng, Shakeel Butt, Kairui Song
Cc: linux-mm, linux-kernel, Eric Biggers, Theodore Y. Ts'o,
Jaegeuk Kim, linux-fscrypt
On 9/8/26 04:56, Zi Yan wrote:
> The pointer to a plain text folio is stored in bound_page->private and
> cannot be NULL until the bounce_page is freed, making PG_private redundant.
>
> It prepares for a future commit that remove PG_private.
>
> No functional change intended.
>
> Assisted-by: Claude:claude-opus-4-8
> Assisted-by: Codex:gpt-5
> To: Eric Biggers <ebiggers@kernel.org>
> To: "Theodore Y. Ts'o" <tytso@mit.edu>
> To: Jaegeuk Kim <jaegeuk@kernel.org>
> Cc: linux-fscrypt@vger.kernel.org
> Cc: linux-kernel@vger.kernel.org
> Acked-by: Eric Biggers <ebiggers@kernel.org>
> Acked-by: Usama Arif <usama.arif@linux.dev>
> Signed-off-by: Zi Yan <ziy@nvidia.com>
> ---
Acked-by: David Hildenbrand (Arm) <david@kernel.org>
--
Cheers,
David
^ permalink raw reply [flat|nested] 37+ messages in thread
* [f2fs-dev] [PATCH v3 06/14] f2fs: stop using PG_private
2026-09-08 2:56 ` [f2fs-dev] " Zi Yan via Linux-f2fs-devel
(?)
(?)
@ 2026-09-08 2:56 ` Zi Yan via Linux-f2fs-devel
2026-09-08 15:47 ` David Hildenbrand (Arm) via Linux-f2fs-devel
-1 siblings, 1 reply; 37+ messages in thread
From: Zi Yan via Linux-f2fs-devel @ 2026-09-08 2:56 UTC (permalink / raw)
To: David Hildenbrand, Matthew Wilcox (Oracle), Andrew Morton,
Muchun Song, Lorenzo Stoakes, Liam R. Howlett, Vlastimil Babka,
Mike Rapoport, Suren Baghdasaryan, Michal Hocko, Baolin Wang,
Nico Pache, Ryan Roberts, Dev Jain, Barry Song, Lance Yang,
Usama Arif, Gregory Price, Ying Huang, Alistair Popple,
Johannes Weiner, Qi Zheng, Shakeel Butt, Kairui Song
Cc: linux-kernel, linux-f2fs-devel, linux-mm, Zi Yan, Jaegeuk Kim
f2fs sets its PAGE_PRIVATE_* flags in page->private and checking
page->private != NULL is equivalent to checking PG_private. Change
PagePrivate() to page_private(). Meanwhile, in set_page_private_##name(),
page->private is first set to 0/NULL before an PAGE_PRIVATE_* flag is set,
but it can cause confusion when PG_private is removed and
page->private != NULL is used instead. Change it to initialize
page->private to PAGE_PRIVATE_NOT_POINTER instead and retain the original
semantics.
It prepares for a future commit that removes PG_private.
No functional change intended.
Assisted-by: Claude:claude-opus-4-8
Assisted-by: Codex:gpt-5
To: Jaegeuk Kim <jaegeuk@kernel.org>
To: Chao Yu <chao@kernel.org>
Cc: linux-f2fs-devel@lists.sourceforge.net
Cc: linux-kernel@vger.kernel.org
Acked-by: Usama Arif <usama.arif@linux.dev>
Acked-by: Chao Yu <chao@kernel.org>
Signed-off-by: Zi Yan <ziy@nvidia.com>
---
fs/f2fs/f2fs.h | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h
index 9940a6cecf1a2..2f7ab5888b078 100644
--- a/fs/f2fs/f2fs.h
+++ b/fs/f2fs/f2fs.h
@@ -2691,7 +2691,7 @@ static inline bool folio_test_f2fs_##name(const struct folio *folio) \
} \
static inline bool page_private_##name(struct page *page) \
{ \
- return PagePrivate(page) && \
+ return page_private(page) && \
test_bit(PAGE_PRIVATE_NOT_POINTER, &page_private(page)) && \
test_bit(PAGE_PRIVATE_##flagname, &page_private(page)); \
}
@@ -2710,9 +2710,9 @@ static inline void folio_set_f2fs_##name(struct folio *folio) \
} \
static inline void set_page_private_##name(struct page *page) \
{ \
- if (!PagePrivate(page)) \
- attach_page_private(page, (void *)0); \
- set_bit(PAGE_PRIVATE_NOT_POINTER, &page_private(page)); \
+ if (!page_private(page)) \
+ attach_page_private(page, \
+ (void *)BIT(PAGE_PRIVATE_NOT_POINTER)); \
set_bit(PAGE_PRIVATE_##flagname, &page_private(page)); \
}
--
2.53.0
_______________________________________________
Linux-f2fs-devel mailing list
Linux-f2fs-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel
^ permalink raw reply related [flat|nested] 37+ messages in thread* Re: [f2fs-dev] [PATCH v3 06/14] f2fs: stop using PG_private
2026-09-08 2:56 ` [f2fs-dev] [PATCH v3 06/14] f2fs: stop using PG_private Zi Yan via Linux-f2fs-devel
@ 2026-09-08 15:47 ` David Hildenbrand (Arm) via Linux-f2fs-devel
2026-09-08 18:20 ` Tal Zussman
2026-09-10 2:41 ` Chao Yu via Linux-f2fs-devel
0 siblings, 2 replies; 37+ messages in thread
From: David Hildenbrand (Arm) via Linux-f2fs-devel @ 2026-09-08 15:47 UTC (permalink / raw)
To: Zi Yan, Matthew Wilcox (Oracle), Andrew Morton, Muchun Song,
Lorenzo Stoakes, Liam R. Howlett, Vlastimil Babka, Mike Rapoport,
Suren Baghdasaryan, Michal Hocko, Baolin Wang, Nico Pache,
Ryan Roberts, Dev Jain, Barry Song, Lance Yang, Usama Arif,
Gregory Price, Ying Huang, Alistair Popple, Johannes Weiner,
Qi Zheng, Shakeel Butt, Kairui Song
Cc: linux-mm, linux-f2fs-devel, linux-kernel, Jaegeuk Kim
On 9/8/26 04:56, Zi Yan wrote:
> f2fs sets its PAGE_PRIVATE_* flags in page->private and checking
> page->private != NULL is equivalent to checking PG_private. Change
> PagePrivate() to page_private(). Meanwhile, in set_page_private_##name(),
> page->private is first set to 0/NULL before an PAGE_PRIVATE_* flag is set,
> but it can cause confusion when PG_private is removed and
> page->private != NULL is used instead. Change it to initialize
> page->private to PAGE_PRIVATE_NOT_POINTER instead and retain the original
> semantics.
>
> It prepares for a future commit that removes PG_private.
>
> No functional change intended.
>
> Assisted-by: Claude:claude-opus-4-8
> Assisted-by: Codex:gpt-5
> To: Jaegeuk Kim <jaegeuk@kernel.org>
> To: Chao Yu <chao@kernel.org>
> Cc: linux-f2fs-devel@lists.sourceforge.net
> Cc: linux-kernel@vger.kernel.org
> Acked-by: Usama Arif <usama.arif@linux.dev>
> Acked-by: Chao Yu <chao@kernel.org>
> Signed-off-by: Zi Yan <ziy@nvidia.com>
> ---
> fs/f2fs/f2fs.h | 8 ++++----
> 1 file changed, 4 insertions(+), 4 deletions(-)
>
> diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h
> index 9940a6cecf1a2..2f7ab5888b078 100644
> --- a/fs/f2fs/f2fs.h
> +++ b/fs/f2fs/f2fs.h
> @@ -2691,7 +2691,7 @@ static inline bool folio_test_f2fs_##name(const struct folio *folio) \
> } \
> static inline bool page_private_##name(struct page *page) \
> { \
> - return PagePrivate(page) && \
> + return page_private(page) && \
> test_bit(PAGE_PRIVATE_NOT_POINTER, &page_private(page)) && \
> test_bit(PAGE_PRIVATE_##flagname, &page_private(page)); \
> }
> @@ -2710,9 +2710,9 @@ static inline void folio_set_f2fs_##name(struct folio *folio) \
> } \
> static inline void set_page_private_##name(struct page *page) \
> { \
> - if (!PagePrivate(page)) \
> - attach_page_private(page, (void *)0); \
> - set_bit(PAGE_PRIVATE_NOT_POINTER, &page_private(page)); \
> + if (!page_private(page)) \
> + attach_page_private(page, \
> + (void *)BIT(PAGE_PRIVATE_NOT_POINTER)); \
> set_bit(PAGE_PRIVATE_##flagname, &page_private(page)); \
> }
Very weird interface. Why do we even need the page-based interface still?
$ git grep -E "(set|clear)_page_private"
compress.c: clear_page_private_gcing(cc->rpages[i]);
compress.c: set_page_private_gcing(cc->rpages[i]);
compress.c: clear_page_private_gcing(cic->rpages[i]);
f2fs.h:static inline void set_page_private_##name(struct page *page) \
f2fs.h:static inline void clear_page_private_##name(struct page *page) \
Seeing code like:
clear_page_private_gcing(cc->rpages[i]);
if (folio_test_writeback(page_folio(cc->rpages[i])))
end_page_writeback(cc->rpages[i]);
Makes me wonder whether we can just use the folio helper instead?
In f2fs_iget(), we enable large folios only when !f2fs_compressed_file(inode).
So naive me would assume that we can just get rid of the
set_page_private_/clear_page_private_ stuff entirely.
IOW something like:
From efcde918178604de11d16c6dc5485542ab4dcdaf Mon Sep 17 00:00:00 2001
From: "David Hildenbrand (Arm)" <david@kernel.org>
Date: Tue, 8 Sep 2026 17:46:06 +0200
Subject: [PATCH] tmp
Signed-off-by: David Hildenbrand (Arm) <david@kernel.org>
---
fs/f2fs/compress.c | 29 ++++++++++++++++++-----------
fs/f2fs/f2fs.h | 13 -------------
2 files changed, 18 insertions(+), 24 deletions(-)
diff --git a/fs/f2fs/compress.c b/fs/f2fs/compress.c
index ce88092d9ce26..0e9cc0fa297a4 100644
--- a/fs/f2fs/compress.c
+++ b/fs/f2fs/compress.c
@@ -1064,13 +1064,15 @@ static void cancel_cluster_writeback(struct compress_ctx *cc,
/* Cancel writeback and stay locked. */
for (i = 0; i < cc->cluster_size; i++) {
+ struct folio *folio = page_folio(cc->rpages[i]);
+
if (i < submitted) {
inode_inc_dirty_pages(cc->inode);
- lock_page(cc->rpages[i]);
+ folio_lock(folio);
}
- clear_page_private_gcing(cc->rpages[i]);
- if (folio_test_writeback(page_folio(cc->rpages[i])))
- end_page_writeback(cc->rpages[i]);
+ folio_clear_f2fs_gcing(folio);
+ if (folio_test_writeback(folio))
+ folio_end_writeback(folio);
}
}
@@ -1078,11 +1080,15 @@ static void set_cluster_dirty(struct compress_ctx *cc)
{
int i;
- for (i = 0; i < cc->cluster_size; i++)
- if (cc->rpages[i]) {
- set_page_dirty(cc->rpages[i]);
- set_page_private_gcing(cc->rpages[i]);
- }
+ for (i = 0; i < cc->cluster_size; i++) {
+ struct folio *folio;
+
+ if (!cc->rpages[i])
+ continue;
+ folio = page_folio(cc->rpages[i]);
+ folio_mark_dirty(folio);
+ folio_set_f2fs_gcing(folio);
+ }
}
static int prepare_compress_overwrite(struct compress_ctx *cc,
@@ -1477,8 +1483,9 @@ void f2fs_compress_write_end_io(struct bio *bio, struct folio *folio)
for (i = 0; i < cic->nr_rpages; i++) {
WARN_ON(!cic->rpages[i]);
- clear_page_private_gcing(cic->rpages[i]);
- end_page_writeback(cic->rpages[i]);
+ folio = page_folio(cic->rpages[i]);
+ folio_clear_f2fs_gcing(folio);
+ folio_end_writeback(folio);
}
page_array_free(sbi, cic->rpages, cic->nr_rpages);
diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h
index 9940a6cecf1a2..0cfba8742d4b4 100644
--- a/fs/f2fs/f2fs.h
+++ b/fs/f2fs/f2fs.h
@@ -2707,13 +2707,6 @@ static inline void folio_set_f2fs_##name(struct folio *folio) \
v |= (unsigned long)folio->private; \
folio->private = (void *)v; \
} \
-} \
-static inline void set_page_private_##name(struct page *page) \
-{ \
- if (!PagePrivate(page)) \
- attach_page_private(page, (void *)0); \
- set_bit(PAGE_PRIVATE_NOT_POINTER, &page_private(page)); \
- set_bit(PAGE_PRIVATE_##flagname, &page_private(page)); \
}
#define PAGE_PRIVATE_CLEAR_FUNC(name, flagname) \
@@ -2726,12 +2719,6 @@ static inline void folio_clear_f2fs_##name(struct folio *folio) \
folio_detach_private(folio); \
else \
folio->private = (void *)v; \
-} \
-static inline void clear_page_private_##name(struct page *page) \
-{ \
- clear_bit(PAGE_PRIVATE_##flagname, &page_private(page)); \
- if (page_private(page) == BIT(PAGE_PRIVATE_NOT_POINTER)) \
- detach_page_private(page); \
}
PAGE_PRIVATE_GET_FUNC(nonpointer, NOT_POINTER);
--
2.43.0
--
Cheers,
David
_______________________________________________
Linux-f2fs-devel mailing list
Linux-f2fs-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel
^ permalink raw reply related [flat|nested] 37+ messages in thread* Re: [f2fs-dev] [PATCH v3 06/14] f2fs: stop using PG_private
2026-09-08 15:47 ` David Hildenbrand (Arm) via Linux-f2fs-devel
@ 2026-09-08 18:20 ` Tal Zussman
2026-09-09 12:48 ` David Hildenbrand (Arm) via Linux-f2fs-devel
2026-09-10 2:41 ` Chao Yu via Linux-f2fs-devel
1 sibling, 1 reply; 37+ messages in thread
From: Tal Zussman @ 2026-09-08 18:20 UTC (permalink / raw)
To: David Hildenbrand (Arm)
Cc: Michal Hocko, Liam R. Howlett, Jaegeuk Kim, Ying Huang, Qi Zheng,
Vlastimil Babka, Alistair Popple, Dev Jain,
Matthew Wilcox (Oracle), Zi Yan, Gregory Price, Ryan Roberts,
Usama Arif, linux-f2fs-devel, Baolin Wang, Shakeel Butt,
Lorenzo Stoakes, Suren Baghdasaryan, Barry Song, Kairui Song,
linux-mm, Muchun Song, linux-kernel, Nico Pache, Lance Yang,
Johannes Weiner, Andrew Morton, Mike Rapoport
On 2026-09-08 17:47 +0200, David Hildenbrand (Arm) wrote:
> On 9/8/26 04:56, Zi Yan wrote:
> > f2fs sets its PAGE_PRIVATE_* flags in page->private and checking
> > page->private != NULL is equivalent to checking PG_private. Change
> > PagePrivate() to page_private(). Meanwhile, in set_page_private_##name(),
> > page->private is first set to 0/NULL before an PAGE_PRIVATE_* flag is set,
> > but it can cause confusion when PG_private is removed and
> > page->private != NULL is used instead. Change it to initialize
> > page->private to PAGE_PRIVATE_NOT_POINTER instead and retain the original
> > semantics.
> >
> > It prepares for a future commit that removes PG_private.
> >
> > No functional change intended.
> >
> > Assisted-by: Claude:claude-opus-4-8
> > Assisted-by: Codex:gpt-5
> > To: Jaegeuk Kim <jaegeuk@kernel.org>
> > To: Chao Yu <chao@kernel.org>
> > Cc: linux-f2fs-devel@lists.sourceforge.net
> > Cc: linux-kernel@vger.kernel.org
> > Acked-by: Usama Arif <usama.arif@linux.dev>
> > Acked-by: Chao Yu <chao@kernel.org>
> > Signed-off-by: Zi Yan <ziy@nvidia.com>
> > ---
> > fs/f2fs/f2fs.h | 8 ++++----
> > 1 file changed, 4 insertions(+), 4 deletions(-)
> >
> > diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h
> > index 9940a6cecf1a2..2f7ab5888b078 100644
> > --- a/fs/f2fs/f2fs.h
> > +++ b/fs/f2fs/f2fs.h
> > @@ -2691,7 +2691,7 @@ static inline bool folio_test_f2fs_##name(const struct folio *folio) \
> > } \
> > static inline bool page_private_##name(struct page *page) \
> > { \
> > - return PagePrivate(page) && \
> > + return page_private(page) && \
> > test_bit(PAGE_PRIVATE_NOT_POINTER, &page_private(page)) && \
> > test_bit(PAGE_PRIVATE_##flagname, &page_private(page)); \
> > }
> > @@ -2710,9 +2710,9 @@ static inline void folio_set_f2fs_##name(struct folio *folio) \
> > } \
> > static inline void set_page_private_##name(struct page *page) \
> > { \
> > - if (!PagePrivate(page)) \
> > - attach_page_private(page, (void *)0); \
> > - set_bit(PAGE_PRIVATE_NOT_POINTER, &page_private(page)); \
> > + if (!page_private(page)) \
> > + attach_page_private(page, \
> > + (void *)BIT(PAGE_PRIVATE_NOT_POINTER)); \
> > set_bit(PAGE_PRIVATE_##flagname, &page_private(page)); \
> > }
>
> Very weird interface. Why do we even need the page-based interface still?
>
> $ git grep -E "(set|clear)_page_private"
> compress.c: clear_page_private_gcing(cc->rpages[i]);
> compress.c: set_page_private_gcing(cc->rpages[i]);
> compress.c: clear_page_private_gcing(cic->rpages[i]);
> f2fs.h:static inline void set_page_private_##name(struct page *page) \
> f2fs.h:static inline void clear_page_private_##name(struct page *page) \
>
> Seeing code like:
>
> clear_page_private_gcing(cc->rpages[i]);
> if (folio_test_writeback(page_folio(cc->rpages[i])))
> end_page_writeback(cc->rpages[i]);
>
> Makes me wonder whether we can just use the folio helper instead?
>
> In f2fs_iget(), we enable large folios only when !f2fs_compressed_file(inode).
>
> So naive me would assume that we can just get rid of the
> set_page_private_/clear_page_private_ stuff entirely.
>
I have a WIP series of ~30 patches converting much of the remaining page
users in f2fs (including the below) to folios. Still have to do some
testing and clean it up, but hoping to send it out in the next couple of
weeks (in the hopes of eliminating some more folio_compat.c functions by
next cycle...)
> IOW something like:
>
>
> From efcde918178604de11d16c6dc5485542ab4dcdaf Mon Sep 17 00:00:00 2001
> From: "David Hildenbrand (Arm)" <david@kernel.org>
> Date: Tue, 8 Sep 2026 17:46:06 +0200
> Subject: [PATCH] tmp
>
> Signed-off-by: David Hildenbrand (Arm) <david@kernel.org>
> ---
> fs/f2fs/compress.c | 29 ++++++++++++++++++-----------
> fs/f2fs/f2fs.h | 13 -------------
> 2 files changed, 18 insertions(+), 24 deletions(-)
>
> diff --git a/fs/f2fs/compress.c b/fs/f2fs/compress.c
> index ce88092d9ce26..0e9cc0fa297a4 100644
> --- a/fs/f2fs/compress.c
> +++ b/fs/f2fs/compress.c
> @@ -1064,13 +1064,15 @@ static void cancel_cluster_writeback(struct compress_ctx *cc,
>
> /* Cancel writeback and stay locked. */
> for (i = 0; i < cc->cluster_size; i++) {
> + struct folio *folio = page_folio(cc->rpages[i]);
> +
> if (i < submitted) {
> inode_inc_dirty_pages(cc->inode);
> - lock_page(cc->rpages[i]);
> + folio_lock(folio);
> }
> - clear_page_private_gcing(cc->rpages[i]);
> - if (folio_test_writeback(page_folio(cc->rpages[i])))
> - end_page_writeback(cc->rpages[i]);
> + folio_clear_f2fs_gcing(folio);
> + if (folio_test_writeback(folio))
> + folio_end_writeback(folio);
> }
> }
>
> @@ -1078,11 +1080,15 @@ static void set_cluster_dirty(struct compress_ctx *cc)
> {
> int i;
>
> - for (i = 0; i < cc->cluster_size; i++)
> - if (cc->rpages[i]) {
> - set_page_dirty(cc->rpages[i]);
> - set_page_private_gcing(cc->rpages[i]);
> - }
> + for (i = 0; i < cc->cluster_size; i++) {
> + struct folio *folio;
> +
> + if (!cc->rpages[i])
> + continue;
> + folio = page_folio(cc->rpages[i]);
> + folio_mark_dirty(folio);
> + folio_set_f2fs_gcing(folio);
> + }
> }
>
> static int prepare_compress_overwrite(struct compress_ctx *cc,
> @@ -1477,8 +1483,9 @@ void f2fs_compress_write_end_io(struct bio *bio, struct folio *folio)
>
> for (i = 0; i < cic->nr_rpages; i++) {
> WARN_ON(!cic->rpages[i]);
> - clear_page_private_gcing(cic->rpages[i]);
> - end_page_writeback(cic->rpages[i]);
> + folio = page_folio(cic->rpages[i]);
> + folio_clear_f2fs_gcing(folio);
> + folio_end_writeback(folio);
> }
>
> page_array_free(sbi, cic->rpages, cic->nr_rpages);
> diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h
> index 9940a6cecf1a2..0cfba8742d4b4 100644
> --- a/fs/f2fs/f2fs.h
> +++ b/fs/f2fs/f2fs.h
> @@ -2707,13 +2707,6 @@ static inline void folio_set_f2fs_##name(struct folio *folio) \
> v |= (unsigned long)folio->private; \
> folio->private = (void *)v; \
> } \
> -} \
> -static inline void set_page_private_##name(struct page *page) \
> -{ \
> - if (!PagePrivate(page)) \
> - attach_page_private(page, (void *)0); \
> - set_bit(PAGE_PRIVATE_NOT_POINTER, &page_private(page)); \
> - set_bit(PAGE_PRIVATE_##flagname, &page_private(page)); \
> }
>
> #define PAGE_PRIVATE_CLEAR_FUNC(name, flagname) \
> @@ -2726,12 +2719,6 @@ static inline void folio_clear_f2fs_##name(struct folio *folio) \
> folio_detach_private(folio); \
> else \
> folio->private = (void *)v; \
> -} \
> -static inline void clear_page_private_##name(struct page *page) \
> -{ \
> - clear_bit(PAGE_PRIVATE_##flagname, &page_private(page)); \
> - if (page_private(page) == BIT(PAGE_PRIVATE_NOT_POINTER)) \
> - detach_page_private(page); \
> }
>
> PAGE_PRIVATE_GET_FUNC(nonpointer, NOT_POINTER);
> --
> 2.43.0
>
>
> --
> Cheers,
>
> David
>
_______________________________________________
Linux-f2fs-devel mailing list
Linux-f2fs-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel
^ permalink raw reply [flat|nested] 37+ messages in thread* Re: [f2fs-dev] [PATCH v3 06/14] f2fs: stop using PG_private
2026-09-08 18:20 ` Tal Zussman
@ 2026-09-09 12:48 ` David Hildenbrand (Arm) via Linux-f2fs-devel
2026-09-09 17:47 ` Tal Zussman
0 siblings, 1 reply; 37+ messages in thread
From: David Hildenbrand (Arm) via Linux-f2fs-devel @ 2026-09-09 12:48 UTC (permalink / raw)
To: Tal Zussman
Cc: Michal Hocko, Liam R. Howlett, Jaegeuk Kim, Ying Huang, Qi Zheng,
Vlastimil Babka, Alistair Popple, Dev Jain,
Matthew Wilcox (Oracle), Zi Yan, Gregory Price, Ryan Roberts,
Usama Arif, linux-f2fs-devel, Baolin Wang, Shakeel Butt,
Lorenzo Stoakes, Suren Baghdasaryan, Barry Song, Kairui Song,
linux-mm, Muchun Song, linux-kernel, Nico Pache, Lance Yang,
Johannes Weiner, Andrew Morton, Mike Rapoport
On 9/8/26 20:20, Tal Zussman wrote:
> On 2026-09-08 17:47 +0200, David Hildenbrand (Arm) wrote:
>> On 9/8/26 04:56, Zi Yan wrote:
>>> f2fs sets its PAGE_PRIVATE_* flags in page->private and checking
>>> page->private != NULL is equivalent to checking PG_private. Change
>>> PagePrivate() to page_private(). Meanwhile, in set_page_private_##name(),
>>> page->private is first set to 0/NULL before an PAGE_PRIVATE_* flag is set,
>>> but it can cause confusion when PG_private is removed and
>>> page->private != NULL is used instead. Change it to initialize
>>> page->private to PAGE_PRIVATE_NOT_POINTER instead and retain the original
>>> semantics.
>>>
>>> It prepares for a future commit that removes PG_private.
>>>
>>> No functional change intended.
>>>
>>> Assisted-by: Claude:claude-opus-4-8
>>> Assisted-by: Codex:gpt-5
>>> To: Jaegeuk Kim <jaegeuk@kernel.org>
>>> To: Chao Yu <chao@kernel.org>
>>> Cc: linux-f2fs-devel@lists.sourceforge.net
>>> Cc: linux-kernel@vger.kernel.org
>>> Acked-by: Usama Arif <usama.arif@linux.dev>
>>> Acked-by: Chao Yu <chao@kernel.org>
>>> Signed-off-by: Zi Yan <ziy@nvidia.com>
>>> ---
>>> fs/f2fs/f2fs.h | 8 ++++----
>>> 1 file changed, 4 insertions(+), 4 deletions(-)
>>>
>>> diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h
>>> index 9940a6cecf1a2..2f7ab5888b078 100644
>>> --- a/fs/f2fs/f2fs.h
>>> +++ b/fs/f2fs/f2fs.h
>>> @@ -2691,7 +2691,7 @@ static inline bool folio_test_f2fs_##name(const struct folio *folio) \
>>> } \
>>> static inline bool page_private_##name(struct page *page) \
>>> { \
>>> - return PagePrivate(page) && \
>>> + return page_private(page) && \
>>> test_bit(PAGE_PRIVATE_NOT_POINTER, &page_private(page)) && \
>>> test_bit(PAGE_PRIVATE_##flagname, &page_private(page)); \
>>> }
>>> @@ -2710,9 +2710,9 @@ static inline void folio_set_f2fs_##name(struct folio *folio) \
>>> } \
>>> static inline void set_page_private_##name(struct page *page) \
>>> { \
>>> - if (!PagePrivate(page)) \
>>> - attach_page_private(page, (void *)0); \
>>> - set_bit(PAGE_PRIVATE_NOT_POINTER, &page_private(page)); \
>>> + if (!page_private(page)) \
>>> + attach_page_private(page, \
>>> + (void *)BIT(PAGE_PRIVATE_NOT_POINTER)); \
>>> set_bit(PAGE_PRIVATE_##flagname, &page_private(page)); \
>>> }
>>
>> Very weird interface. Why do we even need the page-based interface still?
>>
>> $ git grep -E "(set|clear)_page_private"
>> compress.c: clear_page_private_gcing(cc->rpages[i]);
>> compress.c: set_page_private_gcing(cc->rpages[i]);
>> compress.c: clear_page_private_gcing(cic->rpages[i]);
>> f2fs.h:static inline void set_page_private_##name(struct page *page) \
>> f2fs.h:static inline void clear_page_private_##name(struct page *page) \
>>
>> Seeing code like:
>>
>> clear_page_private_gcing(cc->rpages[i]);
>> if (folio_test_writeback(page_folio(cc->rpages[i])))
>> end_page_writeback(cc->rpages[i]);
>>
>> Makes me wonder whether we can just use the folio helper instead?
>>
>> In f2fs_iget(), we enable large folios only when !f2fs_compressed_file(inode).
>>
>> So naive me would assume that we can just get rid of the
>> set_page_private_/clear_page_private_ stuff entirely.
>>
>
> I have a WIP series of ~30 patches converting much of the remaining page
> users in f2fs (including the below) to folios. Still have to do some
> testing and clean it up, but hoping to send it out in the next couple of
> weeks (in the hopes of eliminating some more folio_compat.c functions by
> next cycle...)
Indeed best to wait a bit before flooding -mm even more, it's rather a lot at
this point.
In the context of this series, it would be great if you could review whether the
diff I proposed would get the job done, thanks!
--
Cheers,
David
_______________________________________________
Linux-f2fs-devel mailing list
Linux-f2fs-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel
^ permalink raw reply [flat|nested] 37+ messages in thread* Re: [f2fs-dev] [PATCH v3 06/14] f2fs: stop using PG_private
2026-09-09 12:48 ` David Hildenbrand (Arm) via Linux-f2fs-devel
@ 2026-09-09 17:47 ` Tal Zussman
2026-09-10 7:35 ` David Hildenbrand (Arm) via Linux-f2fs-devel
0 siblings, 1 reply; 37+ messages in thread
From: Tal Zussman @ 2026-09-09 17:47 UTC (permalink / raw)
To: David Hildenbrand (Arm)
Cc: Michal Hocko, Liam R. Howlett, Jaegeuk Kim, Ying Huang, Qi Zheng,
Vlastimil Babka, Alistair Popple, Dev Jain,
Matthew Wilcox (Oracle), Zi Yan, Gregory Price, Ryan Roberts,
Usama Arif, linux-f2fs-devel, Baolin Wang, Shakeel Butt,
Lorenzo Stoakes, Suren Baghdasaryan, Barry Song, Kairui Song,
linux-mm, Muchun Song, linux-kernel, Nico Pache, Lance Yang,
Johannes Weiner, Andrew Morton, Mike Rapoport
On 9/9/26 3:48 PM, David Hildenbrand (Arm) wrote:
> On 9/8/26 20:20, Tal Zussman wrote:
>> On 2026-09-08 17:47 +0200, David Hildenbrand (Arm) wrote:
>>> On 9/8/26 04:56, Zi Yan wrote:
>>>> f2fs sets its PAGE_PRIVATE_* flags in page->private and checking
>>>> page->private != NULL is equivalent to checking PG_private. Change
>>>> PagePrivate() to page_private(). Meanwhile, in set_page_private_##name(),
>>>> page->private is first set to 0/NULL before an PAGE_PRIVATE_* flag is set,
>>>> but it can cause confusion when PG_private is removed and
>>>> page->private != NULL is used instead. Change it to initialize
>>>> page->private to PAGE_PRIVATE_NOT_POINTER instead and retain the original
>>>> semantics.
>>>>
>>>> It prepares for a future commit that removes PG_private.
>>>>
>>>> No functional change intended.
>>>>
>>>> Assisted-by: Claude:claude-opus-4-8
>>>> Assisted-by: Codex:gpt-5
>>>> To: Jaegeuk Kim <jaegeuk@kernel.org>
>>>> To: Chao Yu <chao@kernel.org>
>>>> Cc: linux-f2fs-devel@lists.sourceforge.net
>>>> Cc: linux-kernel@vger.kernel.org
>>>> Acked-by: Usama Arif <usama.arif@linux.dev>
>>>> Acked-by: Chao Yu <chao@kernel.org>
>>>> Signed-off-by: Zi Yan <ziy@nvidia.com>
>>>> ---
>>>> fs/f2fs/f2fs.h | 8 ++++----
>>>> 1 file changed, 4 insertions(+), 4 deletions(-)
>>>>
>>>> diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h
>>>> index 9940a6cecf1a2..2f7ab5888b078 100644
>>>> --- a/fs/f2fs/f2fs.h
>>>> +++ b/fs/f2fs/f2fs.h
>>>> @@ -2691,7 +2691,7 @@ static inline bool folio_test_f2fs_##name(const struct folio *folio) \
>>>> } \
>>>> static inline bool page_private_##name(struct page *page) \
>>>> { \
>>>> - return PagePrivate(page) && \
>>>> + return page_private(page) && \
>>>> test_bit(PAGE_PRIVATE_NOT_POINTER, &page_private(page)) && \
>>>> test_bit(PAGE_PRIVATE_##flagname, &page_private(page)); \
>>>> }
>>>> @@ -2710,9 +2710,9 @@ static inline void folio_set_f2fs_##name(struct folio *folio) \
>>>> } \
>>>> static inline void set_page_private_##name(struct page *page) \
>>>> { \
>>>> - if (!PagePrivate(page)) \
>>>> - attach_page_private(page, (void *)0); \
>>>> - set_bit(PAGE_PRIVATE_NOT_POINTER, &page_private(page)); \
>>>> + if (!page_private(page)) \
>>>> + attach_page_private(page, \
>>>> + (void *)BIT(PAGE_PRIVATE_NOT_POINTER)); \
>>>> set_bit(PAGE_PRIVATE_##flagname, &page_private(page)); \
>>>> }
>>>
>>> Very weird interface. Why do we even need the page-based interface still?
>>>
>>> $ git grep -E "(set|clear)_page_private"
>>> compress.c: clear_page_private_gcing(cc->rpages[i]);
>>> compress.c: set_page_private_gcing(cc->rpages[i]);
>>> compress.c: clear_page_private_gcing(cic->rpages[i]);
>>> f2fs.h:static inline void set_page_private_##name(struct page *page) \
>>> f2fs.h:static inline void clear_page_private_##name(struct page *page) \
>>>
>>> Seeing code like:
>>>
>>> clear_page_private_gcing(cc->rpages[i]);
>>> if (folio_test_writeback(page_folio(cc->rpages[i])))
>>> end_page_writeback(cc->rpages[i]);
>>>
>>> Makes me wonder whether we can just use the folio helper instead?
>>>
>>> In f2fs_iget(), we enable large folios only when !f2fs_compressed_file(inode).
>>>
>>> So naive me would assume that we can just get rid of the
>>> set_page_private_/clear_page_private_ stuff entirely.
>>>
>>
>> I have a WIP series of ~30 patches converting much of the remaining page
>> users in f2fs (including the below) to folios. Still have to do some
>> testing and clean it up, but hoping to send it out in the next couple of
>> weeks (in the hopes of eliminating some more folio_compat.c functions by
>> next cycle...)
>
> Indeed best to wait a bit before flooding -mm even more, it's rather a lot at
> this point.
>
> In the context of this series, it would be great if you could review whether the
> diff I proposed would get the job done, thanks!
>
What it changes looks good, but I would go a little further.
There are only two more users of page_private_gcing(), which pass fio->page.
Those could easily be converted to folio_test_f2fs_gcing() by passing fio->folio,
which is in a union with fio->page. That would let you delete the
page_private_##name() implementation in PAGE_PRIVATE_GET_FUNC() as well and just
remove the entire family. At that point PAGE_PRIVATE_{GET,SET,CLEAR}_FUNC()
could be renamed to something like F2FS_FOLIO_PRIVATE_{GET,SET,CLEAR}_FUNC() and
all of this cruft is gone and folio-based, with no more f2fs use of page_private()
either.
The renaming could be done as a later step, but I would get rid of the accessors
as well in one swoop.
> --
> Cheers,
>
> David
>
_______________________________________________
Linux-f2fs-devel mailing list
Linux-f2fs-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel
^ permalink raw reply [flat|nested] 37+ messages in thread* Re: [f2fs-dev] [PATCH v3 06/14] f2fs: stop using PG_private
2026-09-09 17:47 ` Tal Zussman
@ 2026-09-10 7:35 ` David Hildenbrand (Arm) via Linux-f2fs-devel
2026-09-10 12:21 ` Zi Yan via Linux-f2fs-devel
0 siblings, 1 reply; 37+ messages in thread
From: David Hildenbrand (Arm) via Linux-f2fs-devel @ 2026-09-10 7:35 UTC (permalink / raw)
To: Tal Zussman
Cc: Michal Hocko, Liam R. Howlett, Jaegeuk Kim, Ying Huang, Qi Zheng,
Vlastimil Babka, Alistair Popple, Dev Jain,
Matthew Wilcox (Oracle), Zi Yan, Gregory Price, Ryan Roberts,
Usama Arif, linux-f2fs-devel, Baolin Wang, Shakeel Butt,
Lorenzo Stoakes, Suren Baghdasaryan, Barry Song, Kairui Song,
linux-mm, Muchun Song, linux-kernel, Nico Pache, Lance Yang,
Johannes Weiner, Andrew Morton, Mike Rapoport
On 9/9/26 19:47, Tal Zussman wrote:
> On 9/9/26 3:48 PM, David Hildenbrand (Arm) wrote:
>> On 9/8/26 20:20, Tal Zussman wrote:
>>>
>>> I have a WIP series of ~30 patches converting much of the remaining page
>>> users in f2fs (including the below) to folios. Still have to do some
>>> testing and clean it up, but hoping to send it out in the next couple of
>>> weeks (in the hopes of eliminating some more folio_compat.c functions by
>>> next cycle...)
>>
>> Indeed best to wait a bit before flooding -mm even more, it's rather a lot at
>> this point.
>>
>> In the context of this series, it would be great if you could review whether the
>> diff I proposed would get the job done, thanks!
>>
>
> What it changes looks good, but I would go a little further.
Thanks!
>
> There are only two more users of page_private_gcing(), which pass fio->page.
> Those could easily be converted to folio_test_f2fs_gcing() by passing fio->folio,
> which is in a union with fio->page. That would let you delete the
> page_private_##name() implementation in PAGE_PRIVATE_GET_FUNC() as well and just
> remove the entire family. At that point PAGE_PRIVATE_{GET,SET,CLEAR}_FUNC()
> could be renamed to something like F2FS_FOLIO_PRIVATE_{GET,SET,CLEAR}_FUNC() and
> all of this cruft is gone and folio-based, with no more f2fs use of page_private()
> either.
>
> The renaming could be done as a later step, but I would get rid of the accessors
> as well in one swoop.
Yes, either as part of the same patch or as a separate patch. Zi, can you take
care of that? Thanks!
--
Cheers,
David
_______________________________________________
Linux-f2fs-devel mailing list
Linux-f2fs-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel
^ permalink raw reply [flat|nested] 37+ messages in thread* Re: [f2fs-dev] [PATCH v3 06/14] f2fs: stop using PG_private
2026-09-10 7:35 ` David Hildenbrand (Arm) via Linux-f2fs-devel
@ 2026-09-10 12:21 ` Zi Yan via Linux-f2fs-devel
2026-09-10 21:11 ` Zi Yan via Linux-f2fs-devel
0 siblings, 1 reply; 37+ messages in thread
From: Zi Yan via Linux-f2fs-devel @ 2026-09-10 12:21 UTC (permalink / raw)
To: David Hildenbrand (Arm)
Cc: Michal Hocko, Liam R. Howlett, Jaegeuk Kim, Ying Huang,
Tal Zussman, Qi Zheng, Vlastimil Babka, Alistair Popple, Dev Jain,
Matthew Wilcox (Oracle), Gregory Price, Ryan Roberts, Usama Arif,
linux-f2fs-devel, Baolin Wang, Shakeel Butt, Lorenzo Stoakes,
Suren Baghdasaryan, Barry Song, Kairui Song, linux-mm,
Muchun Song, linux-kernel, Nico Pache, Lance Yang,
Johannes Weiner, Andrew Morton, Mike Rapoport
On 10 Sep 2026, at 3:35, David Hildenbrand (Arm) wrote:
> On 9/9/26 19:47, Tal Zussman wrote:
>> On 9/9/26 3:48 PM, David Hildenbrand (Arm) wrote:
>>> On 9/8/26 20:20, Tal Zussman wrote:
>>>>
>>>> I have a WIP series of ~30 patches converting much of the remaining page
>>>> users in f2fs (including the below) to folios. Still have to do some
>>>> testing and clean it up, but hoping to send it out in the next couple of
>>>> weeks (in the hopes of eliminating some more folio_compat.c functions by
>>>> next cycle...)
>>>
>>> Indeed best to wait a bit before flooding -mm even more, it's rather a lot at
>>> this point.
>>>
>>> In the context of this series, it would be great if you could review whether the
>>> diff I proposed would get the job done, thanks!
>>>
>>
>> What it changes looks good, but I would go a little further.
>
> Thanks!
>
>>
>> There are only two more users of page_private_gcing(), which pass fio->page.
>> Those could easily be converted to folio_test_f2fs_gcing() by passing fio->folio,
>> which is in a union with fio->page. That would let you delete the
>> page_private_##name() implementation in PAGE_PRIVATE_GET_FUNC() as well and just
>> remove the entire family. At that point PAGE_PRIVATE_{GET,SET,CLEAR}_FUNC()
>> could be renamed to something like F2FS_FOLIO_PRIVATE_{GET,SET,CLEAR}_FUNC() and
>> all of this cruft is gone and folio-based, with no more f2fs use of page_private()
>> either.
>>
>> The renaming could be done as a later step, but I would get rid of the accessors
>> as well in one swoop.
>
> Yes, either as part of the same patch or as a separate patch. Zi, can you take
> care of that? Thanks!
OK, I will come up with a patch based on your patch plus the suggestion here
on top of this “f2fs: stop using PG_private”. I will post the patch here
for feedback to avoid extra churn of the whole series.
Best Regards,
Yan, Zi
_______________________________________________
Linux-f2fs-devel mailing list
Linux-f2fs-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel
^ permalink raw reply [flat|nested] 37+ messages in thread* Re: [f2fs-dev] [PATCH v3 06/14] f2fs: stop using PG_private
2026-09-10 12:21 ` Zi Yan via Linux-f2fs-devel
@ 2026-09-10 21:11 ` Zi Yan via Linux-f2fs-devel
2026-09-13 20:11 ` Tal Zussman
0 siblings, 1 reply; 37+ messages in thread
From: Zi Yan via Linux-f2fs-devel @ 2026-09-10 21:11 UTC (permalink / raw)
To: David Hildenbrand (Arm)
Cc: Michal Hocko, Liam R. Howlett, Jaegeuk Kim, Ying Huang,
Tal Zussman, Qi Zheng, Vlastimil Babka, Alistair Popple, Dev Jain,
Matthew Wilcox (Oracle), Gregory Price, Ryan Roberts, Usama Arif,
linux-f2fs-devel, Baolin Wang, Shakeel Butt, Lorenzo Stoakes,
Suren Baghdasaryan, Barry Song, Kairui Song, linux-mm,
Muchun Song, linux-kernel, Nico Pache, Lance Yang,
Johannes Weiner, Andrew Morton, Mike Rapoport
On Thu Sep 10, 2026 at 8:21 AM EDT, Zi Yan wrote:
> On 10 Sep 2026, at 3:35, David Hildenbrand (Arm) wrote:
>
>> On 9/9/26 19:47, Tal Zussman wrote:
>>> On 9/9/26 3:48 PM, David Hildenbrand (Arm) wrote:
>>>> On 9/8/26 20:20, Tal Zussman wrote:
>>>>>
>>>>> I have a WIP series of ~30 patches converting much of the remaining page
>>>>> users in f2fs (including the below) to folios. Still have to do some
>>>>> testing and clean it up, but hoping to send it out in the next couple of
>>>>> weeks (in the hopes of eliminating some more folio_compat.c functions by
>>>>> next cycle...)
>>>>
>>>> Indeed best to wait a bit before flooding -mm even more, it's rather a lot at
>>>> this point.
>>>>
>>>> In the context of this series, it would be great if you could review whether the
>>>> diff I proposed would get the job done, thanks!
>>>>
>>>
>>> What it changes looks good, but I would go a little further.
>>
>> Thanks!
>>
>>>
>>> There are only two more users of page_private_gcing(), which pass fio->page.
>>> Those could easily be converted to folio_test_f2fs_gcing() by passing fio->folio,
>>> which is in a union with fio->page. That would let you delete the
>>> page_private_##name() implementation in PAGE_PRIVATE_GET_FUNC() as well and just
>>> remove the entire family. At that point PAGE_PRIVATE_{GET,SET,CLEAR}_FUNC()
>>> could be renamed to something like F2FS_FOLIO_PRIVATE_{GET,SET,CLEAR}_FUNC() and
>>> all of this cruft is gone and folio-based, with no more f2fs use of page_private()
>>> either.
>>>
>>> The renaming could be done as a later step, but I would get rid of the accessors
>>> as well in one swoop.
>>
>> Yes, either as part of the same patch or as a separate patch. Zi, can you take
>> care of that? Thanks!
>
> OK, I will come up with a patch based on your patch plus the suggestion here
> on top of this “f2fs: stop using PG_private”. I will post the patch here
> for feedback to avoid extra churn of the whole series.
>
OK, here is the patch. In addition to David's patch and Tal' suggestion,
I also
1. converted PAGE_PRIVATE_* flags to F2FS_FOLIO_PRIVATE_*,
2. converted page/folio union in f2fs_io_info to folio only, since no
one is using fio->page any more.
Let me know your feedback. I will add this to my patch series once you
are OK with it. Thanks.
From 3bae5c494459b3dd05893df6051e3eb37164f810 Mon Sep 17 00:00:00 2001
From: Zi Yan <ziy@nvidia.com>
Date: Thu, 10 Sep 2026 16:42:39 -0400
Subject: [PATCH] f2fs: convert the ->private flag helpers to folio-only
page-based ->private flag helpers are used in the compression path, where
large folios are not enabled. They can use folio versions with
page_folio(). The two remaining users in data.c and segment.c can use
fio->folio instead of fio->page (two are in a union).
Drop page-based helpers after the conversion and rename
PAGE_PRIVATE_{GET,SET,CLEAR}_FUNC() and the PAGE_PRIVATE_* flags to
F2FS_FOLIO_PRIVATE_* to match. Convert the folio/page union from
f2fs_io_info union to folio only, since no page user is left.
The folio helpers do a plain read-modify-write where the page ones used
set_bit()/clear_bit(). It is fine because the converted code either holds
folio lock or, in f2fs_compress_write_end_io(), matches what the
non-compressed code does in f2fs_write_end_bio().
Assisted-by: Claude:claude-opus-5
Suggested-by: Tal Zussman <tz2294@columbia.edu>
Co-developed-by: David Hildenbrand (Arm) <david@kernel.org>
Signed-off-by: David Hildenbrand (Arm) <david@kernel.org>
Signed-off-by: Zi Yan <ziy@nvidia.com>
To: Jaegeuk Kim <jaegeuk@kernel.org>
To: Chao Yu <chao@kernel.org>
Cc: linux-f2fs-devel@lists.sourceforge.net
Cc: linux-kernel@vger.kernel.org
---
fs/f2fs/compress.c | 35 ++++++++++------
fs/f2fs/data.c | 2 +-
fs/f2fs/f2fs.h | 99 ++++++++++++++++++----------------------------
fs/f2fs/segment.c | 2 +-
4 files changed, 63 insertions(+), 75 deletions(-)
diff --git a/fs/f2fs/compress.c b/fs/f2fs/compress.c
index ce88092d9ce26..09d9b8d0fdcce 100644
--- a/fs/f2fs/compress.c
+++ b/fs/f2fs/compress.c
@@ -1064,13 +1064,15 @@ static void cancel_cluster_writeback(struct compress_ctx *cc,
/* Cancel writeback and stay locked. */
for (i = 0; i < cc->cluster_size; i++) {
+ struct folio *folio = page_folio(cc->rpages[i]);
+
if (i < submitted) {
inode_inc_dirty_pages(cc->inode);
- lock_page(cc->rpages[i]);
+ folio_lock(folio);
}
- clear_page_private_gcing(cc->rpages[i]);
- if (folio_test_writeback(page_folio(cc->rpages[i])))
- end_page_writeback(cc->rpages[i]);
+ folio_clear_f2fs_gcing(folio);
+ if (folio_test_writeback(folio))
+ folio_end_writeback(folio);
}
}
@@ -1078,11 +1080,15 @@ static void set_cluster_dirty(struct compress_ctx *cc)
{
int i;
- for (i = 0; i < cc->cluster_size; i++)
- if (cc->rpages[i]) {
- set_page_dirty(cc->rpages[i]);
- set_page_private_gcing(cc->rpages[i]);
- }
+ for (i = 0; i < cc->cluster_size; i++) {
+ struct folio *folio;
+
+ if (!cc->rpages[i])
+ continue;
+ folio = page_folio(cc->rpages[i]);
+ folio_mark_dirty(folio);
+ folio_set_f2fs_gcing(folio);
+ }
}
static int prepare_compress_overwrite(struct compress_ctx *cc,
@@ -1281,7 +1287,7 @@ static int f2fs_write_compressed_pages(struct compress_ctx *cc,
.op = REQ_OP_WRITE,
.op_flags = wbc_to_write_flags(wbc),
.old_blkaddr = NEW_ADDR,
- .page = NULL,
+ .folio = NULL,
.encrypted_page = NULL,
.compressed_page = NULL,
.io_type = io_type,
@@ -1370,7 +1376,7 @@ static int f2fs_write_compressed_pages(struct compress_ctx *cc,
block_t blkaddr;
blkaddr = f2fs_data_blkaddr(&dn);
- fio.page = cc->rpages[i];
+ fio.folio = page_folio(cc->rpages[i]);
fio.old_blkaddr = blkaddr;
/* cluster header */
@@ -1476,9 +1482,12 @@ void f2fs_compress_write_end_io(struct bio *bio, struct folio *folio)
}
for (i = 0; i < cic->nr_rpages; i++) {
+ struct folio *rfolio;
+
WARN_ON(!cic->rpages[i]);
- clear_page_private_gcing(cic->rpages[i]);
- end_page_writeback(cic->rpages[i]);
+ rfolio = page_folio(cic->rpages[i]);
+ folio_clear_f2fs_gcing(rfolio);
+ folio_end_writeback(rfolio);
}
page_array_free(sbi, cic->rpages, cic->nr_rpages);
diff --git a/fs/f2fs/data.c b/fs/f2fs/data.c
index 21f396ebe22ca..ca8232a9095f8 100644
--- a/fs/f2fs/data.c
+++ b/fs/f2fs/data.c
@@ -2923,7 +2923,7 @@ bool f2fs_should_update_outplace(struct inode *inode, struct f2fs_io_info *fio)
return true;
if (fio) {
- if (page_private_gcing(fio->page))
+ if (folio_test_f2fs_gcing(fio->folio))
return true;
if (unlikely(is_sbi_flag_set(sbi, SBI_CP_DISABLED) &&
f2fs_is_checkpointed_data(sbi, fio->old_blkaddr)))
diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h
index 2f7ab5888b078..85937de3d7016 100644
--- a/fs/f2fs/f2fs.h
+++ b/fs/f2fs/f2fs.h
@@ -1357,10 +1357,7 @@ struct f2fs_io_info {
blk_opf_t op_flags; /* req_flag_bits */
block_t new_blkaddr; /* new block address to be written */
block_t old_blkaddr; /* old block address before Cow */
- union {
- struct page *page; /* page to be written */
- struct folio *folio;
- };
+ struct folio *folio; /* folio to be written */
struct page *encrypted_page; /* encrypted page */
struct page *compressed_page; /* compressed page */
struct list_head list; /* serialize IOs */
@@ -1613,27 +1610,27 @@ static inline void f2fs_set_bit(unsigned int nr, char *addr);
static inline void f2fs_clear_bit(unsigned int nr, char *addr);
/*
- * Layout of f2fs page.private:
+ * Layout of f2fs folio->private:
*
* Layout A: lowest bit should be 1
* | bit0 = 1 | bit1 | bit2 | ... | bit MAX | private data .... |
- * bit 0 PAGE_PRIVATE_NOT_POINTER
- * bit 1 PAGE_PRIVATE_ONGOING_MIGRATION
- * bit 2 PAGE_PRIVATE_INLINE_INODE
- * bit 3 PAGE_PRIVATE_REF_RESOURCE
- * bit 4 PAGE_PRIVATE_ATOMIC_WRITE
+ * bit 0 F2FS_FOLIO_PRIVATE_NOT_POINTER
+ * bit 1 F2FS_FOLIO_PRIVATE_ONGOING_MIGRATION
+ * bit 2 F2FS_FOLIO_PRIVATE_INLINE_INODE
+ * bit 3 F2FS_FOLIO_PRIVATE_REF_RESOURCE
+ * bit 4 F2FS_FOLIO_PRIVATE_ATOMIC_WRITE
* bit 5- f2fs private data
*
* Layout B: lowest bit should be 0
- * page.private is a wrapped pointer.
+ * folio->private is a wrapped pointer.
*/
enum {
- PAGE_PRIVATE_NOT_POINTER, /* private contains non-pointer data */
- PAGE_PRIVATE_ONGOING_MIGRATION, /* data page which is on-going migrating */
- PAGE_PRIVATE_INLINE_INODE, /* inode page contains inline data */
- PAGE_PRIVATE_REF_RESOURCE, /* dirty page has referenced resources */
- PAGE_PRIVATE_ATOMIC_WRITE, /* data page from atomic write path */
- PAGE_PRIVATE_MAX
+ F2FS_FOLIO_PRIVATE_NOT_POINTER, /* private contains non-pointer data */
+ F2FS_FOLIO_PRIVATE_ONGOING_MIGRATION, /* data page which is on-going migrating */
+ F2FS_FOLIO_PRIVATE_INLINE_INODE, /* inode page contains inline data */
+ F2FS_FOLIO_PRIVATE_REF_RESOURCE, /* dirty page has referenced resources */
+ F2FS_FOLIO_PRIVATE_ATOMIC_WRITE, /* data page from atomic write path */
+ F2FS_FOLIO_PRIVATE_MAX
};
/* For compression */
@@ -2681,86 +2678,68 @@ static inline int inc_valid_block_count(struct f2fs_sb_info *sbi,
return -ENOSPC;
}
-#define PAGE_PRIVATE_GET_FUNC(name, flagname) \
+#define F2FS_FOLIO_PRIVATE_GET_FUNC(name, flagname) \
static inline bool folio_test_f2fs_##name(const struct folio *folio) \
{ \
unsigned long priv = (unsigned long)folio->private; \
- unsigned long v = (1UL << PAGE_PRIVATE_NOT_POINTER) | \
- (1UL << PAGE_PRIVATE_##flagname); \
+ unsigned long v = (1UL << F2FS_FOLIO_PRIVATE_NOT_POINTER) | \
+ (1UL << F2FS_FOLIO_PRIVATE_##flagname); \
return (priv & v) == v; \
-} \
-static inline bool page_private_##name(struct page *page) \
-{ \
- return page_private(page) && \
- test_bit(PAGE_PRIVATE_NOT_POINTER, &page_private(page)) && \
- test_bit(PAGE_PRIVATE_##flagname, &page_private(page)); \
}
-#define PAGE_PRIVATE_SET_FUNC(name, flagname) \
+#define F2FS_FOLIO_PRIVATE_SET_FUNC(name, flagname) \
static inline void folio_set_f2fs_##name(struct folio *folio) \
{ \
- unsigned long v = (1UL << PAGE_PRIVATE_NOT_POINTER) | \
- (1UL << PAGE_PRIVATE_##flagname); \
+ unsigned long v = (1UL << F2FS_FOLIO_PRIVATE_NOT_POINTER) | \
+ (1UL << F2FS_FOLIO_PRIVATE_##flagname); \
if (!folio->private) \
folio_attach_private(folio, (void *)v); \
else { \
v |= (unsigned long)folio->private; \
folio->private = (void *)v; \
} \
-} \
-static inline void set_page_private_##name(struct page *page) \
-{ \
- if (!page_private(page)) \
- attach_page_private(page, \
- (void *)BIT(PAGE_PRIVATE_NOT_POINTER)); \
- set_bit(PAGE_PRIVATE_##flagname, &page_private(page)); \
}
-#define PAGE_PRIVATE_CLEAR_FUNC(name, flagname) \
+#define F2FS_FOLIO_PRIVATE_CLEAR_FUNC(name, flagname) \
static inline void folio_clear_f2fs_##name(struct folio *folio) \
{ \
unsigned long v = (unsigned long)folio->private; \
\
- v &= ~(1UL << PAGE_PRIVATE_##flagname); \
- if (v == (1UL << PAGE_PRIVATE_NOT_POINTER)) \
+ v &= ~(1UL << F2FS_FOLIO_PRIVATE_##flagname); \
+ if (v == (1UL << F2FS_FOLIO_PRIVATE_NOT_POINTER)) \
folio_detach_private(folio); \
else \
folio->private = (void *)v; \
-} \
-static inline void clear_page_private_##name(struct page *page) \
-{ \
- clear_bit(PAGE_PRIVATE_##flagname, &page_private(page)); \
- if (page_private(page) == BIT(PAGE_PRIVATE_NOT_POINTER)) \
- detach_page_private(page); \
}
-PAGE_PRIVATE_GET_FUNC(nonpointer, NOT_POINTER);
-PAGE_PRIVATE_GET_FUNC(inline, INLINE_INODE);
-PAGE_PRIVATE_GET_FUNC(gcing, ONGOING_MIGRATION);
-PAGE_PRIVATE_GET_FUNC(atomic, ATOMIC_WRITE);
+F2FS_FOLIO_PRIVATE_GET_FUNC(nonpointer, NOT_POINTER);
+F2FS_FOLIO_PRIVATE_GET_FUNC(inline, INLINE_INODE);
+F2FS_FOLIO_PRIVATE_GET_FUNC(gcing, ONGOING_MIGRATION);
+F2FS_FOLIO_PRIVATE_GET_FUNC(atomic, ATOMIC_WRITE);
-PAGE_PRIVATE_SET_FUNC(reference, REF_RESOURCE);
-PAGE_PRIVATE_SET_FUNC(inline, INLINE_INODE);
-PAGE_PRIVATE_SET_FUNC(gcing, ONGOING_MIGRATION);
-PAGE_PRIVATE_SET_FUNC(atomic, ATOMIC_WRITE);
+F2FS_FOLIO_PRIVATE_SET_FUNC(reference, REF_RESOURCE);
+F2FS_FOLIO_PRIVATE_SET_FUNC(inline, INLINE_INODE);
+F2FS_FOLIO_PRIVATE_SET_FUNC(gcing, ONGOING_MIGRATION);
+F2FS_FOLIO_PRIVATE_SET_FUNC(atomic, ATOMIC_WRITE);
-PAGE_PRIVATE_CLEAR_FUNC(reference, REF_RESOURCE);
-PAGE_PRIVATE_CLEAR_FUNC(inline, INLINE_INODE);
-PAGE_PRIVATE_CLEAR_FUNC(gcing, ONGOING_MIGRATION);
-PAGE_PRIVATE_CLEAR_FUNC(atomic, ATOMIC_WRITE);
+F2FS_FOLIO_PRIVATE_CLEAR_FUNC(reference, REF_RESOURCE);
+F2FS_FOLIO_PRIVATE_CLEAR_FUNC(inline, INLINE_INODE);
+F2FS_FOLIO_PRIVATE_CLEAR_FUNC(gcing, ONGOING_MIGRATION);
+F2FS_FOLIO_PRIVATE_CLEAR_FUNC(atomic, ATOMIC_WRITE);
static inline unsigned long folio_get_f2fs_data(struct folio *folio)
{
unsigned long data = (unsigned long)folio->private;
- if (!test_bit(PAGE_PRIVATE_NOT_POINTER, &data))
+ if (!test_bit(F2FS_FOLIO_PRIVATE_NOT_POINTER, &data))
return 0;
- return data >> PAGE_PRIVATE_MAX;
+ return data >> F2FS_FOLIO_PRIVATE_MAX;
}
static inline void folio_set_f2fs_data(struct folio *folio, unsigned long data)
{
- data = (1UL << PAGE_PRIVATE_NOT_POINTER) | (data << PAGE_PRIVATE_MAX);
+ data = (1UL << F2FS_FOLIO_PRIVATE_NOT_POINTER) |
+ (data << F2FS_FOLIO_PRIVATE_MAX);
if (!folio_test_private(folio))
folio_attach_private(folio, (void *)data);
diff --git a/fs/f2fs/segment.c b/fs/f2fs/segment.c
index 63b712d3d599e..8c156e1fd37d0 100644
--- a/fs/f2fs/segment.c
+++ b/fs/f2fs/segment.c
@@ -3803,7 +3803,7 @@ static int __get_segment_type_6(struct f2fs_io_info *fio)
if (is_inode_flag_set(inode, FI_ALIGNED_WRITE))
return CURSEG_COLD_DATA_PINNED;
- if (page_private_gcing(fio->page)) {
+ if (folio_test_f2fs_gcing(fio->folio)) {
if (fio->sbi->am.atgc_enabled &&
(fio->io_type == FS_DATA_IO) &&
(fio->sbi->gc_mode != GC_URGENT_HIGH) &&
--
2.53.0
--
Best Regards,
Yan, Zi
_______________________________________________
Linux-f2fs-devel mailing list
Linux-f2fs-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel
^ permalink raw reply related [flat|nested] 37+ messages in thread* Re: [f2fs-dev] [PATCH v3 06/14] f2fs: stop using PG_private
2026-09-10 21:11 ` Zi Yan via Linux-f2fs-devel
@ 2026-09-13 20:11 ` Tal Zussman
0 siblings, 0 replies; 37+ messages in thread
From: Tal Zussman @ 2026-09-13 20:11 UTC (permalink / raw)
To: Zi Yan, David Hildenbrand (Arm)
Cc: Michal Hocko, Liam R. Howlett, Jaegeuk Kim, Ying Huang, Qi Zheng,
Vlastimil Babka, Alistair Popple, Dev Jain,
Matthew Wilcox (Oracle), Gregory Price, Ryan Roberts, Usama Arif,
linux-f2fs-devel, Baolin Wang, Shakeel Butt, Lorenzo Stoakes,
Suren Baghdasaryan, Barry Song, Kairui Song, linux-mm,
Muchun Song, linux-kernel, Nico Pache, Lance Yang,
Johannes Weiner, Andrew Morton, Mike Rapoport
On 9/10/26 5:11 PM, Zi Yan wrote:
> OK, here is the patch. In addition to David's patch and Tal' suggestion,
> I also
> 1. converted PAGE_PRIVATE_* flags to F2FS_FOLIO_PRIVATE_*,
> 2. converted page/folio union in f2fs_io_info to folio only, since no
> one is using fio->page any more.
>
Nice!
> Let me know your feedback. I will add this to my patch series once you
> are OK with it. Thanks.
>
> From 3bae5c494459b3dd05893df6051e3eb37164f810 Mon Sep 17 00:00:00 2001
> From: Zi Yan <ziy@nvidia.com>
> Date: Thu, 10 Sep 2026 16:42:39 -0400
> Subject: [PATCH] f2fs: convert the ->private flag helpers to folio-only
>
> page-based ->private flag helpers are used in the compression path, where
> large folios are not enabled. They can use folio versions with
> page_folio(). The two remaining users in data.c and segment.c can use
> fio->folio instead of fio->page (two are in a union).
>
> Drop page-based helpers after the conversion and rename
> PAGE_PRIVATE_{GET,SET,CLEAR}_FUNC() and the PAGE_PRIVATE_* flags to
> F2FS_FOLIO_PRIVATE_* to match. Convert the folio/page union from
> f2fs_io_info union to folio only, since no page user is left.
>
> The folio helpers do a plain read-modify-write where the page ones used
> set_bit()/clear_bit(). It is fine because the converted code either holds
> folio lock or, in f2fs_compress_write_end_io(), matches what the
> non-compressed code does in f2fs_write_end_bio().
>
> Assisted-by: Claude:claude-opus-5
> Suggested-by: Tal Zussman <tz2294@columbia.edu>
> Co-developed-by: David Hildenbrand (Arm) <david@kernel.org>
> Signed-off-by: David Hildenbrand (Arm) <david@kernel.org>
> Signed-off-by: Zi Yan <ziy@nvidia.com>
> To: Jaegeuk Kim <jaegeuk@kernel.org>
> To: Chao Yu <chao@kernel.org>
> Cc: linux-f2fs-devel@lists.sourceforge.net
> Cc: linux-kernel@vger.kernel.org
Looks good, so:
Reviewed-by: Tal Zussman <tz2294@columbia.edu>
_______________________________________________
Linux-f2fs-devel mailing list
Linux-f2fs-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel
^ permalink raw reply [flat|nested] 37+ messages in thread
* Re: [f2fs-dev] [PATCH v3 06/14] f2fs: stop using PG_private
2026-09-08 15:47 ` David Hildenbrand (Arm) via Linux-f2fs-devel
2026-09-08 18:20 ` Tal Zussman
@ 2026-09-10 2:41 ` Chao Yu via Linux-f2fs-devel
2026-09-10 7:34 ` David Hildenbrand (Arm) via Linux-f2fs-devel
1 sibling, 1 reply; 37+ messages in thread
From: Chao Yu via Linux-f2fs-devel @ 2026-09-10 2:41 UTC (permalink / raw)
To: David Hildenbrand (Arm), Zi Yan, Matthew Wilcox (Oracle),
Andrew Morton, Muchun Song, Lorenzo Stoakes, Liam R. Howlett,
Vlastimil Babka, Mike Rapoport, Suren Baghdasaryan, Michal Hocko,
Baolin Wang, Nico Pache, Ryan Roberts, Dev Jain, Barry Song,
Lance Yang, Usama Arif, Gregory Price, Ying Huang,
Alistair Popple, Johannes Weiner, Qi Zheng, Shakeel Butt,
Kairui Song
Cc: linux-mm, linux-f2fs-devel, linux-kernel, Jaegeuk Kim
On 9/8/26 23:47, David Hildenbrand (Arm) wrote:
> On 9/8/26 04:56, Zi Yan wrote:
>> f2fs sets its PAGE_PRIVATE_* flags in page->private and checking
>> page->private != NULL is equivalent to checking PG_private. Change
>> PagePrivate() to page_private(). Meanwhile, in set_page_private_##name(),
>> page->private is first set to 0/NULL before an PAGE_PRIVATE_* flag is set,
>> but it can cause confusion when PG_private is removed and
>> page->private != NULL is used instead. Change it to initialize
>> page->private to PAGE_PRIVATE_NOT_POINTER instead and retain the original
>> semantics.
>>
>> It prepares for a future commit that removes PG_private.
>>
>> No functional change intended.
>>
>> Assisted-by: Claude:claude-opus-4-8
>> Assisted-by: Codex:gpt-5
>> To: Jaegeuk Kim <jaegeuk@kernel.org>
>> To: Chao Yu <chao@kernel.org>
>> Cc: linux-f2fs-devel@lists.sourceforge.net
>> Cc: linux-kernel@vger.kernel.org
>> Acked-by: Usama Arif <usama.arif@linux.dev>
>> Acked-by: Chao Yu <chao@kernel.org>
>> Signed-off-by: Zi Yan <ziy@nvidia.com>
>> ---
>> fs/f2fs/f2fs.h | 8 ++++----
>> 1 file changed, 4 insertions(+), 4 deletions(-)
>>
>> diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h
>> index 9940a6cecf1a2..2f7ab5888b078 100644
>> --- a/fs/f2fs/f2fs.h
>> +++ b/fs/f2fs/f2fs.h
>> @@ -2691,7 +2691,7 @@ static inline bool folio_test_f2fs_##name(const struct folio *folio) \
>> } \
>> static inline bool page_private_##name(struct page *page) \
>> { \
>> - return PagePrivate(page) && \
>> + return page_private(page) && \
>> test_bit(PAGE_PRIVATE_NOT_POINTER, &page_private(page)) && \
>> test_bit(PAGE_PRIVATE_##flagname, &page_private(page)); \
>> }
>> @@ -2710,9 +2710,9 @@ static inline void folio_set_f2fs_##name(struct folio *folio) \
>> } \
>> static inline void set_page_private_##name(struct page *page) \
>> { \
>> - if (!PagePrivate(page)) \
>> - attach_page_private(page, (void *)0); \
>> - set_bit(PAGE_PRIVATE_NOT_POINTER, &page_private(page)); \
>> + if (!page_private(page)) \
>> + attach_page_private(page, \
>> + (void *)BIT(PAGE_PRIVATE_NOT_POINTER)); \
>> set_bit(PAGE_PRIVATE_##flagname, &page_private(page)); \
>> }
>
> Very weird interface. Why do we even need the page-based interface still?
>
> $ git grep -E "(set|clear)_page_private"
> compress.c: clear_page_private_gcing(cc->rpages[i]);
> compress.c: set_page_private_gcing(cc->rpages[i]);
> compress.c: clear_page_private_gcing(cic->rpages[i]);
> f2fs.h:static inline void set_page_private_##name(struct page *page) \
> f2fs.h:static inline void clear_page_private_##name(struct page *page) \
>
> Seeing code like:
>
> clear_page_private_gcing(cc->rpages[i]);
> if (folio_test_writeback(page_folio(cc->rpages[i])))
> end_page_writeback(cc->rpages[i]);
>
> Makes me wonder whether we can just use the folio helper instead?
>
> In f2fs_iget(), we enable large folios only when !f2fs_compressed_file(inode).
>
> So naive me would assume that we can just get rid of the
> set_page_private_/clear_page_private_ stuff entirely.
David,
Thanks for the patch, at a glance, it seems fine, can you please send
a formal patch? then we can apply to dev-test for test.
Thanks,
>
> IOW something like:
>
>
> From efcde918178604de11d16c6dc5485542ab4dcdaf Mon Sep 17 00:00:00 2001
> From: "David Hildenbrand (Arm)" <david@kernel.org>
> Date: Tue, 8 Sep 2026 17:46:06 +0200
> Subject: [PATCH] tmp
>
> Signed-off-by: David Hildenbrand (Arm) <david@kernel.org>
> ---
> fs/f2fs/compress.c | 29 ++++++++++++++++++-----------
> fs/f2fs/f2fs.h | 13 -------------
> 2 files changed, 18 insertions(+), 24 deletions(-)
>
> diff --git a/fs/f2fs/compress.c b/fs/f2fs/compress.c
> index ce88092d9ce26..0e9cc0fa297a4 100644
> --- a/fs/f2fs/compress.c
> +++ b/fs/f2fs/compress.c
> @@ -1064,13 +1064,15 @@ static void cancel_cluster_writeback(struct compress_ctx *cc,
>
> /* Cancel writeback and stay locked. */
> for (i = 0; i < cc->cluster_size; i++) {
> + struct folio *folio = page_folio(cc->rpages[i]);
> +
> if (i < submitted) {
> inode_inc_dirty_pages(cc->inode);
> - lock_page(cc->rpages[i]);
> + folio_lock(folio);
> }
> - clear_page_private_gcing(cc->rpages[i]);
> - if (folio_test_writeback(page_folio(cc->rpages[i])))
> - end_page_writeback(cc->rpages[i]);
> + folio_clear_f2fs_gcing(folio);
> + if (folio_test_writeback(folio))
> + folio_end_writeback(folio);
> }
> }
>
> @@ -1078,11 +1080,15 @@ static void set_cluster_dirty(struct compress_ctx *cc)
> {
> int i;
>
> - for (i = 0; i < cc->cluster_size; i++)
> - if (cc->rpages[i]) {
> - set_page_dirty(cc->rpages[i]);
> - set_page_private_gcing(cc->rpages[i]);
> - }
> + for (i = 0; i < cc->cluster_size; i++) {
> + struct folio *folio;
> +
> + if (!cc->rpages[i])
> + continue;
> + folio = page_folio(cc->rpages[i]);
> + folio_mark_dirty(folio);
> + folio_set_f2fs_gcing(folio);
> + }
> }
>
> static int prepare_compress_overwrite(struct compress_ctx *cc,
> @@ -1477,8 +1483,9 @@ void f2fs_compress_write_end_io(struct bio *bio, struct folio *folio)
>
> for (i = 0; i < cic->nr_rpages; i++) {
> WARN_ON(!cic->rpages[i]);
> - clear_page_private_gcing(cic->rpages[i]);
> - end_page_writeback(cic->rpages[i]);
> + folio = page_folio(cic->rpages[i]);
> + folio_clear_f2fs_gcing(folio);
> + folio_end_writeback(folio);
> }
>
> page_array_free(sbi, cic->rpages, cic->nr_rpages);
> diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h
> index 9940a6cecf1a2..0cfba8742d4b4 100644
> --- a/fs/f2fs/f2fs.h
> +++ b/fs/f2fs/f2fs.h
> @@ -2707,13 +2707,6 @@ static inline void folio_set_f2fs_##name(struct folio *folio) \
> v |= (unsigned long)folio->private; \
> folio->private = (void *)v; \
> } \
> -} \
> -static inline void set_page_private_##name(struct page *page) \
> -{ \
> - if (!PagePrivate(page)) \
> - attach_page_private(page, (void *)0); \
> - set_bit(PAGE_PRIVATE_NOT_POINTER, &page_private(page)); \
> - set_bit(PAGE_PRIVATE_##flagname, &page_private(page)); \
> }
>
> #define PAGE_PRIVATE_CLEAR_FUNC(name, flagname) \
> @@ -2726,12 +2719,6 @@ static inline void folio_clear_f2fs_##name(struct folio *folio) \
> folio_detach_private(folio); \
> else \
> folio->private = (void *)v; \
> -} \
> -static inline void clear_page_private_##name(struct page *page) \
> -{ \
> - clear_bit(PAGE_PRIVATE_##flagname, &page_private(page)); \
> - if (page_private(page) == BIT(PAGE_PRIVATE_NOT_POINTER)) \
> - detach_page_private(page); \
> }
>
> PAGE_PRIVATE_GET_FUNC(nonpointer, NOT_POINTER);
_______________________________________________
Linux-f2fs-devel mailing list
Linux-f2fs-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel
^ permalink raw reply [flat|nested] 37+ messages in thread* Re: [f2fs-dev] [PATCH v3 06/14] f2fs: stop using PG_private
2026-09-10 2:41 ` Chao Yu via Linux-f2fs-devel
@ 2026-09-10 7:34 ` David Hildenbrand (Arm) via Linux-f2fs-devel
2026-09-10 8:43 ` Chao Yu via Linux-f2fs-devel
0 siblings, 1 reply; 37+ messages in thread
From: David Hildenbrand (Arm) via Linux-f2fs-devel @ 2026-09-10 7:34 UTC (permalink / raw)
To: Chao Yu, Zi Yan, Matthew Wilcox (Oracle), Andrew Morton,
Muchun Song, Lorenzo Stoakes, Liam R. Howlett, Vlastimil Babka,
Mike Rapoport, Suren Baghdasaryan, Michal Hocko, Baolin Wang,
Nico Pache, Ryan Roberts, Dev Jain, Barry Song, Lance Yang,
Usama Arif, Gregory Price, Ying Huang, Alistair Popple,
Johannes Weiner, Qi Zheng, Shakeel Butt, Kairui Song
Cc: linux-mm, linux-f2fs-devel, linux-kernel, Jaegeuk Kim
On 9/10/26 04:41, Chao Yu wrote:
> On 9/8/26 23:47, David Hildenbrand (Arm) wrote:
>> On 9/8/26 04:56, Zi Yan wrote:
>>> f2fs sets its PAGE_PRIVATE_* flags in page->private and checking
>>> page->private != NULL is equivalent to checking PG_private. Change
>>> PagePrivate() to page_private(). Meanwhile, in set_page_private_##name(),
>>> page->private is first set to 0/NULL before an PAGE_PRIVATE_* flag is set,
>>> but it can cause confusion when PG_private is removed and
>>> page->private != NULL is used instead. Change it to initialize
>>> page->private to PAGE_PRIVATE_NOT_POINTER instead and retain the original
>>> semantics.
>>>
>>> It prepares for a future commit that removes PG_private.
>>>
>>> No functional change intended.
>>>
>>> Assisted-by: Claude:claude-opus-4-8
>>> Assisted-by: Codex:gpt-5
>>> To: Jaegeuk Kim <jaegeuk@kernel.org>
>>> To: Chao Yu <chao@kernel.org>
>>> Cc: linux-f2fs-devel@lists.sourceforge.net
>>> Cc: linux-kernel@vger.kernel.org
>>> Acked-by: Usama Arif <usama.arif@linux.dev>
>>> Acked-by: Chao Yu <chao@kernel.org>
>>> Signed-off-by: Zi Yan <ziy@nvidia.com>
>>> ---
>>> fs/f2fs/f2fs.h | 8 ++++----
>>> 1 file changed, 4 insertions(+), 4 deletions(-)
>>>
>>> diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h
>>> index 9940a6cecf1a2..2f7ab5888b078 100644
>>> --- a/fs/f2fs/f2fs.h
>>> +++ b/fs/f2fs/f2fs.h
>>> @@ -2691,7 +2691,7 @@ static inline bool folio_test_f2fs_##name(const struct folio *folio) \
>>> } \
>>> static inline bool page_private_##name(struct page *page) \
>>> { \
>>> - return PagePrivate(page) && \
>>> + return page_private(page) && \
>>> test_bit(PAGE_PRIVATE_NOT_POINTER, &page_private(page)) && \
>>> test_bit(PAGE_PRIVATE_##flagname, &page_private(page)); \
>>> }
>>> @@ -2710,9 +2710,9 @@ static inline void folio_set_f2fs_##name(struct folio *folio) \
>>> } \
>>> static inline void set_page_private_##name(struct page *page) \
>>> { \
>>> - if (!PagePrivate(page)) \
>>> - attach_page_private(page, (void *)0); \
>>> - set_bit(PAGE_PRIVATE_NOT_POINTER, &page_private(page)); \
>>> + if (!page_private(page)) \
>>> + attach_page_private(page, \
>>> + (void *)BIT(PAGE_PRIVATE_NOT_POINTER)); \
>>> set_bit(PAGE_PRIVATE_##flagname, &page_private(page)); \
>>> }
>>
>> Very weird interface. Why do we even need the page-based interface still?
>>
>> $ git grep -E "(set|clear)_page_private"
>> compress.c: clear_page_private_gcing(cc->rpages[i]);
>> compress.c: set_page_private_gcing(cc->rpages[i]);
>> compress.c: clear_page_private_gcing(cic->rpages[i]);
>> f2fs.h:static inline void set_page_private_##name(struct page *page) \
>> f2fs.h:static inline void clear_page_private_##name(struct page *page) \
>>
>> Seeing code like:
>>
>> clear_page_private_gcing(cc->rpages[i]);
>> if (folio_test_writeback(page_folio(cc->rpages[i])))
>> end_page_writeback(cc->rpages[i]);
>>
>> Makes me wonder whether we can just use the folio helper instead?
>>
>> In f2fs_iget(), we enable large folios only when !f2fs_compressed_file(inode).
>>
>> So naive me would assume that we can just get rid of the
>> set_page_private_/clear_page_private_ stuff entirely.
>
> David,
>
> Thanks for the patch, at a glance, it seems fine, can you please send
> a formal patch? then we can apply to dev-test for test.
I'm hoping Zi will drag that along as part of this patch set. Is this fine or do
you want it sent as a complete standalone patch (will make merging Zi's series
slightly more complicated :) ).
--
Cheers,
David
_______________________________________________
Linux-f2fs-devel mailing list
Linux-f2fs-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel
^ permalink raw reply [flat|nested] 37+ messages in thread* Re: [f2fs-dev] [PATCH v3 06/14] f2fs: stop using PG_private
2026-09-10 7:34 ` David Hildenbrand (Arm) via Linux-f2fs-devel
@ 2026-09-10 8:43 ` Chao Yu via Linux-f2fs-devel
2026-09-10 9:15 ` David Hildenbrand (Arm) via Linux-f2fs-devel
0 siblings, 1 reply; 37+ messages in thread
From: Chao Yu via Linux-f2fs-devel @ 2026-09-10 8:43 UTC (permalink / raw)
To: David Hildenbrand (Arm), Zi Yan, Matthew Wilcox (Oracle),
Andrew Morton, Muchun Song, Lorenzo Stoakes, Liam R. Howlett,
Vlastimil Babka, Mike Rapoport, Suren Baghdasaryan, Michal Hocko,
Baolin Wang, Nico Pache, Ryan Roberts, Dev Jain, Barry Song,
Lance Yang, Usama Arif, Gregory Price, Ying Huang,
Alistair Popple, Johannes Weiner, Qi Zheng, Shakeel Butt,
Kairui Song
Cc: linux-mm, linux-f2fs-devel, linux-kernel, Jaegeuk Kim
On 9/10/26 15:34, David Hildenbrand (Arm) wrote:
> On 9/10/26 04:41, Chao Yu wrote:
>> On 9/8/26 23:47, David Hildenbrand (Arm) wrote:
>>> On 9/8/26 04:56, Zi Yan wrote:
>>>> f2fs sets its PAGE_PRIVATE_* flags in page->private and checking
>>>> page->private != NULL is equivalent to checking PG_private. Change
>>>> PagePrivate() to page_private(). Meanwhile, in set_page_private_##name(),
>>>> page->private is first set to 0/NULL before an PAGE_PRIVATE_* flag is set,
>>>> but it can cause confusion when PG_private is removed and
>>>> page->private != NULL is used instead. Change it to initialize
>>>> page->private to PAGE_PRIVATE_NOT_POINTER instead and retain the original
>>>> semantics.
>>>>
>>>> It prepares for a future commit that removes PG_private.
>>>>
>>>> No functional change intended.
>>>>
>>>> Assisted-by: Claude:claude-opus-4-8
>>>> Assisted-by: Codex:gpt-5
>>>> To: Jaegeuk Kim <jaegeuk@kernel.org>
>>>> To: Chao Yu <chao@kernel.org>
>>>> Cc: linux-f2fs-devel@lists.sourceforge.net
>>>> Cc: linux-kernel@vger.kernel.org
>>>> Acked-by: Usama Arif <usama.arif@linux.dev>
>>>> Acked-by: Chao Yu <chao@kernel.org>
>>>> Signed-off-by: Zi Yan <ziy@nvidia.com>
>>>> ---
>>>> fs/f2fs/f2fs.h | 8 ++++----
>>>> 1 file changed, 4 insertions(+), 4 deletions(-)
>>>>
>>>> diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h
>>>> index 9940a6cecf1a2..2f7ab5888b078 100644
>>>> --- a/fs/f2fs/f2fs.h
>>>> +++ b/fs/f2fs/f2fs.h
>>>> @@ -2691,7 +2691,7 @@ static inline bool folio_test_f2fs_##name(const struct folio *folio) \
>>>> } \
>>>> static inline bool page_private_##name(struct page *page) \
>>>> { \
>>>> - return PagePrivate(page) && \
>>>> + return page_private(page) && \
>>>> test_bit(PAGE_PRIVATE_NOT_POINTER, &page_private(page)) && \
>>>> test_bit(PAGE_PRIVATE_##flagname, &page_private(page)); \
>>>> }
>>>> @@ -2710,9 +2710,9 @@ static inline void folio_set_f2fs_##name(struct folio *folio) \
>>>> } \
>>>> static inline void set_page_private_##name(struct page *page) \
>>>> { \
>>>> - if (!PagePrivate(page)) \
>>>> - attach_page_private(page, (void *)0); \
>>>> - set_bit(PAGE_PRIVATE_NOT_POINTER, &page_private(page)); \
>>>> + if (!page_private(page)) \
>>>> + attach_page_private(page, \
>>>> + (void *)BIT(PAGE_PRIVATE_NOT_POINTER)); \
>>>> set_bit(PAGE_PRIVATE_##flagname, &page_private(page)); \
>>>> }
>>>
>>> Very weird interface. Why do we even need the page-based interface still?
>>>
>>> $ git grep -E "(set|clear)_page_private"
>>> compress.c: clear_page_private_gcing(cc->rpages[i]);
>>> compress.c: set_page_private_gcing(cc->rpages[i]);
>>> compress.c: clear_page_private_gcing(cic->rpages[i]);
>>> f2fs.h:static inline void set_page_private_##name(struct page *page) \
>>> f2fs.h:static inline void clear_page_private_##name(struct page *page) \
>>>
>>> Seeing code like:
>>>
>>> clear_page_private_gcing(cc->rpages[i]);
>>> if (folio_test_writeback(page_folio(cc->rpages[i])))
>>> end_page_writeback(cc->rpages[i]);
>>>
>>> Makes me wonder whether we can just use the folio helper instead?
>>>
>>> In f2fs_iget(), we enable large folios only when !f2fs_compressed_file(inode).
>>>
>>> So naive me would assume that we can just get rid of the
>>> set_page_private_/clear_page_private_ stuff entirely.
>>
>> David,
>>
>> Thanks for the patch, at a glance, it seems fine, can you please send
>> a formal patch? then we can apply to dev-test for test.
>
> I'm hoping Zi will drag that along as part of this patch set. Is this fine or do
Oh, I see.
> you want it sent as a complete standalone patch (will make merging Zi's series
> slightly more complicated :) ).
I think sending as a separated patch based on Zi Yan's patch is fine, since the
purpose of this patch is a little different from Zi's one.
Note that: ("f2fs: stop using PG_private") has been merged in
https://git.kernel.org/pub/scm/linux/kernel/git/jaegeuk/f2fs.git/log/?h=dev-test,
Thanks,
_______________________________________________
Linux-f2fs-devel mailing list
Linux-f2fs-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel
^ permalink raw reply [flat|nested] 37+ messages in thread* Re: [f2fs-dev] [PATCH v3 06/14] f2fs: stop using PG_private
2026-09-10 8:43 ` Chao Yu via Linux-f2fs-devel
@ 2026-09-10 9:15 ` David Hildenbrand (Arm) via Linux-f2fs-devel
2026-09-10 14:15 ` Chao Yu via Linux-f2fs-devel
0 siblings, 1 reply; 37+ messages in thread
From: David Hildenbrand (Arm) via Linux-f2fs-devel @ 2026-09-10 9:15 UTC (permalink / raw)
To: Chao Yu, Zi Yan, Matthew Wilcox (Oracle), Andrew Morton,
Muchun Song, Lorenzo Stoakes, Liam R. Howlett, Vlastimil Babka,
Mike Rapoport, Suren Baghdasaryan, Michal Hocko, Baolin Wang,
Nico Pache, Ryan Roberts, Dev Jain, Barry Song, Lance Yang,
Usama Arif, Gregory Price, Ying Huang, Alistair Popple,
Johannes Weiner, Qi Zheng, Shakeel Butt, Kairui Song
Cc: linux-mm, linux-f2fs-devel, linux-kernel, Jaegeuk Kim
On 9/10/26 10:43, Chao Yu wrote:
> On 9/10/26 15:34, David Hildenbrand (Arm) wrote:
>> On 9/10/26 04:41, Chao Yu wrote:
>>>
>>> David,
>>>
>>> Thanks for the patch, at a glance, it seems fine, can you please send
>>> a formal patch? then we can apply to dev-test for test.
>>
>> I'm hoping Zi will drag that along as part of this patch set. Is this fine or do
>
> Oh, I see.
>
>> you want it sent as a complete standalone patch (will make merging Zi's series
>> slightly more complicated :) ).
>
> I think sending as a separated patch based on Zi Yan's patch is fine, since the
> purpose of this patch is a little different from Zi's one.
I'd prefer this patch over of Zi's patch.
>
> Note that: ("f2fs: stop using PG_private") has been merged in
> https://git.kernel.org/pub/scm/linux/kernel/git/jaegeuk/f2fs.git/log/?h=dev-test
That just a testing branch, right?
--
Cheers,
David
_______________________________________________
Linux-f2fs-devel mailing list
Linux-f2fs-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel
^ permalink raw reply [flat|nested] 37+ messages in thread* Re: [f2fs-dev] [PATCH v3 06/14] f2fs: stop using PG_private
2026-09-10 9:15 ` David Hildenbrand (Arm) via Linux-f2fs-devel
@ 2026-09-10 14:15 ` Chao Yu via Linux-f2fs-devel
0 siblings, 0 replies; 37+ messages in thread
From: Chao Yu via Linux-f2fs-devel @ 2026-09-10 14:15 UTC (permalink / raw)
To: David Hildenbrand (Arm), Zi Yan, Matthew Wilcox (Oracle),
Andrew Morton, Muchun Song, Lorenzo Stoakes, Liam R. Howlett,
Vlastimil Babka, Mike Rapoport, Suren Baghdasaryan, Michal Hocko,
Baolin Wang, Nico Pache, Ryan Roberts, Dev Jain, Barry Song,
Lance Yang, Usama Arif, Gregory Price, Ying Huang,
Alistair Popple, Johannes Weiner, Qi Zheng, Shakeel Butt,
Kairui Song
Cc: linux-mm, linux-f2fs-devel, linux-kernel, Jaegeuk Kim
On 9/10/26 17:15, David Hildenbrand (Arm) wrote:
> On 9/10/26 10:43, Chao Yu wrote:
>> On 9/10/26 15:34, David Hildenbrand (Arm) wrote:
>>> On 9/10/26 04:41, Chao Yu wrote:
>>>>
>>>> David,
>>>>
>>>> Thanks for the patch, at a glance, it seems fine, can you please send
>>>> a formal patch? then we can apply to dev-test for test.
>>>
>>> I'm hoping Zi will drag that along as part of this patch set. Is this fine or do
>>
>> Oh, I see.
>>
>>> you want it sent as a complete standalone patch (will make merging Zi's series
>>> slightly more complicated :) ).
>>
>> I think sending as a separated patch based on Zi Yan's patch is fine, since the
>> purpose of this patch is a little different from Zi's one.
>
> I'd prefer this patch over of Zi's patch.
>
>>
>> Note that: ("f2fs: stop using PG_private") has been merged in
>> https://git.kernel.org/pub/scm/linux/kernel/git/jaegeuk/f2fs.git/log/?h=dev-test
> That just a testing branch, right?
Yes, if necessary we can append the new patch based on this branch. :)
Thanks,
_______________________________________________
Linux-f2fs-devel mailing list
Linux-f2fs-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel
^ permalink raw reply [flat|nested] 37+ messages in thread
* [PATCH v3 07/14] erofs: mm/pagemap: add readahead_folio_last() to avoid folio->private
2026-09-08 2:56 ` [f2fs-dev] " Zi Yan via Linux-f2fs-devel
` (2 preceding siblings ...)
(?)
@ 2026-09-08 2:56 ` Zi Yan
2026-09-08 16:04 ` David Hildenbrand (Arm)
-1 siblings, 1 reply; 37+ messages in thread
From: Zi Yan @ 2026-09-08 2:56 UTC (permalink / raw)
To: David Hildenbrand, Matthew Wilcox (Oracle), Andrew Morton,
Muchun Song, Lorenzo Stoakes, Liam R. Howlett, Vlastimil Babka,
Mike Rapoport, Suren Baghdasaryan, Michal Hocko, Baolin Wang,
Nico Pache, Ryan Roberts, Dev Jain, Barry Song, Lance Yang,
Usama Arif, Gregory Price, Ying Huang, Alistair Popple,
Johannes Weiner, Qi Zheng, Shakeel Butt, Kairui Song
Cc: linux-mm, linux-kernel, Zi Yan, Gao Xiang, Chao Yu, Jan Kara,
Yue Hu, Jeffle Xu, Sandeep Dhavale, Hongbo Li, Chunhai Guo,
linux-erofs, linux-fsdevel
erofs needs to traverse readahead folios in reverse order to achieve
maximum performance by
1. reading all folios from readahead_folio();
2. storing the prior folio pointer in folio->private;
3. traverse from the last folio to the first one.
Add readahead_folio_last() to achieve the same function without using
folio->private. __readahead_advance() helper shares readahead_control
adjustment code among __readahead_folio(), readahead_folio_last(), and
__readahead_batch() by checking new private member, _forward, of
readahead_control.
It prepares for a future commit that replaces PG_private checks with
!folio->private checks. After switching the checks, erofs's use of
folio->private without bumping folio refcount can cause unexpected
outcomes, e.g., in filemap_release_folio(), try_to_free_buffers() becomes
reachable.
No functional change intended.
Assisted-by: Claude:claude-opus-4-8
Assisted-by: Codex:gpt-5
Signed-off-by: Zi Yan <ziy@nvidia.com>
To: Gao Xiang <xiang@kernel.org>
To: Chao Yu <chao@kernel.org>
To: "Matthew Wilcox (Oracle)" <willy@infradead.org>
To: Jan Kara <jack@suse.cz>
Cc: Yue Hu <zbestahu@gmail.com>
Cc: Jeffle Xu <jefflexu@linux.alibaba.com>
Cc: Sandeep Dhavale <dhavale@google.com>
Cc: Hongbo Li <hongbohbli@tencent.com>
Cc: Chunhai Guo <guochunhai@vivo.com>
Cc: linux-erofs@lists.ozlabs.org
Cc: linux-kernel@vger.kernel.org
Cc: linux-fsdevel@vger.kernel.org
Cc: linux-mm@kvack.org
---
fs/erofs/zdata.c | 13 +++---------
include/linux/pagemap.h | 56 ++++++++++++++++++++++++++++++++++++++++++-------
2 files changed, 51 insertions(+), 18 deletions(-)
diff --git a/fs/erofs/zdata.c b/fs/erofs/zdata.c
index e1e25ca0d1904..78fd7d980e957 100644
--- a/fs/erofs/zdata.c
+++ b/fs/erofs/zdata.c
@@ -1898,21 +1898,14 @@ static void z_erofs_readahead(struct readahead_control *rac)
struct inode *realinode = erofs_real_inode(sharedinode, &need_iput);
Z_EROFS_DEFINE_FRONTEND(f, realinode, sharedinode, readahead_pos(rac));
unsigned int nrpages = readahead_count(rac);
- struct folio *head = NULL, *folio;
+ struct folio *folio;
int err;
trace_erofs_readahead(realinode, readahead_index(rac), nrpages, false);
z_erofs_pcluster_readmore(&f, rac, true);
- while ((folio = readahead_folio(rac))) {
- folio->private = head;
- head = folio;
- }
-
- /* traverse in reverse order for best metadata I/O performance */
- while (head) {
- folio = head;
- head = folio_get_private(folio);
+ /* traverse from last to first for best metadata I/O performance */
+ while ((folio = readahead_folio_last(rac))) {
err = z_erofs_scan_folio(&f, folio, true);
if (err && err != -EINTR)
erofs_err(realinode->i_sb, "readahead error at folio %lu @ nid %llu",
diff --git a/include/linux/pagemap.h b/include/linux/pagemap.h
index 939f3a5e973f6..2257df004305e 100644
--- a/include/linux/pagemap.h
+++ b/include/linux/pagemap.h
@@ -1415,6 +1415,7 @@ struct readahead_control {
bool dropbehind;
bool _workingset;
unsigned long _pflags;
+ bool _forward;
};
#define DEFINE_READAHEAD(ractl, f, r, m, i) \
@@ -1479,18 +1480,25 @@ void page_cache_async_readahead(struct address_space *mapping,
page_cache_async_ra(&ractl, folio, req_count);
}
+static inline void __readahead_advance(struct readahead_control *rac)
+{
+ if (rac->_forward)
+ rac->_index += rac->_batch_count;
+
+ rac->_nr_pages -= rac->_batch_count;
+ rac->_batch_count = 0;
+}
+
static inline struct folio *__readahead_folio(struct readahead_control *ractl)
{
struct folio *folio;
BUG_ON(ractl->_batch_count > ractl->_nr_pages);
- ractl->_nr_pages -= ractl->_batch_count;
- ractl->_index += ractl->_batch_count;
+ __readahead_advance(ractl);
+ ractl->_forward = true;
- if (!ractl->_nr_pages) {
- ractl->_batch_count = 0;
+ if (!ractl->_nr_pages)
return NULL;
- }
folio = xa_load(&ractl->mapping->i_pages, ractl->_index);
VM_BUG_ON_FOLIO(!folio_test_locked(folio), folio);
@@ -1516,6 +1524,39 @@ static inline struct folio *readahead_folio(struct readahead_control *ractl)
return folio;
}
+/**
+ * readahead_folio_last - Get the next folio to read, from the tail.
+ * @ractl: The current readahead request.
+ *
+ * Like readahead_folio(), but walks the range back-to-front. The folio is
+ * returned locked with its refcount dropped; the caller unlocks it once I/O
+ * completes. Compound folios are returned once, at their head index.
+ *
+ * Context: The folio is locked.
+ * Return: A pointer to the next folio, or %NULL when done.
+ */
+static inline struct folio *readahead_folio_last(struct readahead_control *ractl)
+{
+ struct folio *folio;
+
+ /* Drop the previously returned batch from the remaining range. */
+ __readahead_advance(ractl);
+ ractl->_forward = false;
+
+ if (!ractl->_nr_pages)
+ return NULL;
+
+ /* xa_load() follows sibling entries, so a tail index returns the head */
+ folio = xa_load(&ractl->mapping->i_pages,
+ ractl->_index + ractl->_nr_pages - 1);
+ VM_WARN_ON_ONCE_FOLIO(!folio_test_locked(folio), folio);
+
+ ractl->_batch_count = folio_nr_pages(folio);
+
+ folio_put(folio);
+ return folio;
+}
+
static inline unsigned int __readahead_batch(struct readahead_control *rac,
struct page **array, unsigned int array_sz)
{
@@ -1524,9 +1565,8 @@ static inline unsigned int __readahead_batch(struct readahead_control *rac,
struct folio *folio;
BUG_ON(rac->_batch_count > rac->_nr_pages);
- rac->_nr_pages -= rac->_batch_count;
- rac->_index += rac->_batch_count;
- rac->_batch_count = 0;
+ __readahead_advance(rac);
+ rac->_forward = true;
xas_set(&xas, rac->_index);
rcu_read_lock();
--
2.53.0
^ permalink raw reply related [flat|nested] 37+ messages in thread* Re: [PATCH v3 07/14] erofs: mm/pagemap: add readahead_folio_last() to avoid folio->private
2026-09-08 2:56 ` [PATCH v3 07/14] erofs: mm/pagemap: add readahead_folio_last() to avoid folio->private Zi Yan
@ 2026-09-08 16:04 ` David Hildenbrand (Arm)
2026-09-08 17:05 ` Zi Yan
0 siblings, 1 reply; 37+ messages in thread
From: David Hildenbrand (Arm) @ 2026-09-08 16:04 UTC (permalink / raw)
To: Zi Yan, Matthew Wilcox (Oracle), Andrew Morton, Muchun Song,
Lorenzo Stoakes, Liam R. Howlett, Vlastimil Babka, Mike Rapoport,
Suren Baghdasaryan, Michal Hocko, Baolin Wang, Nico Pache,
Ryan Roberts, Dev Jain, Barry Song, Lance Yang, Usama Arif,
Gregory Price, Ying Huang, Alistair Popple, Johannes Weiner,
Qi Zheng, Shakeel Butt, Kairui Song
Cc: linux-mm, linux-kernel, Gao Xiang, Chao Yu, Jan Kara, Yue Hu,
Jeffle Xu, Sandeep Dhavale, Hongbo Li, Chunhai Guo, linux-erofs,
linux-fsdevel
On 9/8/26 04:56, Zi Yan wrote:
> erofs needs to traverse readahead folios in reverse order to achieve
> maximum performance by
> 1. reading all folios from readahead_folio();
> 2. storing the prior folio pointer in folio->private;
> 3. traverse from the last folio to the first one.
>
> Add readahead_folio_last() to achieve the same function without using
> folio->private. __readahead_advance() helper shares readahead_control
> adjustment code among __readahead_folio(), readahead_folio_last(), and
> __readahead_batch() by checking new private member, _forward, of
> readahead_control.
>
> It prepares for a future commit that replaces PG_private checks with
> !folio->private checks. After switching the checks, erofs's use of
> folio->private without bumping folio refcount can cause unexpected
> outcomes, e.g., in filemap_release_folio(), try_to_free_buffers() becomes
> reachable.
Ah, I was just about to ask. So it's really about folios never using
folio->private manually (without the attach/detach).
>
> No functional change intended.
>
> Assisted-by: Claude:claude-opus-4-8
> Assisted-by: Codex:gpt-5
> Signed-off-by: Zi Yan <ziy@nvidia.com>
> To: Gao Xiang <xiang@kernel.org>
> To: Chao Yu <chao@kernel.org>
> To: "Matthew Wilcox (Oracle)" <willy@infradead.org>
> To: Jan Kara <jack@suse.cz>
> Cc: Yue Hu <zbestahu@gmail.com>
> Cc: Jeffle Xu <jefflexu@linux.alibaba.com>
> Cc: Sandeep Dhavale <dhavale@google.com>
> Cc: Hongbo Li <hongbohbli@tencent.com>
> Cc: Chunhai Guo <guochunhai@vivo.com>
> Cc: linux-erofs@lists.ozlabs.org
> Cc: linux-kernel@vger.kernel.org
> Cc: linux-fsdevel@vger.kernel.org
> Cc: linux-mm@kvack.org
> ---
> fs/erofs/zdata.c | 13 +++---------
> include/linux/pagemap.h | 56 ++++++++++++++++++++++++++++++++++++++++++-------
> 2 files changed, 51 insertions(+), 18 deletions(-)
>
> diff --git a/fs/erofs/zdata.c b/fs/erofs/zdata.c
> index e1e25ca0d1904..78fd7d980e957 100644
> --- a/fs/erofs/zdata.c
> +++ b/fs/erofs/zdata.c
> @@ -1898,21 +1898,14 @@ static void z_erofs_readahead(struct readahead_control *rac)
> struct inode *realinode = erofs_real_inode(sharedinode, &need_iput);
> Z_EROFS_DEFINE_FRONTEND(f, realinode, sharedinode, readahead_pos(rac));
> unsigned int nrpages = readahead_count(rac);
> - struct folio *head = NULL, *folio;
> + struct folio *folio;
> int err;
>
> trace_erofs_readahead(realinode, readahead_index(rac), nrpages, false);
> z_erofs_pcluster_readmore(&f, rac, true);
> - while ((folio = readahead_folio(rac))) {
> - folio->private = head;
> - head = folio;
> - }
> -
> - /* traverse in reverse order for best metadata I/O performance */
> - while (head) {
> - folio = head;
> - head = folio_get_private(folio);
>
> + /* traverse from last to first for best metadata I/O performance */
> + while ((folio = readahead_folio_last(rac))) {
Intuitively, this should be called readahead_folio_reverse /
readahead_folio_reversed, thinking of list_for_each_entry_reverse()?
list_for_each_entry_reverse - iterate backwards over list of given type.
or maybe readahead_folio_backwards (which matches the forward below)
But I'm not a readahead expert :)
> err = z_erofs_scan_folio(&f, folio, true);
> if (err && err != -EINTR)
> erofs_err(realinode->i_sb, "readahead error at folio %lu @ nid %llu",
> diff --git a/include/linux/pagemap.h b/include/linux/pagemap.h
> index 939f3a5e973f6..2257df004305e 100644
> --- a/include/linux/pagemap.h
> +++ b/include/linux/pagemap.h
> @@ -1415,6 +1415,7 @@ struct readahead_control {
> bool dropbehind;
> bool _workingset;
> unsigned long _pflags;
> + bool _forward;
> };
>
> #define DEFINE_READAHEAD(ractl, f, r, m, i) \
> @@ -1479,18 +1480,25 @@ void page_cache_async_readahead(struct address_space *mapping,
> page_cache_async_ra(&ractl, folio, req_count);
> }
>
> +static inline void __readahead_advance(struct readahead_control *rac)
> +{
> + if (rac->_forward)
> + rac->_index += rac->_batch_count;
No expert, but shouldn't we decrement the _index somewhere in the other case? Or
where is that done? A comment might help :)
--
Cheers,
David
^ permalink raw reply [flat|nested] 37+ messages in thread* Re: [PATCH v3 07/14] erofs: mm/pagemap: add readahead_folio_last() to avoid folio->private
2026-09-08 16:04 ` David Hildenbrand (Arm)
@ 2026-09-08 17:05 ` Zi Yan
2026-09-09 14:10 ` David Hildenbrand (Arm)
0 siblings, 1 reply; 37+ messages in thread
From: Zi Yan @ 2026-09-08 17:05 UTC (permalink / raw)
To: David Hildenbrand (Arm), Matthew Wilcox (Oracle), Andrew Morton,
Muchun Song, Lorenzo Stoakes, Liam R. Howlett, Vlastimil Babka,
Mike Rapoport, Suren Baghdasaryan, Michal Hocko, Baolin Wang,
Nico Pache, Ryan Roberts, Dev Jain, Barry Song, Lance Yang,
Usama Arif, Gregory Price, Ying Huang, Alistair Popple,
Johannes Weiner, Qi Zheng, Shakeel Butt, Kairui Song
Cc: linux-mm, linux-kernel, Gao Xiang, Chao Yu, Jan Kara, Yue Hu,
Jeffle Xu, Sandeep Dhavale, Hongbo Li, Chunhai Guo, linux-erofs,
linux-fsdevel
On Tue Sep 8, 2026 at 12:04 PM EDT, David Hildenbrand (Arm) wrote:
> On 9/8/26 04:56, Zi Yan wrote:
>> erofs needs to traverse readahead folios in reverse order to achieve
>> maximum performance by
>> 1. reading all folios from readahead_folio();
>> 2. storing the prior folio pointer in folio->private;
>> 3. traverse from the last folio to the first one.
>>
>> Add readahead_folio_last() to achieve the same function without using
>> folio->private. __readahead_advance() helper shares readahead_control
>> adjustment code among __readahead_folio(), readahead_folio_last(), and
>> __readahead_batch() by checking new private member, _forward, of
>> readahead_control.
>>
>> It prepares for a future commit that replaces PG_private checks with
>> !folio->private checks. After switching the checks, erofs's use of
>> folio->private without bumping folio refcount can cause unexpected
>> outcomes, e.g., in filemap_release_folio(), try_to_free_buffers() becomes
>> reachable.
>
> Ah, I was just about to ask. So it's really about folios never using
> folio->private manually (without the attach/detach).
>
>>
>> No functional change intended.
>>
>> Assisted-by: Claude:claude-opus-4-8
>> Assisted-by: Codex:gpt-5
>> Signed-off-by: Zi Yan <ziy@nvidia.com>
>> To: Gao Xiang <xiang@kernel.org>
>> To: Chao Yu <chao@kernel.org>
>> To: "Matthew Wilcox (Oracle)" <willy@infradead.org>
>> To: Jan Kara <jack@suse.cz>
>> Cc: Yue Hu <zbestahu@gmail.com>
>> Cc: Jeffle Xu <jefflexu@linux.alibaba.com>
>> Cc: Sandeep Dhavale <dhavale@google.com>
>> Cc: Hongbo Li <hongbohbli@tencent.com>
>> Cc: Chunhai Guo <guochunhai@vivo.com>
>> Cc: linux-erofs@lists.ozlabs.org
>> Cc: linux-kernel@vger.kernel.org
>> Cc: linux-fsdevel@vger.kernel.org
>> Cc: linux-mm@kvack.org
>> ---
>> fs/erofs/zdata.c | 13 +++---------
>> include/linux/pagemap.h | 56 ++++++++++++++++++++++++++++++++++++++++++-------
>> 2 files changed, 51 insertions(+), 18 deletions(-)
>>
>> diff --git a/fs/erofs/zdata.c b/fs/erofs/zdata.c
>> index e1e25ca0d1904..78fd7d980e957 100644
>> --- a/fs/erofs/zdata.c
>> +++ b/fs/erofs/zdata.c
>> @@ -1898,21 +1898,14 @@ static void z_erofs_readahead(struct readahead_control *rac)
>> struct inode *realinode = erofs_real_inode(sharedinode, &need_iput);
>> Z_EROFS_DEFINE_FRONTEND(f, realinode, sharedinode, readahead_pos(rac));
>> unsigned int nrpages = readahead_count(rac);
>> - struct folio *head = NULL, *folio;
>> + struct folio *folio;
>> int err;
>>
>> trace_erofs_readahead(realinode, readahead_index(rac), nrpages, false);
>> z_erofs_pcluster_readmore(&f, rac, true);
>> - while ((folio = readahead_folio(rac))) {
>> - folio->private = head;
>> - head = folio;
>> - }
>> -
>> - /* traverse in reverse order for best metadata I/O performance */
>> - while (head) {
>> - folio = head;
>> - head = folio_get_private(folio);
>>
>> + /* traverse from last to first for best metadata I/O performance */
>> + while ((folio = readahead_folio_last(rac))) {
>
> Intuitively, this should be called readahead_folio_reverse /
> readahead_folio_reversed, thinking of list_for_each_entry_reverse()?
>
> list_for_each_entry_reverse - iterate backwards over list of given type.
>
> or maybe readahead_folio_backwards (which matches the forward below)
>
> But I'm not a readahead expert :)
Jan suggested the name[1]. It can be readahead_folio_reverse() if you
prefer it, like Jan said.
[1] https://lore.kernel.org/all/332rknj4vo3cfhvfhhlf6pvg37s3lbrnzbbnv4swa6gctsiu6a@ndotgokvnglc/
>
>> err = z_erofs_scan_folio(&f, folio, true);
>> if (err && err != -EINTR)
>> erofs_err(realinode->i_sb, "readahead error at folio %lu @ nid %llu",
>> diff --git a/include/linux/pagemap.h b/include/linux/pagemap.h
>> index 939f3a5e973f6..2257df004305e 100644
>> --- a/include/linux/pagemap.h
>> +++ b/include/linux/pagemap.h
>> @@ -1415,6 +1415,7 @@ struct readahead_control {
>> bool dropbehind;
>> bool _workingset;
>> unsigned long _pflags;
>> + bool _forward;
>> };
>>
>> #define DEFINE_READAHEAD(ractl, f, r, m, i) \
>> @@ -1479,18 +1480,25 @@ void page_cache_async_readahead(struct address_space *mapping,
>> page_cache_async_ra(&ractl, folio, req_count);
>> }
>>
>> +static inline void __readahead_advance(struct readahead_control *rac)
>> +{
>> + if (rac->_forward)
>> + rac->_index += rac->_batch_count;
>
> No expert, but shouldn't we decrement the _index somewhere in the other case? Or
> where is that done? A comment might help :)
A readahead folio comes from [_index, _index + _nr_pages), so for
last/reverse/backwards case, the code only needs to decrease _nr_pages.
Will add a comment about this.
--
Best Regards,
Yan, Zi
^ permalink raw reply [flat|nested] 37+ messages in thread* Re: [PATCH v3 07/14] erofs: mm/pagemap: add readahead_folio_last() to avoid folio->private
2026-09-08 17:05 ` Zi Yan
@ 2026-09-09 14:10 ` David Hildenbrand (Arm)
0 siblings, 0 replies; 37+ messages in thread
From: David Hildenbrand (Arm) @ 2026-09-09 14:10 UTC (permalink / raw)
To: Zi Yan, Matthew Wilcox (Oracle), Andrew Morton, Muchun Song,
Lorenzo Stoakes, Liam R. Howlett, Vlastimil Babka, Mike Rapoport,
Suren Baghdasaryan, Michal Hocko, Baolin Wang, Nico Pache,
Ryan Roberts, Dev Jain, Barry Song, Lance Yang, Usama Arif,
Gregory Price, Ying Huang, Alistair Popple, Johannes Weiner,
Qi Zheng, Shakeel Butt, Kairui Song
Cc: linux-mm, linux-kernel, Gao Xiang, Chao Yu, Jan Kara, Yue Hu,
Jeffle Xu, Sandeep Dhavale, Hongbo Li, Chunhai Guo, linux-erofs,
linux-fsdevel
On 9/8/26 19:05, Zi Yan wrote:
> On Tue Sep 8, 2026 at 12:04 PM EDT, David Hildenbrand (Arm) wrote:
>> On 9/8/26 04:56, Zi Yan wrote:
>>> erofs needs to traverse readahead folios in reverse order to achieve
>>> maximum performance by
>>> 1. reading all folios from readahead_folio();
>>> 2. storing the prior folio pointer in folio->private;
>>> 3. traverse from the last folio to the first one.
>>>
>>> Add readahead_folio_last() to achieve the same function without using
>>> folio->private. __readahead_advance() helper shares readahead_control
>>> adjustment code among __readahead_folio(), readahead_folio_last(), and
>>> __readahead_batch() by checking new private member, _forward, of
>>> readahead_control.
>>>
>>> It prepares for a future commit that replaces PG_private checks with
>>> !folio->private checks. After switching the checks, erofs's use of
>>> folio->private without bumping folio refcount can cause unexpected
>>> outcomes, e.g., in filemap_release_folio(), try_to_free_buffers() becomes
>>> reachable.
>>
>> Ah, I was just about to ask. So it's really about folios never using
>> folio->private manually (without the attach/detach).
>>
>>>
>>> No functional change intended.
>>>
>>> Assisted-by: Claude:claude-opus-4-8
>>> Assisted-by: Codex:gpt-5
>>> Signed-off-by: Zi Yan <ziy@nvidia.com>
>>> To: Gao Xiang <xiang@kernel.org>
>>> To: Chao Yu <chao@kernel.org>
>>> To: "Matthew Wilcox (Oracle)" <willy@infradead.org>
>>> To: Jan Kara <jack@suse.cz>
>>> Cc: Yue Hu <zbestahu@gmail.com>
>>> Cc: Jeffle Xu <jefflexu@linux.alibaba.com>
>>> Cc: Sandeep Dhavale <dhavale@google.com>
>>> Cc: Hongbo Li <hongbohbli@tencent.com>
>>> Cc: Chunhai Guo <guochunhai@vivo.com>
>>> Cc: linux-erofs@lists.ozlabs.org
>>> Cc: linux-kernel@vger.kernel.org
>>> Cc: linux-fsdevel@vger.kernel.org
>>> Cc: linux-mm@kvack.org
>>> ---
>>> fs/erofs/zdata.c | 13 +++---------
>>> include/linux/pagemap.h | 56 ++++++++++++++++++++++++++++++++++++++++++-------
>>> 2 files changed, 51 insertions(+), 18 deletions(-)
>>>
>>> diff --git a/fs/erofs/zdata.c b/fs/erofs/zdata.c
>>> index e1e25ca0d1904..78fd7d980e957 100644
>>> --- a/fs/erofs/zdata.c
>>> +++ b/fs/erofs/zdata.c
>>> @@ -1898,21 +1898,14 @@ static void z_erofs_readahead(struct readahead_control *rac)
>>> struct inode *realinode = erofs_real_inode(sharedinode, &need_iput);
>>> Z_EROFS_DEFINE_FRONTEND(f, realinode, sharedinode, readahead_pos(rac));
>>> unsigned int nrpages = readahead_count(rac);
>>> - struct folio *head = NULL, *folio;
>>> + struct folio *folio;
>>> int err;
>>>
>>> trace_erofs_readahead(realinode, readahead_index(rac), nrpages, false);
>>> z_erofs_pcluster_readmore(&f, rac, true);
>>> - while ((folio = readahead_folio(rac))) {
>>> - folio->private = head;
>>> - head = folio;
>>> - }
>>> -
>>> - /* traverse in reverse order for best metadata I/O performance */
>>> - while (head) {
>>> - folio = head;
>>> - head = folio_get_private(folio);
>>>
>>> + /* traverse from last to first for best metadata I/O performance */
>>> + while ((folio = readahead_folio_last(rac))) {
>>
>> Intuitively, this should be called readahead_folio_reverse /
>> readahead_folio_reversed, thinking of list_for_each_entry_reverse()?
>>
>> list_for_each_entry_reverse - iterate backwards over list of given type.
>>
>> or maybe readahead_folio_backwards (which matches the forward below)
>>
>> But I'm not a readahead expert :)
>
> Jan suggested the name[1]. It can be readahead_folio_reverse() if you
> prefer it, like Jan said.
>
> [1] https://lore.kernel.org/all/332rknj4vo3cfhvfhhlf6pvg37s3lbrnzbbnv4swa6gctsiu6a@ndotgokvnglc/
Heh, to me _reverse() is clearer; whatever people prefer.
Acked-by: David Hildenbrand (Arm) <david@kernel.org>
--
Cheers,
David
^ permalink raw reply [flat|nested] 37+ messages in thread
* [PATCH v3 08/14] erofs: use folio_attach/detach_private() instead of direct assignment
2026-09-08 2:56 ` [f2fs-dev] " Zi Yan via Linux-f2fs-devel
` (3 preceding siblings ...)
(?)
@ 2026-09-08 2:56 ` Zi Yan
2026-09-08 16:13 ` David Hildenbrand (Arm)
-1 siblings, 1 reply; 37+ messages in thread
From: Zi Yan @ 2026-09-08 2:56 UTC (permalink / raw)
To: David Hildenbrand, Matthew Wilcox (Oracle), Andrew Morton,
Muchun Song, Lorenzo Stoakes, Liam R. Howlett, Vlastimil Babka,
Mike Rapoport, Suren Baghdasaryan, Michal Hocko, Baolin Wang,
Nico Pache, Ryan Roberts, Dev Jain, Barry Song, Lance Yang,
Usama Arif, Gregory Price, Ying Huang, Alistair Popple,
Johannes Weiner, Qi Zheng, Shakeel Butt, Kairui Song
Cc: linux-mm, linux-kernel, Zi Yan, Gao Xiang, Chao Yu, Yue Hu,
Jeffle Xu, Sandeep Dhavale, Hongbo Li, Chunhai Guo, linux-erofs
erofs_onlinefolio_init/split/end() use folio->private without setting
PG_private or increasing folio refcount and it works. But after PG_private
is replaced by checking folio->private in a future commit, it can break
folio_expected_ref_count(), since the folio has private data without
elevated refcount. Change them to use folio_attach/detach_private().
Furthermore, because folio->private is used to store in-flight I/O counter
and the counter reaches 0 when all I/O completes successfully without error
or being dirty, ->private=0 causes folio_detach_private() to not drop the
elevated folio refcount. Solve this issue by using bias=1 for the counter,
so that ->private stays non NULL throughout every attach-to-detach process.
Add a macro EROFS_ONLINEFOLIO_BIAS=1. While at it, fix the comment about
->private bit layout and add EROFS_ONLINEFOLIO_COUNT_MASK.
It prepares for a future commit that removes PG_private.
Assisted-by: Claude:claude-opus-4-8
Assisted-by: Codex:gpt-5
To: Gao Xiang <xiang@kernel.org>
To: Chao Yu <chao@kernel.org>
Cc: Yue Hu <zbestahu@gmail.com>
Cc: Jeffle Xu <jefflexu@linux.alibaba.com>
Cc: Sandeep Dhavale <dhavale@google.com>
Cc: Hongbo Li <hongbohbli@tencent.com>
Cc: Chunhai Guo <guochunhai@vivo.com>
Cc: linux-erofs@lists.ozlabs.org
Cc: linux-kernel@vger.kernel.org
Reviewed-by: Gao Xiang <xiang@kernel.org>
Signed-off-by: Zi Yan <ziy@nvidia.com>
---
fs/erofs/data.c | 16 ++++++++++------
1 file changed, 10 insertions(+), 6 deletions(-)
diff --git a/fs/erofs/data.c b/fs/erofs/data.c
index 0885b1f2fc925..f71c7b51bb720 100644
--- a/fs/erofs/data.c
+++ b/fs/erofs/data.c
@@ -239,19 +239,23 @@ int erofs_map_dev(struct super_block *sb, struct erofs_map_dev *map)
/*
* bit 30: I/O error occurred on this folio
* bit 29: CPU has dirty data in D-cache (needs aliasing handling);
- * bit 0 - 29: remaining parts to complete this folio
+ * bit 0 - 28: remaining parts to complete this folio, biased by 1 so that
+ * ->private stays non-NULL while the folio is attached
*/
#define EROFS_ONLINEFOLIO_EIO 30
#define EROFS_ONLINEFOLIO_DIRTY 29
+#define EROFS_ONLINEFOLIO_COUNT_MASK (BIT(EROFS_ONLINEFOLIO_DIRTY) - 1)
+#define EROFS_ONLINEFOLIO_BIAS 1
void erofs_onlinefolio_init(struct folio *folio)
{
union {
atomic_t o;
void *v;
- } u = { .o = ATOMIC_INIT(1) };
+ } u = { .o = ATOMIC_INIT(1 + EROFS_ONLINEFOLIO_BIAS) };
- folio->private = u.v; /* valid only if file-backed folio is locked */
+ /* valid only if file-backed folio is locked */
+ folio_attach_private(folio, u.v);
}
void erofs_onlinefolio_split(struct folio *folio)
@@ -265,14 +269,14 @@ void erofs_onlinefolio_end(struct folio *folio, int err, bool dirty)
do {
orig = atomic_read((atomic_t *)&folio->private);
- DBG_BUGON(orig <= 0);
+ DBG_BUGON((orig & EROFS_ONLINEFOLIO_COUNT_MASK) <= EROFS_ONLINEFOLIO_BIAS);
v = dirty << EROFS_ONLINEFOLIO_DIRTY;
v |= (orig - 1) | (!!err << EROFS_ONLINEFOLIO_EIO);
} while (atomic_cmpxchg((atomic_t *)&folio->private, orig, v) != orig);
- if (v & (BIT(EROFS_ONLINEFOLIO_DIRTY) - 1))
+ if ((v & EROFS_ONLINEFOLIO_COUNT_MASK) != EROFS_ONLINEFOLIO_BIAS)
return;
- folio->private = 0;
+ folio_detach_private(folio);
if (v & BIT(EROFS_ONLINEFOLIO_DIRTY))
flush_dcache_folio(folio);
folio_end_read(folio, !(v & BIT(EROFS_ONLINEFOLIO_EIO)));
--
2.53.0
^ permalink raw reply related [flat|nested] 37+ messages in thread* Re: [PATCH v3 08/14] erofs: use folio_attach/detach_private() instead of direct assignment
2026-09-08 2:56 ` [PATCH v3 08/14] erofs: use folio_attach/detach_private() instead of direct assignment Zi Yan
@ 2026-09-08 16:13 ` David Hildenbrand (Arm)
2026-09-08 17:19 ` Zi Yan
0 siblings, 1 reply; 37+ messages in thread
From: David Hildenbrand (Arm) @ 2026-09-08 16:13 UTC (permalink / raw)
To: Zi Yan, Matthew Wilcox (Oracle), Andrew Morton, Muchun Song,
Lorenzo Stoakes, Liam R. Howlett, Vlastimil Babka, Mike Rapoport,
Suren Baghdasaryan, Michal Hocko, Baolin Wang, Nico Pache,
Ryan Roberts, Dev Jain, Barry Song, Lance Yang, Usama Arif,
Gregory Price, Ying Huang, Alistair Popple, Johannes Weiner,
Qi Zheng, Shakeel Butt, Kairui Song
Cc: linux-mm, linux-kernel, Gao Xiang, Chao Yu, Yue Hu, Jeffle Xu,
Sandeep Dhavale, Hongbo Li, Chunhai Guo, linux-erofs
On 9/8/26 04:56, Zi Yan wrote:
> erofs_onlinefolio_init/split/end() use folio->private without setting
> PG_private or increasing folio refcount and it works. But after PG_private
> is replaced by checking folio->private in a future commit, it can break
> folio_expected_ref_count(), since the folio has private data without
> elevated refcount. Change them to use folio_attach/detach_private().
Freezing the folio will properly work I assume, as we'd always freeze with that
refcount in mind or remove the reference (detach private) early?
I'm thinking of folio_ref_freeze() in __folio_freeze_and_split_unmapped().
Or is the ref only very short-lived either way such that we don't care?
--
Cheers,
David
^ permalink raw reply [flat|nested] 37+ messages in thread
* Re: [PATCH v3 08/14] erofs: use folio_attach/detach_private() instead of direct assignment
2026-09-08 16:13 ` David Hildenbrand (Arm)
@ 2026-09-08 17:19 ` Zi Yan
2026-09-09 13:27 ` David Hildenbrand (Arm)
0 siblings, 1 reply; 37+ messages in thread
From: Zi Yan @ 2026-09-08 17:19 UTC (permalink / raw)
To: David Hildenbrand (Arm), Matthew Wilcox (Oracle), Andrew Morton,
Muchun Song, Lorenzo Stoakes, Liam R. Howlett, Vlastimil Babka,
Mike Rapoport, Suren Baghdasaryan, Michal Hocko, Baolin Wang,
Nico Pache, Ryan Roberts, Dev Jain, Barry Song, Lance Yang,
Usama Arif, Gregory Price, Ying Huang, Alistair Popple,
Johannes Weiner, Qi Zheng, Shakeel Butt, Kairui Song
Cc: linux-mm, linux-kernel, Gao Xiang, Chao Yu, Yue Hu, Jeffle Xu,
Sandeep Dhavale, Hongbo Li, Chunhai Guo, linux-erofs
On Tue Sep 8, 2026 at 12:13 PM EDT, David Hildenbrand (Arm) wrote:
> On 9/8/26 04:56, Zi Yan wrote:
>> erofs_onlinefolio_init/split/end() use folio->private without setting
>> PG_private or increasing folio refcount and it works. But after PG_private
>> is replaced by checking folio->private in a future commit, it can break
>> folio_expected_ref_count(), since the folio has private data without
>> elevated refcount. Change them to use folio_attach/detach_private().
>
> Freezing the folio will properly work I assume, as we'd always freeze with that
> refcount in mind or remove the reference (detach private) early?
Yes.
>
> I'm thinking of folio_ref_freeze() in __folio_freeze_and_split_unmapped().
>
> Or is the ref only very short-lived either way such that we don't care?
The folios here are locked since they are in the process of
readahead, which requires all folios locked. So they are not reachable
from folio split code. In additio, the private is deatched and ref is
decreased before the folio lock is dropped.
--
Best Regards,
Yan, Zi
^ permalink raw reply [flat|nested] 37+ messages in thread
* Re: [PATCH v3 08/14] erofs: use folio_attach/detach_private() instead of direct assignment
2026-09-08 17:19 ` Zi Yan
@ 2026-09-09 13:27 ` David Hildenbrand (Arm)
2026-09-10 2:06 ` Zi Yan
0 siblings, 1 reply; 37+ messages in thread
From: David Hildenbrand (Arm) @ 2026-09-09 13:27 UTC (permalink / raw)
To: Zi Yan, Matthew Wilcox (Oracle), Andrew Morton, Muchun Song,
Lorenzo Stoakes, Liam R. Howlett, Vlastimil Babka, Mike Rapoport,
Suren Baghdasaryan, Michal Hocko, Baolin Wang, Nico Pache,
Ryan Roberts, Dev Jain, Barry Song, Lance Yang, Usama Arif,
Gregory Price, Ying Huang, Alistair Popple, Johannes Weiner,
Qi Zheng, Shakeel Butt, Kairui Song
Cc: linux-mm, linux-kernel, Gao Xiang, Chao Yu, Yue Hu, Jeffle Xu,
Sandeep Dhavale, Hongbo Li, Chunhai Guo, linux-erofs
On 9/8/26 19:19, Zi Yan wrote:
> On Tue Sep 8, 2026 at 12:13 PM EDT, David Hildenbrand (Arm) wrote:
>> On 9/8/26 04:56, Zi Yan wrote:
>>> erofs_onlinefolio_init/split/end() use folio->private without setting
>>> PG_private or increasing folio refcount and it works. But after PG_private
>>> is replaced by checking folio->private in a future commit, it can break
>>> folio_expected_ref_count(), since the folio has private data without
>>> elevated refcount. Change them to use folio_attach/detach_private().
>>
>> Freezing the folio will properly work I assume, as we'd always freeze with that
>> refcount in mind or remove the reference (detach private) early?
>
> Yes.
>
>>
>> I'm thinking of folio_ref_freeze() in __folio_freeze_and_split_unmapped().
>>
>> Or is the ref only very short-lived either way such that we don't care?
>
> The folios here are locked since they are in the process of
> readahead, which requires all folios locked. So they are not reachable
> from folio split code. In additio, the private is deatched and ref is
> decreased before the folio lock is dropped.
It would be great to summarize this interaction with core-mm (migration/split)
in the patch description.
--
Cheers,
David
^ permalink raw reply [flat|nested] 37+ messages in thread
* Re: [PATCH v3 08/14] erofs: use folio_attach/detach_private() instead of direct assignment
2026-09-09 13:27 ` David Hildenbrand (Arm)
@ 2026-09-10 2:06 ` Zi Yan
0 siblings, 0 replies; 37+ messages in thread
From: Zi Yan @ 2026-09-10 2:06 UTC (permalink / raw)
To: David Hildenbrand (Arm), Matthew Wilcox (Oracle), Andrew Morton,
Muchun Song, Lorenzo Stoakes, Liam R. Howlett, Vlastimil Babka,
Mike Rapoport, Suren Baghdasaryan, Michal Hocko, Baolin Wang,
Nico Pache, Ryan Roberts, Dev Jain, Barry Song, Lance Yang,
Usama Arif, Gregory Price, Ying Huang, Alistair Popple,
Johannes Weiner, Qi Zheng, Shakeel Butt, Kairui Song
Cc: linux-mm, linux-kernel, Gao Xiang, Chao Yu, Yue Hu, Jeffle Xu,
Sandeep Dhavale, Hongbo Li, Chunhai Guo, linux-erofs
On Wed Sep 9, 2026 at 9:27 AM EDT, David Hildenbrand (Arm) wrote:
> On 9/8/26 19:19, Zi Yan wrote:
>> On Tue Sep 8, 2026 at 12:13 PM EDT, David Hildenbrand (Arm) wrote:
>>> On 9/8/26 04:56, Zi Yan wrote:
>>>> erofs_onlinefolio_init/split/end() use folio->private without setting
>>>> PG_private or increasing folio refcount and it works. But after PG_private
>>>> is replaced by checking folio->private in a future commit, it can break
>>>> folio_expected_ref_count(), since the folio has private data without
>>>> elevated refcount. Change them to use folio_attach/detach_private().
>>>
>>> Freezing the folio will properly work I assume, as we'd always freeze with that
>>> refcount in mind or remove the reference (detach private) early?
>>
>> Yes.
>>
>>>
>>> I'm thinking of folio_ref_freeze() in __folio_freeze_and_split_unmapped().
>>>
>>> Or is the ref only very short-lived either way such that we don't care?
>>
>> The folios here are locked since they are in the process of
>> readahead, which requires all folios locked. So they are not reachable
>> from folio split code. In additio, the private is deatched and ref is
>> decreased before the folio lock is dropped.
>
> It would be great to summarize this interaction with core-mm (migration/split)
> in the patch description.
Will update the commit message.
--
Best Regards,
Yan, Zi
^ permalink raw reply [flat|nested] 37+ messages in thread
* [PATCH v3 12/14] treewide: replace PagePrivate() with page_private()
2026-09-08 2:56 ` [f2fs-dev] " Zi Yan via Linux-f2fs-devel
` (4 preceding siblings ...)
(?)
@ 2026-09-08 2:56 ` Zi Yan
2026-09-09 14:18 ` David Hildenbrand (Arm)
-1 siblings, 1 reply; 37+ messages in thread
From: Zi Yan @ 2026-09-08 2:56 UTC (permalink / raw)
To: David Hildenbrand, Matthew Wilcox (Oracle), Andrew Morton,
Muchun Song, Lorenzo Stoakes, Liam R. Howlett, Vlastimil Babka,
Mike Rapoport, Suren Baghdasaryan, Michal Hocko, Baolin Wang,
Nico Pache, Ryan Roberts, Dev Jain, Barry Song, Lance Yang,
Usama Arif, Gregory Price, Ying Huang, Alistair Popple,
Johannes Weiner, Qi Zheng, Shakeel Butt, Kairui Song
Cc: linux-mm, linux-kernel, Zi Yan, Song Liu, Yu Kuai, Ilya Dryomov,
Alex Markuze, Viacheslav Dubeyko, Li Nan, Xiao Ni, linux-raid,
ceph-devel
PG_private is going to be removed and its check is replaced by checking
page->private != NULL.
Replace page_buffers() with page_private() and delete page_buffers(),
since only two users left and both can be converted to use page_private().
Assisted-by: Claude:claude-opus-4-8
Assisted-by: Codex:gpt-5
Signed-off-by: Zi Yan <ziy@nvidia.com>
To: Song Liu <song@kernel.org>
To: Yu Kuai <yukuai@fygo.io>
To: Ilya Dryomov <idryomov@gmail.com>
To: Alex Markuze <amarkuze@redhat.com>
To: Viacheslav Dubeyko <slava@dubeyko.com>
Cc: Li Nan <magiclinan@didiglobal.com>
Cc: Xiao Ni <xiao@kernel.org>
Cc: linux-raid@vger.kernel.org
Cc: linux-kernel@vger.kernel.org
Cc: ceph-devel@vger.kernel.org
---
drivers/md/md-bitmap.c | 6 +++---
fs/ceph/addr.c | 4 +---
include/linux/buffer_head.h | 6 ------
3 files changed, 4 insertions(+), 12 deletions(-)
diff --git a/drivers/md/md-bitmap.c b/drivers/md/md-bitmap.c
index b8325cb09a371..0cf14bc1cff32 100644
--- a/drivers/md/md-bitmap.c
+++ b/drivers/md/md-bitmap.c
@@ -516,7 +516,7 @@ static void end_bitmap_write(struct bio *bio)
static void write_file_page(struct bitmap *bitmap, struct page *page, int wait)
{
- struct buffer_head *bh = page_buffers(page);
+ struct buffer_head *bh = (struct buffer_head *)page_private(page);
while (bh && bh->b_blocknr) {
atomic_inc(&bitmap->pending_writes);
@@ -535,10 +535,10 @@ static void free_buffers(struct page *page)
{
struct buffer_head *bh;
- if (!PagePrivate(page))
+ if (!page_private(page))
return;
- bh = page_buffers(page);
+ bh = (struct buffer_head *)page_private(page);
while (bh) {
struct buffer_head *next = bh->b_this_page;
free_buffer_head(bh);
diff --git a/fs/ceph/addr.c b/fs/ceph/addr.c
index 657c2cb0f8811..fad17df1d5082 100644
--- a/fs/ceph/addr.c
+++ b/fs/ceph/addr.c
@@ -70,9 +70,7 @@ static int ceph_netfs_check_write_begin(struct file *file, loff_t pos, unsigned
static inline struct ceph_snap_context *page_snap_context(struct page *page)
{
- if (PagePrivate(page))
- return (void *)page->private;
- return NULL;
+ return (void *)page->private;
}
/*
diff --git a/include/linux/buffer_head.h b/include/linux/buffer_head.h
index fd2c7115c0542..e47fbd0387b69 100644
--- a/include/linux/buffer_head.h
+++ b/include/linux/buffer_head.h
@@ -175,12 +175,6 @@ static inline unsigned long bh_offset(const struct buffer_head *bh)
return (unsigned long)(bh)->b_data & (page_size(bh->b_page) - 1);
}
-/* If we *know* page->private refers to buffer_heads */
-#define page_buffers(page) \
- ({ \
- BUG_ON(!PagePrivate(page)); \
- ((struct buffer_head *)page_private(page)); \
- })
#define folio_buffers(folio) folio_get_private(folio)
void buffer_check_dirty_writeback(struct folio *folio,
--
2.53.0
^ permalink raw reply related [flat|nested] 37+ messages in thread* Re: [PATCH v3 12/14] treewide: replace PagePrivate() with page_private()
2026-09-08 2:56 ` [PATCH v3 12/14] treewide: replace PagePrivate() with page_private() Zi Yan
@ 2026-09-09 14:18 ` David Hildenbrand (Arm)
2026-09-09 14:23 ` David Hildenbrand (Arm)
0 siblings, 1 reply; 37+ messages in thread
From: David Hildenbrand (Arm) @ 2026-09-09 14:18 UTC (permalink / raw)
To: Zi Yan, Matthew Wilcox (Oracle), Andrew Morton, Muchun Song,
Lorenzo Stoakes, Liam R. Howlett, Vlastimil Babka, Mike Rapoport,
Suren Baghdasaryan, Michal Hocko, Baolin Wang, Nico Pache,
Ryan Roberts, Dev Jain, Barry Song, Lance Yang, Usama Arif,
Gregory Price, Ying Huang, Alistair Popple, Johannes Weiner,
Qi Zheng, Shakeel Butt, Kairui Song
Cc: linux-mm, linux-kernel, Song Liu, Yu Kuai, Ilya Dryomov,
Alex Markuze, Viacheslav Dubeyko, Li Nan, Xiao Ni, linux-raid,
ceph-devel
On 9/8/26 04:56, Zi Yan wrote:
> PG_private is going to be removed and its check is replaced by checking
> page->private != NULL.
>
You should likely clarify here that, for these users (the pages they deal with),
PG_private is set if and only if page->private != NULL. Consequently, there is
no functional change.
> Replace page_buffers() with page_private() and delete page_buffers(),
> since only two users left and both can be converted to use page_private().
>
[...]
> diff --git a/fs/ceph/addr.c b/fs/ceph/addr.c
> index 657c2cb0f8811..fad17df1d5082 100644
> --- a/fs/ceph/addr.c
> +++ b/fs/ceph/addr.c
> @@ -70,9 +70,7 @@ static int ceph_netfs_check_write_begin(struct file *file, loff_t pos, unsigned
>
> static inline struct ceph_snap_context *page_snap_context(struct page *page)
> {
> - if (PagePrivate(page))
> - return (void *)page->private;
> - return NULL;
> + return (void *)page->private;
> }
I'd even split this up into 2 (or even 3) patches:
1) Remove PagePrivate usage in ceph
2) Remove PagePrivate usage in md
3) Inline page_buffers() and remove it
Acked-by: David Hildenbrand (Arm) <david@kernel.org>
--
Cheers,
David
^ permalink raw reply [flat|nested] 37+ messages in thread* Re: [PATCH v3 12/14] treewide: replace PagePrivate() with page_private()
2026-09-09 14:18 ` David Hildenbrand (Arm)
@ 2026-09-09 14:23 ` David Hildenbrand (Arm)
2026-09-10 2:09 ` Zi Yan
0 siblings, 1 reply; 37+ messages in thread
From: David Hildenbrand (Arm) @ 2026-09-09 14:23 UTC (permalink / raw)
To: Zi Yan, Matthew Wilcox (Oracle), Andrew Morton, Muchun Song,
Lorenzo Stoakes, Liam R. Howlett, Vlastimil Babka, Mike Rapoport,
Suren Baghdasaryan, Michal Hocko, Baolin Wang, Nico Pache,
Ryan Roberts, Dev Jain, Barry Song, Lance Yang, Usama Arif,
Gregory Price, Ying Huang, Alistair Popple, Johannes Weiner,
Qi Zheng, Shakeel Butt, Kairui Song
Cc: linux-mm, linux-kernel, Song Liu, Yu Kuai, Ilya Dryomov,
Alex Markuze, Viacheslav Dubeyko, Li Nan, Xiao Ni, linux-raid,
ceph-devel
On 9/9/26 16:18, David Hildenbrand (Arm) wrote:
> On 9/8/26 04:56, Zi Yan wrote:
>> PG_private is going to be removed and its check is replaced by checking
>> page->private != NULL.
>>
>
> You should likely clarify here that, for these users (the pages they deal with),
> PG_private is set if and only if page->private != NULL. Consequently, there is
> no functional change.
Ah, in previous patch:
+static __always_inline int PagePrivate(const struct page *page)
+{
+ return !!page->private;
+}
So this is not about PG_private *at all* :) Best to clarify that.
--
Cheers,
David
^ permalink raw reply [flat|nested] 37+ messages in thread* Re: [PATCH v3 12/14] treewide: replace PagePrivate() with page_private()
2026-09-09 14:23 ` David Hildenbrand (Arm)
@ 2026-09-10 2:09 ` Zi Yan
0 siblings, 0 replies; 37+ messages in thread
From: Zi Yan @ 2026-09-10 2:09 UTC (permalink / raw)
To: David Hildenbrand (Arm), Matthew Wilcox (Oracle), Andrew Morton,
Muchun Song, Lorenzo Stoakes, Liam R. Howlett, Vlastimil Babka,
Mike Rapoport, Suren Baghdasaryan, Michal Hocko, Baolin Wang,
Nico Pache, Ryan Roberts, Dev Jain, Barry Song, Lance Yang,
Usama Arif, Gregory Price, Ying Huang, Alistair Popple,
Johannes Weiner, Qi Zheng, Shakeel Butt, Kairui Song
Cc: linux-mm, linux-kernel, Song Liu, Yu Kuai, Ilya Dryomov,
Alex Markuze, Viacheslav Dubeyko, Li Nan, Xiao Ni, linux-raid,
ceph-devel
On Wed Sep 9, 2026 at 10:23 AM EDT, David Hildenbrand (Arm) wrote:
> On 9/9/26 16:18, David Hildenbrand (Arm) wrote:
>> On 9/8/26 04:56, Zi Yan wrote:
>>> PG_private is going to be removed and its check is replaced by checking
>>> page->private != NULL.
>>>
>>
>> You should likely clarify here that, for these users (the pages they deal with),
>> PG_private is set if and only if page->private != NULL. Consequently, there is
>> no functional change.
>
> Ah, in previous patch:
>
> +static __always_inline int PagePrivate(const struct page *page)
> +{
> + return !!page->private;
> +}
>
> So this is not about PG_private *at all* :) Best to clarify that.
Will do the patch split like you suggested and clarify this code change
in the commit message.
--
Best Regards,
Yan, Zi
^ permalink raw reply [flat|nested] 37+ messages in thread
* [PATCH v3 13/14] treewide: adjust comments on PagePrivate and PG_private
2026-09-08 2:56 ` [f2fs-dev] " Zi Yan via Linux-f2fs-devel
` (5 preceding siblings ...)
(?)
@ 2026-09-08 2:56 ` Zi Yan
2026-09-09 14:20 ` David Hildenbrand (Arm)
2026-09-09 14:27 ` David Hildenbrand (Arm)
-1 siblings, 2 replies; 37+ messages in thread
From: Zi Yan @ 2026-09-08 2:56 UTC (permalink / raw)
To: David Hildenbrand, Matthew Wilcox (Oracle), Andrew Morton,
Muchun Song, Lorenzo Stoakes, Liam R. Howlett, Vlastimil Babka,
Mike Rapoport, Suren Baghdasaryan, Michal Hocko, Baolin Wang,
Nico Pache, Ryan Roberts, Dev Jain, Barry Song, Lance Yang,
Usama Arif, Gregory Price, Ying Huang, Alistair Popple,
Johannes Weiner, Qi Zheng, Shakeel Butt, Kairui Song
Cc: linux-mm, linux-kernel, Zi Yan, Ilya Dryomov, Alex Markuze,
Viacheslav Dubeyko, Trond Myklebust, Anna Schumaker,
Richard Weinberger, Zhihao Cheng, ceph-devel, linux-nfs,
linux-mtd
PG_private is going to be deleted. Adjust related comments to refer to
page/folio->private instead.
Assisted-by: Claude:claude-opus-4-8
Assisted-by: Codex:gpt-5
Signed-off-by: Zi Yan <ziy@nvidia.com>
To: Ilya Dryomov <idryomov@gmail.com>
To: Alex Markuze <amarkuze@redhat.com>
To: Viacheslav Dubeyko <slava@dubeyko.com>
To: Trond Myklebust <trondmy@kernel.org>
To: Anna Schumaker <anna@kernel.org>
To: Richard Weinberger <richard@nod.at>
To: Andrew Morton <akpm@linux-foundation.org>
To: David Hildenbrand <david@kernel.org>
Cc: Zhihao Cheng <chengzhihao1@huawei.com>
Cc: Lorenzo Stoakes <ljs@kernel.org>
Cc: "Liam R. Howlett" <liam@infradead.org>
Cc: Vlastimil Babka <vbabka@kernel.org>
Cc: Mike Rapoport <rppt@kernel.org>
Cc: Suren Baghdasaryan <surenb@google.com>
Cc: Michal Hocko <mhocko@suse.com>
Cc: ceph-devel@vger.kernel.org
Cc: linux-kernel@vger.kernel.org
Cc: linux-nfs@vger.kernel.org
Cc: linux-mtd@lists.infradead.org
Cc: linux-mm@kvack.org
---
fs/ceph/addr.c | 4 ++--
fs/nfs/file.c | 4 ++--
fs/ubifs/file.c | 8 ++++----
include/linux/mm.h | 15 ++++++++-------
include/linux/mm_types.h | 4 ++--
5 files changed, 18 insertions(+), 17 deletions(-)
diff --git a/fs/ceph/addr.c b/fs/ceph/addr.c
index fad17df1d5082..f9b2ec9550481 100644
--- a/fs/ceph/addr.c
+++ b/fs/ceph/addr.c
@@ -122,8 +122,8 @@ static bool ceph_dirty_folio(struct address_space *mapping, struct folio *folio)
spin_unlock(&ci->i_ceph_lock);
/*
- * Reference snap context in folio->private. Also set
- * PagePrivate so that we get invalidate_folio callback.
+ * Reference snap context in folio->private. Setting folio->private is
+ * what gets us the invalidate_folio callback.
*/
VM_WARN_ON_FOLIO(folio->private, folio);
folio_attach_private(folio, snapc);
diff --git a/fs/nfs/file.c b/fs/nfs/file.c
index e1bdd10b35f10..38f830a6467c9 100644
--- a/fs/nfs/file.c
+++ b/fs/nfs/file.c
@@ -484,7 +484,7 @@ static int nfs_write_end(const struct kiocb *iocb,
* Partially or wholly invalidate a page
* - Release the private state associated with a page if undergoing complete
* page invalidation
- * - Called if either PG_private or PG_fscache is set on the page
+ * - Called if either folio->private or PG_fscache is set on the page
* - Caller holds page lock
*/
static void nfs_invalidate_folio(struct folio *folio, size_t offset,
@@ -555,7 +555,7 @@ static void nfs_check_dirty_writeback(struct folio *folio,
* Attempt to clear the private state associated with a page when an error
* occurs that requires the cached contents of an inode to be written back or
* destroyed
- * - Called if either PG_private or fscache is set on the page
+ * - Called if either page->private or fscache is set on the page
* - Caller holds page lock
* - Return 0 if successful, -error otherwise
*/
diff --git a/fs/ubifs/file.c b/fs/ubifs/file.c
index e73c28b12f97f..aa0298ce451ef 100644
--- a/fs/ubifs/file.c
+++ b/fs/ubifs/file.c
@@ -12,14 +12,14 @@
* This file implements VFS file and inode operations for regular files, device
* nodes and symlinks as well as address space operations.
*
- * UBIFS uses 2 page flags: @PG_private and @PG_checked. @PG_private is set if
+ * UBIFS uses folio->private and page flag @PG_checked. folio->private is set if
* the page is dirty and is used for optimization purposes - dirty pages are
- * not budgeted so the flag shows that 'ubifs_write_end()' should not release
+ * not budgeted so it shows that 'ubifs_write_end()' should not release
* the budget for this page. The @PG_checked flag is set if full budgeting is
* required for the page e.g., when it corresponds to a file hole or it is
* beyond the file size. The budgeting is done in 'ubifs_write_begin()', because
* it is OK to fail in this function, and the budget is released in
- * 'ubifs_write_end()'. So the @PG_private and @PG_checked flags carry
+ * 'ubifs_write_end()'. So the folio->private and the @PG_checked flag carry
* information about how the page was budgeted, to make it possible to release
* the budget properly.
*
@@ -1509,7 +1509,7 @@ static vm_fault_t ubifs_vm_page_mkwrite(struct vm_fault *vmf)
*
* At the moment we do not know whether the folio is dirty or not, so we
* assume that it is not and budget for a new folio. We could look at
- * the @PG_private flag and figure this out, but we may race with write
+ * folio->private and figure this out, but we may race with write
* back and the folio state may change by the time we lock it, so this
* would need additional care. We do not bother with this at the
* moment, although it might be good idea to do. Instead, we allocate
diff --git a/include/linux/mm.h b/include/linux/mm.h
index c861525cda83f..0ceffe4f9ca02 100644
--- a/include/linux/mm.h
+++ b/include/linux/mm.h
@@ -2048,20 +2048,21 @@ vm_fault_t finish_fault(struct vm_fault *vmf);
*
* A pagecache page contains an opaque `private' member, which belongs to the
* page's address_space. Usually, this is the address of a circular list of
- * the page's disk buffers. PG_private must be set to tell the VM to call
- * into the filesystem to release these pages.
+ * the page's disk buffers. It tells the VM to call into the filesystem to
+ * release these pages.
*
* A folio may belong to an inode's memory mapping. In this case,
* folio->mapping points to the inode, and folio->index is the file
* offset of the folio, in units of PAGE_SIZE.
*
- * If pagecache pages are not associated with an inode, they are said to be
- * anonymous pages. These may become associated with the swapcache, and in that
- * case PG_swapcache is set, and page->private is an offset into the swapcache.
+ * If pagecache folios are not associated with an inode, they are said to be
+ * anonymous folios. These may become associated with the swapcache, and in that
+ * case PG_swapcache is set, and folio->private is an offset into the swapcache.
*
* In either case (swapcache or inode backed), the pagecache itself holds one
- * reference to the page. Setting PG_private should also increment the
- * refcount. The each user mapping also has a reference to the page.
+ * reference to the folio. Attaching filesystem private data via
+ * folio_attach_private() also increments the refcount. Each user mapping also
+ * has a reference to the folio.
*
* The pagecache pages are stored in a per-mapping radix tree, which is
* rooted at mapping->i_pages, and indexed by offset.
diff --git a/include/linux/mm_types.h b/include/linux/mm_types.h
index 5413bd10fff2c..9d6c945ba4104 100644
--- a/include/linux/mm_types.h
+++ b/include/linux/mm_types.h
@@ -108,7 +108,7 @@ struct page {
};
/**
* @private: Mapping-private opaque data.
- * Usually used for buffer_heads if PagePrivate.
+ * Usually used for buffer_heads.
* Used for swp_entry_t if swapcache flag set.
* Indicates order in the buddy system if PageBuddy
* or on pcp_llist.
@@ -675,7 +675,7 @@ static inline void ptdesc_pmd_pts_init(struct ptdesc *ptdesc)
#define STRUCT_PAGE_MAX_SHIFT (order_base_2(sizeof(struct page)))
/*
- * page_private can be used on tail pages. However, PagePrivate is only
+ * page_private can be used on tail pages. However, it is only
* checked by the VM on the head page. So page_private on the tail pages
* should be used for data that's ancillary to the head page (eg attaching
* buffer heads to tail pages after attaching buffer heads to the head page)
--
2.53.0
^ permalink raw reply related [flat|nested] 37+ messages in thread* Re: [PATCH v3 13/14] treewide: adjust comments on PagePrivate and PG_private
2026-09-08 2:56 ` [PATCH v3 13/14] treewide: adjust comments on PagePrivate and PG_private Zi Yan
@ 2026-09-09 14:20 ` David Hildenbrand (Arm)
2026-09-09 14:27 ` David Hildenbrand (Arm)
1 sibling, 0 replies; 37+ messages in thread
From: David Hildenbrand (Arm) @ 2026-09-09 14:20 UTC (permalink / raw)
To: Zi Yan, Matthew Wilcox (Oracle), Andrew Morton, Muchun Song,
Lorenzo Stoakes, Liam R. Howlett, Vlastimil Babka, Mike Rapoport,
Suren Baghdasaryan, Michal Hocko, Baolin Wang, Nico Pache,
Ryan Roberts, Dev Jain, Barry Song, Lance Yang, Usama Arif,
Gregory Price, Ying Huang, Alistair Popple, Johannes Weiner,
Qi Zheng, Shakeel Butt, Kairui Song
Cc: linux-mm, linux-kernel, Ilya Dryomov, Alex Markuze,
Viacheslav Dubeyko, Trond Myklebust, Anna Schumaker,
Richard Weinberger, Zhihao Cheng, ceph-devel, linux-nfs,
linux-mtd
On 9/8/26 04:56, Zi Yan wrote:
> PG_private is going to be deleted. Adjust related comments to refer to
> page/folio->private instead.
Acked-by: David Hildenbrand (Arm) <david@kernel.org>
--
Cheers,
David
^ permalink raw reply [flat|nested] 37+ messages in thread
* Re: [PATCH v3 13/14] treewide: adjust comments on PagePrivate and PG_private
2026-09-08 2:56 ` [PATCH v3 13/14] treewide: adjust comments on PagePrivate and PG_private Zi Yan
2026-09-09 14:20 ` David Hildenbrand (Arm)
@ 2026-09-09 14:27 ` David Hildenbrand (Arm)
2026-09-10 2:12 ` Zi Yan
1 sibling, 1 reply; 37+ messages in thread
From: David Hildenbrand (Arm) @ 2026-09-09 14:27 UTC (permalink / raw)
To: Zi Yan, Matthew Wilcox (Oracle), Andrew Morton, Muchun Song,
Lorenzo Stoakes, Liam R. Howlett, Vlastimil Babka, Mike Rapoport,
Suren Baghdasaryan, Michal Hocko, Baolin Wang, Nico Pache,
Ryan Roberts, Dev Jain, Barry Song, Lance Yang, Usama Arif,
Gregory Price, Ying Huang, Alistair Popple, Johannes Weiner,
Qi Zheng, Shakeel Butt, Kairui Song
Cc: linux-mm, linux-kernel, Ilya Dryomov, Alex Markuze,
Viacheslav Dubeyko, Trond Myklebust, Anna Schumaker,
Richard Weinberger, Zhihao Cheng, ceph-devel, linux-nfs,
linux-mtd
On 9/8/26 04:56, Zi Yan wrote:
> PG_private is going to be deleted. Adjust related comments to refer to
> page/folio->private instead.
Thinking again, I think this is misleading.
PG_private is defectively already unused for all of these cases, no? In that
case it's rather a documentation fix. (could some of that go into patches that
convert away from PagePrivate, like in the previous patch?)
--
Cheers,
David
^ permalink raw reply [flat|nested] 37+ messages in thread
* Re: [PATCH v3 13/14] treewide: adjust comments on PagePrivate and PG_private
2026-09-09 14:27 ` David Hildenbrand (Arm)
@ 2026-09-10 2:12 ` Zi Yan
0 siblings, 0 replies; 37+ messages in thread
From: Zi Yan @ 2026-09-10 2:12 UTC (permalink / raw)
To: David Hildenbrand (Arm), Matthew Wilcox (Oracle), Andrew Morton,
Muchun Song, Lorenzo Stoakes, Liam R. Howlett, Vlastimil Babka,
Mike Rapoport, Suren Baghdasaryan, Michal Hocko, Baolin Wang,
Nico Pache, Ryan Roberts, Dev Jain, Barry Song, Lance Yang,
Usama Arif, Gregory Price, Ying Huang, Alistair Popple,
Johannes Weiner, Qi Zheng, Shakeel Butt, Kairui Song
Cc: linux-mm, linux-kernel, Ilya Dryomov, Alex Markuze,
Viacheslav Dubeyko, Trond Myklebust, Anna Schumaker,
Richard Weinberger, Zhihao Cheng, ceph-devel, linux-nfs,
linux-mtd
On Wed Sep 9, 2026 at 10:27 AM EDT, David Hildenbrand (Arm) wrote:
> On 9/8/26 04:56, Zi Yan wrote:
>> PG_private is going to be deleted. Adjust related comments to refer to
>> page/folio->private instead.
>
> Thinking again, I think this is misleading.
>
> PG_private is defectively already unused for all of these cases, no? In that
Right.
> case it's rather a documentation fix. (could some of that go into patches that
> convert away from PagePrivate, like in the previous patch?)
Will rephase the message and fold comments in previous patches if
possible.
--
Best Regards,
Yan, Zi
^ permalink raw reply [flat|nested] 37+ messages in thread
* Re: [f2fs-dev] [PATCH v3 00/14] Remove PG_private by using page/folio->private checks instead
2026-09-08 2:56 ` [f2fs-dev] " Zi Yan via Linux-f2fs-devel
@ 2026-09-14 15:30 ` patchwork-bot+f2fs--- via Linux-f2fs-devel
-1 siblings, 0 replies; 37+ messages in thread
From: patchwork-bot+f2fs @ 2026-09-14 15:30 UTC (permalink / raw)
To: Zi Yan
Cc: david, willy, akpm, muchun.song, ljs, liam, vbabka, rppt, surenb,
mhocko, baolin.wang, nico.pache, ryan.roberts, dev.jain, baohua,
lance.yang, usama.arif, gourry, ying.huang, apopple, hannes,
qi.zheng, shakeel.butt, kasong, mark.rutland, irogers, jack,
linux-doc, amarkuze, peterz, kexec, dave.hansen, ruirui.yang,
adrian.hunter, linux-mm, hongbohbli, hpa, guochunhai, skhan,
ceph-devel, baoquan.he, matthew.brost, anna, sstabellini,
zbestahu, rakie.kim, minchan, richard, x86, ebiggers,
alexander.shishkin, mingo, slava, weixugc, yukuai, xen-devel,
xiang, magiclinan, mhiramat, joshua.hahnjy, xiao, byungchul,
james.clark, acme, linux-raid, linux-fscrypt, bp, rostedt,
linux-mtd, axelrasmussen, jefflexu, namhyung, jaegeuk, yuanchu,
idryomov, osalvador, jgross, pratyush, linux-nfs, tytso,
oleksandr_tyshchenko, song, corbet, pasha.tatashin, linux-kernel,
linux-f2fs-devel, linux-perf-users, senozhatsky, tglx, jolsa,
linux-fsdevel, mathieu.desnoyers, linux-trace-kernel, linux-erofs,
trondmy
Hello:
This patch was applied to jaegeuk/f2fs.git (dev)
by Jaegeuk Kim <jaegeuk@kernel.org>:
On Mon, 07 Sep 2026 22:56:07 -0400 you wrote:
> Hi all,
>
> This patchset removes PG_private to make space for upcoming PG_folio
> (reserved as __PG_folio) for identifying pages from a folio (more details
> in Note below). Instead of checking PG_private, all code is changed to
> check page/folio->private != NULL instead.
>
> [...]
Here is the summary with links:
- [f2fs-dev,v3,06/14] f2fs: stop using PG_private
https://git.kernel.org/jaegeuk/f2fs/c/60105162524e
You are awesome, thank you!
--
Deet-doot-dot, I am a bot.
https://korg.docs.kernel.org/patchwork/pwbot.html
^ permalink raw reply [flat|nested] 37+ messages in thread* Re: [f2fs-dev] [PATCH v3 00/14] Remove PG_private by using page/folio->private checks instead
@ 2026-09-14 15:30 ` patchwork-bot+f2fs--- via Linux-f2fs-devel
0 siblings, 0 replies; 37+ messages in thread
From: patchwork-bot+f2fs--- via Linux-f2fs-devel @ 2026-09-14 15:30 UTC (permalink / raw)
To: Zi Yan
Cc: qi.zheng, matthew.brost, apopple, ebiggers, xen-devel, gourry,
acme, linux-fscrypt, skhan, david, surenb, linux-kernel,
nico.pache, linux-perf-users, oleksandr_tyshchenko, mhiramat,
jolsa, linux-fsdevel, akpm, trondmy, mark.rutland, linux-doc,
dave.hansen, song, hongbohbli, ying.huang, sstabellini, vbabka,
senozhatsky, byungchul, linux-trace-kernel, jaegeuk, ljs,
joshua.hahnjy, baohua, kasong, tytso, magiclinan, muchun.song,
linux-f2fs-devel, minchan, lance.yang, tglx, anna, pratyush,
amarkuze, alexander.shishkin, linux-mtd, guochunhai, corbet,
dev.jain, willy, slava, xiang, weixugc, baoquan.he, james.clark,
rostedt, bp, baolin.wang, shakeel.butt, ceph-devel, idryomov,
osalvador, linux-nfs, linux-mm, linux-erofs, rppt, irogers,
mhocko, jack, peterz, ruirui.yang, yuanchu, liam, hpa, zbestahu,
rakie.kim, richard, x86, mingo, yukuai, axelrasmussen,
ryan.roberts, pasha.tatashin, usama.arif, xiao, linux-raid,
jefflexu, namhyung, jgross, kexec, adrian.hunter, hannes,
mathieu.desnoyers
Hello:
This patch was applied to jaegeuk/f2fs.git (dev)
by Jaegeuk Kim <jaegeuk@kernel.org>:
On Mon, 07 Sep 2026 22:56:07 -0400 you wrote:
> Hi all,
>
> This patchset removes PG_private to make space for upcoming PG_folio
> (reserved as __PG_folio) for identifying pages from a folio (more details
> in Note below). Instead of checking PG_private, all code is changed to
> check page/folio->private != NULL instead.
>
> [...]
Here is the summary with links:
- [f2fs-dev,v3,06/14] f2fs: stop using PG_private
https://git.kernel.org/jaegeuk/f2fs/c/60105162524e
You are awesome, thank you!
--
Deet-doot-dot, I am a bot.
https://korg.docs.kernel.org/patchwork/pwbot.html
_______________________________________________
Linux-f2fs-devel mailing list
Linux-f2fs-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel
^ permalink raw reply [flat|nested] 37+ messages in thread