From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-alma10-1.taild15c8.ts.net [100.103.45.18]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 2D02470830 for ; Thu, 20 Aug 2026 05:11:08 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=100.103.45.18 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1787202673; cv=none; b=ZXc2xEdowVhRE6fG2toGEd3LKvlslsUz1ed+eWMyQbh2VcSGtrZ3R7IGqgvje4byDCOtws+OPxT4huzPqxdgGOAy5+pLBmG2Og9Jde6EkHxLOOE7KIw6JBP1I4ibE4yZISZvil0TK+booUP708nj8BR5jUUfx3yDDWAPsdlFwoQ= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1787202673; c=relaxed/simple; bh=2rvesGqzo4VerWV4P1M0+ssfXimEy6/KNpmp/96NLlE=; h=Date:From:To:Cc:Subject:Message-ID:References:MIME-Version: Content-Type:Content-Disposition:In-Reply-To; b=WWXJbitsLC3FWvrrEFN3+2x1M5vx2wf0JNxgTukJzuopnTAwhY/RzF6WL+i7FGBKUt546zY07cLBZODUCUVHXJyIl7gFKxpg80GR/LA6Z6WyYyzs91uiKrn0XwP7dhqYeh53jzEMEip3Y4vPvaoqZhUUqcgh5VhmAePnXizrqoo= ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=SfHylVxQ; arc=none smtp.client-ip=100.103.45.18 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="SfHylVxQ" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 8EBE11F000E9; Thu, 20 Aug 2026 05:11:08 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=kernel.org; s=k20260515; t=1787202668; bh=7Tl9iK7FVCmFxTt6cStgJFHHMMXxyTMgPUsN8Xf9Lgw=; h=Date:From:To:Cc:Subject:References:In-Reply-To; b=SfHylVxQGc7xf+hpWNRw4kobQj2392dq8rgBdRG7v9ymqwEFIvidmpGtdUHVIQtIr ij+ipw0daKxXZxrV8dZE2HTPDfuvCQx16Wip3LlYMyIJ83nxjFE1R9M4BeWN9rmAN1 BtI83juMXaMwmunra0odWMXZ7fHuKTzlOFrX5Q7ruHLZaWtwAXF9PzKjqswS8aufyq ri4Fq/M3kioWMuY0G4ONk5GdUDJKqo2quOzIfSjWMQgBK4dxNJTtHRy3OVv3iGNAQU Cgij18kvALw6i5nJHMVYxXPRj2lX7tgxkLYPMQ5HvNisljhboBFhP8IMmly8XqKHeE ANsFQAewR7BIw== Date: Thu, 20 Aug 2026 05:11:07 +0000 From: Jaegeuk Kim To: Chao Yu Cc: linux-kernel@vger.kernel.org, linux-f2fs-devel@lists.sourceforge.net Subject: Re: [f2fs-dev] [PATCH v1 05/12] f2fs: cache: use meta cache Message-ID: References: <20260820031721.12218-1-chao@kernel.org> <20260820031721.12218-6-chao@kernel.org> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20260820031721.12218-6-chao@kernel.org> On 08/20, Chao Yu via Linux-f2fs-devel wrote: > This patch migrates F2FS meta block caching from the fake VFS inode > page cache (sbi->meta_inode) to meta cache (sbi->meta_blocks). > > It converts CP, SIT, NAT, SSA, recovery, and GC metadata I/O paths to > operate on struct f2fs_cached_block instead of folio, and removes > sbi->meta_inode. > > Signed-off-by: Chao Yu > --- > fs/f2fs/cache.c | 2 + > fs/f2fs/checkpoint.c | 394 ++++++++++++++++++---------------------- > fs/f2fs/compress.c | 4 +- > fs/f2fs/data.c | 29 ++- > fs/f2fs/debug.c | 12 +- > fs/f2fs/f2fs.h | 81 +++------ > fs/f2fs/file.c | 4 +- > fs/f2fs/gc.c | 134 +++++++------- > fs/f2fs/inline.c | 9 +- > fs/f2fs/inode.c | 9 +- > fs/f2fs/node.c | 125 +++++++------ > fs/f2fs/node.h | 4 +- > fs/f2fs/recovery.c | 198 ++++++++++---------- > fs/f2fs/segment.c | 201 ++++++++++---------- > fs/f2fs/segment.h | 31 +++- > fs/f2fs/super.c | 31 +--- > include/linux/f2fs_fs.h | 1 - > 17 files changed, 606 insertions(+), 663 deletions(-) > > diff --git a/fs/f2fs/cache.c b/fs/f2fs/cache.c > index cb5b26046162..afef808e485a 100644 > --- a/fs/f2fs/cache.c > +++ b/fs/f2fs/cache.c > @@ -631,6 +631,8 @@ static int f2fs_cache_writeback_kthread(void *data) > break; > if (f2fs_cp_error(sbi)) > continue; > + > + f2fs_write_meta_caches(sbi); > } > return 0; > } > diff --git a/fs/f2fs/checkpoint.c b/fs/f2fs/checkpoint.c > index 729d19680caf..1a7083540b82 100644 > --- a/fs/f2fs/checkpoint.c > +++ b/fs/f2fs/checkpoint.c > @@ -17,6 +17,7 @@ > #include > #include > #include > +#include > > #include "f2fs.h" > #include "node.h" > @@ -235,27 +236,27 @@ struct kmem_cache *f2fs_inode_entry_slab; > /* > * We guarantee no failure on the returned page. > */ > -struct folio *f2fs_grab_meta_folio(struct f2fs_sb_info *sbi, pgoff_t index) > +struct f2fs_cached_block *f2fs_grab_meta_cache(struct f2fs_sb_info *sbi, > + pgoff_t index) > { > - struct address_space *mapping = META_MAPPING(sbi); > - struct folio *folio; > + struct f2fs_cached_block *entry; > repeat: > - folio = f2fs_grab_cache_folio(mapping, index, false); > - if (IS_ERR(folio)) { > + entry = f2fs_grab_cache(META_CACHE(sbi), index, > + F2FS_CACHE_LOCK_CREATE); > + if (IS_ERR(entry)) { > cond_resched(); > goto repeat; > } > - f2fs_folio_wait_writeback(folio, META, true, true); > - if (!folio_test_uptodate(folio)) > - folio_mark_uptodate(folio); > - return folio; > + f2fs_cache_wait_writeback(entry); > + if (!f2fs_cache_test_uptodate(entry)) > + f2fs_cache_set_uptodate(entry); > + return entry; > } > > -static struct folio *__get_meta_folio(struct f2fs_sb_info *sbi, pgoff_t index, > - bool is_meta) > +static struct f2fs_cached_block *__get_meta_cache(struct f2fs_sb_info *sbi, > + pgoff_t index, bool is_meta) > { > - struct address_space *mapping = META_MAPPING(sbi); > - struct folio *folio; > + struct f2fs_cached_block *entry; > struct f2fs_io_info fio = { > .sbi = sbi, > .type = META, > @@ -265,70 +266,75 @@ static struct folio *__get_meta_folio(struct f2fs_sb_info *sbi, pgoff_t index, > .new_blkaddr = index, > .encrypted_page = NULL, > .is_por = !is_meta ? 1 : 0, > + .is_cache = 1, > }; > int err; > > if (unlikely(!is_meta)) > fio.op_flags &= ~REQ_META; > repeat: > - folio = f2fs_grab_cache_folio(mapping, index, false); > - if (IS_ERR(folio)) { > + entry = f2fs_grab_cache(META_CACHE(sbi), index, > + F2FS_CACHE_LOCK_CREATE); > + if (IS_ERR(entry)) { > cond_resched(); > goto repeat; > } > - if (folio_test_uptodate(folio)) > + if (f2fs_cache_test_uptodate(entry)) > goto out; > > - fio.folio = folio; > + fio.cache_entry = entry; > > - err = f2fs_submit_page_bio(&fio); > + err = f2fs_submit_cache_read(&fio); > if (err) { > - f2fs_folio_put(folio, true); > + f2fs_put_cache(entry, true); > return ERR_PTR(err); > } > > f2fs_update_iostat(sbi, NULL, FS_META_READ_IO, F2FS_BLKSIZE); > > - folio_lock(folio); > - if (unlikely(!is_meta_folio(folio))) { > - f2fs_folio_put(folio, true); > + f2fs_lock_cache(entry); > + if (unlikely(!f2fs_is_meta_cache(entry))) { > + f2fs_put_cache(entry, true); > goto repeat; > } > > - if (unlikely(!folio_test_uptodate(folio))) { > - f2fs_handle_page_eio(sbi, folio, META); > - f2fs_folio_put(folio, true); > + if (unlikely(!f2fs_cache_test_uptodate(entry))) { > + f2fs_handle_page_eio(sbi, entry->index, META); > + f2fs_put_cache(entry, true); > return ERR_PTR(-EIO); > } > out: > - return folio; > + return entry; > } > > -struct folio *f2fs_get_meta_folio(struct f2fs_sb_info *sbi, pgoff_t index) > +struct f2fs_cached_block *f2fs_get_meta_cache(struct f2fs_sb_info *sbi, > + pgoff_t index) > { > - return __get_meta_folio(sbi, index, true); > + return __get_meta_cache(sbi, index, true); > } > > -struct folio *f2fs_get_meta_folio_retry(struct f2fs_sb_info *sbi, pgoff_t index) > +struct f2fs_cached_block *f2fs_get_meta_cache_retry(struct f2fs_sb_info *sbi, > + pgoff_t index) > { > - struct folio *folio; > + struct f2fs_cached_block *entry; > int count = 0; > > retry: > - folio = __get_meta_folio(sbi, index, true); > - if (IS_ERR(folio)) { > - if (PTR_ERR(folio) == -EIO && > + entry = __get_meta_cache(sbi, index, true); > + if (IS_ERR(entry)) { > + if (PTR_ERR(entry) == -EIO && > ++count <= DEFAULT_RETRY_IO_COUNT) > goto retry; > f2fs_stop_checkpoint(sbi, false, STOP_CP_REASON_META_PAGE); > } > - return folio; > + return entry; > } > > /* for POR only */ > -struct folio *f2fs_get_tmp_folio(struct f2fs_sb_info *sbi, pgoff_t index) > +struct f2fs_cached_block *f2fs_get_tmp_cache(struct f2fs_sb_info *sbi, > + pgoff_t index) > { > - return __get_meta_folio(sbi, index, false); > + return __get_meta_cache(sbi, index, false); > } > > static bool __is_bitmap_valid(struct f2fs_sb_info *sbi, block_t blkaddr, > @@ -446,9 +452,10 @@ bool f2fs_is_valid_blkaddr_raw(struct f2fs_sb_info *sbi, > /* > * Readahead CP/NAT/SIT/SSA/POR pages > */ > -int f2fs_ra_meta_pages(struct f2fs_sb_info *sbi, block_t start, int nrpages, > - int type, bool sync) > +int f2fs_ra_meta_caches(struct f2fs_sb_info *sbi, block_t start, > + int nrpages, int type, bool sync) > { > + struct f2fs_cached_block_list *cache = META_CACHE(sbi); > block_t blkno = start; > struct f2fs_io_info fio = { > .sbi = sbi, > @@ -458,6 +465,7 @@ int f2fs_ra_meta_pages(struct f2fs_sb_info *sbi, block_t start, int nrpages, > .encrypted_page = NULL, > .in_list = 0, > .is_por = (type == META_POR) ? 1 : 0, > + .is_cache = 1, > }; > struct blk_plug plug; > int err; > @@ -467,7 +475,7 @@ int f2fs_ra_meta_pages(struct f2fs_sb_info *sbi, block_t start, int nrpages, > > blk_start_plug(&plug); > for (; nrpages-- > 0; blkno++) { > - struct folio *folio; > + struct f2fs_cached_block *entry; > > if (!f2fs_is_valid_blkaddr(sbi, blkno, type)) > goto out; > @@ -494,62 +502,58 @@ int f2fs_ra_meta_pages(struct f2fs_sb_info *sbi, block_t start, int nrpages, > fio.new_blkaddr = blkno; > break; > default: > - BUG(); > + f2fs_bug_on(sbi, 1); > } > > - folio = f2fs_grab_cache_folio(META_MAPPING(sbi), > - fio.new_blkaddr, false); > - if (IS_ERR(folio)) > + entry = f2fs_grab_cache(cache, fio.new_blkaddr, > + F2FS_CACHE_LOCK_CREATE); > + if (IS_ERR(entry)) > continue; > - if (folio_test_uptodate(folio)) { > - f2fs_folio_put(folio, true); > + if (f2fs_cache_test_uptodate(entry)) { > + f2fs_put_cache(entry, true); > continue; > } > > - fio.folio = folio; > - err = f2fs_submit_page_bio(&fio); > - f2fs_folio_put(folio, err ? true : false); > + fio.cache_entry = entry; > + err = f2fs_submit_cache_read(&fio); > + f2fs_put_cache(entry, err ? true : false); > > if (!err) > f2fs_update_iostat(sbi, NULL, FS_META_READ_IO, > - F2FS_BLKSIZE); > + sbi->blocksize); > } > out: > blk_finish_plug(&plug); > return blkno - start; > } > > -void f2fs_ra_meta_pages_cond(struct f2fs_sb_info *sbi, pgoff_t index, > - unsigned int ra_blocks) > +void f2fs_ra_meta_caches_cond(struct f2fs_sb_info *sbi, pgoff_t index, > + unsigned int ra_blocks) > { > - struct folio *folio; > + struct f2fs_cached_block *entry; > bool readahead = false; > > if (ra_blocks == RECOVERY_MIN_RA_BLOCKS) > return; > > - folio = filemap_get_folio(META_MAPPING(sbi), index); > - if (IS_ERR(folio) || !folio_test_uptodate(folio)) > + entry = f2fs_find_cache(META_CACHE(sbi), index); > + if (IS_ERR(entry) || !f2fs_cache_test_uptodate(entry)) > readahead = true; > - f2fs_folio_put(folio, false); > + f2fs_put_cache(entry, false); > > if (readahead) > - f2fs_ra_meta_pages(sbi, index, ra_blocks, META_POR, true); > + f2fs_ra_meta_caches(sbi, index, ra_blocks, META_POR, true); > } > > -static bool __f2fs_write_meta_folio(struct folio *folio, > - struct writeback_control *wbc, > +static bool __f2fs_write_meta_cache(struct f2fs_cached_block *entry, > enum iostat_type io_type) > { > - struct f2fs_sb_info *sbi = F2FS_F_SB(folio); > - > - trace_f2fs_writepage(folio, META); > + struct f2fs_sb_info *sbi = entry->cache->sbi; > > if (unlikely(f2fs_cp_error(sbi))) { > if (is_sbi_flag_set(sbi, SBI_IS_CLOSE)) { > - folio_clear_uptodate(folio); > - dec_page_count(sbi, F2FS_DIRTY_META); > - folio_unlock(folio); > + f2fs_force_clear_cache_dirty(entry); > + f2fs_unlock_cache(entry); > return true; > } > goto redirty_out; > @@ -557,10 +561,10 @@ static bool __f2fs_write_meta_folio(struct folio *folio, > if (unlikely(is_sbi_flag_set(sbi, SBI_POR_DOING))) > goto redirty_out; > > - f2fs_do_write_meta_page(sbi, folio, io_type); > + f2fs_do_write_meta_cache(sbi, entry, io_type); > dec_page_count(sbi, F2FS_DIRTY_META); > > - folio_unlock(folio); > + f2fs_unlock_cache(entry); > > if (unlikely(f2fs_cp_error(sbi))) > f2fs_submit_merged_write(sbi, META); > @@ -568,101 +572,89 @@ static bool __f2fs_write_meta_folio(struct folio *folio, > return true; > > redirty_out: > - folio_redirty_for_writepage(wbc, folio); > + f2fs_cache_set_dirty(entry); > return false; > } > > -static int f2fs_write_meta_pages(struct address_space *mapping, > - struct writeback_control *wbc) > +void f2fs_write_meta_caches(struct f2fs_sb_info *sbi) > { > - struct f2fs_sb_info *sbi = F2FS_M_SB(mapping); > struct f2fs_lock_context lc; > - long diff, written; > + long nr_to_write = LONG_MAX; > > if (unlikely(is_sbi_flag_set(sbi, SBI_POR_DOING))) > - goto skip_write; > + return; > > - /* collect a number of dirty meta pages and write together */ > - if (wbc->sync_mode != WB_SYNC_ALL && > - get_pages(sbi, F2FS_DIRTY_META) < > - nr_pages_to_skip(sbi, META)) > - goto skip_write; > + /* collect a number of dirty meta caches and write together */ > + if (get_pages(sbi, F2FS_DIRTY_META) < > + nr_pages_to_skip(sbi, META)) > + return; > > - /* if locked failed, cp will flush dirty pages instead */ > + /* if locked failed, cp will flush dirty caches instead */ > if (!f2fs_down_write_trylock_trace(&sbi->cp_global_sem, &lc)) > - goto skip_write; > + return; > > - trace_f2fs_writepages(mapping->host, wbc, META); > - diff = nr_pages_to_write(sbi, META, wbc); > - written = f2fs_sync_meta_pages(sbi, wbc->nr_to_write, FS_META_IO); > + nr_to_write = adjust_flush_cache_number(sbi, META); > + f2fs_sync_meta_caches(sbi, nr_to_write, false, FS_META_IO); > f2fs_up_write_trace(&sbi->cp_global_sem, &lc); > - wbc->nr_to_write = max((long)0, wbc->nr_to_write - written - diff); > - return 0; > - > -skip_write: > - wbc->pages_skipped += get_pages(sbi, F2FS_DIRTY_META); > - trace_f2fs_writepages(mapping->host, wbc, META); > - return 0; > } > > -long f2fs_sync_meta_pages(struct f2fs_sb_info *sbi, long nr_to_write, > - enum iostat_type io_type) > +long f2fs_sync_meta_caches(struct f2fs_sb_info *sbi, long nr_to_write, > + bool sync, enum iostat_type io_type) > { > - struct address_space *mapping = META_MAPPING(sbi); > pgoff_t index = 0, prev = ULONG_MAX; > - struct folio_batch fbatch; > + struct f2fs_cached_block *entries[F2FS_ONSTACK_CACHES]; > long nwritten = 0; > - int nr_folios; > - struct writeback_control wbc = {}; > + int nr; > struct blk_plug plug; > - > - folio_batch_init(&fbatch); > + bool background = nr_to_write != LONG_MAX; > > blk_start_plug(&plug); > > - while ((nr_folios = filemap_get_folios_tag(mapping, &index, > - (pgoff_t)-1, > - PAGECACHE_TAG_DIRTY, &fbatch))) { > + while ((nr = f2fs_cache_gang_lookup_tag(META_CACHE(sbi), entries, > + &index, F2FS_ONSTACK_CACHES, F2FS_CACHE_TAG_DIRTY))) { > int i; > > - for (i = 0; i < nr_folios; i++) { > - struct folio *folio = fbatch.folios[i]; > + for (i = 0; i < nr; i++) { > + struct f2fs_cached_block *entry = entries[i]; > + > + if (background && unlikely(freezing(current))) { > + f2fs_cache_gang_release(entries, nr); > + goto stop; > + } > > - if (nr_to_write != LONG_MAX && i != 0 && > - folio->index != prev + > - folio_nr_pages(fbatch.folios[i-1])) { > - folio_batch_release(&fbatch); > + if (background && i != 0 && > + entry->index != prev + 1) { > + f2fs_cache_gang_release(entries, nr); > goto stop; > } > > - folio_lock(folio); > + f2fs_lock_cache(entry); > > - if (unlikely(!is_meta_folio(folio))) { > + if (unlikely(!f2fs_is_meta_cache(entry))) { > continue_unlock: > - folio_unlock(folio); > + f2fs_unlock_cache(entry); > continue; > } > - if (!folio_test_dirty(folio)) { > + if (!f2fs_cache_test_dirty(entry)) { > /* someone wrote it for us */ > goto continue_unlock; > } > > - f2fs_folio_wait_writeback(folio, META, true, true); > + f2fs_cache_wait_writeback(entry); > > - if (!folio_clear_dirty_for_io(folio)) > + if (!f2fs_clear_cache_dirty(entry)) > goto continue_unlock; > > - if (!__f2fs_write_meta_folio(folio, &wbc, > - io_type)) { > - folio_unlock(folio); > + if (!__f2fs_write_meta_cache(entry, io_type)) { > + f2fs_unlock_cache(entry); > break; > } > - nwritten += folio_nr_pages(folio); > - prev = folio->index; > + nwritten += sbi->blocksize; > + prev = entry->index; > if (unlikely(nwritten >= nr_to_write)) > break; > } > - folio_batch_release(&fbatch); > + f2fs_cache_gang_release(entries, nr); > cond_resched(); > } > stop: > @@ -674,29 +666,6 @@ long f2fs_sync_meta_pages(struct f2fs_sb_info *sbi, long nr_to_write, > return nwritten; > } > > -static bool f2fs_dirty_meta_folio(struct address_space *mapping, > - struct folio *folio) > -{ > - trace_f2fs_set_page_dirty(folio, META); > - > - if (!folio_test_uptodate(folio)) > - folio_mark_uptodate(folio); > - if (filemap_dirty_folio(mapping, folio)) { > - inc_page_count(F2FS_M_SB(mapping), F2FS_DIRTY_META); > - folio_set_f2fs_reference(folio); > - return true; > - } > - return false; > -} > - > -const struct address_space_operations f2fs_meta_aops = { > - .writepages = f2fs_write_meta_pages, > - .dirty_folio = f2fs_dirty_meta_folio, > - .invalidate_folio = f2fs_invalidate_folio, > - .release_folio = f2fs_release_folio, > - .migrate_folio = filemap_migrate_folio, > -}; > - > static void __add_ino_entry(struct f2fs_sb_info *sbi, nid_t ino, > unsigned int devidx, int type) > { > @@ -1036,20 +1005,20 @@ int f2fs_recover_orphan_inodes(struct f2fs_sb_info *sbi) > start_blk = __start_cp_addr(sbi) + 1 + __cp_payload(sbi); > orphan_blocks = __start_sum_addr(sbi) - 1 - __cp_payload(sbi); > > - f2fs_ra_meta_pages(sbi, start_blk, orphan_blocks, META_CP, true); > + f2fs_ra_meta_caches(sbi, start_blk, orphan_blocks, META_CP, true); > > for (i = 0; i < orphan_blocks; i++) { > - struct folio *folio; > + struct f2fs_cached_block *entry; > struct f2fs_orphan_block *orphan_blk; > unsigned int entry_count; > > - folio = f2fs_get_meta_folio(sbi, start_blk + i); > - if (IS_ERR(folio)) { > - err = PTR_ERR(folio); > + entry = f2fs_get_meta_cache(sbi, start_blk + i); > + if (IS_ERR(entry)) { > + err = PTR_ERR(entry); > goto out; > } > > - orphan_blk = folio_address(folio); > + orphan_blk = cache_address(entry); > entry_count = le32_to_cpu(orphan_blk->entry_count); > if (entry_count > F2FS_ORPHANS_PER_BLOCK) { > f2fs_err(sbi, "invalid orphan inode entry count %u", > @@ -1057,7 +1026,7 @@ int f2fs_recover_orphan_inodes(struct f2fs_sb_info *sbi) > set_sbi_flag(sbi, SBI_NEED_FSCK); > f2fs_handle_error(sbi, ERROR_INCONSISTENT_ORPHAN); > err = -EFSCORRUPTED; > - f2fs_folio_put(folio, true); > + f2fs_put_cache(entry, true); > goto out; > } > > @@ -1066,11 +1035,11 @@ int f2fs_recover_orphan_inodes(struct f2fs_sb_info *sbi) > > err = recover_orphan_inode(sbi, ino); > if (err) { > - f2fs_folio_put(folio, true); > + f2fs_put_cache(entry, true); > goto out; > } > } > - f2fs_folio_put(folio, true); > + f2fs_put_cache(entry, true); > } > /* clear Orphan Flag */ > clear_ckpt_flags(sbi, CP_ORPHAN_PRESENT_FLAG); > @@ -1087,9 +1056,9 @@ static void write_orphan_inodes(struct f2fs_sb_info *sbi, block_t start_blk) > unsigned int nentries = 0; > unsigned short index = 1; > unsigned short orphan_blocks; > - struct folio *folio = NULL; > struct ino_entry *orphan = NULL; > struct inode_management *im = &sbi->im[ORPHAN_INO]; > + struct f2fs_cached_block *entry = NULL; > > orphan_blocks = GET_ORPHAN_BLOCKS(im->ino_num); > > @@ -1102,9 +1071,9 @@ static void write_orphan_inodes(struct f2fs_sb_info *sbi, block_t start_blk) > > /* loop for each orphan inode entry and write them in journal block */ > list_for_each_entry(orphan, head, list) { > - if (!folio) { > - folio = f2fs_grab_meta_folio(sbi, start_blk++); > - orphan_blk = folio_address(folio); > + if (!entry) { > + entry = f2fs_grab_meta_cache(sbi, start_blk++); > + orphan_blk = (struct f2fs_orphan_block *)cache_address(entry); > memset(orphan_blk, 0, sizeof(*orphan_blk)); > } > > @@ -1119,20 +1088,20 @@ static void write_orphan_inodes(struct f2fs_sb_info *sbi, block_t start_blk) > orphan_blk->blk_addr = cpu_to_le16(index); > orphan_blk->blk_count = cpu_to_le16(orphan_blocks); > orphan_blk->entry_count = cpu_to_le32(nentries); > - folio_mark_dirty(folio); > - f2fs_folio_put(folio, true); > + f2fs_mark_cache_dirty(entry); > + f2fs_put_cache(entry, true); > index++; > nentries = 0; > - folio = NULL; > + entry = NULL; > } > } > > - if (folio) { > + if (entry) { > orphan_blk->blk_addr = cpu_to_le16(index); > orphan_blk->blk_count = cpu_to_le16(orphan_blocks); > orphan_blk->entry_count = cpu_to_le32(nentries); > - folio_mark_dirty(folio); > - f2fs_folio_put(folio, true); > + f2fs_mark_cache_dirty(entry); > + f2fs_put_cache(entry, true); > } > } > > @@ -1151,29 +1120,29 @@ static __u32 f2fs_checkpoint_chksum(struct f2fs_checkpoint *ckpt) > } > > static int get_checkpoint_version(struct f2fs_sb_info *sbi, block_t cp_addr, > - struct f2fs_checkpoint **cp_block, struct folio **cp_folio, > + struct f2fs_checkpoint **cp_block, struct f2fs_cached_block **cp_entry, > unsigned long long *version) > { > size_t crc_offset = 0; > __u32 crc; > > - *cp_folio = f2fs_get_meta_folio(sbi, cp_addr); > - if (IS_ERR(*cp_folio)) > - return PTR_ERR(*cp_folio); > + *cp_entry = f2fs_get_meta_cache(sbi, cp_addr); > + if (IS_ERR(*cp_entry)) > + return PTR_ERR(*cp_entry); > > - *cp_block = folio_address(*cp_folio); > + *cp_block = (struct f2fs_checkpoint *)cache_address(*cp_entry); > > crc_offset = le32_to_cpu((*cp_block)->checksum_offset); > if (crc_offset < CP_MIN_CHKSUM_OFFSET || > crc_offset > CP_CHKSUM_OFFSET) { > - f2fs_folio_put(*cp_folio, true); > + f2fs_put_cache(*cp_entry, true); > f2fs_warn(sbi, "invalid crc_offset: %zu", crc_offset); > return -EINVAL; > } > > crc = f2fs_checkpoint_chksum(*cp_block); > if (crc != cur_cp_crc(*cp_block)) { > - f2fs_folio_put(*cp_folio, true); > + f2fs_put_cache(*cp_entry, true); > f2fs_warn(sbi, "invalid crc value"); > return -EINVAL; > } > @@ -1182,17 +1151,17 @@ static int get_checkpoint_version(struct f2fs_sb_info *sbi, block_t cp_addr, > return 0; > } > > -static struct folio *validate_checkpoint(struct f2fs_sb_info *sbi, > +static struct f2fs_cached_block *validate_checkpoint(struct f2fs_sb_info *sbi, > block_t cp_addr, unsigned long long *version) > { > - struct folio *cp_folio_1 = NULL, *cp_folio_2 = NULL; > + struct f2fs_cached_block *cp_entry_1 = NULL, *cp_entry_2 = NULL; > struct f2fs_checkpoint *cp_block = NULL; > unsigned long long cur_version = 0, pre_version = 0; > unsigned int cp_blocks; > int err; > > err = get_checkpoint_version(sbi, cp_addr, &cp_block, > - &cp_folio_1, version); > + &cp_entry_1, version); > if (err) > return NULL; > > @@ -1207,19 +1176,20 @@ static struct folio *validate_checkpoint(struct f2fs_sb_info *sbi, > > cp_addr += cp_blocks - 1; > err = get_checkpoint_version(sbi, cp_addr, &cp_block, > - &cp_folio_2, version); > + &cp_entry_2, version); > if (err) > goto invalid_cp; > cur_version = *version; > > if (cur_version == pre_version) { > *version = cur_version; > - f2fs_folio_put(cp_folio_2, true); > - return cp_folio_1; > + f2fs_put_cache(cp_entry_2, true); > + return cp_entry_1; > } > - f2fs_folio_put(cp_folio_2, true); > + f2fs_put_cache(cp_entry_2, true); > invalid_cp: > - f2fs_folio_put(cp_folio_1, true); > + if (cp_entry_1) > + f2fs_put_cache(cp_entry_1, true); > return NULL; > } > > @@ -1227,7 +1197,7 @@ int f2fs_get_valid_checkpoint(struct f2fs_sb_info *sbi) > { > struct f2fs_checkpoint *cp_block; > struct f2fs_super_block *fsb = sbi->raw_super; > - struct folio *cp1, *cp2, *cur_folio; > + struct f2fs_cached_block *cp1 = NULL, *cp2 = NULL, *cur_entry; > unsigned long blk_size = sbi->blocksize; > unsigned long long cp1_version = 0, cp2_version = 0; > unsigned long long cp_start_blk_no; > @@ -1254,22 +1224,22 @@ int f2fs_get_valid_checkpoint(struct f2fs_sb_info *sbi) > > if (cp1 && cp2) { > if (ver_after(cp2_version, cp1_version)) > - cur_folio = cp2; > + cur_entry = cp2; > else > - cur_folio = cp1; > + cur_entry = cp1; > } else if (cp1) { > - cur_folio = cp1; > + cur_entry = cp1; > } else if (cp2) { > - cur_folio = cp2; > + cur_entry = cp2; > } else { > err = -EFSCORRUPTED; > goto fail_no_cp; > } > > - cp_block = folio_address(cur_folio); > + cp_block = (struct f2fs_checkpoint *)cache_address(cur_entry); > memcpy(sbi->ckpt, cp_block, blk_size); > > - if (cur_folio == cp1) > + if (cur_entry == cp1) > sbi->cur_cp_pack = 1; > else > sbi->cur_cp_pack = 2; > @@ -1284,30 +1254,35 @@ int f2fs_get_valid_checkpoint(struct f2fs_sb_info *sbi) > goto done; > > cp_blk_no = le32_to_cpu(fsb->cp_blkaddr); > - if (cur_folio == cp2) > + if (cur_entry == cp2) > cp_blk_no += BIT(le32_to_cpu(fsb->log_blocks_per_seg)); > > for (i = 1; i < cp_blks; i++) { > + struct f2fs_cached_block *cur_entry_payload; > void *sit_bitmap_ptr; > unsigned char *ckpt = (unsigned char *)sbi->ckpt; > > - cur_folio = f2fs_get_meta_folio(sbi, cp_blk_no + i); > - if (IS_ERR(cur_folio)) { > - err = PTR_ERR(cur_folio); > + cur_entry_payload = f2fs_get_meta_cache(sbi, cp_blk_no + i); > + if (IS_ERR(cur_entry_payload)) { > + err = PTR_ERR(cur_entry_payload); > goto free_fail_no_cp; > } > - sit_bitmap_ptr = folio_address(cur_folio); > + sit_bitmap_ptr = cache_address(cur_entry_payload); > memcpy(ckpt + i * blk_size, sit_bitmap_ptr, blk_size); > - f2fs_folio_put(cur_folio, true); > + f2fs_put_cache(cur_entry_payload, true); > } > done: > - f2fs_folio_put(cp1, true); > - f2fs_folio_put(cp2, true); > + if (cp1) > + f2fs_put_cache(cp1, true); In f2fs_put_cache(x, y), if (!x) return; > + if (cp2) > + f2fs_put_cache(cp2, true); > return 0; > > free_fail_no_cp: > - f2fs_folio_put(cp1, true); > - f2fs_folio_put(cp2, true); > + if (cp1) > + f2fs_put_cache(cp1, true); > + if (cp2) > + f2fs_put_cache(cp2, true); > fail_no_cp: > kvfree(sbi->ckpt); > return err; > @@ -1621,7 +1596,7 @@ void f2fs_wait_on_all_pages(struct f2fs_sb_info *sbi, int type) > break; > > if (type == F2FS_DIRTY_META) > - f2fs_sync_meta_pages(sbi, LONG_MAX, FS_CP_META_IO); > + f2fs_sync_meta_caches(sbi, LONG_MAX, true, FS_META_IO); > else if (type == F2FS_WB_CP_DATA) > f2fs_submit_merged_write(sbi, DATA); > > @@ -1700,31 +1675,24 @@ static void update_ckpt_flags(struct f2fs_sb_info *sbi, struct cp_control *cpc) > static void commit_checkpoint(struct f2fs_sb_info *sbi, > void *src, block_t blk_addr) > { > - struct writeback_control wbc = {}; > - > - /* > - * filemap_get_folios_tag and folio_lock again will take > - * some extra time. Therefore, f2fs_update_meta_pages and > - * f2fs_sync_meta_pages are combined in this function. > - */ > - struct folio *folio = f2fs_grab_meta_folio(sbi, blk_addr); > + struct f2fs_cached_block *entry = f2fs_grab_meta_cache(sbi, blk_addr); > > - memcpy(folio_address(folio), src, PAGE_SIZE); > + memcpy(cache_address(entry), src, F2FS_BLKSIZE); > > - folio_mark_dirty(folio); > - if (unlikely(!folio_clear_dirty_for_io(folio))) > + f2fs_mark_cache_dirty(entry); > + if (unlikely(!f2fs_clear_cache_dirty(entry))) > f2fs_bug_on(sbi, 1); > > /* writeout cp pack 2 page */ > - if (unlikely(!__f2fs_write_meta_folio(folio, &wbc, FS_CP_META_IO))) { > + if (unlikely(!__f2fs_write_meta_cache(entry, FS_CP_META_IO))) { > if (f2fs_cp_error(sbi)) { > - f2fs_folio_put(folio, true); > + f2fs_put_cache(entry, true); > return; > } > f2fs_bug_on(sbi, true); > } > > - f2fs_folio_put(folio, false); > + f2fs_put_cache(entry, false); > > /* submit checkpoint (with barrier if NOBARRIER is not set) */ > f2fs_submit_merged_write(sbi, META_FLUSH); > @@ -1793,7 +1761,7 @@ static int do_checkpoint(struct f2fs_sb_info *sbi, struct cp_control *cpc) > int err; > > /* Flush all the NAT/SIT pages */ > - f2fs_sync_meta_pages(sbi, LONG_MAX, FS_CP_META_IO); > + f2fs_sync_meta_caches(sbi, LONG_MAX, true, FS_CP_META_IO); > > stat_cp_time(cpc, CP_TIME_SYNC_META); > > @@ -1892,7 +1860,7 @@ static int do_checkpoint(struct f2fs_sb_info *sbi, struct cp_control *cpc) > } > > /* Here, we have one bio having CP pack except cp pack 2 page */ > - f2fs_sync_meta_pages(sbi, LONG_MAX, FS_CP_META_IO); > + f2fs_sync_meta_caches(sbi, LONG_MAX, true, FS_CP_META_IO); > stat_cp_time(cpc, CP_TIME_SYNC_CP_META); > > /* Wait for all dirty meta pages to be submitted for IO */ > @@ -1919,10 +1887,10 @@ static int do_checkpoint(struct f2fs_sb_info *sbi, struct cp_control *cpc) > * used for migration of encrypted, verity or compressed inode's blocks. > */ > if (f2fs_sb_has_encrypt(sbi) || f2fs_sb_has_verity(sbi) || > - f2fs_sb_has_compression(sbi)) > - f2fs_bug_on(sbi, > - invalidate_inode_pages2_range(META_MAPPING(sbi), > - MAIN_BLKADDR(sbi), MAX_BLKADDR(sbi) - 1)); > + f2fs_sb_has_compression(sbi)) { > + f2fs_truncate_meta_caches(sbi, MAIN_BLKADDR(sbi), > + MAX_BLKADDR(sbi) - MAIN_BLKADDR(sbi)); > + } > > f2fs_release_ino_entry(sbi, false); > > diff --git a/fs/f2fs/compress.c b/fs/f2fs/compress.c > index 91855d91bbdd..bb749f6257a1 100644 > --- a/fs/f2fs/compress.c > +++ b/fs/f2fs/compress.c > @@ -1150,7 +1150,7 @@ static int prepare_compress_overwrite(struct compress_ctx *cc, > f2fs_compress_ctx_add_page(cc, folio); > > if (!folio_test_uptodate(folio)) { > - f2fs_handle_page_eio(sbi, folio, DATA); > + f2fs_handle_page_eio(sbi, folio->index, DATA); > release_and_retry: > f2fs_put_rpages(cc); > f2fs_unlock_rpages(cc, i + 1); > @@ -1359,7 +1359,7 @@ static int f2fs_write_compressed_pages(struct compress_ctx *cc, > fio.old_blkaddr = data_blkaddr(dn.inode, dn.node_folio, > dn.ofs_in_node + i + 1); > > - /* wait for GCed page writeback via META_MAPPING */ > + /* wait for GCed page writeback via generic cache */ > f2fs_wait_on_block_writeback(inode, fio.old_blkaddr); > > if (fio.encrypted) { > diff --git a/fs/f2fs/data.c b/fs/f2fs/data.c > index 110282bb8dcd..92c3293f0a1e 100644 > --- a/fs/f2fs/data.c > +++ b/fs/f2fs/data.c > @@ -65,8 +65,7 @@ bool f2fs_is_cp_guaranteed(const struct folio *folio) > > inode = mapping->host; > > - if (inode->i_ino == F2FS_META_INO(sbi) || > - inode->i_ino == F2FS_NODE_INO(sbi) || > + if (inode->i_ino == F2FS_NODE_INO(sbi) || > S_ISDIR(inode->i_mode)) > return true; > > @@ -84,9 +83,6 @@ static enum count_type __read_io_type(struct folio *folio) > struct inode *inode = mapping->host; > struct f2fs_sb_info *sbi = F2FS_I_SB(inode); > > - if (inode->i_ino == F2FS_META_INO(sbi)) > - return F2FS_RD_META; > - > if (inode->i_ino == F2FS_NODE_INO(sbi)) > return F2FS_RD_NODE; > } > @@ -1452,7 +1448,7 @@ static void f2fs_submit_page_read(struct inode *inode, struct fsverity_info *vi, > bio = f2fs_grab_read_bio(inode, vi, blkaddr, 1, op_flags, folio->index, > for_write); > > - /* wait for GCed page writeback via META_MAPPING */ > + /* wait for GCed page writeback via generic cache */ > f2fs_wait_on_block_writeback(inode, blkaddr); > > if (!bio_add_folio(bio, folio, PAGE_SIZE, 0)) > @@ -3110,7 +3106,7 @@ static void f2fs_readahead(struct readahead_control *rac) > int f2fs_encrypt_one_page(struct f2fs_io_info *fio) > { > struct inode *inode = fio_inode(fio); > - struct folio *mfolio; > + struct f2fs_cached_block *entry; > struct page *page; > > if (!f2fs_encrypted_file(inode)) > @@ -3126,12 +3122,13 @@ int f2fs_encrypt_one_page(struct f2fs_io_info *fio) > if (IS_ERR(fio->encrypted_page)) > return PTR_ERR(fio->encrypted_page); > > - mfolio = filemap_lock_folio(META_MAPPING(fio->sbi), fio->old_blkaddr); > - if (!IS_ERR(mfolio)) { > - if (folio_test_uptodate(mfolio)) > - memcpy(folio_address(mfolio), > - page_address(fio->encrypted_page), PAGE_SIZE); > - f2fs_folio_put(mfolio, true); > + entry = f2fs_find_cache(META_CACHE(fio->sbi), fio->old_blkaddr); > + if (!IS_ERR(entry)) { > + f2fs_lock_cache(entry); > + if (f2fs_cache_test_uptodate(entry)) > + memcpy(cache_address(entry), page_address(fio->encrypted_page), > + F2FS_BLKSIZE); > + f2fs_put_cache(entry, true); > } > return 0; > } > @@ -3297,7 +3294,7 @@ int f2fs_do_write_data_page(struct f2fs_io_info *fio) > goto out_writepage; > } > > - /* wait for GCed page writeback via META_MAPPING */ > + /* wait for GCed page writeback via generic cache */ > if (fio->meta_gc) > f2fs_wait_on_block_writeback(inode, fio->old_blkaddr); > > @@ -4380,9 +4377,7 @@ void f2fs_invalidate_folio(struct folio *folio, size_t offset, size_t length) > return; > > if (folio_test_dirty(folio)) { > - if (inode->i_ino == F2FS_META_INO(sbi)) { > - dec_page_count(sbi, F2FS_DIRTY_META); > - } else if (inode->i_ino == F2FS_NODE_INO(sbi)) { > + if (inode->i_ino == F2FS_NODE_INO(sbi)) { > dec_page_count(sbi, F2FS_DIRTY_NODES); > } else { > inode_dec_dirty_pages(inode); > diff --git a/fs/f2fs/debug.c b/fs/f2fs/debug.c > index ff379aff4472..14059a50739c 100644 > --- a/fs/f2fs/debug.c > +++ b/fs/f2fs/debug.c > @@ -224,8 +224,7 @@ static void update_general_status(struct f2fs_sb_info *sbi) > si->dirty_count = dirty_segments(sbi); > if (sbi->node_inode) > si->node_pages = NODE_MAPPING(sbi)->nrpages; > - if (sbi->meta_inode) > - si->meta_pages = META_MAPPING(sbi)->nrpages; > + si->meta_caches = META_CACHE(sbi)->num_entries; > #ifdef CONFIG_F2FS_FS_COMPRESSION > if (sbi->compress_inode) { > si->compress_pages = COMPRESS_MAPPING(sbi)->nrpages; > @@ -388,11 +387,8 @@ static void update_mem_info(struct f2fs_sb_info *sbi) > > si->page_mem += (unsigned long long)npages << PAGE_SHIFT; > } > - if (sbi->meta_inode) { > - unsigned long npages = META_MAPPING(sbi)->nrpages; > - > - si->page_mem += (unsigned long long)npages << PAGE_SHIFT; > - } > + si->page_mem += (unsigned long long)META_CACHE(sbi)->num_entries << PAGE_SHIFT; > + si->cache_mem += META_CACHE(sbi)->num_entries * sizeof(struct f2fs_cached_block); > #ifdef CONFIG_F2FS_FS_COMPRESSION > if (sbi->compress_inode) { > unsigned long npages = COMPRESS_MAPPING(sbi)->nrpages; > @@ -708,7 +704,7 @@ static int stat_show(struct seq_file *s, void *v) > seq_printf(s, " - quota data: %4d in quota files:%4d\n", > si->ndirty_qdata, si->nquota_files); > seq_printf(s, " - meta: %4d in %4d\n", > - si->ndirty_meta, si->meta_pages); > + si->ndirty_meta, si->meta_caches); > seq_printf(s, " - imeta: %4d\n", > si->ndirty_imeta); > seq_printf(s, " - fsync mark: %4lld\n", > diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h > index 6e20b3586f26..9a353dcd6658 100644 > --- a/fs/f2fs/f2fs.h > +++ b/fs/f2fs/f2fs.h > @@ -1828,7 +1828,6 @@ struct f2fs_sb_info { > struct f2fs_checkpoint *ckpt; /* raw checkpoint pointer */ > int cur_cp_pack; /* remain current cp pack */ > spinlock_t cp_lock; /* for flag in ckpt */ > - struct inode *meta_inode; /* cache meta blocks */ > struct f2fs_rwsem cp_global_sem; /* checkpoint procedure lock */ > struct f2fs_rwsem cp_rwsem; /* blocking FS operations */ > struct f2fs_rwsem node_write; /* locking node writes */ > @@ -1873,7 +1872,6 @@ struct f2fs_sb_info { > unsigned int blocksize; /* block size */ > unsigned int root_ino_num; /* root inode number*/ > unsigned int node_ino_num; /* node inode number*/ > - unsigned int meta_ino_num; /* meta inode number*/ > unsigned int log_blocks_per_seg; /* log2 blocks per segment */ > unsigned int blocks_per_seg; /* blocks per segment */ > unsigned int segs_per_sec; /* segments per section */ > @@ -2319,9 +2317,9 @@ static inline struct dirty_seglist_info *DIRTY_I(struct f2fs_sb_info *sbi) > return (struct dirty_seglist_info *)(SM_I(sbi)->dirty_info); > } > > -static inline struct address_space *META_MAPPING(struct f2fs_sb_info *sbi) > +static inline bool f2fs_is_meta_cache(struct f2fs_cached_block *entry) > { > - return sbi->meta_inode->i_mapping; > + return entry->cache && entry->cache == META_CACHE(entry->cache->sbi); > } > > static inline struct address_space *NODE_MAPPING(struct f2fs_sb_info *sbi) > @@ -2329,11 +2327,6 @@ static inline struct address_space *NODE_MAPPING(struct f2fs_sb_info *sbi) > return sbi->node_inode->i_mapping; > } > > -static inline bool is_meta_folio(struct folio *folio) > -{ > - return folio->mapping == META_MAPPING(F2FS_F_SB(folio)); > -} > - > static inline bool is_node_folio(struct folio *folio) > { > return folio->mapping == NODE_MAPPING(F2FS_F_SB(folio)); > @@ -4057,9 +4050,9 @@ bool f2fs_alloc_nid(struct f2fs_sb_info *sbi, nid_t *nid); > void f2fs_alloc_nid_done(struct f2fs_sb_info *sbi, nid_t nid); > void f2fs_alloc_nid_failed(struct f2fs_sb_info *sbi, nid_t nid); > int f2fs_try_to_free_nids(struct f2fs_sb_info *sbi, int nr_shrink); > -int f2fs_recover_inline_xattr(struct inode *inode, struct folio *folio); > -int f2fs_recover_xattr_data(struct inode *inode, struct folio *folio); > -int f2fs_recover_inode_page(struct f2fs_sb_info *sbi, struct folio *folio); > +int f2fs_recover_inline_xattr(struct inode *inode, struct f2fs_cached_block *entry); > +int f2fs_recover_xattr_data(struct inode *inode, struct f2fs_cached_block *entry); > +int f2fs_recover_inode_page(struct f2fs_sb_info *sbi, struct f2fs_cached_block *entry); > int f2fs_restore_node_summary(struct f2fs_sb_info *sbi, > unsigned int segno, struct f2fs_summary_block *sum); > int f2fs_flush_nat_entries(struct f2fs_sb_info *sbi, struct cp_control *cpc); > @@ -4109,11 +4102,13 @@ int f2fs_allocate_new_segments(struct f2fs_sb_info *sbi); > int f2fs_trim_fs(struct f2fs_sb_info *sbi, struct fstrim_range *range); > bool f2fs_exist_trim_candidates(struct f2fs_sb_info *sbi, > struct cp_control *cpc); > -struct folio *f2fs_get_sum_folio(struct f2fs_sb_info *sbi, unsigned int segno); > +struct f2fs_cached_block *f2fs_get_sum_cache(struct f2fs_sb_info *sbi, > + unsigned int segno); > void f2fs_update_meta_page(struct f2fs_sb_info *sbi, void *src, > block_t blk_addr); > -void f2fs_do_write_meta_page(struct f2fs_sb_info *sbi, struct folio *folio, > - enum iostat_type io_type); > +void f2fs_do_write_meta_cache(struct f2fs_sb_info *sbi, > + struct f2fs_cached_block *entry, > + enum iostat_type io_type); > void f2fs_do_write_node_page(unsigned int nid, struct f2fs_io_info *fio); > void f2fs_outplace_write_data(struct dnode_of_data *dn, > struct f2fs_io_info *fio); > @@ -4136,8 +4131,6 @@ void f2fs_update_device_state(struct f2fs_sb_info *sbi, nid_t ino, > block_t blkaddr, unsigned int blkcnt); > void f2fs_folio_wait_writeback(struct folio *folio, enum page_type type, > bool ordered, bool locked); > -#define f2fs_wait_on_page_writeback(page, type, ordered, locked) \ > - f2fs_folio_wait_writeback(page_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); > @@ -4203,20 +4196,21 @@ void f2fs_unlock_op(struct f2fs_sb_info *sbi, struct f2fs_lock_context *lc); > void f2fs_stop_checkpoint(struct f2fs_sb_info *sbi, bool end_io, > unsigned char reason); > void f2fs_flush_ckpt_thread(struct f2fs_sb_info *sbi); > -struct folio *f2fs_grab_meta_folio(struct f2fs_sb_info *sbi, pgoff_t index); > -struct folio *f2fs_get_meta_folio(struct f2fs_sb_info *sbi, pgoff_t index); > -struct folio *f2fs_get_meta_folio_retry(struct f2fs_sb_info *sbi, pgoff_t index); > -struct folio *f2fs_get_tmp_folio(struct f2fs_sb_info *sbi, pgoff_t index); > +struct f2fs_cached_block *f2fs_grab_meta_cache(struct f2fs_sb_info *sbi, pgoff_t index); > +struct f2fs_cached_block *f2fs_get_meta_cache(struct f2fs_sb_info *sbi, pgoff_t index); > +struct f2fs_cached_block *f2fs_get_meta_cache_retry(struct f2fs_sb_info *sbi, pgoff_t index); > +struct f2fs_cached_block *f2fs_get_tmp_cache(struct f2fs_sb_info *sbi, pgoff_t index); > bool f2fs_is_valid_blkaddr(struct f2fs_sb_info *sbi, > block_t blkaddr, int type); > bool f2fs_is_valid_blkaddr_raw(struct f2fs_sb_info *sbi, > block_t blkaddr, int type); > -int f2fs_ra_meta_pages(struct f2fs_sb_info *sbi, block_t start, int nrpages, > +int f2fs_ra_meta_caches(struct f2fs_sb_info *sbi, block_t start, int nrpages, > int type, bool sync); > -void f2fs_ra_meta_pages_cond(struct f2fs_sb_info *sbi, pgoff_t index, > +void f2fs_ra_meta_caches_cond(struct f2fs_sb_info *sbi, pgoff_t index, > unsigned int ra_blocks); > -long f2fs_sync_meta_pages(struct f2fs_sb_info *sbi, long nr_to_write, > - enum iostat_type io_type); > +void f2fs_write_meta_caches(struct f2fs_sb_info *sbi); > +long f2fs_sync_meta_caches(struct f2fs_sb_info *sbi, long nr_to_write, > + bool sync, enum iostat_type io_type); > void f2fs_add_ino_entry(struct f2fs_sb_info *sbi, nid_t ino, int type); > void f2fs_remove_ino_entry(struct f2fs_sb_info *sbi, nid_t ino, int type); > void f2fs_release_ino_entry(struct f2fs_sb_info *sbi, bool all); > @@ -4403,7 +4397,7 @@ struct f2fs_stat_info { > unsigned int bimodal, avg_vblocks; > int util_free, util_valid, util_invalid; > int rsvd_segs, overp_segs; > - int dirty_count, node_pages, meta_pages, compress_pages; > + int dirty_count, node_pages, meta_caches, compress_pages; > int compress_page_hit; > int prefree_count, free_segs, free_secs; > int cp_call_count[MAX_CALL_TYPE], cp_count; > @@ -4605,7 +4599,6 @@ extern const struct file_operations f2fs_file_operations; > extern const struct inode_operations f2fs_file_inode_operations; > extern const struct address_space_operations f2fs_dblock_aops; > extern const struct address_space_operations f2fs_node_aops; > -extern const struct address_space_operations f2fs_meta_aops; > extern const struct inode_operations f2fs_dir_inode_operations; > extern const struct inode_operations f2fs_symlink_inode_operations; > extern const struct inode_operations f2fs_encrypted_symlink_inode_operations; > @@ -4626,7 +4619,7 @@ int f2fs_convert_inline_folio(struct dnode_of_data *dn, struct folio *folio); > int f2fs_convert_inline_inode(struct inode *inode); > int f2fs_try_convert_inline_dir(struct inode *dir, struct dentry *dentry); > int f2fs_write_inline_data(struct inode *inode, struct folio *folio); > -int f2fs_recover_inline_data(struct inode *inode, struct folio *nfolio); > +int f2fs_recover_inline_data(struct inode *inode, struct f2fs_cached_block *entry); > struct f2fs_dir_entry *f2fs_find_in_inline_dir(struct inode *dir, > const struct f2fs_filename *fname, struct folio **res_folio, > bool use_hash); > @@ -5186,10 +5179,8 @@ static inline void f2fs_schedule_timeout_killable(long timeout, bool io) > } > > static inline void f2fs_handle_page_eio(struct f2fs_sb_info *sbi, > - struct folio *folio, enum page_type type) > + pgoff_t ofs, enum page_type type) > { > - pgoff_t ofs = folio->index; > - > if (unlikely(f2fs_cp_error(sbi))) > return; > > @@ -5224,36 +5215,10 @@ static inline bool f2fs_is_readonly(struct f2fs_sb_info *sbi) > return f2fs_sb_has_readonly(sbi) || f2fs_readonly(sbi->sb); > } > > -static inline void f2fs_truncate_meta_inode_pages(struct f2fs_sb_info *sbi, > - block_t blkaddr, unsigned int cnt) > -{ > - bool need_submit = false; > - int i = 0; > - > - do { > - struct folio *folio; > - > - folio = filemap_get_folio(META_MAPPING(sbi), blkaddr + i); > - if (!IS_ERR(folio)) { > - if (folio_test_writeback(folio)) > - need_submit = true; > - f2fs_folio_put(folio, false); > - } > - } while (++i < cnt && !need_submit); > - > - if (need_submit) > - f2fs_submit_merged_write_cond(sbi, sbi->meta_inode, > - NULL, 0, DATA); > - > - truncate_inode_pages_range(META_MAPPING(sbi), > - F2FS_BLK_TO_BYTES((loff_t)blkaddr), > - F2FS_BLK_END_BYTES((loff_t)(blkaddr + cnt - 1))); > -} > - > static inline void f2fs_invalidate_internal_cache(struct f2fs_sb_info *sbi, > block_t blkaddr, unsigned int len) > { > - f2fs_truncate_meta_inode_pages(sbi, blkaddr, len); > + f2fs_truncate_meta_caches(sbi, blkaddr, len); > f2fs_invalidate_compress_pages_range(sbi, blkaddr, len); > } > > diff --git a/fs/f2fs/file.c b/fs/f2fs/file.c > index a54b3ab52f1a..92daa41dd96d 100644 > --- a/fs/f2fs/file.c > +++ b/fs/f2fs/file.c > @@ -214,7 +214,7 @@ static vm_fault_t f2fs_vm_page_mkwrite(struct vm_fault *vmf) > > f2fs_folio_wait_writeback(folio, DATA, false, true); > > - /* wait for GCed page writeback via META_MAPPING */ > + /* wait for GCed page writeback via generic cache */ > f2fs_wait_on_block_writeback(inode, dn.data_blkaddr); > > /* > @@ -2563,7 +2563,7 @@ int f2fs_do_shutdown(struct f2fs_sb_info *sbi, unsigned int flag, > f2fs_stop_checkpoint(sbi, false, STOP_CP_REASON_SHUTDOWN); > break; > case F2FS_GOING_DOWN_METAFLUSH: > - f2fs_sync_meta_pages(sbi, LONG_MAX, FS_META_IO); > + f2fs_sync_meta_caches(sbi, LONG_MAX, true, FS_META_IO); > f2fs_stop_checkpoint(sbi, false, STOP_CP_REASON_SHUTDOWN); > break; > case F2FS_GOING_DOWN_NEED_FSCK: > diff --git a/fs/f2fs/gc.c b/fs/f2fs/gc.c > index c4da2f31805b..54327cb2e27e 100644 > --- a/fs/f2fs/gc.c > +++ b/fs/f2fs/gc.c > @@ -1066,7 +1066,7 @@ static int gc_node_segment(struct f2fs_sb_info *sbi, > continue; > > if (phase == 0) { > - f2fs_ra_meta_pages(sbi, NAT_BLOCK_OFFSET(nid), 1, > + f2fs_ra_meta_caches(sbi, NAT_BLOCK_OFFSET(nid), 1, > META_NAT, true); > continue; > } > @@ -1217,7 +1217,8 @@ static int ra_data_block(struct inode *inode, pgoff_t index) > struct address_space *mapping = inode->i_mapping; > struct inode *atomic_inode = NULL; > struct dnode_of_data dn; > - struct folio *folio, *efolio; > + struct folio *folio; > + struct f2fs_cached_block *entry; > struct f2fs_io_info fio = { > .sbi = sbi, > .ino = inode->i_ino, > @@ -1227,6 +1228,7 @@ static int ra_data_block(struct inode *inode, pgoff_t index) > .op_flags = 0, > .encrypted_page = NULL, > .in_list = 0, > + .is_cache = 1, > }; > int err = 0; > > @@ -1285,22 +1287,21 @@ static int ra_data_block(struct inode *inode, pgoff_t index) > > f2fs_wait_on_block_writeback(inode, dn.data_blkaddr); > > - efolio = f2fs_filemap_get_folio(META_MAPPING(sbi), dn.data_blkaddr, > - FGP_LOCK | FGP_CREAT, GFP_NOFS); > - if (IS_ERR(efolio)) { > - err = PTR_ERR(efolio); > + entry = f2fs_grab_cache(META_CACHE(sbi), dn.data_blkaddr, > + F2FS_CACHE_LOCK_CREATE); > + if (IS_ERR(entry)) { > + err = PTR_ERR(entry); > goto put_folio; > } > > - fio.encrypted_page = &efolio->page; > - > - if (folio_test_uptodate(efolio)) > - goto put_encrypted_page; > + if (f2fs_cache_test_uptodate(entry)) > + goto put_cache; > > - err = f2fs_submit_page_bio(&fio); > + fio.cache_entry = entry; > + err = f2fs_submit_cache_read(&fio); > if (err) > - goto put_encrypted_page; > - f2fs_put_page(fio.encrypted_page, false); > + goto put_cache; > + f2fs_put_cache(entry, false); > f2fs_folio_put(folio, true); > > f2fs_update_iostat(sbi, inode, FS_DATA_READ_IO, F2FS_BLKSIZE); > @@ -1309,8 +1310,8 @@ static int ra_data_block(struct inode *inode, pgoff_t index) > if (atomic_inode) > iput(atomic_inode); > return 0; > -put_encrypted_page: > - f2fs_put_page(fio.encrypted_page, true); > +put_cache: > + f2fs_put_cache(entry, true); > put_folio: > f2fs_folio_put(folio, true); > out_iput: > @@ -1320,7 +1321,7 @@ static int ra_data_block(struct inode *inode, pgoff_t index) > } > > /* > - * Move data block via META_MAPPING while keeping locked data page. > + * Move data block via meta cache while keeping locked data page. > * This can be used to move blocks, aka LBAs, directly on disk. > */ > static int move_data_block(struct inode *inode, block_t bidx, > @@ -1337,11 +1338,13 @@ static int move_data_block(struct inode *inode, block_t bidx, > .op_flags = 0, > .encrypted_page = NULL, > .in_list = 0, > + .is_cache = 1, > }; > struct dnode_of_data dn; > struct f2fs_summary sum; > struct node_info ni; > - struct folio *folio, *mfolio, *efolio; > + struct folio *folio; > + struct f2fs_cached_block *sentry, *tentry; > block_t newaddr; > int err = 0; > bool lfs_mode = f2fs_lfs_mode(fio.sbi); > @@ -1406,20 +1409,20 @@ static int move_data_block(struct inode *inode, block_t bidx, > if (lfs_mode) > f2fs_down_write(&fio.sbi->io_order_lock); > > - mfolio = f2fs_grab_cache_folio(META_MAPPING(fio.sbi), > - fio.old_blkaddr, false); > - if (IS_ERR(mfolio)) { > - err = PTR_ERR(mfolio); > + sentry = f2fs_grab_cache(META_CACHE(fio.sbi), fio.old_blkaddr, > + F2FS_CACHE_LOCK_CREATE); > + if (IS_ERR(sentry)) { > + err = PTR_ERR(sentry); > goto up_out; > } > > - fio.encrypted_page = folio_file_page(mfolio, fio.old_blkaddr); > + fio.cache_entry = sentry; > > - /* read source block in mfolio */ > - if (!folio_test_uptodate(mfolio)) { > - err = f2fs_submit_page_bio(&fio); > + /* read source block in cache */ > + if (!f2fs_cache_test_uptodate(sentry)) { > + err = f2fs_submit_cache_read(&fio); > if (err) { > - f2fs_folio_put(mfolio, true); > + f2fs_put_cache(sentry, true); > goto up_out; > } > > @@ -1428,11 +1431,11 @@ static int move_data_block(struct inode *inode, block_t bidx, > f2fs_update_iostat(fio.sbi, NULL, FS_GDATA_READ_IO, > F2FS_BLKSIZE); > > - folio_lock(mfolio); > - if (unlikely(!is_meta_folio(mfolio) || > - !folio_test_uptodate(mfolio))) { > + f2fs_lock_cache(sentry); > + if (unlikely(!f2fs_is_meta_cache(sentry) || > + !f2fs_cache_test_uptodate(sentry))) { > err = -EIO; > - f2fs_folio_put(mfolio, true); > + f2fs_put_cache(sentry, true); > goto up_out; > } > } > @@ -1443,46 +1446,45 @@ static int move_data_block(struct inode *inode, block_t bidx, > err = f2fs_allocate_data_block(fio.sbi, NULL, fio.old_blkaddr, &newaddr, > &sum, type, NULL); > if (err) { > - f2fs_folio_put(mfolio, true); > + f2fs_put_cache(sentry, true); > /* filesystem should shutdown, no need to recovery block */ > goto up_out; > } > > - efolio = f2fs_filemap_get_folio(META_MAPPING(fio.sbi), newaddr, > - FGP_LOCK | FGP_CREAT, GFP_NOFS); > - if (IS_ERR(efolio)) { > - err = PTR_ERR(efolio); > - f2fs_folio_put(mfolio, true); > + tentry = f2fs_grab_cache(META_CACHE(fio.sbi), newaddr, > + F2FS_CACHE_LOCK_CREATE); > + if (IS_ERR(tentry)) { > + err = PTR_ERR(tentry); > + f2fs_put_cache(sentry, true); > goto recover_block; > } > > - fio.encrypted_page = &efolio->page; > + fio.cache_entry = tentry; > > /* write target block */ > - f2fs_wait_on_page_writeback(fio.encrypted_page, DATA, true, true); > - memcpy(page_address(fio.encrypted_page), > - folio_address(mfolio), PAGE_SIZE); > - f2fs_folio_put(mfolio, true); > + f2fs_cache_wait_writeback_cond(tentry, DATA); > + memcpy(cache_address(tentry), cache_address(sentry), PAGE_SIZE); > + f2fs_put_cache(sentry, true); > > f2fs_invalidate_internal_cache(fio.sbi, fio.old_blkaddr, 1); > > - set_page_dirty(fio.encrypted_page); > - if (clear_page_dirty_for_io(fio.encrypted_page)) > + f2fs_mark_cache_dirty(tentry); > + if (f2fs_clear_cache_dirty(tentry)) > dec_page_count(fio.sbi, F2FS_DIRTY_META); > > - set_page_writeback(fio.encrypted_page); > + f2fs_start_cache_writeback(tentry); > > fio.op = REQ_OP_WRITE; > fio.op_flags = REQ_SYNC; > fio.new_blkaddr = newaddr; > - f2fs_submit_page_write(&fio); > + f2fs_submit_cache_write(&fio); > > f2fs_update_iostat(fio.sbi, NULL, FS_GC_DATA_IO, F2FS_BLKSIZE); > > f2fs_update_data_blkaddr(&dn, newaddr); > set_inode_flag(inode, FI_APPEND_WRITE); > > - f2fs_put_page(fio.encrypted_page, true); > + f2fs_put_cache(tentry, true); > recover_block: > if (err) > f2fs_do_replace_block(fio.sbi, &sum, newaddr, fio.old_blkaddr, > @@ -1614,7 +1616,7 @@ static int gc_data_segment(struct f2fs_sb_info *sbi, struct f2fs_summary *sum, > continue; > > if (phase == 0) { > - f2fs_ra_meta_pages(sbi, NAT_BLOCK_OFFSET(nid), 1, > + f2fs_ra_meta_caches(sbi, NAT_BLOCK_OFFSET(nid), 1, > META_NAT, true); > continue; > } > @@ -1818,28 +1820,31 @@ static int do_garbage_collect(struct f2fs_sb_info *sbi, > sum_blk_cnt = DIV_ROUND_UP(end_segno - segno, sbi->sums_per_block); > /* readahead multi ssa blocks those have contiguous address */ > if (__is_large_section(sbi)) > - f2fs_ra_meta_pages(sbi, GET_SUM_BLOCK(sbi, segno), > + f2fs_ra_meta_caches(sbi, GET_SUM_BLOCK(sbi, segno), > sum_blk_cnt, META_SSA, true); > > /* reference all summary page */ > while (segno < end_segno) { > - struct folio *sum_folio = f2fs_get_sum_folio(sbi, segno); > + struct f2fs_cached_block *sum_entry = > + f2fs_get_sum_cache(sbi, segno); > > segno += sbi->sums_per_block; > - if (IS_ERR(sum_folio)) { > - int err = PTR_ERR(sum_folio); > + if (IS_ERR(sum_entry)) { > + int err = PTR_ERR(sum_entry); > > end_segno = segno - sbi->sums_per_block; > segno = rounddown(start_segno, sbi->sums_per_block); > while (segno < end_segno) { > - sum_folio = filemap_get_folio(META_MAPPING(sbi), > + sum_entry = f2fs_find_meta_cache(sbi, > GET_SUM_BLOCK(sbi, segno)); > - folio_put_refs(sum_folio, 2); > + f2fs_put_cache(sum_entry, false); > + f2fs_put_cache(sum_entry, false); > segno += sbi->sums_per_block; > } > return err; > } > - folio_unlock(sum_folio); > + f2fs_unlock_cache(sum_entry); > + > } > > blk_start_plug(&plug); > @@ -1847,11 +1852,16 @@ static int do_garbage_collect(struct f2fs_sb_info *sbi, > segno = start_segno; > while (segno < end_segno) { > unsigned int cur_segno; > + unsigned int block_end_segno; > > /* find segment summary of victim */ > - struct folio *sum_folio = filemap_get_folio(META_MAPPING(sbi), > + struct f2fs_cached_block *sum_entry = > + f2fs_find_meta_cache(sbi, > GET_SUM_BLOCK(sbi, segno)); > - unsigned int block_end_segno = rounddown(segno, sbi->sums_per_block) > + > + f2fs_bug_on(sbi, IS_ERR(sum_entry)); > + > + block_end_segno = rounddown(segno, sbi->sums_per_block) > + sbi->sums_per_block; > > if (block_end_segno > end_segno) > @@ -1864,8 +1874,8 @@ static int do_garbage_collect(struct f2fs_sb_info *sbi, > goto next_block; > } > > - if (!folio_test_uptodate(sum_folio) || > - unlikely(f2fs_cp_error(sbi))) > + if (!f2fs_cache_test_uptodate(sum_entry) || > + unlikely(f2fs_cp_error(sbi))) > goto next_block; > > for (cur_segno = segno; cur_segno < block_end_segno; > @@ -1884,7 +1894,7 @@ static int do_garbage_collect(struct f2fs_sb_info *sbi, > data_type = (type == SUM_TYPE_DATA) ? DATA : NODE; > } > > - sum = SUM_BLK_PAGE_ADDR(sbi, sum_folio, cur_segno); > + sum = SUM_BLK_ENTRY_ADDR(sbi, sum_entry, cur_segno); > if (type != GET_SUM_TYPE(sum_footer(sbi, sum))) { > f2fs_err(sbi, "Inconsistent segment (%u) type " > "[%d, %d] in SIT and SSA", > @@ -1926,12 +1936,14 @@ static int do_garbage_collect(struct f2fs_sb_info *sbi, > cur_segno + 1 : NULL_SEGNO; > > if (unlikely(freezing(current))) { > - folio_put_refs(sum_folio, 2); > + f2fs_put_cache(sum_entry, false); > + f2fs_put_cache(sum_entry, false); > goto stop; > } > } > next_block: > - folio_put_refs(sum_folio, 2); > + f2fs_put_cache(sum_entry, false); > + f2fs_put_cache(sum_entry, false); > segno = block_end_segno; > } > > diff --git a/fs/f2fs/inline.c b/fs/f2fs/inline.c > index aec06fb4fd76..2156fb1fc57d 100644 > --- a/fs/f2fs/inline.c > +++ b/fs/f2fs/inline.c > @@ -294,7 +294,7 @@ int f2fs_write_inline_data(struct inode *inode, struct folio *folio) > return 0; > } > > -int f2fs_recover_inline_data(struct inode *inode, struct folio *nfolio) > +int f2fs_recover_inline_data(struct inode *inode, struct f2fs_cached_block *entry) > { > struct f2fs_sb_info *sbi = F2FS_I_SB(inode); > struct f2fs_inode *ri = NULL; > @@ -308,12 +308,13 @@ int f2fs_recover_inline_data(struct inode *inode, struct folio *nfolio) > * x o -> remove data blocks, and then recover inline_data > * x x -> recover data blocks > */ > - if (IS_INODE(nfolio)) > - ri = F2FS_INODE(nfolio); > + if (IS_INODE(cache_folio(entry))) > + ri = &CACHED_NODE(entry)->i; > > if (f2fs_has_inline_data(inode) && > ri && (ri->i_inline & F2FS_INLINE_DATA)) { > struct folio *ifolio; > + > process_inline: > ifolio = f2fs_get_inode_folio(sbi, inode->i_ino); > if (IS_ERR(ifolio)) > @@ -321,7 +322,7 @@ int f2fs_recover_inline_data(struct inode *inode, struct folio *nfolio) > > f2fs_folio_wait_writeback(ifolio, NODE, true, true); > > - src_addr = inline_data_addr(inode, nfolio); > + src_addr = inline_data_addr(inode, cache_folio(entry)); > dst_addr = inline_data_addr(inode, ifolio); > memcpy(dst_addr, src_addr, MAX_INLINE_DATA(inode)); > > diff --git a/fs/f2fs/inode.c b/fs/f2fs/inode.c > index bac1e360d966..c533da4d4d70 100644 > --- a/fs/f2fs/inode.c > +++ b/fs/f2fs/inode.c > @@ -577,7 +577,7 @@ static int do_read_inode(struct inode *inode) > > static bool is_meta_ino(struct f2fs_sb_info *sbi, unsigned int ino) > { > - if (ino == F2FS_NODE_INO(sbi) || ino == F2FS_META_INO(sbi)) > + if (ino == F2FS_NODE_INO(sbi)) > return true; > #ifdef CONFIG_F2FS_FS_COMPRESSION > if (test_opt(sbi, COMPRESS_CACHE) && ino == F2FS_COMPRESS_INO(sbi)) > @@ -624,9 +624,6 @@ struct inode *f2fs_iget(struct super_block *sb, unsigned long ino) > if (ino == F2FS_NODE_INO(sbi)) { > inode->i_mapping->a_ops = &f2fs_node_aops; > mapping_set_gfp_mask(inode->i_mapping, GFP_NOFS); > - } else if (ino == F2FS_META_INO(sbi)) { > - inode->i_mapping->a_ops = &f2fs_meta_aops; > - mapping_set_gfp_mask(inode->i_mapping, GFP_NOFS); > } else if (ino == F2FS_COMPRESS_INO(sbi)) { > #ifdef CONFIG_F2FS_FS_COMPRESSION > inode->i_mapping->a_ops = &f2fs_compress_aops; > @@ -824,8 +821,7 @@ int f2fs_write_inode(struct inode *inode, struct writeback_control *wbc) > { > struct f2fs_sb_info *sbi = F2FS_I_SB(inode); > > - if (inode->i_ino == F2FS_NODE_INO(sbi) || > - inode->i_ino == F2FS_META_INO(sbi)) > + if (inode->i_ino == F2FS_NODE_INO(sbi)) > return 0; > > /* > @@ -919,7 +915,6 @@ static bool f2fs_pre_evict_inode(struct inode *inode) > f2fs_invalidate_compress_pages(sbi, inode->i_ino); > > if (inode->i_ino == F2FS_NODE_INO(sbi) || > - inode->i_ino == F2FS_META_INO(sbi) || > inode->i_ino == F2FS_COMPRESS_INO(sbi)) > return true; > > diff --git a/fs/f2fs/node.c b/fs/f2fs/node.c > index 46bea52e35c3..398c58fc6cad 100644 > --- a/fs/f2fs/node.c > +++ b/fs/f2fs/node.c > @@ -140,38 +140,36 @@ static void clear_node_folio_dirty(struct folio *folio) > folio_clear_uptodate(folio); > } > > -static struct folio *get_current_nat_folio(struct f2fs_sb_info *sbi, nid_t nid) > +static struct f2fs_cached_block *get_current_nat_cache(struct f2fs_sb_info *sbi, > + nid_t nid) > { > - return f2fs_get_meta_folio_retry(sbi, current_nat_addr(sbi, nid)); > + return f2fs_get_meta_cache_retry(sbi, current_nat_addr(sbi, nid)); > } > > -static struct folio *get_next_nat_folio(struct f2fs_sb_info *sbi, nid_t nid) > +static struct f2fs_cached_block *get_next_nat_cache(struct f2fs_sb_info *sbi, > + nid_t nid) > { > - struct folio *src_folio; > - struct folio *dst_folio; > + struct f2fs_cached_block *src_entry; > + struct f2fs_cached_block *dst_entry; > pgoff_t dst_off; > - void *src_addr; > - void *dst_addr; > struct f2fs_nm_info *nm_i = NM_I(sbi); > > dst_off = next_nat_addr(sbi, current_nat_addr(sbi, nid)); > > /* get current nat block page with lock */ > - src_folio = get_current_nat_folio(sbi, nid); > - if (IS_ERR(src_folio)) > - return src_folio; > - dst_folio = f2fs_grab_meta_folio(sbi, dst_off); > - f2fs_bug_on(sbi, folio_test_dirty(src_folio)); > - > - src_addr = folio_address(src_folio); > - dst_addr = folio_address(dst_folio); > - memcpy(dst_addr, src_addr, PAGE_SIZE); > - folio_mark_dirty(dst_folio); > - f2fs_folio_put(src_folio, true); > + src_entry = get_current_nat_cache(sbi, nid); > + if (IS_ERR(src_entry)) > + return src_entry; > + dst_entry = f2fs_grab_meta_cache(sbi, dst_off); > + f2fs_bug_on(sbi, f2fs_cache_test_dirty(src_entry)); > + > + memcpy(cache_address(dst_entry), cache_address(src_entry), sbi->blocksize); > + f2fs_mark_cache_dirty(dst_entry); > + f2fs_put_cache(src_entry, true); > > set_to_next_nat(nm_i, nid); > > - return dst_folio; > + return dst_entry; > } > > static struct nat_entry *__alloc_nat_entry(struct f2fs_sb_info *sbi, > @@ -575,7 +573,7 @@ int f2fs_get_node_info(struct f2fs_sb_info *sbi, nid_t nid, > struct f2fs_journal *journal = curseg->journal; > nid_t start_nid = START_NID(nid); > struct f2fs_nat_block *nat_blk; > - struct folio *folio = NULL; > + struct f2fs_cached_block *entry = NULL; > struct f2fs_nat_entry ne; > struct nat_entry *e; > pgoff_t index; > @@ -629,14 +627,14 @@ int f2fs_get_node_info(struct f2fs_sb_info *sbi, nid_t nid, > index = current_nat_addr(sbi, nid); > f2fs_up_read(&nm_i->nat_tree_lock); > > - folio = f2fs_get_meta_folio(sbi, index); > - if (IS_ERR(folio)) > - return PTR_ERR(folio); > + entry = f2fs_get_meta_cache(sbi, index); > + if (IS_ERR(entry)) > + return PTR_ERR(entry); > > - nat_blk = folio_address(folio); > + nat_blk = cache_address(entry); > ne = nat_blk->entries[nid - start_nid]; > node_info_from_raw_nat(ni, &ne); > - f2fs_folio_put(folio, true); > + f2fs_put_cache(entry, true); > sanity_check: > if (__is_valid_data_blkaddr(ni->blk_addr) && > !f2fs_is_valid_blkaddr(sbi, ni->blk_addr, > @@ -1622,7 +1620,7 @@ static struct folio *__get_node_folio(struct f2fs_sb_info *sbi, pgoff_t nid, > out_put_err: > /* ENOENT comes from read_node_folio which is not an error. */ > if (err != -ENOENT) > - f2fs_handle_page_eio(sbi, folio, NODE); > + f2fs_handle_page_eio(sbi, folio->index, NODE); > f2fs_folio_put(folio, true); > return ERR_PTR(err); > } > @@ -2598,6 +2596,7 @@ static int __f2fs_build_free_nids(struct f2fs_sb_info *sbi, > bool sync, bool mount) > { > struct f2fs_nm_info *nm_i = NM_I(sbi); > + struct f2fs_cached_block *entry = NULL; > int i = 0, ret; > nid_t nid = nm_i->next_scan_nid; > > @@ -2623,7 +2622,7 @@ static int __f2fs_build_free_nids(struct f2fs_sb_info *sbi, > } > > /* readahead nat pages to be scanned */ > - f2fs_ra_meta_pages(sbi, NAT_BLOCK_OFFSET(nid), FREE_NID_PAGES, > + f2fs_ra_meta_caches(sbi, NAT_BLOCK_OFFSET(nid), FREE_NID_PAGES, > META_NAT, true); > > f2fs_down_read(&nm_i->nat_tree_lock); > @@ -2631,14 +2630,14 @@ static int __f2fs_build_free_nids(struct f2fs_sb_info *sbi, > while (1) { > if (!test_bit_le(NAT_BLOCK_OFFSET(nid), > nm_i->nat_block_bitmap)) { > - struct folio *folio = get_current_nat_folio(sbi, nid); > + entry = get_current_nat_cache(sbi, nid); > > - if (IS_ERR(folio)) { > - ret = PTR_ERR(folio); > + if (IS_ERR(entry)) { > + ret = PTR_ERR(entry); > } else { > - ret = scan_nat_page(sbi, folio_address(folio), > + ret = scan_nat_page(sbi, cache_address(entry), > nid); > - f2fs_folio_put(folio, true); > + f2fs_put_cache(entry, true); > } > > if (ret) { > @@ -2671,7 +2670,7 @@ static int __f2fs_build_free_nids(struct f2fs_sb_info *sbi, > > f2fs_up_read(&nm_i->nat_tree_lock); > > - f2fs_ra_meta_pages(sbi, NAT_BLOCK_OFFSET(nm_i->next_scan_nid), > + f2fs_ra_meta_caches(sbi, NAT_BLOCK_OFFSET(nm_i->next_scan_nid), > nm_i->ra_nid_pages, META_NAT, false); > > return 0; > @@ -2826,7 +2825,7 @@ int f2fs_try_to_free_nids(struct f2fs_sb_info *sbi, int nr_shrink) > return nr - nr_shrink; > } > > -int f2fs_recover_inline_xattr(struct inode *inode, struct folio *folio) > +int f2fs_recover_inline_xattr(struct inode *inode, struct f2fs_cached_block *entry) > { > void *src_addr, *dst_addr; > size_t inline_size; > @@ -2837,7 +2836,7 @@ int f2fs_recover_inline_xattr(struct inode *inode, struct folio *folio) > if (IS_ERR(ifolio)) > return PTR_ERR(ifolio); > > - ri = F2FS_INODE(folio); > + ri = &CACHED_NODE(entry)->i; > if (ri->i_inline & F2FS_INLINE_XATTR) { > if (!f2fs_has_inline_xattr(inode)) { > set_inode_flag(inode, FI_INLINE_XATTR); > @@ -2852,7 +2851,7 @@ int f2fs_recover_inline_xattr(struct inode *inode, struct folio *folio) > } > > dst_addr = inline_xattr_addr(inode, ifolio); > - src_addr = inline_xattr_addr(inode, folio); > + src_addr = inline_xattr_addr(inode, cache_folio(entry)); > inline_size = inline_xattr_size(inode); > > f2fs_folio_wait_writeback(ifolio, NODE, true, true); > @@ -2863,7 +2862,7 @@ int f2fs_recover_inline_xattr(struct inode *inode, struct folio *folio) > return 0; > } > > -int f2fs_recover_xattr_data(struct inode *inode, struct folio *folio) > +int f2fs_recover_xattr_data(struct inode *inode, struct f2fs_cached_block *entry) > { > struct f2fs_sb_info *sbi = F2FS_I_SB(inode); > nid_t prev_xnid = F2FS_I(inode)->i_xattr_nid; > @@ -2901,8 +2900,8 @@ int f2fs_recover_xattr_data(struct inode *inode, struct folio *folio) > f2fs_update_inode_page(inode); > > /* 3: update and set xattr node page dirty */ > - if (folio) { > - memcpy(F2FS_NODE(xfolio), F2FS_NODE(folio), > + if (entry) { > + memcpy(F2FS_NODE(xfolio), CACHED_NODE(entry), > VALID_XATTR_BLOCK_SIZE); > folio_mark_dirty(xfolio); > } > @@ -2911,10 +2910,10 @@ int f2fs_recover_xattr_data(struct inode *inode, struct folio *folio) > return 0; > } > > -int f2fs_recover_inode_page(struct f2fs_sb_info *sbi, struct folio *folio) > +int f2fs_recover_inode_page(struct f2fs_sb_info *sbi, struct f2fs_cached_block *entry) > { > struct f2fs_inode *src, *dst; > - nid_t ino = ino_of_node(folio); > + nid_t ino = ino_of_node(cache_folio(entry)); > struct node_info old_ni, new_ni; > struct folio *ifolio; > int err; > @@ -2940,7 +2939,7 @@ int f2fs_recover_inode_page(struct f2fs_sb_info *sbi, struct folio *folio) > fill_node_footer(ifolio, ino, ino, 0, true); > set_cold_node(ifolio, false); > > - src = F2FS_INODE(folio); > + src = &CACHED_NODE(entry)->i; > dst = F2FS_INODE(ifolio); > > memcpy(dst, src, offsetof(struct f2fs_inode, i_ext)); > @@ -2999,24 +2998,24 @@ int f2fs_restore_node_summary(struct f2fs_sb_info *sbi, > nrpages = bio_max_segs(last_offset - i); > > /* readahead node pages */ > - f2fs_ra_meta_pages(sbi, addr, nrpages, META_POR, true); > + f2fs_ra_meta_caches(sbi, addr, nrpages, META_POR, true); > > for (idx = addr; idx < addr + nrpages; idx++) { > - struct folio *folio = f2fs_get_tmp_folio(sbi, idx); > + struct f2fs_cached_block *entry = > + f2fs_get_tmp_cache(sbi, idx); > > - if (IS_ERR(folio)) > - return PTR_ERR(folio); > + if (IS_ERR(entry)) > + return PTR_ERR(entry); > > - rn = F2FS_NODE(folio); > + rn = CACHED_NODE(entry); > sum_entry->nid = rn->footer.nid; > sum_entry->version = 0; > sum_entry->ofs_in_node = 0; > sum_entry++; > - f2fs_folio_put(folio, true); > + f2fs_put_cache(entry, true); > } > > - invalidate_mapping_pages(META_MAPPING(sbi), addr, > - addr + nrpages); > + f2fs_truncate_meta_caches(sbi, addr, nrpages); > } > return 0; > } > @@ -3126,7 +3125,7 @@ static int __flush_nat_entry_set(struct f2fs_sb_info *sbi, > bool to_journal = true; > struct f2fs_nat_block *nat_blk; > struct nat_entry *ne, *cur; > - struct folio *folio = NULL; > + struct f2fs_cached_block *entry = NULL; > > /* > * there are two steps to flush nat entries: > @@ -3140,11 +3139,11 @@ static int __flush_nat_entry_set(struct f2fs_sb_info *sbi, > if (to_journal) { > down_write(&curseg->journal_rwsem); > } else { > - folio = get_next_nat_folio(sbi, start_nid); > - if (IS_ERR(folio)) > - return PTR_ERR(folio); > + entry = get_next_nat_cache(sbi, start_nid); > + if (IS_ERR(entry)) > + return PTR_ERR(entry); > > - nat_blk = folio_address(folio); > + nat_blk = cache_address(entry); > f2fs_bug_on(sbi, !nat_blk); > } > > @@ -3181,7 +3180,7 @@ static int __flush_nat_entry_set(struct f2fs_sb_info *sbi, > up_write(&curseg->journal_rwsem); > } else { > __update_nat_bits(sbi, start_nid, nat_blk); > - f2fs_folio_put(folio, true); > + f2fs_put_cache(entry, true); > } > > /* Allow dirty nats by node block allocation in write_begin */ > @@ -3252,7 +3251,7 @@ int f2fs_flush_nat_entries(struct f2fs_sb_info *sbi, struct cp_control *cpc) > __has_cursum_space(sbi, journal, > entry_count, NAT_JOURNAL)) > continue; > - f2fs_ra_meta_pages(sbi, set->set, 1, META_NAT, true); > + f2fs_ra_meta_caches(sbi, set->set, 1, META_NAT, true); > } > /* flush dirty nats in nat entry set */ > list_for_each_entry_safe(set, tmp, &sets, set_list) { > @@ -3288,15 +3287,15 @@ static int __get_nat_bitmaps(struct f2fs_sb_info *sbi) > nat_bits_addr = __start_cp_addr(sbi) + BLKS_PER_SEG(sbi) - > nm_i->nat_bits_blocks; > for (i = 0; i < nm_i->nat_bits_blocks; i++) { > - struct folio *folio; > + struct f2fs_cached_block *entry; > > - folio = f2fs_get_meta_folio(sbi, nat_bits_addr++); > - if (IS_ERR(folio)) > - return PTR_ERR(folio); > + entry = f2fs_get_meta_cache(sbi, nat_bits_addr++); > + if (IS_ERR(entry)) > + return PTR_ERR(entry); > > memcpy(nm_i->nat_bits + F2FS_BLK_TO_BYTES(i), > - folio_address(folio), F2FS_BLKSIZE); > - f2fs_folio_put(folio, true); > + cache_address(entry), F2FS_BLKSIZE); > + f2fs_put_cache(entry, true); > } > > cp_ver |= (cur_cp_crc(ckpt) << 32); > diff --git a/fs/f2fs/node.h b/fs/f2fs/node.h > index 5e114f352099..de8dcd5d4392 100644 > --- a/fs/f2fs/node.h > +++ b/fs/f2fs/node.h > @@ -311,9 +311,9 @@ static inline void fill_node_footer_blkaddr(struct folio *folio, block_t blkaddr > rn->footer.next_blkaddr = cpu_to_le32(blkaddr); > } > > -static inline bool is_recoverable_dnode(const struct folio *folio) > +static inline bool is_recoverable_dnode(struct f2fs_sb_info *sbi, const struct folio *folio) > { > - struct f2fs_checkpoint *ckpt = F2FS_CKPT(F2FS_F_SB(folio)); > + struct f2fs_checkpoint *ckpt = F2FS_CKPT(sbi); > __u64 cp_ver = cur_cp_version(ckpt); > > /* Don't care crc part, if fsck.f2fs sets it. */ > diff --git a/fs/f2fs/recovery.c b/fs/f2fs/recovery.c > index aaa5227739c8..5cb56b4c1879 100644 > --- a/fs/f2fs/recovery.c > +++ b/fs/f2fs/recovery.c > @@ -182,33 +182,33 @@ static const char *recover_printable_name(struct inode *inode, > return raw->i_name; > } > > -static int recover_dentry(struct inode *inode, struct folio *ifolio, > +static int recover_dentry(struct inode *inode, struct f2fs_cached_block *entry, > struct list_head *dir_list) > { > - struct f2fs_inode *raw_inode = F2FS_INODE(ifolio); > + struct f2fs_inode *raw_inode = &CACHED_NODE(entry)->i; > nid_t pino = le32_to_cpu(raw_inode->i_pino); > struct f2fs_dir_entry *de; > struct f2fs_filename fname; > struct qstr usr_fname; > struct folio *folio; > struct inode *dir, *einode; > - struct fsync_inode_entry *entry; > + struct fsync_inode_entry *fsync_entry; > int err = 0; > const char *name; > int name_len; > > - entry = get_fsync_inode(dir_list, pino); > - if (!entry) { > - entry = add_fsync_inode(F2FS_I_SB(inode), dir_list, > + fsync_entry = get_fsync_inode(dir_list, pino); > + if (!fsync_entry) { > + fsync_entry = add_fsync_inode(F2FS_I_SB(inode), dir_list, > pino, false); > - if (IS_ERR(entry)) { > - dir = ERR_CAST(entry); > - err = PTR_ERR(entry); > + if (IS_ERR(fsync_entry)) { > + dir = ERR_CAST(fsync_entry); > + err = PTR_ERR(fsync_entry); > goto out; > } > } > > - dir = entry->inode; > + dir = fsync_entry->inode; > err = init_recovered_filename(dir, inode, raw_inode, &fname, &usr_fname); > if (err) > goto out; > @@ -256,14 +256,14 @@ static int recover_dentry(struct inode *inode, struct folio *ifolio, > out: > name = recover_printable_name(inode, raw_inode, &name_len); > f2fs_notice(F2FS_I_SB(inode), "%s: ino = %x, name = %.*s, dir = %llu, err = %d", > - __func__, ino_of_node(ifolio), name_len, name, > + __func__, ino_of_node(cache_folio(entry)), name_len, name, > IS_ERR(dir) ? 0 : dir->i_ino, err); > return err; > } > > -static int recover_quota_data(struct inode *inode, struct folio *folio) > +static int recover_quota_data(struct inode *inode, struct f2fs_cached_block *entry) > { > - struct f2fs_inode *raw = F2FS_INODE(folio); > + struct f2fs_inode *raw = &CACHED_NODE(entry)->i; > struct iattr attr; > uid_t i_uid = le32_to_cpu(raw->i_uid); > gid_t i_gid = le32_to_cpu(raw->i_gid); > @@ -300,9 +300,9 @@ static void recover_inline_flags(struct inode *inode, struct f2fs_inode *ri) > clear_inode_flag(inode, FI_DATA_EXIST); > } > > -static int recover_inode(struct inode *inode, struct folio *folio) > +static int recover_inode(struct inode *inode, struct f2fs_cached_block *entry) > { > - struct f2fs_inode *raw = F2FS_INODE(folio); > + struct f2fs_inode *raw = &CACHED_NODE(entry)->i; > struct f2fs_inode_info *fi = F2FS_I(inode); > const char *name; > int name_len; > @@ -310,7 +310,7 @@ static int recover_inode(struct inode *inode, struct folio *folio) > > inode->i_mode = le16_to_cpu(raw->i_mode); > > - err = recover_quota_data(inode, folio); > + err = recover_quota_data(inode, entry); > if (err) > return err; > > @@ -357,7 +357,7 @@ static int recover_inode(struct inode *inode, struct folio *folio) > name = recover_printable_name(inode, raw, &name_len); > > f2fs_notice(F2FS_I_SB(inode), "%s: ino = %x, name = %.*s, inline = %x", > - __func__, ino_of_node(folio), name_len, name, > + __func__, ino_of_node(cache_folio(entry)), name_len, name, > raw->i_inline); > return 0; > } > @@ -386,30 +386,30 @@ static int sanity_check_node_chain(struct f2fs_sb_info *sbi, block_t blkaddr, > return 0; > > for (i = 0; i < 2; i++) { > - struct folio *folio; > + struct f2fs_cached_block *entry; > > if (!f2fs_is_valid_blkaddr(sbi, *blkaddr_fast, META_POR)) { > *is_detecting = false; > return 0; > } > > - folio = f2fs_get_tmp_folio(sbi, *blkaddr_fast); > - if (IS_ERR(folio)) > - return PTR_ERR(folio); > + entry = f2fs_get_tmp_cache(sbi, *blkaddr_fast); > + if (IS_ERR(entry)) > + return PTR_ERR(entry); > > - if (!is_recoverable_dnode(folio)) { > - f2fs_folio_put(folio, true); > + if (!is_recoverable_dnode(sbi, cache_folio(entry))) { > + f2fs_put_cache(entry, true); > *is_detecting = false; > return 0; > } > > ra_blocks = adjust_por_ra_blocks(sbi, ra_blocks, *blkaddr_fast, > - next_blkaddr_of_node(folio)); > + next_blkaddr_of_node(cache_folio(entry))); > > - *blkaddr_fast = next_blkaddr_of_node(folio); > - f2fs_folio_put(folio, true); > + *blkaddr_fast = next_blkaddr_of_node(cache_folio(entry)); > + f2fs_put_cache(entry, true); > > - f2fs_ra_meta_pages_cond(sbi, *blkaddr_fast, ra_blocks); > + f2fs_ra_meta_caches_cond(sbi, *blkaddr_fast, ra_blocks); > } > > if (*blkaddr_fast == blkaddr) { > @@ -434,45 +434,47 @@ static int find_fsync_dnodes(struct f2fs_sb_info *sbi, struct list_head *head, > blkaddr_fast = blkaddr; > > while (1) { > - struct fsync_inode_entry *entry; > - struct folio *folio; > + struct fsync_inode_entry *fsync_entry; > + struct f2fs_cached_block *entry; > + struct f2fs_node *rn; > > if (!f2fs_is_valid_blkaddr(sbi, blkaddr, META_POR)) > return 0; > > - folio = f2fs_get_tmp_folio(sbi, blkaddr); > - if (IS_ERR(folio)) { > - err = PTR_ERR(folio); > + entry = f2fs_get_tmp_cache(sbi, blkaddr); > + if (IS_ERR(entry)) { > + err = PTR_ERR(entry); > break; > } > + rn = CACHED_NODE(entry); > > - if (!is_recoverable_dnode(folio)) { > - f2fs_folio_put(folio, true); > + if (!is_recoverable_dnode(sbi, cache_folio(entry))) { > + f2fs_put_cache(entry, true); > break; > } > > - if (!is_fsync_dnode(folio)) > + if (!is_fsync_dnode(cache_folio(entry))) > goto next; > > - entry = get_fsync_inode(head, ino_of_node(folio)); > - if (!entry) { > + fsync_entry = get_fsync_inode(head, ino_of_node(cache_folio(entry))); > + if (!fsync_entry) { > bool quota_inode = false; > > if (!check_only && > - IS_INODE(folio) && > - is_dent_dnode(folio)) { > - err = f2fs_recover_inode_page(sbi, folio); > + IS_INODE(cache_folio(entry)) && > + is_dent_dnode(cache_folio(entry))) { > + err = f2fs_recover_inode_page(sbi, entry); > if (err) { > - f2fs_folio_put(folio, true); > + f2fs_put_cache(entry, true); > break; > } > quota_inode = true; > } > > - entry = add_fsync_inode(sbi, head, ino_of_node(folio), > + fsync_entry = add_fsync_inode(sbi, head, ino_of_node(cache_folio(entry)), > quota_inode); > - if (IS_ERR(entry)) { > - err = PTR_ERR(entry); > + if (IS_ERR(fsync_entry)) { > + err = PTR_ERR(fsync_entry); > /* > * CP | dnode(F) | inode(DF) > * For this case, we should not give up now. > @@ -482,18 +484,18 @@ static int find_fsync_dnodes(struct f2fs_sb_info *sbi, struct list_head *head, > *new_inode = true; > goto next; > } > - f2fs_folio_put(folio, true); > + f2fs_put_cache(entry, true); > break; > } > } > - entry->blkaddr = blkaddr; > + fsync_entry->blkaddr = blkaddr; > > - if (IS_INODE(folio) && is_dent_dnode(folio)) > - entry->last_dentry = blkaddr; > + if (IS_INODE(cache_folio(entry)) && is_dent_dnode(cache_folio(entry))) > + fsync_entry->last_dentry = blkaddr; > next: > /* check next segment */ > - blkaddr = next_blkaddr_of_node(folio); > - f2fs_folio_put(folio, true); > + blkaddr = next_blkaddr_of_node(cache_folio(entry)); > + f2fs_put_cache(entry, true); > > err = sanity_check_node_chain(sbi, blkaddr, &blkaddr_fast, > &is_detecting); > @@ -519,7 +521,8 @@ static int check_index_in_prev_nodes(struct f2fs_sb_info *sbi, > unsigned short blkoff = GET_BLKOFF_FROM_SEG0(sbi, blkaddr); > struct f2fs_summary_block *sum_node; > struct f2fs_summary sum; > - struct folio *sum_folio, *node_folio; > + struct f2fs_cached_block *entry = NULL; > + struct folio *node_folio; > struct dnode_of_data tdn = *dn; > nid_t ino, nid; > struct inode *inode; > @@ -541,12 +544,12 @@ static int check_index_in_prev_nodes(struct f2fs_sb_info *sbi, > } > } > > - sum_folio = f2fs_get_sum_folio(sbi, segno); > - if (IS_ERR(sum_folio)) > - return PTR_ERR(sum_folio); > - sum_node = SUM_BLK_PAGE_ADDR(sbi, sum_folio, segno); > + entry = f2fs_get_sum_cache(sbi, segno); > + if (IS_ERR(entry)) > + return PTR_ERR(entry); > + sum_node = SUM_BLK_ENTRY_ADDR(sbi, entry, segno); > sum = sum_entries(sum_node)[blkoff]; > - f2fs_folio_put(sum_folio, true); > + f2fs_put_cache(entry, true); > got_it: > /* Use the locked dnode page and inode */ > nid = le32_to_cpu(sum.nid); > @@ -645,7 +648,7 @@ static int f2fs_reserve_new_block_retry(struct dnode_of_data *dn) > } > > static int do_recover_data(struct f2fs_sb_info *sbi, struct inode *inode, > - struct folio *folio) > + struct f2fs_cached_block *entry) > { > struct dnode_of_data dn; > struct node_info ni; > @@ -653,19 +656,19 @@ static int do_recover_data(struct f2fs_sb_info *sbi, struct inode *inode, > int err = 0, recovered = 0; > > /* step 1: recover xattr */ > - if (IS_INODE(folio)) { > - err = f2fs_recover_inline_xattr(inode, folio); > + if (IS_INODE(cache_folio(entry))) { > + err = f2fs_recover_inline_xattr(inode, entry); > if (err) > goto out; > - } else if (f2fs_has_xattr_block(ofs_of_node(folio))) { > - err = f2fs_recover_xattr_data(inode, folio); > + } else if (f2fs_has_xattr_block(ofs_of_node(cache_folio(entry)))) { > + err = f2fs_recover_xattr_data(inode, entry); > if (!err) > recovered++; > goto out; > } > > /* step 2: recover inline data */ > - err = f2fs_recover_inline_data(inode, folio); > + err = f2fs_recover_inline_data(inode, entry); > if (err) { > if (err == 1) > err = 0; > @@ -673,8 +676,8 @@ static int do_recover_data(struct f2fs_sb_info *sbi, struct inode *inode, > } > > /* step 3: recover data indices */ > - start = f2fs_start_bidx_of_node(ofs_of_node(folio), inode); > - end = start + ADDRS_PER_PAGE(folio, inode); > + start = f2fs_start_bidx_of_node(ofs_of_node(cache_folio(entry)), inode); > + end = start + addrs_per_page(inode, IS_INODE(cache_folio(entry))); > > set_new_dnode(&dn, inode, NULL, NULL, 0); > retry_dn: > @@ -693,12 +696,12 @@ static int do_recover_data(struct f2fs_sb_info *sbi, struct inode *inode, > if (err) > goto err; > > - f2fs_bug_on(sbi, ni.ino != ino_of_node(folio)); > + f2fs_bug_on(sbi, ni.ino != ino_of_node(cache_folio(entry))); > > - if (ofs_of_node(dn.node_folio) != ofs_of_node(folio)) { > + if (ofs_of_node(dn.node_folio) != ofs_of_node(cache_folio(entry))) { > f2fs_warn(sbi, "Inconsistent ofs_of_node, ino:%llu, ofs:%u, %u", > inode->i_ino, ofs_of_node(dn.node_folio), > - ofs_of_node(folio)); > + ofs_of_node(cache_folio(entry))); > err = -EFSCORRUPTED; > f2fs_handle_error(sbi, ERROR_INCONSISTENT_FOOTER); > fserror_report_file_metadata(dn.inode, err, GFP_NOFS); > @@ -709,7 +712,7 @@ static int do_recover_data(struct f2fs_sb_info *sbi, struct inode *inode, > block_t src, dest; > > src = f2fs_data_blkaddr(&dn); > - dest = data_blkaddr(dn.inode, folio, dn.ofs_in_node); > + dest = data_blkaddr(dn.inode, cache_folio(entry), dn.ofs_in_node); > > if (__is_valid_data_blkaddr(src) && > !f2fs_is_valid_blkaddr(sbi, src, META_POR)) { > @@ -784,16 +787,16 @@ static int do_recover_data(struct f2fs_sb_info *sbi, struct inode *inode, > } > } > > - copy_node_footer(dn.node_folio, folio); > + copy_node_footer(dn.node_folio, cache_folio(entry)); > fill_node_footer(dn.node_folio, dn.nid, ni.ino, > - ofs_of_node(folio), false); > + ofs_of_node(cache_folio(entry)), false); > folio_mark_dirty(dn.node_folio); > err: > f2fs_put_dnode(&dn); > out: > f2fs_notice(sbi, "recover_data: ino = %llx, nid = %x (i_size: %s), " > "range (%u, %u), recovered = %d, err = %d", > - inode->i_ino, nid_of_node(folio), > + inode->i_ino, nid_of_node(cache_folio(entry)), > file_keep_isize(inode) ? "keep" : "recover", > start, end, recovered, err); > return err; > @@ -820,26 +823,26 @@ static int recover_data(struct f2fs_sb_info *sbi, struct list_head *inode_list, > blkaddr = NEXT_FREE_BLKADDR(sbi, curseg); > > while (1) { > - struct fsync_inode_entry *entry; > - struct folio *folio; > + struct fsync_inode_entry *fsync_entry; > + struct f2fs_cached_block *entry; > > if (!f2fs_is_valid_blkaddr(sbi, blkaddr, META_POR)) > break; > > - folio = f2fs_get_tmp_folio(sbi, blkaddr); > - if (IS_ERR(folio)) { > - err = PTR_ERR(folio); > + entry = f2fs_get_tmp_cache(sbi, blkaddr); > + if (IS_ERR(entry)) { > + err = PTR_ERR(entry); > break; > } > > - if (!is_recoverable_dnode(folio)) { > - f2fs_folio_put(folio, true); > + if (!is_recoverable_dnode(sbi, cache_folio(entry))) { > + f2fs_put_cache(entry, true); > break; > } > recoverable_dnode++; > > - entry = get_fsync_inode(inode_list, ino_of_node(folio)); > - if (!entry) > + fsync_entry = get_fsync_inode(inode_list, ino_of_node(cache_folio(entry))); > + if (!fsync_entry) > goto next; > fsynced_dnode++; > /* > @@ -847,40 +850,40 @@ static int recover_data(struct f2fs_sb_info *sbi, struct list_head *inode_list, > * In this case, we can lose the latest inode(x). > * So, call recover_inode for the inode update. > */ > - if (IS_INODE(folio)) { > - err = recover_inode(entry->inode, folio); > + if (IS_INODE(cache_folio(entry))) { > + err = recover_inode(fsync_entry->inode, entry); > if (err) { > - f2fs_folio_put(folio, true); > + f2fs_put_cache(entry, true); > break; > } > recovered_inode++; > } > - if (entry->last_dentry == blkaddr) { > - err = recover_dentry(entry->inode, folio, dir_list); > + if (fsync_entry->last_dentry == blkaddr) { > + err = recover_dentry(fsync_entry->inode, entry, dir_list); > if (err) { > - f2fs_folio_put(folio, true); > + f2fs_put_cache(entry, true); > break; > } > recovered_dentry++; > } > - err = do_recover_data(sbi, entry->inode, folio); > + err = do_recover_data(sbi, fsync_entry->inode, entry); > if (err) { > - f2fs_folio_put(folio, true); > + f2fs_put_cache(entry, true); > break; > } > recovered_dnode++; > > - if (entry->blkaddr == blkaddr) > - list_move_tail(&entry->list, tmp_inode_list); > + if (fsync_entry->blkaddr == blkaddr) > + list_move_tail(&fsync_entry->list, tmp_inode_list); > next: > ra_blocks = adjust_por_ra_blocks(sbi, ra_blocks, blkaddr, > - next_blkaddr_of_node(folio)); > + next_blkaddr_of_node(cache_folio(entry))); > > /* check next segment */ > - blkaddr = next_blkaddr_of_node(folio); > - f2fs_folio_put(folio, true); > + blkaddr = next_blkaddr_of_node(cache_folio(entry)); > + f2fs_put_cache(entry, true); > > - f2fs_ra_meta_pages_cond(sbi, blkaddr, ra_blocks); > + f2fs_ra_meta_caches_cond(sbi, blkaddr, ra_blocks); > total_dnode++; > } > if (!err) > @@ -937,12 +940,11 @@ int f2fs_recover_fsync_data(struct f2fs_sb_info *sbi, bool check_only) > destroy_fsync_dnodes(&tmp_inode_list, err); > > /* truncate meta pages to be used by the recovery */ > - truncate_inode_pages_range(META_MAPPING(sbi), > - (loff_t)MAIN_BLKADDR(sbi) << PAGE_SHIFT, -1); > - > + f2fs_truncate_meta_caches(sbi, MAIN_BLKADDR(sbi), > + MAX_BLKADDR(sbi) - MAIN_BLKADDR(sbi)); > if (err) { > truncate_inode_pages_final(NODE_MAPPING(sbi)); > - truncate_inode_pages_final(META_MAPPING(sbi)); > + f2fs_truncate_meta_caches(sbi, 0, ULONG_MAX); > } > > /* > diff --git a/fs/f2fs/segment.c b/fs/f2fs/segment.c > index 56decf9c691c..cbb3a8c9f4ab 100644 > --- a/fs/f2fs/segment.c > +++ b/fs/f2fs/segment.c > @@ -2774,63 +2774,62 @@ int f2fs_npages_for_summary_flush(struct f2fs_sb_info *sbi, bool for_ra) > return 3; > } > > -/* > - * Caller should put this summary folio > - */ > -struct folio *f2fs_get_sum_folio(struct f2fs_sb_info *sbi, unsigned int segno) > + > +struct f2fs_cached_block *f2fs_get_sum_cache(struct f2fs_sb_info *sbi, > + unsigned int segno) > { > if (unlikely(f2fs_cp_error(sbi))) > return ERR_PTR(-EIO); > - return f2fs_get_meta_folio_retry(sbi, GET_SUM_BLOCK(sbi, segno)); > + return f2fs_get_meta_cache_retry(sbi, GET_SUM_BLOCK(sbi, segno)); > } > > void f2fs_update_meta_page(struct f2fs_sb_info *sbi, > void *src, block_t blk_addr) > { > - struct folio *folio; > + struct f2fs_cached_block *entry; > > if (!f2fs_sb_has_packed_ssa(sbi)) > - folio = f2fs_grab_meta_folio(sbi, blk_addr); > + entry = f2fs_grab_meta_cache(sbi, blk_addr); > else > - folio = f2fs_get_meta_folio_retry(sbi, blk_addr); > + entry = f2fs_get_meta_cache_retry(sbi, blk_addr); > > - if (IS_ERR(folio)) > + if (IS_ERR(entry)) > return; > > - memcpy(folio_address(folio), src, PAGE_SIZE); > - folio_mark_dirty(folio); > - f2fs_folio_put(folio, true); > + memcpy(cache_address(entry), src, sbi->blocksize); > + f2fs_mark_cache_dirty(entry); > + f2fs_put_cache(entry, true); > } > > static void write_sum_page(struct f2fs_sb_info *sbi, > struct f2fs_summary_block *sum_blk, unsigned int segno) > { > - struct folio *folio; > + struct f2fs_cached_block *entry; > > if (!f2fs_sb_has_packed_ssa(sbi)) > return f2fs_update_meta_page(sbi, (void *)sum_blk, > GET_SUM_BLOCK(sbi, segno)); > > - folio = f2fs_get_sum_folio(sbi, segno); > - if (IS_ERR(folio)) > + entry = f2fs_get_sum_cache(sbi, GET_SUM_BLOCK(sbi, segno)); > + if (IS_ERR(entry)) > return; > > - memcpy(SUM_BLK_PAGE_ADDR(sbi, folio, segno), sum_blk, > + memcpy(SUM_BLK_ENTRY_ADDR(sbi, entry, segno), sum_blk, > sbi->sum_blocksize); > - folio_mark_dirty(folio); > - f2fs_folio_put(folio, true); > + f2fs_mark_cache_dirty(entry); > + f2fs_put_cache(entry, true); > } > > static void write_current_sum_page(struct f2fs_sb_info *sbi, > int type, block_t blk_addr) > { > struct curseg_info *curseg = CURSEG_I(sbi, type); > - struct folio *folio = f2fs_grab_meta_folio(sbi, blk_addr); > + struct f2fs_cached_block *entry = f2fs_grab_meta_cache(sbi, blk_addr); > struct f2fs_summary_block *src = curseg->sum_blk; > struct f2fs_summary_block *dst; > > - dst = folio_address(folio); > - memset(dst, 0, PAGE_SIZE); > + dst = cache_address(entry); > + memset(dst, 0, sbi->blocksize); > > mutex_lock(&curseg->curseg_mutex); > > @@ -2843,8 +2842,8 @@ static void write_current_sum_page(struct f2fs_sb_info *sbi, > > mutex_unlock(&curseg->curseg_mutex); > > - folio_mark_dirty(folio); > - f2fs_folio_put(folio, true); > + f2fs_mark_cache_dirty(entry); > + f2fs_put_cache(entry, true); > } > > static int is_next_segment_free(struct f2fs_sb_info *sbi, > @@ -3160,7 +3159,7 @@ static int change_curseg(struct f2fs_sb_info *sbi, int type) > struct curseg_info *curseg = CURSEG_I(sbi, type); > unsigned int new_segno = curseg->next_segno; > struct f2fs_summary_block *sum_node; > - struct folio *sum_folio; > + struct f2fs_cached_block *entry = NULL; > > if (curseg->inited) > write_sum_page(sbi, curseg->sum_blk, curseg->segno); > @@ -3176,15 +3175,15 @@ static int change_curseg(struct f2fs_sb_info *sbi, int type) > curseg->alloc_type = SSR; > curseg->next_blkoff = __next_free_blkoff(sbi, curseg->segno, 0); > > - sum_folio = f2fs_get_sum_folio(sbi, new_segno); > - if (IS_ERR(sum_folio)) { > + entry = f2fs_get_sum_cache(sbi, new_segno); > + if (IS_ERR(entry)) { > /* GC won't be able to use stale summary pages by cp_error */ > memset(curseg->sum_blk, 0, sbi->sum_entry_size); > - return PTR_ERR(sum_folio); > + return PTR_ERR(entry); > } > - sum_node = SUM_BLK_PAGE_ADDR(sbi, sum_folio, new_segno); > + sum_node = SUM_BLK_ENTRY_ADDR(sbi, entry, new_segno); > memcpy(curseg->sum_blk, sum_node, sbi->sum_entry_size); > - f2fs_folio_put(sum_folio, true); > + f2fs_put_cache(entry, true); > return 0; > } > > @@ -4127,8 +4126,9 @@ static void do_write_page(struct f2fs_summary *sum, struct f2fs_io_info *fio) > f2fs_up_read(&fio->sbi->io_order_lock); > } > > -void f2fs_do_write_meta_page(struct f2fs_sb_info *sbi, struct folio *folio, > - enum iostat_type io_type) > +void f2fs_do_write_meta_cache(struct f2fs_sb_info *sbi, > + struct f2fs_cached_block *entry, > + enum iostat_type io_type) > { > struct f2fs_io_info fio = { > .sbi = sbi, > @@ -4136,20 +4136,21 @@ void f2fs_do_write_meta_page(struct f2fs_sb_info *sbi, struct folio *folio, > .temp = HOT, > .op = REQ_OP_WRITE, > .op_flags = REQ_SYNC | REQ_META | REQ_PRIO, > - .old_blkaddr = folio->index, > - .new_blkaddr = folio->index, > - .folio = folio, > + .old_blkaddr = entry->index, > + .new_blkaddr = entry->index, > .encrypted_page = NULL, > .in_list = 0, > + .cache_entry = entry, > + .is_cache = 1, > }; > > - if (unlikely(folio->index >= MAIN_BLKADDR(sbi))) > + if (unlikely(entry->index >= MAIN_BLKADDR(sbi))) > fio.op_flags &= ~REQ_META; > > - folio_start_writeback(folio); > - f2fs_submit_page_write(&fio); > + f2fs_start_cache_writeback(entry); > + f2fs_submit_cache_write(&fio); > > - stat_inc_meta_count(sbi, folio->index); > + stat_inc_meta_count(sbi, entry->index); > f2fs_update_iostat(sbi, NULL, io_type, F2FS_BLKSIZE); > } > > @@ -4206,7 +4207,7 @@ int f2fs_inplace_write_data(struct f2fs_io_info *fio) > } > > if (fio->meta_gc) > - f2fs_truncate_meta_inode_pages(sbi, fio->new_blkaddr, 1); > + f2fs_truncate_meta_caches(sbi, fio->new_blkaddr, 1); > > stat_inc_inplace_blocks(fio->sbi); > > @@ -4372,7 +4373,7 @@ void f2fs_folio_wait_writeback(struct folio *folio, enum page_type type, > void f2fs_wait_on_block_writeback(struct inode *inode, block_t blkaddr) > { > struct f2fs_sb_info *sbi = F2FS_I_SB(inode); > - struct folio *cfolio; > + struct f2fs_cached_block *entry; > > if (!f2fs_meta_inode_gc_required(inode)) > return; > @@ -4380,11 +4381,12 @@ void f2fs_wait_on_block_writeback(struct inode *inode, block_t blkaddr) > if (!__is_valid_data_blkaddr(blkaddr)) > return; > > - cfolio = filemap_lock_folio(META_MAPPING(sbi), blkaddr); > - if (!IS_ERR(cfolio)) { > - f2fs_folio_wait_writeback(cfolio, DATA, true, true); > - f2fs_folio_put(cfolio, true); > - } > + entry = f2fs_find_cache(META_CACHE(sbi), blkaddr); > + if (IS_ERR(entry)) > + return; > + f2fs_lock_cache(entry); > + f2fs_cache_wait_writeback_cond(entry, DATA); > + f2fs_put_cache(entry, true); > } > > void f2fs_wait_on_block_writeback_range(struct inode *inode, block_t blkaddr, > @@ -4399,7 +4401,7 @@ void f2fs_wait_on_block_writeback_range(struct inode *inode, block_t blkaddr, > for (i = 0; i < len; i++) > f2fs_wait_on_block_writeback(inode, blkaddr + i); > > - f2fs_truncate_meta_inode_pages(sbi, blkaddr, len); > + f2fs_truncate_meta_caches(sbi, blkaddr, len); > } > > static int read_compacted_summaries(struct f2fs_sb_info *sbi) > @@ -4407,16 +4409,16 @@ static int read_compacted_summaries(struct f2fs_sb_info *sbi) > struct f2fs_checkpoint *ckpt = F2FS_CKPT(sbi); > struct curseg_info *seg_i; > unsigned char *kaddr; > - struct folio *folio; > + struct f2fs_cached_block *entry; > block_t start; > int i, j, offset; > > start = start_sum_block(sbi); > > - folio = f2fs_get_meta_folio(sbi, start++); > - if (IS_ERR(folio)) > - return PTR_ERR(folio); > - kaddr = folio_address(folio); > + entry = f2fs_get_meta_cache(sbi, start++); > + if (IS_ERR(entry)) > + return PTR_ERR(entry); > + kaddr = cache_address(entry); > > /* Step 1: restore nat cache */ > seg_i = CURSEG_I(sbi, CURSEG_HOT_DATA); > @@ -4453,16 +4455,16 @@ static int read_compacted_summaries(struct f2fs_sb_info *sbi) > SUM_FOOTER_SIZE) > continue; > > - f2fs_folio_put(folio, true); > + f2fs_put_cache(entry, true); > > - folio = f2fs_get_meta_folio(sbi, start++); > - if (IS_ERR(folio)) > - return PTR_ERR(folio); > - kaddr = folio_address(folio); > + entry = f2fs_get_meta_cache(sbi, start++); > + if (IS_ERR(entry)) > + return PTR_ERR(entry); > + kaddr = cache_address(entry); > offset = 0; > } > } > - f2fs_folio_put(folio, true); > + f2fs_put_cache(entry, true); > return 0; > } > > @@ -4471,7 +4473,7 @@ static int read_normal_summaries(struct f2fs_sb_info *sbi, int type) > struct f2fs_checkpoint *ckpt = F2FS_CKPT(sbi); > struct f2fs_summary_block *sum; > struct curseg_info *curseg; > - struct folio *new; > + struct f2fs_cached_block *entry; > unsigned short blk_off; > unsigned int segno = 0; > block_t blk_addr = 0; > @@ -4498,10 +4500,10 @@ static int read_normal_summaries(struct f2fs_sb_info *sbi, int type) > blk_addr = GET_SUM_BLOCK(sbi, segno); > } > > - new = f2fs_get_meta_folio(sbi, blk_addr); > - if (IS_ERR(new)) > - return PTR_ERR(new); > - sum = folio_address(new); > + entry = f2fs_get_meta_cache(sbi, blk_addr); > + if (IS_ERR(entry)) > + return PTR_ERR(entry); > + sum = cache_address(entry); > > if (IS_NODESEG(type)) { > if (__exist_node_summaries(sbi)) { > @@ -4538,7 +4540,7 @@ static int read_normal_summaries(struct f2fs_sb_info *sbi, int type) > curseg->next_blkoff = blk_off; > mutex_unlock(&curseg->curseg_mutex); > out: > - f2fs_folio_put(new, true); > + f2fs_put_cache(entry, true); > return err; > } > > @@ -4553,8 +4555,8 @@ static int restore_curseg_summaries(struct f2fs_sb_info *sbi) > int npages = f2fs_npages_for_summary_flush(sbi, true); > > if (npages >= 2) > - f2fs_ra_meta_pages(sbi, start_sum_block(sbi), npages, > - META_CP, true); > + f2fs_ra_meta_caches(sbi, start_sum_block(sbi), > + npages, META_CP, true); > > /* restore for compacted data summary */ > err = read_compacted_summaries(sbi); > @@ -4564,7 +4566,7 @@ static int restore_curseg_summaries(struct f2fs_sb_info *sbi) > } > > if (__exist_node_summaries(sbi)) > - f2fs_ra_meta_pages(sbi, > + f2fs_ra_meta_caches(sbi, > sum_blk_addr(sbi, NR_CURSEG_PERSIST_TYPE, type), > NR_CURSEG_PERSIST_TYPE - type, META_CP, true); > > @@ -4587,16 +4589,16 @@ static int restore_curseg_summaries(struct f2fs_sb_info *sbi) > > static void write_compacted_summaries(struct f2fs_sb_info *sbi, block_t blkaddr) > { > - struct folio *folio; > + struct f2fs_cached_block *entry = NULL; > unsigned char *kaddr; > struct f2fs_summary *summary; > struct curseg_info *seg_i; > int written_size = 0; > int i, j; > > - folio = f2fs_grab_meta_folio(sbi, blkaddr++); > - kaddr = folio_address(folio); > - memset(kaddr, 0, PAGE_SIZE); > + entry = f2fs_grab_meta_cache(sbi, blkaddr++); > + kaddr = cache_address(entry); > + memset(kaddr, 0, sbi->blocksize); > > /* Step 1: write nat cache */ > seg_i = CURSEG_I(sbi, CURSEG_HOT_DATA); > @@ -4612,10 +4614,10 @@ static void write_compacted_summaries(struct f2fs_sb_info *sbi, block_t blkaddr) > for (i = CURSEG_HOT_DATA; i <= CURSEG_COLD_DATA; i++) { > seg_i = CURSEG_I(sbi, i); > for (j = 0; j < f2fs_curseg_valid_blocks(sbi, i); j++) { > - if (!folio) { > - folio = f2fs_grab_meta_folio(sbi, blkaddr++); > - kaddr = folio_address(folio); > - memset(kaddr, 0, PAGE_SIZE); > + if (!entry) { > + entry = f2fs_grab_meta_cache(sbi, blkaddr++); > + kaddr = cache_address(entry); > + memset(kaddr, 0, sbi->blocksize); > written_size = 0; > } > summary = (struct f2fs_summary *)(kaddr + written_size); > @@ -4626,14 +4628,14 @@ static void write_compacted_summaries(struct f2fs_sb_info *sbi, block_t blkaddr) > SUM_FOOTER_SIZE) > continue; > > - folio_mark_dirty(folio); > - f2fs_folio_put(folio, true); > - folio = NULL; > + f2fs_mark_cache_dirty(entry); > + f2fs_put_cache(entry, true); > + entry = NULL; > } > } > - if (folio) { > - folio_mark_dirty(folio); > - f2fs_folio_put(folio, true); > + if (entry) { > + f2fs_mark_cache_dirty(entry); > + f2fs_put_cache(entry, true); > } > } > > @@ -4687,29 +4689,29 @@ int f2fs_lookup_journal_in_cursum(struct f2fs_sb_info *sbi, > return -1; > } > > -static struct folio *get_current_sit_folio(struct f2fs_sb_info *sbi, > +static struct f2fs_cached_block *get_current_sit_cache(struct f2fs_sb_info *sbi, > unsigned int segno) > { > - return f2fs_get_meta_folio(sbi, current_sit_addr(sbi, segno)); > + return f2fs_get_meta_cache(sbi, current_sit_addr(sbi, segno)); > } > > -static struct folio *get_next_sit_folio(struct f2fs_sb_info *sbi, > +static struct f2fs_cached_block *get_next_sit_cache(struct f2fs_sb_info *sbi, > unsigned int start) > { > struct sit_info *sit_i = SIT_I(sbi); > - struct folio *folio; > + struct f2fs_cached_block *entry; > pgoff_t src_off, dst_off; > > src_off = current_sit_addr(sbi, start); > dst_off = next_sit_addr(sbi, src_off); > > - folio = f2fs_grab_meta_folio(sbi, dst_off); > - seg_info_to_sit_folio(sbi, folio, start); > + entry = f2fs_grab_meta_cache(sbi, dst_off); > + seg_info_to_sit_block(sbi, entry, start); > > - folio_mark_dirty(folio); > + f2fs_mark_cache_dirty(entry); > set_to_next_sit(sit_i, start); > > - return folio; > + return entry; > } > > static struct sit_entry_set *grab_sit_entry_set(void) > @@ -4839,8 +4841,9 @@ void f2fs_flush_sit_entries(struct f2fs_sb_info *sbi, struct cp_control *cpc) > * #2, flush sit entries to sit page. > */ > list_for_each_entry_safe(ses, tmp, head, set_list) { > - struct folio *folio = NULL; > + struct f2fs_cached_block *entry = NULL; > struct f2fs_sit_block *raw_sit = NULL; > + > unsigned int start_segno = ses->start_segno; > unsigned int end = min(start_segno + SIT_ENTRY_PER_BLOCK, > (unsigned long)MAIN_SEGS(sbi)); > @@ -4854,8 +4857,8 @@ void f2fs_flush_sit_entries(struct f2fs_sb_info *sbi, struct cp_control *cpc) > if (to_journal) { > down_write(&curseg->journal_rwsem); > } else { > - folio = get_next_sit_folio(sbi, start_segno); > - raw_sit = folio_address(folio); > + entry = get_next_sit_cache(sbi, start_segno); > + raw_sit = cache_address(entry); > } > > /* flush dirty sit entries in region of current sit set */ > @@ -4900,7 +4903,7 @@ void f2fs_flush_sit_entries(struct f2fs_sb_info *sbi, struct cp_control *cpc) > if (to_journal) > up_write(&curseg->journal_rwsem); > else > - f2fs_folio_put(folio, true); > + f2fs_put_cache(entry, true); > > f2fs_bug_on(sbi, ses->entry_cnt); > release_sit_entry_set(ses); > @@ -5091,7 +5094,7 @@ static int build_sit_entries(struct f2fs_sb_info *sbi) > block_t sit_valid_blocks[2] = {0, 0}; > > do { > - readed = f2fs_ra_meta_pages(sbi, start_blk, BIO_MAX_VECS, > + readed = f2fs_ra_meta_caches(sbi, start_blk, BIO_MAX_VECS, > META_SIT, true); > > start = start_blk * sit_i->sents_per_block; > @@ -5099,15 +5102,15 @@ static int build_sit_entries(struct f2fs_sb_info *sbi) > > for (; start < end && start < MAIN_SEGS(sbi); start++) { > struct f2fs_sit_block *sit_blk; > - struct folio *folio; > + struct f2fs_cached_block *entry; > > se = &sit_i->sentries[start]; > - folio = get_current_sit_folio(sbi, start); > - if (IS_ERR(folio)) > - return PTR_ERR(folio); > - sit_blk = folio_address(folio); > + entry = get_current_sit_cache(sbi, start); > + if (IS_ERR(entry)) > + return PTR_ERR(entry); > + sit_blk = cache_address(entry); > sit = sit_blk->entries[SIT_ENTRY_OFFSET(sit_i, start)]; > - f2fs_folio_put(folio, true); > + f2fs_put_cache(entry, true); > > err = check_block_count(sbi, start, &sit); > if (err) > diff --git a/fs/f2fs/segment.h b/fs/f2fs/segment.h > index db1079169a23..fff35c63a00f 100644 > --- a/fs/f2fs/segment.h > +++ b/fs/f2fs/segment.h > @@ -95,6 +95,8 @@ static inline void sanity_check_seg_type(struct f2fs_sb_info *sbi, > #define GET_SUM_BLKOFF(sbi, segno) (segno % (sbi)->sums_per_block) > #define SUM_BLK_PAGE_ADDR(sbi, folio, segno) \ > (folio_address(folio) + GET_SUM_BLKOFF(sbi, segno) * (sbi)->sum_blocksize) > +#define SUM_BLK_ENTRY_ADDR(sbi, entry, segno) \ > + (cache_address(entry) + GET_SUM_BLKOFF(sbi, segno) * (sbi)->sum_blocksize) > > #define GET_SUM_TYPE(footer) ((footer)->entry_type) > #define SET_SUM_TYPE(footer, type) ((footer)->entry_type = (type)) > @@ -417,8 +419,8 @@ static inline void __seg_info_to_raw_sit(struct seg_entry *se, > rs->mtime = cpu_to_le64(se->mtime); > } > > -static inline void seg_info_to_sit_folio(struct f2fs_sb_info *sbi, > - struct folio *folio, unsigned int start) > +static inline void seg_info_to_sit_block(struct f2fs_sb_info *sbi, > + struct f2fs_cached_block *entry, unsigned int start) > { > struct f2fs_sit_block *raw_sit; > struct seg_entry *se; > @@ -427,8 +429,8 @@ static inline void seg_info_to_sit_folio(struct f2fs_sb_info *sbi, > (unsigned long)MAIN_SEGS(sbi)); > int i; > > - raw_sit = folio_address(folio); > - memset(raw_sit, 0, PAGE_SIZE); > + raw_sit = cache_address(entry); > + memset(raw_sit, 0, sbi->blocksize); > for (i = 0; i < end - start; i++) { > rs = &raw_sit->entries[i]; > se = get_seg_entry(sbi, start + i); > @@ -991,6 +993,27 @@ static inline int nr_pages_to_skip(struct f2fs_sb_info *sbi, int type) > return 0; > } > > +/* > + * When writing cache asynchronously, align nr_to_write to BIO_MAX_VECS. > + */ > +static inline long adjust_flush_cache_number(struct f2fs_sb_info *sbi, int type) > +{ > + long nr_to_write; > + > + switch (type) { > + case META: > + nr_to_write = BIO_MAX_VECS; > + break; > + case NODE: > + nr_to_write = BIO_MAX_VECS << 1; > + break; > + default: > + f2fs_bug_on(sbi, 1); > + return 0; > + } > + return nr_to_write; > +} > + > /* > * When writing pages, it'd better align nr_to_write for segment size. > */ > diff --git a/fs/f2fs/super.c b/fs/f2fs/super.c > index 89affe72f4fc..d3dee9b7d999 100644 > --- a/fs/f2fs/super.c > +++ b/fs/f2fs/super.c > @@ -1839,8 +1839,7 @@ static int f2fs_drop_inode(struct inode *inode) > * drop useless meta/node dirty pages. > */ > if (unlikely(is_sbi_flag_set(sbi, SBI_CP_DISABLED))) { > - if (inode->i_ino == F2FS_NODE_INO(sbi) || > - inode->i_ino == F2FS_META_INO(sbi)) { > + if (inode->i_ino == F2FS_NODE_INO(sbi)) { > trace_f2fs_drop_inode(inode, 1); > return 1; > } > @@ -1942,8 +1941,7 @@ static void f2fs_dirty_inode(struct inode *inode, int flags) > { > struct f2fs_sb_info *sbi = F2FS_I_SB(inode); > > - if (inode->i_ino == F2FS_NODE_INO(sbi) || > - inode->i_ino == F2FS_META_INO(sbi)) > + if (inode->i_ino == F2FS_NODE_INO(sbi)) > return; > > if (is_inode_flag_set(inode, FI_AUTO_RECOVER)) > @@ -2039,9 +2037,10 @@ static void f2fs_put_super(struct super_block *sb) > > f2fs_wait_on_all_pages(sbi, F2FS_WB_CP_DATA); > > - if (err || f2fs_cp_error(sbi)) { > + if (err || f2fs_cp_error(sbi) || > + unlikely(is_sbi_flag_set(sbi, SBI_CP_DISABLED))) { > truncate_inode_pages_final(NODE_MAPPING(sbi)); > - truncate_inode_pages_final(META_MAPPING(sbi)); > + f2fs_truncate_meta_caches(sbi, 0, ULONG_MAX); > } > > f2fs_bug_on(sbi, sbi->fsync_node_num); > @@ -2051,9 +2050,6 @@ static void f2fs_put_super(struct super_block *sb) > iput(sbi->node_inode); > sbi->node_inode = NULL; > > - iput(sbi->meta_inode); > - sbi->meta_inode = NULL; > - > f2fs_destroy_cache(META_CACHE(sbi)); > > /* Should check the page counts after dropping all node/meta pages */ > @@ -4383,7 +4379,6 @@ static void init_sb_info(struct f2fs_sb_info *sbi) > sbi->allocate_section_policy = ALLOCATE_FORWARD_NOHINT; > F2FS_ROOT_INO(sbi) = le32_to_cpu(raw_super->root_ino); > F2FS_NODE_INO(sbi) = le32_to_cpu(raw_super->node_ino); > - F2FS_META_INO(sbi) = le32_to_cpu(raw_super->meta_ino); > sbi->cur_victim_sec = NULL_SECNO; > sbi->gc_mode = GC_NORMAL; > sbi->next_victim_seg[BG_GC] = NULL_SEGNO; > @@ -5224,18 +5219,10 @@ static int f2fs_fill_super(struct super_block *sb, struct fs_context *fc) > if (err) > goto free_page_array_cache; > > - /* get an inode for meta space */ > - sbi->meta_inode = f2fs_iget(sb, F2FS_META_INO(sbi)); > - if (IS_ERR(sbi->meta_inode)) { > - f2fs_err(sbi, "Failed to read F2FS meta data inode"); > - err = PTR_ERR(sbi->meta_inode); > - goto free_meta_cache; > - } > - > err = f2fs_get_valid_checkpoint(sbi); > if (err) { > f2fs_err(sbi, "Failed to get valid F2FS checkpoint"); > - goto free_meta_inode; > + goto free_meta_cache; > } > > if (__is_set_ckpt_flags(F2FS_CKPT(sbi), CP_QUOTA_NEED_FSCK_FLAG)) > @@ -5529,7 +5516,7 @@ static int f2fs_fill_super(struct super_block *sb, struct fs_context *fc) > * followed by f2fs_write_checkpoint() through f2fs_write_node_pages(), which > * falls into an infinite loop in f2fs_sync_meta_pages(). > */ > - truncate_inode_pages_final(META_MAPPING(sbi)); > + f2fs_truncate_meta_caches(sbi, 0, ULONG_MAX); > /* evict some inodes being cached by GC */ > evict_inodes(sb); > f2fs_unregister_sysfs(sbi); > @@ -5559,10 +5546,6 @@ static int f2fs_fill_super(struct super_block *sb, struct fs_context *fc) > free_devices: > destroy_device_list(sbi); > kvfree(sbi->ckpt); > -free_meta_inode: > - make_bad_inode(sbi->meta_inode); > - iput(sbi->meta_inode); > - sbi->meta_inode = NULL; > free_meta_cache: > f2fs_destroy_cache(META_CACHE(sbi)); > free_page_array_cache: > diff --git a/include/linux/f2fs_fs.h b/include/linux/f2fs_fs.h > index bb2b6cd5d507..0c027d00a1ea 100644 > --- a/include/linux/f2fs_fs.h > +++ b/include/linux/f2fs_fs.h > @@ -35,7 +35,6 @@ > > #define F2FS_ROOT_INO(sbi) ((sbi)->root_ino_num) > #define F2FS_NODE_INO(sbi) ((sbi)->node_ino_num) > -#define F2FS_META_INO(sbi) ((sbi)->meta_ino_num) > #define F2FS_COMPRESS_INO(sbi) (NM_I(sbi)->max_nid) > > #define F2FS_MAX_QUOTAS 3 > -- > 2.49.0 > > > > _______________________________________________ > Linux-f2fs-devel mailing list > Linux-f2fs-devel@lists.sourceforge.net > https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel