Commit 72ece201 authored by Linus Torvalds's avatar Linus Torvalds
Browse files
Pull f2fs updates from Jaegeuk Kim:
 "In this round, we've tried to address some performance issues on zoned
  storage such as direct IO and write_hints. In addition, we've migrated
  some IO paths using folio. Meanwhile, there are multiple bug fixes in
  the compression paths, sanity check conditions, and error handlers.

  Enhancements:
   - allow direct io of pinned files for zoned storage
   - assign the write hint per stream by default
   - convert read paths and test_writeback to folio
   - avoid allocating WARM_DATA segment for direct IO

  Bug fixes:
   - fix false alarm on invalid block address
   - fix to add missing iput() in gc_data_segment()
   - fix to release node block count in error path of
     f2fs_new_node_page()
   - compress:
       - don't allow unaligned truncation on released compress inode
       - cover {reserve,release}_compress_blocks() w/ cp_rwsem lock
       - fix error path of inc_valid_block_count()
       - fix to update i_compr_blocks correctly
   - fix block migration when section is not aligned to pow2
   - don't trigger OPU on pinfile for direct IO
   - fix to do sanity check on i_xattr_nid in sanity_check_inode()
   - write missing last sum blk of file pinning section
   - clear writeback when compression failed
   - fix to adjust appropirate defragment pg_end

  As usual, there are several minor code clean-ups, and fixes to manage
  missing corner cases in the error paths"

* tag 'f2fs-for-6.10.rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/jaegeuk/f2fs: (50 commits)
  f2fs: initialize last_block_in_bio variable
  f2fs: Add inline to f2fs_build_fault_attr() stub
  f2fs: fix some ambiguous comments
  f2fs: fix to add missing iput() in gc_data_segment()
  f2fs: allow dirty sections with zero valid block for checkpoint disabled
  f2fs: compress: don't allow unaligned truncation on released compress inode
  f2fs: fix to release node block count in error path of f2fs_new_node_page()
  f2fs: compress: fix to cover {reserve,release}_compress_blocks() w/ cp_rwsem lock
  f2fs: compress: fix error path of inc_valid_block_count()
  f2fs: compress: fix typo in f2fs_reserve_compress_blocks()
  f2fs: compress: fix to update i_compr_blocks correctly
  f2fs: check validation of fault attrs in f2fs_build_fault_attr()
  f2fs: fix to limit gc_pin_file_threshold
  f2fs: remove unused GC_FAILURE_PIN
  f2fs: use f2fs_{err,info}_ratelimited() for cleanup
  f2fs: fix block migration when section is not aligned to pow2
  f2fs: zone: fix to don't trigger OPU on pinfile for direct IO
  f2fs: fix to do sanity check on i_xattr_nid in sanity_check_inode()
  f2fs: fix to avoid allocating WARM_DATA segment for direct IO
  f2fs: remove redundant parameter in is_next_segment_free()
  ...
parents 119d1b8a 16409fdb
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -331,7 +331,7 @@ Date: January 2018
Contact:	Jaegeuk Kim <jaegeuk@kernel.org>
Description:	This indicates how many GC can be failed for the pinned
		file. If it exceeds this, F2FS doesn't guarantee its pinning
		state. 2048 trials is set by default.
		state. 2048 trials is set by default, and 65535 as maximum.

What:		/sys/fs/f2fs/<disk>/extension_list
Date:		February 2018
+29 −0
Original line number Diff line number Diff line
@@ -774,6 +774,35 @@ In order to identify whether the data in the victim segment are valid or not,
F2FS manages a bitmap. Each bit represents the validity of a block, and the
bitmap is composed of a bit stream covering whole blocks in main area.

Write-hint Policy
-----------------

F2FS sets the whint all the time with the below policy.

===================== ======================== ===================
User                  F2FS                     Block
===================== ======================== ===================
N/A                   META                     WRITE_LIFE_NONE|REQ_META
N/A                   HOT_NODE                 WRITE_LIFE_NONE
N/A                   WARM_NODE                WRITE_LIFE_MEDIUM
N/A                   COLD_NODE                WRITE_LIFE_LONG
ioctl(COLD)           COLD_DATA                WRITE_LIFE_EXTREME
extension list        "                        "

-- buffered io
N/A                   COLD_DATA                WRITE_LIFE_EXTREME
N/A                   HOT_DATA                 WRITE_LIFE_SHORT
N/A                   WARM_DATA                WRITE_LIFE_NOT_SET

-- direct io
WRITE_LIFE_EXTREME    COLD_DATA                WRITE_LIFE_EXTREME
WRITE_LIFE_SHORT      HOT_DATA                 WRITE_LIFE_SHORT
WRITE_LIFE_NOT_SET    WARM_DATA                WRITE_LIFE_NOT_SET
WRITE_LIFE_NONE       "                        WRITE_LIFE_NONE
WRITE_LIFE_MEDIUM     "                        WRITE_LIFE_MEDIUM
WRITE_LIFE_LONG       "                        WRITE_LIFE_LONG
===================== ======================== ===================

Fallocate(2) Policy
-------------------

+7 −6
Original line number Diff line number Diff line
@@ -179,22 +179,22 @@ static bool __f2fs_is_valid_blkaddr(struct f2fs_sb_info *sbi,
		break;
	case META_SIT:
		if (unlikely(blkaddr >= SIT_BLK_CNT(sbi)))
			goto err;
			goto check_only;
		break;
	case META_SSA:
		if (unlikely(blkaddr >= MAIN_BLKADDR(sbi) ||
			blkaddr < SM_I(sbi)->ssa_blkaddr))
			goto err;
			goto check_only;
		break;
	case META_CP:
		if (unlikely(blkaddr >= SIT_I(sbi)->sit_base_addr ||
			blkaddr < __start_cp_addr(sbi)))
			goto err;
			goto check_only;
		break;
	case META_POR:
		if (unlikely(blkaddr >= MAX_BLKADDR(sbi) ||
			blkaddr < MAIN_BLKADDR(sbi)))
			goto err;
			goto check_only;
		break;
	case DATA_GENERIC:
	case DATA_GENERIC_ENHANCE:
@@ -228,6 +228,7 @@ static bool __f2fs_is_valid_blkaddr(struct f2fs_sb_info *sbi,
	return true;
err:
	f2fs_handle_error(sbi, ERROR_INVALID_BLKADDR);
check_only:
	return false;
}

@@ -345,7 +346,7 @@ static int __f2fs_write_meta_page(struct page *page,
{
	struct f2fs_sb_info *sbi = F2FS_P_SB(page);

	trace_f2fs_writepage(page, META);
	trace_f2fs_writepage(page_folio(page), META);

	if (unlikely(f2fs_cp_error(sbi))) {
		if (is_sbi_flag_set(sbi, SBI_IS_CLOSE)) {
@@ -492,7 +493,7 @@ long f2fs_sync_meta_pages(struct f2fs_sb_info *sbi, enum page_type type,
static bool f2fs_dirty_meta_folio(struct address_space *mapping,
		struct folio *folio)
{
	trace_f2fs_set_page_dirty(&folio->page, META);
	trace_f2fs_set_page_dirty(folio, META);

	if (!folio_test_uptodate(folio))
		folio_mark_uptodate(folio);
+63 −33
Original line number Diff line number Diff line
@@ -198,8 +198,8 @@ static int lzo_compress_pages(struct compress_ctx *cc)
	ret = lzo1x_1_compress(cc->rbuf, cc->rlen, cc->cbuf->cdata,
					&cc->clen, cc->private);
	if (ret != LZO_E_OK) {
		printk_ratelimited("%sF2FS-fs (%s): lzo compress failed, ret:%d\n",
				KERN_ERR, F2FS_I_SB(cc->inode)->sb->s_id, ret);
		f2fs_err_ratelimited(F2FS_I_SB(cc->inode),
				"lzo compress failed, ret:%d", ret);
		return -EIO;
	}
	return 0;
@@ -212,17 +212,15 @@ 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) {
		printk_ratelimited("%sF2FS-fs (%s): lzo decompress failed, ret:%d\n",
				KERN_ERR, F2FS_I_SB(dic->inode)->sb->s_id, ret);
		f2fs_err_ratelimited(F2FS_I_SB(dic->inode),
				"lzo decompress failed, ret:%d", ret);
		return -EIO;
	}

	if (dic->rlen != PAGE_SIZE << dic->log_cluster_size) {
		printk_ratelimited("%sF2FS-fs (%s): lzo invalid rlen:%zu, "
					"expected:%lu\n", KERN_ERR,
					F2FS_I_SB(dic->inode)->sb->s_id,
					dic->rlen,
					PAGE_SIZE << dic->log_cluster_size);
		f2fs_err_ratelimited(F2FS_I_SB(dic->inode),
				"lzo invalid rlen:%zu, expected:%lu",
				dic->rlen, PAGE_SIZE << dic->log_cluster_size);
		return -EIO;
	}
	return 0;
@@ -294,16 +292,15 @@ 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) {
		printk_ratelimited("%sF2FS-fs (%s): lz4 decompress failed, ret:%d\n",
				KERN_ERR, F2FS_I_SB(dic->inode)->sb->s_id, ret);
		f2fs_err_ratelimited(F2FS_I_SB(dic->inode),
				"lz4 decompress failed, ret:%d", ret);
		return -EIO;
	}

	if (ret != PAGE_SIZE << dic->log_cluster_size) {
		printk_ratelimited("%sF2FS-fs (%s): lz4 invalid ret:%d, "
					"expected:%lu\n", KERN_ERR,
					F2FS_I_SB(dic->inode)->sb->s_id, ret,
					PAGE_SIZE << dic->log_cluster_size);
		f2fs_err_ratelimited(F2FS_I_SB(dic->inode),
				"lz4 invalid ret:%d, expected:%lu",
				ret, PAGE_SIZE << dic->log_cluster_size);
		return -EIO;
	}
	return 0;
@@ -350,9 +347,8 @@ static int zstd_init_compress_ctx(struct compress_ctx *cc)

	stream = zstd_init_cstream(&params, 0, workspace, workspace_size);
	if (!stream) {
		printk_ratelimited("%sF2FS-fs (%s): %s zstd_init_cstream failed\n",
				KERN_ERR, F2FS_I_SB(cc->inode)->sb->s_id,
				__func__);
		f2fs_err_ratelimited(F2FS_I_SB(cc->inode),
				"%s zstd_init_cstream failed", __func__);
		kvfree(workspace);
		return -EIO;
	}
@@ -390,16 +386,16 @@ static int zstd_compress_pages(struct compress_ctx *cc)

	ret = zstd_compress_stream(stream, &outbuf, &inbuf);
	if (zstd_is_error(ret)) {
		printk_ratelimited("%sF2FS-fs (%s): %s zstd_compress_stream failed, ret: %d\n",
				KERN_ERR, F2FS_I_SB(cc->inode)->sb->s_id,
		f2fs_err_ratelimited(F2FS_I_SB(cc->inode),
				"%s zstd_compress_stream failed, ret: %d",
				__func__, zstd_get_error_code(ret));
		return -EIO;
	}

	ret = zstd_end_stream(stream, &outbuf);
	if (zstd_is_error(ret)) {
		printk_ratelimited("%sF2FS-fs (%s): %s zstd_end_stream returned %d\n",
				KERN_ERR, F2FS_I_SB(cc->inode)->sb->s_id,
		f2fs_err_ratelimited(F2FS_I_SB(cc->inode),
				"%s zstd_end_stream returned %d",
				__func__, zstd_get_error_code(ret));
		return -EIO;
	}
@@ -432,9 +428,8 @@ static int zstd_init_decompress_ctx(struct decompress_io_ctx *dic)

	stream = zstd_init_dstream(max_window_size, workspace, workspace_size);
	if (!stream) {
		printk_ratelimited("%sF2FS-fs (%s): %s zstd_init_dstream failed\n",
				KERN_ERR, F2FS_I_SB(dic->inode)->sb->s_id,
				__func__);
		f2fs_err_ratelimited(F2FS_I_SB(dic->inode),
				"%s zstd_init_dstream failed", __func__);
		kvfree(workspace);
		return -EIO;
	}
@@ -469,16 +464,15 @@ static int zstd_decompress_pages(struct decompress_io_ctx *dic)

	ret = zstd_decompress_stream(stream, &outbuf, &inbuf);
	if (zstd_is_error(ret)) {
		printk_ratelimited("%sF2FS-fs (%s): %s zstd_decompress_stream failed, ret: %d\n",
				KERN_ERR, F2FS_I_SB(dic->inode)->sb->s_id,
		f2fs_err_ratelimited(F2FS_I_SB(dic->inode),
				"%s zstd_decompress_stream failed, ret: %d",
				__func__, zstd_get_error_code(ret));
		return -EIO;
	}

	if (dic->rlen != outbuf.pos) {
		printk_ratelimited("%sF2FS-fs (%s): %s ZSTD invalid rlen:%zu, "
				"expected:%lu\n", KERN_ERR,
				F2FS_I_SB(dic->inode)->sb->s_id,
		f2fs_err_ratelimited(F2FS_I_SB(dic->inode),
				"%s ZSTD invalid rlen:%zu, expected:%lu",
				__func__, dic->rlen,
				PAGE_SIZE << dic->log_cluster_size);
		return -EIO;
@@ -1031,6 +1025,31 @@ static void set_cluster_writeback(struct compress_ctx *cc)
	}
}

static void cancel_cluster_writeback(struct compress_ctx *cc,
			struct compress_io_ctx *cic, int submitted)
{
	int i;

	/* Wait for submitted IOs. */
	if (submitted > 1) {
		f2fs_submit_merged_write(F2FS_I_SB(cc->inode), DATA);
		while (atomic_read(&cic->pending_pages) !=
					(cc->valid_nr_cpages - submitted + 1))
			f2fs_io_schedule_timeout(DEFAULT_IO_TIMEOUT);
	}

	/* Cancel writeback and stay locked. */
	for (i = 0; i < cc->cluster_size; i++) {
		if (i < submitted) {
			inode_inc_dirty_pages(cc->inode);
			lock_page(cc->rpages[i]);
		}
		clear_page_private_gcing(cc->rpages[i]);
		if (folio_test_writeback(page_folio(cc->rpages[i])))
			end_page_writeback(cc->rpages[i]);
	}
}

static void set_cluster_dirty(struct compress_ctx *cc)
{
	int i;
@@ -1232,7 +1251,6 @@ static int f2fs_write_compressed_pages(struct compress_ctx *cc,
		.page = NULL,
		.encrypted_page = NULL,
		.compressed_page = NULL,
		.submitted = 0,
		.io_type = io_type,
		.io_wbc = wbc,
		.encrypted = fscrypt_inode_uses_fs_layer_crypto(cc->inode) ?
@@ -1358,7 +1376,16 @@ static int f2fs_write_compressed_pages(struct compress_ctx *cc,
			fio.compressed_page = cc->cpages[i - 1];

		cc->cpages[i - 1] = NULL;
		fio.submitted = 0;
		f2fs_outplace_write_data(&dn, &fio);
		if (unlikely(!fio.submitted)) {
			cancel_cluster_writeback(cc, cic, i);

			/* To call fscrypt_finalize_bounce_page */
			i = cc->valid_nr_cpages;
			*submitted = 0;
			goto out_destroy_crypt;
		}
		(*submitted)++;
unlock_continue:
		inode_dec_dirty_pages(cc->inode);
@@ -1392,8 +1419,11 @@ static int f2fs_write_compressed_pages(struct compress_ctx *cc,
out_destroy_crypt:
	page_array_free(cc->inode, cic->rpages, cc->cluster_size);

	for (--i; i >= 0; i--)
	for (--i; i >= 0; i--) {
		if (!cc->cpages[i])
			continue;
		fscrypt_finalize_bounce_page(&cc->cpages[i]);
	}
out_put_cic:
	kmem_cache_free(cic_entry_slab, cic);
out_put_dnode:
@@ -1484,7 +1514,7 @@ static int f2fs_write_raw_pages(struct compress_ctx *cc,
		if (!PageDirty(cc->rpages[i]))
			goto continue_unlock;

		if (PageWriteback(cc->rpages[i])) {
		if (folio_test_writeback(page_folio(cc->rpages[i]))) {
			if (wbc->sync_mode == WB_SYNC_NONE)
				goto continue_unlock;
			f2fs_wait_on_page_writeback(cc->rpages[i], DATA, true, true);
+132 −99
Original line number Diff line number Diff line
@@ -465,6 +465,8 @@ static struct bio *__bio_alloc(struct f2fs_io_info *fio, int npages)
	} else {
		bio->bi_end_io = f2fs_write_end_io;
		bio->bi_private = sbi;
		bio->bi_write_hint = f2fs_io_type_to_rw_hint(sbi,
						fio->type, fio->temp);
	}
	iostat_alloc_and_bind_ctx(sbi, bio, NULL);

@@ -593,17 +595,20 @@ int f2fs_init_write_merge_io(struct f2fs_sb_info *sbi)
			return -ENOMEM;

		for (j = HOT; j < n; j++) {
			init_f2fs_rwsem(&sbi->write_io[i][j].io_rwsem);
			sbi->write_io[i][j].sbi = sbi;
			sbi->write_io[i][j].bio = NULL;
			spin_lock_init(&sbi->write_io[i][j].io_lock);
			INIT_LIST_HEAD(&sbi->write_io[i][j].io_list);
			INIT_LIST_HEAD(&sbi->write_io[i][j].bio_list);
			init_f2fs_rwsem(&sbi->write_io[i][j].bio_list_lock);
			struct f2fs_bio_info *io = &sbi->write_io[i][j];

			init_f2fs_rwsem(&io->io_rwsem);
			io->sbi = sbi;
			io->bio = NULL;
			io->last_block_in_bio = 0;
			spin_lock_init(&io->io_lock);
			INIT_LIST_HEAD(&io->io_list);
			INIT_LIST_HEAD(&io->bio_list);
			init_f2fs_rwsem(&io->bio_list_lock);
#ifdef CONFIG_BLK_DEV_ZONED
			init_completion(&sbi->write_io[i][j].zone_wait);
			sbi->write_io[i][j].zone_pending_bio = NULL;
			sbi->write_io[i][j].bi_private = NULL;
			init_completion(&io->zone_wait);
			io->zone_pending_bio = NULL;
			io->bi_private = NULL;
#endif
		}
	}
@@ -1507,6 +1512,25 @@ static bool f2fs_map_blocks_cached(struct inode *inode,
	return true;
}

static bool map_is_mergeable(struct f2fs_sb_info *sbi,
				struct f2fs_map_blocks *map,
				block_t blkaddr, int flag, int bidx,
				int ofs)
{
	if (map->m_multidev_dio && map->m_bdev != FDEV(bidx).bdev)
		return false;
	if (map->m_pblk != NEW_ADDR && blkaddr == (map->m_pblk + ofs))
		return true;
	if (map->m_pblk == NEW_ADDR && blkaddr == NEW_ADDR)
		return true;
	if (flag == F2FS_GET_BLOCK_PRE_DIO)
		return true;
	if (flag == F2FS_GET_BLOCK_DIO &&
		map->m_pblk == NULL_ADDR && blkaddr == NULL_ADDR)
		return true;
	return false;
}

/*
 * f2fs_map_blocks() tries to find or build mapping relationship which
 * maps continuous logical blocks to physical blocks, and return such
@@ -1574,8 +1598,9 @@ int f2fs_map_blocks(struct inode *inode, struct f2fs_map_blocks *map, int flag)
	}

	/* use out-place-update for direct IO under LFS mode */
	if (map->m_may_create &&
	    (is_hole || (f2fs_lfs_mode(sbi) && flag == F2FS_GET_BLOCK_DIO))) {
	if (map->m_may_create && (is_hole ||
		(flag == F2FS_GET_BLOCK_DIO && f2fs_lfs_mode(sbi) &&
		!f2fs_is_pinned_file(inode)))) {
		if (unlikely(f2fs_cp_error(sbi))) {
			err = -EIO;
			goto sync_out;
@@ -1628,6 +1653,10 @@ int f2fs_map_blocks(struct inode *inode, struct f2fs_map_blocks *map, int flag)
				goto sync_out;
			}
			break;
		case F2FS_GET_BLOCK_DIO:
			if (map->m_next_pgofs)
				*map->m_next_pgofs = pgofs + 1;
			break;
		default:
			/* for defragment case */
			if (map->m_next_pgofs)
@@ -1646,6 +1675,7 @@ int f2fs_map_blocks(struct inode *inode, struct f2fs_map_blocks *map, int flag)
		/* reserved delalloc block should be mapped for fiemap. */
		if (blkaddr == NEW_ADDR)
			map->m_flags |= F2FS_MAP_DELALLOC;
		if (flag != F2FS_GET_BLOCK_DIO || !is_hole)
			map->m_flags |= F2FS_MAP_MAPPED;

		map->m_pblk = blkaddr;
@@ -1653,12 +1683,7 @@ int f2fs_map_blocks(struct inode *inode, struct f2fs_map_blocks *map, int flag)

		if (map->m_multidev_dio)
			map->m_bdev = FDEV(bidx).bdev;
	} else if ((map->m_pblk != NEW_ADDR &&
			blkaddr == (map->m_pblk + ofs)) ||
			(map->m_pblk == NEW_ADDR && blkaddr == NEW_ADDR) ||
			flag == F2FS_GET_BLOCK_PRE_DIO) {
		if (map->m_multidev_dio && map->m_bdev != FDEV(bidx).bdev)
			goto sync_out;
	} else if (map_is_mergeable(sbi, map, blkaddr, flag, bidx, ofs)) {
		ofs++;
		map->m_len++;
	} else {
@@ -2042,7 +2067,7 @@ static inline loff_t f2fs_readpage_limit(struct inode *inode)
	return i_size_read(inode);
}

static int f2fs_read_single_page(struct inode *inode, struct page *page,
static int f2fs_read_single_page(struct inode *inode, struct folio *folio,
					unsigned nr_pages,
					struct f2fs_map_blocks *map,
					struct bio **bio_ret,
@@ -2055,9 +2080,10 @@ static int f2fs_read_single_page(struct inode *inode, struct page *page,
	sector_t last_block;
	sector_t last_block_in_file;
	sector_t block_nr;
	pgoff_t index = folio_index(folio);
	int ret = 0;

	block_in_file = (sector_t)page_index(page);
	block_in_file = (sector_t)index;
	last_block = block_in_file + nr_pages;
	last_block_in_file = bytes_to_blks(inode,
			f2fs_readpage_limit(inode) + blocksize - 1);
@@ -2088,7 +2114,7 @@ static int f2fs_read_single_page(struct inode *inode, struct page *page,
got_it:
	if ((map->m_flags & F2FS_MAP_MAPPED)) {
		block_nr = map->m_pblk + block_in_file - map->m_lblk;
		SetPageMappedToDisk(page);
		folio_set_mappedtodisk(folio);

		if (!f2fs_is_valid_blkaddr(F2FS_I_SB(inode), block_nr,
						DATA_GENERIC_ENHANCE_READ)) {
@@ -2097,15 +2123,15 @@ static int f2fs_read_single_page(struct inode *inode, struct page *page,
		}
	} else {
zero_out:
		zero_user_segment(page, 0, PAGE_SIZE);
		if (f2fs_need_verity(inode, page->index) &&
		    !fsverity_verify_page(page)) {
		folio_zero_segment(folio, 0, folio_size(folio));
		if (f2fs_need_verity(inode, index) &&
		    !fsverity_verify_folio(folio)) {
			ret = -EIO;
			goto out;
		}
		if (!PageUptodate(page))
			SetPageUptodate(page);
		unlock_page(page);
		if (!folio_test_uptodate(folio))
			folio_mark_uptodate(folio);
		folio_unlock(folio);
		goto out;
	}

@@ -2115,14 +2141,14 @@ static int f2fs_read_single_page(struct inode *inode, struct page *page,
	 */
	if (bio && (!page_is_mergeable(F2FS_I_SB(inode), bio,
				       *last_block_in_bio, block_nr) ||
		    !f2fs_crypt_mergeable_bio(bio, inode, page->index, NULL))) {
		    !f2fs_crypt_mergeable_bio(bio, inode, index, NULL))) {
submit_and_realloc:
		f2fs_submit_read_bio(F2FS_I_SB(inode), bio, DATA);
		bio = NULL;
	}
	if (bio == NULL) {
		bio = f2fs_grab_read_bio(inode, block_nr, nr_pages,
				is_readahead ? REQ_RAHEAD : 0, page->index,
				is_readahead ? REQ_RAHEAD : 0, index,
				false);
		if (IS_ERR(bio)) {
			ret = PTR_ERR(bio);
@@ -2137,7 +2163,7 @@ static int f2fs_read_single_page(struct inode *inode, struct page *page,
	 */
	f2fs_wait_on_block_writeback(inode, block_nr);

	if (bio_add_page(bio, page, blocksize, 0) < blocksize)
	if (!bio_add_folio(bio, folio, blocksize, 0))
		goto submit_and_realloc;

	inc_page_count(F2FS_I_SB(inode), F2FS_RD_DATA);
@@ -2324,7 +2350,7 @@ int f2fs_read_multi_pages(struct compress_ctx *cc, struct bio **bio_ret,
 * Major change was from block_size == page_size in f2fs by default.
 */
static int f2fs_mpage_readpages(struct inode *inode,
		struct readahead_control *rac, struct page *page)
		struct readahead_control *rac, struct folio *folio)
{
	struct bio *bio = NULL;
	sector_t last_block_in_bio = 0;
@@ -2344,6 +2370,7 @@ static int f2fs_mpage_readpages(struct inode *inode,
#endif
	unsigned nr_pages = rac ? readahead_count(rac) : 1;
	unsigned max_nr_pages = nr_pages;
	pgoff_t index;
	int ret = 0;

	map.m_pblk = 0;
@@ -2357,14 +2384,18 @@ static int f2fs_mpage_readpages(struct inode *inode,

	for (; nr_pages; nr_pages--) {
		if (rac) {
			page = readahead_page(rac);
			prefetchw(&page->flags);
			folio = readahead_folio(rac);
			prefetchw(&folio->flags);
		}

		index = folio_index(folio);

#ifdef CONFIG_F2FS_FS_COMPRESSION
		if (f2fs_compressed_file(inode)) {
		if (!f2fs_compressed_file(inode))
			goto read_single_page;

		/* there are remained compressed pages, submit them */
			if (!f2fs_cluster_can_merge_page(&cc, page->index)) {
		if (!f2fs_cluster_can_merge_page(&cc, index)) {
			ret = f2fs_read_multi_pages(&cc, &bio,
						max_nr_pages,
						&last_block_in_bio,
@@ -2374,17 +2405,15 @@ static int f2fs_mpage_readpages(struct inode *inode,
				goto set_error_page;
		}
		if (cc.cluster_idx == NULL_CLUSTER) {
				if (nc_cluster_idx ==
					page->index >> cc.log_cluster_size) {
			if (nc_cluster_idx == index >> cc.log_cluster_size)
				goto read_single_page;
				}

				ret = f2fs_is_compressed_cluster(inode, page->index);
			ret = f2fs_is_compressed_cluster(inode, index);
			if (ret < 0)
				goto set_error_page;
			else if (!ret) {
				nc_cluster_idx =
						page->index >> cc.log_cluster_size;
					index >> cc.log_cluster_size;
				goto read_single_page;
			}

@@ -2394,27 +2423,24 @@ static int f2fs_mpage_readpages(struct inode *inode,
		if (ret)
			goto set_error_page;

			f2fs_compress_ctx_add_page(&cc, page);
		f2fs_compress_ctx_add_page(&cc, &folio->page);

		goto next_page;
		}
read_single_page:
#endif

		ret = f2fs_read_single_page(inode, page, max_nr_pages, &map,
		ret = f2fs_read_single_page(inode, folio, max_nr_pages, &map,
					&bio, &last_block_in_bio, rac);
		if (ret) {
#ifdef CONFIG_F2FS_FS_COMPRESSION
set_error_page:
#endif
			zero_user_segment(page, 0, PAGE_SIZE);
			unlock_page(page);
			folio_zero_segment(folio, 0, folio_size(folio));
			folio_unlock(folio);
		}
#ifdef CONFIG_F2FS_FS_COMPRESSION
next_page:
#endif
		if (rac)
			put_page(page);

#ifdef CONFIG_F2FS_FS_COMPRESSION
		if (f2fs_compressed_file(inode)) {
@@ -2436,22 +2462,21 @@ static int f2fs_mpage_readpages(struct inode *inode,

static int f2fs_read_data_folio(struct file *file, struct folio *folio)
{
	struct page *page = &folio->page;
	struct inode *inode = page_file_mapping(page)->host;
	struct inode *inode = folio_file_mapping(folio)->host;
	int ret = -EAGAIN;

	trace_f2fs_readpage(page, DATA);
	trace_f2fs_readpage(folio, DATA);

	if (!f2fs_is_compress_backend_ready(inode)) {
		unlock_page(page);
		folio_unlock(folio);
		return -EOPNOTSUPP;
	}

	/* If the file has inline data, try to read it directly */
	if (f2fs_has_inline_data(inode))
		ret = f2fs_read_inline_data(inode, page);
		ret = f2fs_read_inline_data(inode, folio);
	if (ret == -EAGAIN)
		ret = f2fs_mpage_readpages(inode, NULL, page);
		ret = f2fs_mpage_readpages(inode, NULL, folio);
	return ret;
}

@@ -2685,12 +2710,11 @@ int f2fs_do_write_data_page(struct f2fs_io_info *fio)
		if (err) {
			if (fscrypt_inode_uses_fs_layer_crypto(inode))
				fscrypt_finalize_bounce_page(&fio->encrypted_page);
			if (PageWriteback(page))
			end_page_writeback(page);
		} else {
			set_inode_flag(inode, FI_UPDATE_WRITE);
		}
		trace_f2fs_do_write_data_page(fio->page, IPU);
		trace_f2fs_do_write_data_page(page_folio(page), IPU);
		return err;
	}

@@ -2719,7 +2743,7 @@ int f2fs_do_write_data_page(struct f2fs_io_info *fio)

	/* LFS mode write path */
	f2fs_outplace_write_data(&dn, fio);
	trace_f2fs_do_write_data_page(page, OPU);
	trace_f2fs_do_write_data_page(page_folio(page), OPU);
	set_inode_flag(inode, FI_APPEND_WRITE);
out_writepage:
	f2fs_put_dnode(&dn);
@@ -2766,7 +2790,7 @@ int f2fs_write_single_data_page(struct page *page, int *submitted,
		.last_block = last_block,
	};

	trace_f2fs_writepage(page, DATA);
	trace_f2fs_writepage(page_folio(page), DATA);

	/* we should bypass data pages to proceed the kworker jobs */
	if (unlikely(f2fs_cp_error(sbi))) {
@@ -3379,7 +3403,7 @@ static int prepare_write_begin(struct f2fs_sb_info *sbi,

	if (f2fs_has_inline_data(inode)) {
		if (pos + len <= MAX_INLINE_DATA(inode)) {
			f2fs_do_read_inline_data(page, ipage);
			f2fs_do_read_inline_data(page_folio(page), ipage);
			set_inode_flag(inode, FI_DATA_EXIST);
			if (inode->i_nlink)
				set_page_private_inline(ipage);
@@ -3740,7 +3764,7 @@ static bool f2fs_dirty_data_folio(struct address_space *mapping,
{
	struct inode *inode = mapping->host;

	trace_f2fs_set_page_dirty(&folio->page, DATA);
	trace_f2fs_set_page_dirty(folio, DATA);

	if (!folio_test_uptodate(folio))
		folio_mark_uptodate(folio);
@@ -3896,15 +3920,14 @@ static int check_swap_activate(struct swap_info_struct *sis,
	struct address_space *mapping = swap_file->f_mapping;
	struct inode *inode = mapping->host;
	struct f2fs_sb_info *sbi = F2FS_I_SB(inode);
	sector_t cur_lblock;
	sector_t last_lblock;
	sector_t pblock;
	sector_t lowest_pblock = -1;
	sector_t highest_pblock = 0;
	block_t cur_lblock;
	block_t last_lblock;
	block_t pblock;
	block_t lowest_pblock = -1;
	block_t highest_pblock = 0;
	int nr_extents = 0;
	unsigned long nr_pblocks;
	unsigned int nr_pblocks;
	unsigned int blks_per_sec = BLKS_PER_SEC(sbi);
	unsigned int sec_blks_mask = BLKS_PER_SEC(sbi) - 1;
	unsigned int not_aligned = 0;
	int ret = 0;

@@ -3942,8 +3965,8 @@ static int check_swap_activate(struct swap_info_struct *sis,
		pblock = map.m_pblk;
		nr_pblocks = map.m_len;

		if ((pblock - SM_I(sbi)->main_blkaddr) & sec_blks_mask ||
				nr_pblocks & sec_blks_mask ||
		if ((pblock - SM_I(sbi)->main_blkaddr) % blks_per_sec ||
				nr_pblocks % blks_per_sec ||
				!f2fs_valid_pinned_area(sbi, pblock)) {
			bool last_extent = false;

@@ -4160,7 +4183,8 @@ static int f2fs_iomap_begin(struct inode *inode, loff_t offset, loff_t length,
	map.m_lblk = bytes_to_blks(inode, offset);
	map.m_len = bytes_to_blks(inode, offset + length - 1) - map.m_lblk + 1;
	map.m_next_pgofs = &next_pgofs;
	map.m_seg_type = f2fs_rw_hint_to_seg_type(inode->i_write_hint);
	map.m_seg_type = f2fs_rw_hint_to_seg_type(F2FS_I_SB(inode),
						inode->i_write_hint);
	if (flags & IOMAP_WRITE)
		map.m_may_create = true;

@@ -4181,12 +4205,13 @@ static int f2fs_iomap_begin(struct inode *inode, loff_t offset, loff_t length,
	 * We should never see delalloc or compressed extents here based on
	 * prior flushing and checks.
	 */
	if (WARN_ON_ONCE(map.m_pblk == NEW_ADDR))
		return -EINVAL;
	if (WARN_ON_ONCE(map.m_pblk == COMPRESS_ADDR))
		return -EINVAL;

	if (map.m_pblk != NULL_ADDR) {
	if (map.m_flags & F2FS_MAP_MAPPED) {
		if (WARN_ON_ONCE(map.m_pblk == NEW_ADDR))
			return -EINVAL;

		iomap->length = blks_to_bytes(inode, map.m_len);
		iomap->type = IOMAP_MAPPED;
		iomap->flags |= IOMAP_F_MERGED;
@@ -4195,9 +4220,17 @@ static int f2fs_iomap_begin(struct inode *inode, loff_t offset, loff_t length,
	} else {
		if (flags & IOMAP_WRITE)
			return -ENOTBLK;

		if (map.m_pblk == NULL_ADDR) {
			iomap->length = blks_to_bytes(inode, next_pgofs) -
								iomap->offset;
			iomap->type = IOMAP_HOLE;
		} else if (map.m_pblk == NEW_ADDR) {
			iomap->length = blks_to_bytes(inode, map.m_len);
			iomap->type = IOMAP_UNWRITTEN;
		} else {
			f2fs_bug_on(F2FS_I_SB(inode), 1);
		}
		iomap->addr = IOMAP_NULL_ADDR;
	}

Loading