Commit 0974f486 authored by Linus Torvalds's avatar Linus Torvalds
Browse files
Pull f2fs updates from Jaegeuk Kim:
 "Three main updates: folio conversion by Matthew, switch to a new mount
  API by Hongbo and Eric, and several sysfs entries to tune GCs for ZUFS
  with finer granularity by Daeho.

  There are also patches to address bugs and issues in the existing
  features such as GCs, file pinning, write-while-dio-read, contingous
  block allocation, and memory access violations.

  Enhancements:
   - switch to new mount API and folio conversion
   - add sysfs nodes to controle F2FS GCs for ZUFS
   - improve performance on the nat entry cache
   - drop inode from the donation list when the last file is closed
   - avoid splitting bio when reading multiple pages

  Bug fixes:
   - fix to trigger foreground gc during f2fs_map_blocks() in lfs mode
   - make sure zoned device GC to use FG_GC in shortage of free section
   - fix to calculate dirty data during has_not_enough_free_secs()
   - fix to update upper_p in __get_secs_required() correctly
   - wait for inflight dio completion, excluding pinned files read using dio
   - don't break allocation when crossing contiguous sections
   - vm_unmap_ram() may be called from an invalid context
   - fix to avoid out-of-boundary access in dnode page
   - fix to avoid panic in f2fs_evict_inode
   - fix to avoid UAF in f2fs_sync_inode_meta()
   - fix to use f2fs_is_valid_blkaddr_raw() in do_write_page()
   - fix UAF of f2fs_inode_info in f2fs_free_dic
   - fix to avoid invalid wait context issue
   - fix bio memleak when committing super block
   - handle nat.blkaddr corruption in f2fs_get_node_info()

  In addition, there are also clean-ups and minor bug fixes"

* tag 'f2fs-for-6.17-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/jaegeuk/f2fs: (109 commits)
  f2fs: drop inode from the donation list when the last file is closed
  f2fs: add gc_boost_gc_greedy sysfs node
  f2fs: add gc_boost_gc_multiple sysfs node
  f2fs: fix to trigger foreground gc during f2fs_map_blocks() in lfs mode
  f2fs: fix to calculate dirty data during has_not_enough_free_secs()
  f2fs: fix to update upper_p in __get_secs_required() correctly
  f2fs: directly add newly allocated pre-dirty nat entry to dirty set list
  f2fs: avoid redundant clean nat entry move in lru list
  f2fs: zone: wait for inflight dio completion, excluding pinned files read using dio
  f2fs: ignore valid ratio when free section count is low
  f2fs: don't break allocation when crossing contiguous sections
  f2fs: remove unnecessary tracepoint enabled check
  f2fs: merge the two conditions to avoid code duplication
  f2fs: vm_unmap_ram() may be called from an invalid context
  f2fs: fix to avoid out-of-boundary access in dnode page
  f2fs: switch to the new mount api
  f2fs: introduce fs_context_operation structure
  f2fs: separate the options parsing and options checking
  f2fs: Add f2fs_fs_context to record the mount options
  f2fs: Allow sbi to be NULL in f2fs_printk
  ...
parents 35a813e0 078cad82
Loading
Loading
Loading
Loading
+22 −0
Original line number Diff line number Diff line
@@ -861,3 +861,25 @@ Description: This is a read-only entry to show the value of sb.s_encoding_flags,
		SB_ENC_STRICT_MODE_FL            0x00000001
		SB_ENC_NO_COMPAT_FALLBACK_FL     0x00000002
		============================     ==========

What:		/sys/fs/f2fs/<disk>/reserved_pin_section
Date:		June 2025
Contact:	"Chao Yu" <chao@kernel.org>
Description:	This threshold is used to control triggering garbage collection while
		fallocating on pinned file, so, it can guarantee there is enough free
		reserved section before preallocating on pinned file.
		By default, the value is ovp_sections, especially, for zoned ufs, the
		value is 1.

What:		/sys/fs/f2fs/<disk>/gc_boost_gc_multiple
Date:		June 2025
Contact:	"Daeho Jeong" <daehojeong@google.com>
Description:	Set a multiplier for the background GC migration window when F2FS GC is
		boosted. The range should be from 1 to the segment count in a section.
		Default: 5

What:		/sys/fs/f2fs/<disk>/gc_boost_gc_greedy
Date:		June 2025
Contact:	"Daeho Jeong" <daehojeong@google.com>
Description:	Control GC algorithm for boost GC. 0: cost benefit, 1: greedy
		Default: 1
+3 −3
Original line number Diff line number Diff line
@@ -238,9 +238,9 @@ usrjquota=<file> Appoint specified file and type during mount, so that quota
grpjquota=<file>	 information can be properly updated during recovery flow,
prjjquota=<file>	 <quota file>: must be in root directory;
jqfmt=<quota type>	 <quota type>: [vfsold,vfsv0,vfsv1].
offusrjquota		 Turn off user journalled quota.
offgrpjquota		 Turn off group journalled quota.
offprjjquota		 Turn off project journalled quota.
usrjquota=		 Turn off user journalled quota.
grpjquota=		 Turn off group journalled quota.
prjjquota=		 Turn off project journalled quota.
quota			 Enable plain user disk quota accounting.
noquota			 Disable all plain disk quota option.
alloc_mode=%s		 Adjust block allocation policy, which supports "reuse"
+4 −4
Original line number Diff line number Diff line
@@ -82,7 +82,7 @@ static struct folio *__get_meta_folio(struct f2fs_sb_info *sbi, pgoff_t index,
	if (folio_test_uptodate(folio))
		goto out;

	fio.page = &folio->page;
	fio.folio = folio;

	err = f2fs_submit_page_bio(&fio);
	if (err) {
@@ -309,7 +309,7 @@ int f2fs_ra_meta_pages(struct f2fs_sb_info *sbi, block_t start, int nrpages,
			continue;
		}

		fio.page = &folio->page;
		fio.folio = folio;
		err = f2fs_submit_page_bio(&fio);
		f2fs_folio_put(folio, err ? true : false);

@@ -485,7 +485,7 @@ static bool f2fs_dirty_meta_folio(struct address_space *mapping,
		folio_mark_uptodate(folio);
	if (filemap_dirty_folio(mapping, folio)) {
		inc_page_count(F2FS_M_SB(mapping), F2FS_DIRTY_META);
		set_page_private_reference(&folio->page);
		folio_set_f2fs_reference(folio);
		return true;
	}
	return false;
@@ -1045,7 +1045,7 @@ void f2fs_update_dirty_folio(struct inode *inode, struct folio *folio)
	inode_inc_dirty_pages(inode);
	spin_unlock(&sbi->inode_lock[type]);

	set_page_private_reference(&folio->page);
	folio_set_f2fs_reference(folio);
}

void f2fs_remove_dirty_inode(struct inode *inode)
+60 −60
Original line number Diff line number Diff line
@@ -23,20 +23,18 @@
static struct kmem_cache *cic_entry_slab;
static struct kmem_cache *dic_entry_slab;

static void *page_array_alloc(struct inode *inode, int nr)
static void *page_array_alloc(struct f2fs_sb_info *sbi, int nr)
{
	struct f2fs_sb_info *sbi = F2FS_I_SB(inode);
	unsigned int size = sizeof(struct page *) * nr;

	if (likely(size <= sbi->page_array_slab_size))
		return f2fs_kmem_cache_alloc(sbi->page_array_slab,
					GFP_F2FS_ZERO, false, F2FS_I_SB(inode));
					GFP_F2FS_ZERO, false, sbi);
	return f2fs_kzalloc(sbi, size, GFP_NOFS);
}

static void page_array_free(struct inode *inode, void *pages, int nr)
static void page_array_free(struct f2fs_sb_info *sbi, void *pages, int nr)
{
	struct f2fs_sb_info *sbi = F2FS_I_SB(inode);
	unsigned int size = sizeof(struct page *) * nr;

	if (!pages)
@@ -73,17 +71,15 @@ static pgoff_t start_idx_of_cluster(struct compress_ctx *cc)
	return cc->cluster_idx << cc->log_cluster_size;
}

bool f2fs_is_compressed_page(struct page *page)
bool f2fs_is_compressed_page(struct folio *folio)
{
	if (!PagePrivate(page))
		return false;
	if (!page_private(page))
	if (!folio->private)
		return false;
	if (page_private_nonpointer(page))
	if (folio_test_f2fs_nonpointer(folio))
		return false;

	f2fs_bug_on(F2FS_P_SB(page),
		*((u32 *)page_private(page)) != F2FS_COMPRESSED_PAGE_MAGIC);
	f2fs_bug_on(F2FS_F_SB(folio),
		*((u32 *)folio->private) != F2FS_COMPRESSED_PAGE_MAGIC);
	return true;
}

@@ -149,13 +145,13 @@ int f2fs_init_compress_ctx(struct compress_ctx *cc)
	if (cc->rpages)
		return 0;

	cc->rpages = page_array_alloc(cc->inode, cc->cluster_size);
	cc->rpages = page_array_alloc(F2FS_I_SB(cc->inode), cc->cluster_size);
	return cc->rpages ? 0 : -ENOMEM;
}

void f2fs_destroy_compress_ctx(struct compress_ctx *cc, bool reuse)
{
	page_array_free(cc->inode, cc->rpages, cc->cluster_size);
	page_array_free(F2FS_I_SB(cc->inode), cc->rpages, cc->cluster_size);
	cc->rpages = NULL;
	cc->nr_rpages = 0;
	cc->nr_cpages = 0;
@@ -216,13 +212,13 @@ static int lzo_decompress_pages(struct decompress_io_ctx *dic)
	ret = lzo1x_decompress_safe(dic->cbuf->cdata, dic->clen,
						dic->rbuf, &dic->rlen);
	if (ret != LZO_E_OK) {
		f2fs_err_ratelimited(F2FS_I_SB(dic->inode),
		f2fs_err_ratelimited(dic->sbi,
				"lzo decompress failed, ret:%d", ret);
		return -EIO;
	}

	if (dic->rlen != PAGE_SIZE << dic->log_cluster_size) {
		f2fs_err_ratelimited(F2FS_I_SB(dic->inode),
		f2fs_err_ratelimited(dic->sbi,
				"lzo invalid rlen:%zu, expected:%lu",
				dic->rlen, PAGE_SIZE << dic->log_cluster_size);
		return -EIO;
@@ -296,13 +292,13 @@ static int lz4_decompress_pages(struct decompress_io_ctx *dic)
	ret = LZ4_decompress_safe(dic->cbuf->cdata, dic->rbuf,
						dic->clen, dic->rlen);
	if (ret < 0) {
		f2fs_err_ratelimited(F2FS_I_SB(dic->inode),
		f2fs_err_ratelimited(dic->sbi,
				"lz4 decompress failed, ret:%d", ret);
		return -EIO;
	}

	if (ret != PAGE_SIZE << dic->log_cluster_size) {
		f2fs_err_ratelimited(F2FS_I_SB(dic->inode),
		f2fs_err_ratelimited(dic->sbi,
				"lz4 invalid ret:%d, expected:%lu",
				ret, PAGE_SIZE << dic->log_cluster_size);
		return -EIO;
@@ -424,13 +420,13 @@ static int zstd_init_decompress_ctx(struct decompress_io_ctx *dic)

	workspace_size = zstd_dstream_workspace_bound(max_window_size);

	workspace = f2fs_vmalloc(F2FS_I_SB(dic->inode), workspace_size);
	workspace = f2fs_vmalloc(dic->sbi, workspace_size);
	if (!workspace)
		return -ENOMEM;

	stream = zstd_init_dstream(max_window_size, workspace, workspace_size);
	if (!stream) {
		f2fs_err_ratelimited(F2FS_I_SB(dic->inode),
		f2fs_err_ratelimited(dic->sbi,
				"%s zstd_init_dstream failed", __func__);
		vfree(workspace);
		return -EIO;
@@ -466,14 +462,14 @@ static int zstd_decompress_pages(struct decompress_io_ctx *dic)

	ret = zstd_decompress_stream(stream, &outbuf, &inbuf);
	if (zstd_is_error(ret)) {
		f2fs_err_ratelimited(F2FS_I_SB(dic->inode),
		f2fs_err_ratelimited(dic->sbi,
				"%s zstd_decompress_stream failed, ret: %d",
				__func__, zstd_get_error_code(ret));
		return -EIO;
	}

	if (dic->rlen != outbuf.pos) {
		f2fs_err_ratelimited(F2FS_I_SB(dic->inode),
		f2fs_err_ratelimited(dic->sbi,
				"%s ZSTD invalid rlen:%zu, expected:%lu",
				__func__, dic->rlen,
				PAGE_SIZE << dic->log_cluster_size);
@@ -622,6 +618,7 @@ static void *f2fs_vmap(struct page **pages, unsigned int count)

static int f2fs_compress_pages(struct compress_ctx *cc)
{
	struct f2fs_sb_info *sbi = F2FS_I_SB(cc->inode);
	struct f2fs_inode_info *fi = F2FS_I(cc->inode);
	const struct f2fs_compress_ops *cops =
				f2fs_cops[fi->i_compress_algorithm];
@@ -642,7 +639,7 @@ static int f2fs_compress_pages(struct compress_ctx *cc)
	cc->nr_cpages = DIV_ROUND_UP(max_len, PAGE_SIZE);
	cc->valid_nr_cpages = cc->nr_cpages;

	cc->cpages = page_array_alloc(cc->inode, cc->nr_cpages);
	cc->cpages = page_array_alloc(sbi, cc->nr_cpages);
	if (!cc->cpages) {
		ret = -ENOMEM;
		goto destroy_compress_ctx;
@@ -716,7 +713,7 @@ static int f2fs_compress_pages(struct compress_ctx *cc)
		if (cc->cpages[i])
			f2fs_compress_free_page(cc->cpages[i]);
	}
	page_array_free(cc->inode, cc->cpages, cc->nr_cpages);
	page_array_free(sbi, cc->cpages, cc->nr_cpages);
	cc->cpages = NULL;
destroy_compress_ctx:
	if (cops->destroy_compress_ctx)
@@ -734,7 +731,7 @@ static void f2fs_release_decomp_mem(struct decompress_io_ctx *dic,

void f2fs_decompress_cluster(struct decompress_io_ctx *dic, bool in_task)
{
	struct f2fs_sb_info *sbi = F2FS_I_SB(dic->inode);
	struct f2fs_sb_info *sbi = dic->sbi;
	struct f2fs_inode_info *fi = F2FS_I(dic->inode);
	const struct f2fs_compress_ops *cops =
			f2fs_cops[fi->i_compress_algorithm];
@@ -796,25 +793,27 @@ void f2fs_decompress_cluster(struct decompress_io_ctx *dic, bool in_task)
	f2fs_decompress_end_io(dic, ret, in_task);
}

static void f2fs_cache_compressed_page(struct f2fs_sb_info *sbi,
		struct folio *folio, nid_t ino, block_t blkaddr);

/*
 * This is called when a page of a compressed cluster has been read from disk
 * (or failed to be read from disk).  It checks whether this page was the last
 * page being waited on in the cluster, and if so, it decompresses the cluster
 * (or in the case of a failure, cleans up without actually decompressing).
 */
void f2fs_end_read_compressed_page(struct page *page, bool failed,
void f2fs_end_read_compressed_page(struct folio *folio, bool failed,
		block_t blkaddr, bool in_task)
{
	struct decompress_io_ctx *dic =
			(struct decompress_io_ctx *)page_private(page);
	struct f2fs_sb_info *sbi = F2FS_I_SB(dic->inode);
	struct decompress_io_ctx *dic = folio->private;
	struct f2fs_sb_info *sbi = dic->sbi;

	dec_page_count(sbi, F2FS_RD_DATA);

	if (failed)
		WRITE_ONCE(dic->failed, true);
	else if (blkaddr && in_task)
		f2fs_cache_compressed_page(sbi, page,
		f2fs_cache_compressed_page(sbi, folio,
					dic->inode->i_ino, blkaddr);

	if (atomic_dec_and_test(&dic->remaining_pages))
@@ -1340,7 +1339,7 @@ static int f2fs_write_compressed_pages(struct compress_ctx *cc,
	cic->magic = F2FS_COMPRESSED_PAGE_MAGIC;
	cic->inode = inode;
	atomic_set(&cic->pending_pages, cc->valid_nr_cpages);
	cic->rpages = page_array_alloc(cc->inode, cc->cluster_size);
	cic->rpages = page_array_alloc(sbi, cc->cluster_size);
	if (!cic->rpages)
		goto out_put_cic;

@@ -1420,7 +1419,7 @@ static int f2fs_write_compressed_pages(struct compress_ctx *cc,
		(*submitted)++;
unlock_continue:
		inode_dec_dirty_pages(cc->inode);
		unlock_page(fio.page);
		folio_unlock(fio.folio);
	}

	if (fio.compr_blocks)
@@ -1442,13 +1441,13 @@ static int f2fs_write_compressed_pages(struct compress_ctx *cc,
	spin_unlock(&fi->i_size_lock);

	f2fs_put_rpages(cc);
	page_array_free(cc->inode, cc->cpages, cc->nr_cpages);
	page_array_free(sbi, cc->cpages, cc->nr_cpages);
	cc->cpages = NULL;
	f2fs_destroy_compress_ctx(cc, false);
	return 0;

out_destroy_crypt:
	page_array_free(cc->inode, cic->rpages, cc->cluster_size);
	page_array_free(sbi, cic->rpages, cc->cluster_size);

	for (--i; i >= 0; i--) {
		if (!cc->cpages[i])
@@ -1469,18 +1468,18 @@ static int f2fs_write_compressed_pages(struct compress_ctx *cc,
		f2fs_compress_free_page(cc->cpages[i]);
		cc->cpages[i] = NULL;
	}
	page_array_free(cc->inode, cc->cpages, cc->nr_cpages);
	page_array_free(sbi, cc->cpages, cc->nr_cpages);
	cc->cpages = NULL;
	return -EAGAIN;
}

void f2fs_compress_write_end_io(struct bio *bio, struct page *page)
void f2fs_compress_write_end_io(struct bio *bio, struct folio *folio)
{
	struct page *page = &folio->page;
	struct f2fs_sb_info *sbi = bio->bi_private;
	struct compress_io_ctx *cic =
			(struct compress_io_ctx *)page_private(page);
	enum count_type type = WB_DATA_TYPE(page,
				f2fs_is_compressed_page(page));
	struct compress_io_ctx *cic = folio->private;
	enum count_type type = WB_DATA_TYPE(folio,
				f2fs_is_compressed_page(folio));
	int i;

	if (unlikely(bio->bi_status != BLK_STS_OK))
@@ -1499,7 +1498,7 @@ void f2fs_compress_write_end_io(struct bio *bio, struct page *page)
		end_page_writeback(cic->rpages[i]);
	}

	page_array_free(cic->inode, cic->rpages, cic->nr_rpages);
	page_array_free(sbi, cic->rpages, cic->nr_rpages);
	kmem_cache_free(cic_entry_slab, cic);
}

@@ -1633,14 +1632,13 @@ static inline bool allow_memalloc_for_decomp(struct f2fs_sb_info *sbi,
static int f2fs_prepare_decomp_mem(struct decompress_io_ctx *dic,
		bool pre_alloc)
{
	const struct f2fs_compress_ops *cops =
		f2fs_cops[F2FS_I(dic->inode)->i_compress_algorithm];
	const struct f2fs_compress_ops *cops = f2fs_cops[dic->compress_algorithm];
	int i;

	if (!allow_memalloc_for_decomp(F2FS_I_SB(dic->inode), pre_alloc))
	if (!allow_memalloc_for_decomp(dic->sbi, pre_alloc))
		return 0;

	dic->tpages = page_array_alloc(dic->inode, dic->cluster_size);
	dic->tpages = page_array_alloc(dic->sbi, dic->cluster_size);
	if (!dic->tpages)
		return -ENOMEM;

@@ -1670,10 +1668,9 @@ static int f2fs_prepare_decomp_mem(struct decompress_io_ctx *dic,
static void f2fs_release_decomp_mem(struct decompress_io_ctx *dic,
		bool bypass_destroy_callback, bool pre_alloc)
{
	const struct f2fs_compress_ops *cops =
		f2fs_cops[F2FS_I(dic->inode)->i_compress_algorithm];
	const struct f2fs_compress_ops *cops = f2fs_cops[dic->compress_algorithm];

	if (!allow_memalloc_for_decomp(F2FS_I_SB(dic->inode), pre_alloc))
	if (!allow_memalloc_for_decomp(dic->sbi, pre_alloc))
		return;

	if (!bypass_destroy_callback && cops->destroy_decompress_ctx)
@@ -1700,7 +1697,7 @@ struct decompress_io_ctx *f2fs_alloc_dic(struct compress_ctx *cc)
	if (!dic)
		return ERR_PTR(-ENOMEM);

	dic->rpages = page_array_alloc(cc->inode, cc->cluster_size);
	dic->rpages = page_array_alloc(sbi, cc->cluster_size);
	if (!dic->rpages) {
		kmem_cache_free(dic_entry_slab, dic);
		return ERR_PTR(-ENOMEM);
@@ -1708,6 +1705,8 @@ struct decompress_io_ctx *f2fs_alloc_dic(struct compress_ctx *cc)

	dic->magic = F2FS_COMPRESSED_PAGE_MAGIC;
	dic->inode = cc->inode;
	dic->sbi = sbi;
	dic->compress_algorithm = F2FS_I(cc->inode)->i_compress_algorithm;
	atomic_set(&dic->remaining_pages, cc->nr_cpages);
	dic->cluster_idx = cc->cluster_idx;
	dic->cluster_size = cc->cluster_size;
@@ -1721,7 +1720,7 @@ struct decompress_io_ctx *f2fs_alloc_dic(struct compress_ctx *cc)
		dic->rpages[i] = cc->rpages[i];
	dic->nr_rpages = cc->cluster_size;

	dic->cpages = page_array_alloc(dic->inode, dic->nr_cpages);
	dic->cpages = page_array_alloc(sbi, dic->nr_cpages);
	if (!dic->cpages) {
		ret = -ENOMEM;
		goto out_free;
@@ -1751,6 +1750,8 @@ static void f2fs_free_dic(struct decompress_io_ctx *dic,
		bool bypass_destroy_callback)
{
	int i;
	/* use sbi in dic to avoid UFA of dic->inode*/
	struct f2fs_sb_info *sbi = dic->sbi;

	f2fs_release_decomp_mem(dic, bypass_destroy_callback, true);

@@ -1762,7 +1763,7 @@ static void f2fs_free_dic(struct decompress_io_ctx *dic,
				continue;
			f2fs_compress_free_page(dic->tpages[i]);
		}
		page_array_free(dic->inode, dic->tpages, dic->cluster_size);
		page_array_free(sbi, dic->tpages, dic->cluster_size);
	}

	if (dic->cpages) {
@@ -1771,10 +1772,10 @@ static void f2fs_free_dic(struct decompress_io_ctx *dic,
				continue;
			f2fs_compress_free_page(dic->cpages[i]);
		}
		page_array_free(dic->inode, dic->cpages, dic->nr_cpages);
		page_array_free(sbi, dic->cpages, dic->nr_cpages);
	}

	page_array_free(dic->inode, dic->rpages, dic->nr_rpages);
	page_array_free(sbi, dic->rpages, dic->nr_rpages);
	kmem_cache_free(dic_entry_slab, dic);
}

@@ -1793,8 +1794,7 @@ static void f2fs_put_dic(struct decompress_io_ctx *dic, bool in_task)
			f2fs_free_dic(dic, false);
		} else {
			INIT_WORK(&dic->free_work, f2fs_late_free_dic);
			queue_work(F2FS_I_SB(dic->inode)->post_read_wq,
					&dic->free_work);
			queue_work(dic->sbi->post_read_wq, &dic->free_work);
		}
	}
}
@@ -1921,8 +1921,8 @@ void f2fs_invalidate_compress_pages_range(struct f2fs_sb_info *sbi,
	invalidate_mapping_pages(COMPRESS_MAPPING(sbi), blkaddr, blkaddr + len - 1);
}

void f2fs_cache_compressed_page(struct f2fs_sb_info *sbi, struct page *page,
						nid_t ino, block_t blkaddr)
static void f2fs_cache_compressed_page(struct f2fs_sb_info *sbi,
		struct folio *folio, nid_t ino, block_t blkaddr)
{
	struct folio *cfolio;
	int ret;
@@ -1953,9 +1953,9 @@ void f2fs_cache_compressed_page(struct f2fs_sb_info *sbi, struct page *page,
		return;
	}

	set_page_private_data(&cfolio->page, ino);
	folio_set_f2fs_data(cfolio, ino);

	memcpy(folio_address(cfolio), page_address(page), PAGE_SIZE);
	memcpy(folio_address(cfolio), folio_address(folio), PAGE_SIZE);
	folio_mark_uptodate(cfolio);
	f2fs_folio_put(cfolio, true);
}
@@ -2012,7 +2012,7 @@ void f2fs_invalidate_compress_pages(struct f2fs_sb_info *sbi, nid_t ino)
				continue;
			}

			if (ino != get_page_private_data(&folio->page)) {
			if (ino != folio_get_f2fs_data(folio)) {
				folio_unlock(folio);
				continue;
			}
+99 −84

File changed.

Preview size limit exceeded, changes collapsed.

Loading