All of lore.kernel.org
 help / color / mirror / Atom feed
From: Sasha Levin <sashal@kernel.org>
To: stable@vger.kernel.org
Cc: Chao Yu <chao@kernel.org>, Jaegeuk Kim <jaegeuk@kernel.org>,
	Sasha Levin <sashal@kernel.org>
Subject: [PATCH 6.12.y 6/7] f2fs: introduce is_{meta,node}_folio
Date: Fri, 11 Sep 2026 21:32:21 -0400	[thread overview]
Message-ID: <20260912013222.1762882-6-sashal@kernel.org> (raw)
In-Reply-To: <20260912013222.1762882-1-sashal@kernel.org>

From: Chao Yu <chao@kernel.org>

[ Upstream commit 019a8912425e231511042a4eae48b7a9e459453c ]

Just cleanup, no changes.

Signed-off-by: Chao Yu <chao@kernel.org>
Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>

Adapt this dependency to the page-based 6.12 tree:

- Use single-evaluation macros for the folio mapping predicates, with a
  NULL mapping check so that a truncated folio is rejected safely. Keep
  the existing page interfaces and pass page_folio() at their call sites.
- Supply folio allocation, release and writeback adapters using the
  existing page helpers. Earlier dependencies already use these missing
  interfaces. Preserve allocation failures as ERR_PTR(-ENOMEM).
- Repair the existing f2fs_get_node_folio() wrapper to use __get_node_page()
  and preserve error pointers; __get_node_folio() and NODE_TYPE_REGULAR
  are not present in this stable tree.
- Use a local last_folio in the fsync retry block, matching the context
  needed for ce366bfa821ec81dd45bde547ee31e659306cc61 to apply unchanged.

No new functions are introduced. The target's retry escape remains in
its own patch.

Stable-dep-of: ce366bfa821e ("f2fs: fix to avoid potential deadloop in f2fs_fsync_node_pages()")
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
 fs/f2fs/checkpoint.c |  4 ++--
 fs/f2fs/data.c       |  2 +-
 fs/f2fs/f2fs.h       | 26 ++++++++++++++++++++++++++
 fs/f2fs/gc.c         |  2 +-
 fs/f2fs/node.c       | 32 +++++++++++++++++++-------------
 5 files changed, 49 insertions(+), 17 deletions(-)

diff --git a/fs/f2fs/checkpoint.c b/fs/f2fs/checkpoint.c
index 6322bf2e16228..03f2623a822fe 100644
--- a/fs/f2fs/checkpoint.c
+++ b/fs/f2fs/checkpoint.c
@@ -93,7 +93,7 @@ static struct page *__get_meta_page(struct f2fs_sb_info *sbi, pgoff_t index,
 	f2fs_update_iostat(sbi, NULL, FS_META_READ_IO, F2FS_BLKSIZE);
 
 	lock_page(page);
-	if (unlikely(page->mapping != mapping)) {
+	if (unlikely(!is_meta_folio(page_folio(page)))) {
 		f2fs_put_page(page, 1);
 		goto repeat;
 	}
@@ -453,7 +453,7 @@ long f2fs_sync_meta_pages(struct f2fs_sb_info *sbi, enum page_type type,
 
 			folio_lock(folio);
 
-			if (unlikely(folio->mapping != mapping)) {
+			if (unlikely(!is_meta_folio(folio))) {
 continue_unlock:
 				folio_unlock(folio);
 				continue;
diff --git a/fs/f2fs/data.c b/fs/f2fs/data.c
index ec816df4887cc..a57dd4dc5fd2b 100644
--- a/fs/f2fs/data.c
+++ b/fs/f2fs/data.c
@@ -353,7 +353,7 @@ static void f2fs_write_end_io(struct bio *bio)
 						STOP_CP_REASON_WRITE_FAIL);
 		}
 
-		f2fs_bug_on(sbi, page->mapping == NODE_MAPPING(sbi) &&
+		f2fs_bug_on(sbi, is_node_folio(page_folio(page)) &&
 				page_folio(page)->index != nid_of_node(page));
 		if (f2fs_in_warm_node_list(sbi, page))
 			f2fs_del_fsync_node_entry(sbi, page);
diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h
index 67c5b9cb90ee6..a055673524f3c 100644
--- a/fs/f2fs/f2fs.h
+++ b/fs/f2fs/f2fs.h
@@ -2100,6 +2100,17 @@ static inline struct address_space *NODE_MAPPING(struct f2fs_sb_info *sbi)
 	return sbi->node_inode->i_mapping;
 }
 
+/* The caller holds the folio lock or otherwise stabilizes its mapping. */
+#define is_meta_folio(folio) ({						\
+	struct address_space *__mapping = (folio)->mapping;		\
+	__mapping && __mapping == META_MAPPING(F2FS_M_SB(__mapping));	\
+})
+
+#define is_node_folio(folio) ({						\
+	struct address_space *__mapping = (folio)->mapping;		\
+	__mapping && __mapping == NODE_MAPPING(F2FS_M_SB(__mapping));	\
+})
+
 static inline bool is_sbi_flag_set(struct f2fs_sb_info *sbi, unsigned int type)
 {
 	return test_bit(type, &sbi->s_flag);
@@ -2868,6 +2879,13 @@ static inline struct page *f2fs_grab_cache_page(struct address_space *mapping,
 	return page;
 }
 
+/* Folio adapters for the page-based stable-tree helpers. */
+#define f2fs_grab_cache_folio(mapping, index, for_write) ({		\
+	struct page *__page = f2fs_grab_cache_page(mapping, index,		\
+						 for_write);		\
+	__page ? page_folio(__page) : ERR_PTR(-ENOMEM);			\
+})
+
 static inline struct page *f2fs_pagecache_get_page(
 				struct address_space *mapping, pgoff_t index,
 				fgf_t fgp_flags, gfp_t gfp_mask)
@@ -2890,6 +2908,12 @@ static inline void f2fs_put_page(struct page *page, int unlock)
 	put_page(page);
 }
 
+#define f2fs_folio_put(_folio, unlock) do {				\
+	struct folio *__folio = (_folio);					\
+	if (!IS_ERR_OR_NULL(__folio))					\
+		f2fs_put_page(&__folio->page, unlock);			\
+} while (0)
+
 static inline void f2fs_put_dnode(struct dnode_of_data *dn)
 {
 	if (dn->node_page)
@@ -3839,6 +3863,8 @@ void f2fs_update_device_state(struct f2fs_sb_info *sbi, nid_t ino,
 					block_t blkaddr, unsigned int blkcnt);
 void f2fs_wait_on_page_writeback(struct page *page,
 			enum page_type type, bool ordered, bool locked);
+#define f2fs_folio_wait_writeback(folio, type, ordered, locked)		\
+	f2fs_wait_on_page_writeback(&(folio)->page, type, ordered, locked)
 void f2fs_wait_on_block_writeback(struct inode *inode, block_t blkaddr);
 void f2fs_wait_on_block_writeback_range(struct inode *inode, block_t blkaddr,
 								block_t len);
diff --git a/fs/f2fs/gc.c b/fs/f2fs/gc.c
index fbd246b3e550a..f29d461bdb1ef 100644
--- a/fs/f2fs/gc.c
+++ b/fs/f2fs/gc.c
@@ -1425,7 +1425,7 @@ static int move_data_block(struct inode *inode, block_t bidx,
 							F2FS_BLKSIZE);
 
 		folio_lock(mfolio);
-		if (unlikely(mfolio->mapping != META_MAPPING(fio.sbi) ||
+		if (unlikely(!is_meta_folio(mfolio) ||
 			     !folio_test_uptodate(mfolio))) {
 			err = -EIO;
 			f2fs_folio_put(mfolio, true);
diff --git a/fs/f2fs/node.c b/fs/f2fs/node.c
index 1463488fcd832..ce75669332efc 100644
--- a/fs/f2fs/node.c
+++ b/fs/f2fs/node.c
@@ -317,7 +317,7 @@ static unsigned int __gang_lookup_nat_set(struct f2fs_nm_info *nm_i,
 
 bool f2fs_in_warm_node_list(struct f2fs_sb_info *sbi, struct page *page)
 {
-	return NODE_MAPPING(sbi) == page->mapping &&
+	return is_node_folio(page_folio(page)) &&
 			IS_DNODE(page) && is_cold_node(page);
 }
 
@@ -1234,7 +1234,7 @@ int f2fs_truncate_inode_blocks(struct inode *inode, pgoff_t from)
 		if (offset[1] == 0 &&
 				ri->i_nid[offset[0] - NODE_DIR1_BLOCK]) {
 			lock_page(page);
-			BUG_ON(page->mapping != NODE_MAPPING(sbi));
+			BUG_ON(!is_node_folio(page_folio(page)));
 			f2fs_wait_on_page_writeback(page, NODE, true, true);
 			ri->i_nid[offset[0] - NODE_DIR1_BLOCK] = 0;
 			set_page_dirty(page);
@@ -1500,7 +1500,7 @@ static struct page *__get_node_page(struct f2fs_sb_info *sbi, pgoff_t nid,
 
 	lock_page(page);
 
-	if (unlikely(page->mapping != NODE_MAPPING(sbi))) {
+	if (unlikely(!is_node_folio(page_folio(page)))) {
 		f2fs_put_page(page, 1);
 		goto repeat;
 	}
@@ -1537,7 +1537,11 @@ static struct page *__get_node_page(struct f2fs_sb_info *sbi, pgoff_t nid,
 
 struct folio *f2fs_get_node_folio(struct f2fs_sb_info *sbi, pgoff_t nid)
 {
-	return __get_node_folio(sbi, nid, NULL, 0, NODE_TYPE_REGULAR);
+	struct page *page = __get_node_page(sbi, nid, NULL, 0);
+
+	if (IS_ERR(page))
+		return ERR_CAST(page);
+	return page_folio(page);
 }
 
 struct page *f2fs_get_node_page(struct f2fs_sb_info *sbi, pgoff_t nid)
@@ -1620,7 +1624,7 @@ static struct page *last_fsync_dnode(struct f2fs_sb_info *sbi, nid_t ino)
 
 			lock_page(page);
 
-			if (unlikely(page->mapping != NODE_MAPPING(sbi))) {
+			if (unlikely(!is_node_folio(page_folio(page)))) {
 continue_unlock:
 				unlock_page(page);
 				continue;
@@ -1854,7 +1858,7 @@ int f2fs_fsync_node_pages(struct f2fs_sb_info *sbi, struct inode *inode,
 
 			lock_page(page);
 
-			if (unlikely(page->mapping != NODE_MAPPING(sbi))) {
+			if (unlikely(!is_node_folio(page_folio(page)))) {
 continue_unlock:
 				unlock_page(page);
 				continue;
@@ -1916,12 +1920,14 @@ int f2fs_fsync_node_pages(struct f2fs_sb_info *sbi, struct inode *inode,
 			break;
 	}
 	if (!ret && atomic && !marked) {
+		struct folio *last_folio = page_folio(last_page);
+
 		f2fs_debug(sbi, "Retry to write fsync mark: ino=%u, idx=%lx",
-			   ino, page_folio(last_page)->index);
-		lock_page(last_page);
-		f2fs_wait_on_page_writeback(last_page, NODE, true, true);
-		set_page_dirty(last_page);
-		unlock_page(last_page);
+			   ino, last_folio->index);
+		folio_lock(last_folio);
+		f2fs_folio_wait_writeback(last_folio, NODE, true, true);
+		folio_mark_dirty(last_folio);
+		folio_unlock(last_folio);
 		goto retry;
 	}
 out:
@@ -1992,7 +1998,7 @@ void f2fs_flush_inline_data(struct f2fs_sb_info *sbi)
 
 			lock_page(page);
 
-			if (unlikely(page->mapping != NODE_MAPPING(sbi))) {
+			if (unlikely(!is_node_folio(page_folio(page)))) {
 continue_unlock:
 				unlock_page(page);
 				continue;
@@ -2069,7 +2075,7 @@ int f2fs_sync_node_pages(struct f2fs_sb_info *sbi,
 			else if (!trylock_page(page))
 				continue;
 
-			if (unlikely(page->mapping != NODE_MAPPING(sbi))) {
+			if (unlikely(!is_node_folio(page_folio(page)))) {
 continue_unlock:
 				unlock_page(page);
 				continue;
-- 
2.53.0


  parent reply	other threads:[~2026-09-12  1:32 UTC|newest]

Thread overview: 9+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-09-09 11:26 FAILED: patch "[PATCH] f2fs: fix to avoid potential deadloop in" failed to apply to 6.12-stable tree gregkh
2026-09-12  1:32 ` [PATCH 6.12.y 1/7] f2fs: Use a folio in move_data_block() Sasha Levin
2026-09-12  1:32   ` [PATCH 6.12.y 2/7] f2fs: Add f2fs_new_node_folio() Sasha Levin
2026-09-30 13:42     ` Greg KH
2026-09-12  1:32   ` [PATCH 6.12.y 3/7] f2fs: Add f2fs_get_node_folio() Sasha Levin
2026-09-12  1:32   ` [PATCH 6.12.y 4/7] f2fs: Use a folio in truncate_nodes() Sasha Levin
2026-09-12  1:32   ` [PATCH 6.12.y 5/7] f2fs: Use folios in truncate_partial_nodes() Sasha Levin
2026-09-12  1:32   ` Sasha Levin [this message]
2026-09-12  1:32   ` [PATCH 6.12.y 7/7] f2fs: fix to avoid potential deadloop in f2fs_fsync_node_pages() Sasha Levin

Reply instructions:

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

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

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

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

  git send-email \
    --in-reply-to=20260912013222.1762882-6-sashal@kernel.org \
    --to=sashal@kernel.org \
    --cc=chao@kernel.org \
    --cc=jaegeuk@kernel.org \
    --cc=stable@vger.kernel.org \
    /path/to/YOUR_REPLY

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

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