162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0
262306a36Sopenharmony_ci/*
362306a36Sopenharmony_ci * fs/f2fs/data.c
462306a36Sopenharmony_ci *
562306a36Sopenharmony_ci * Copyright (c) 2012 Samsung Electronics Co., Ltd.
662306a36Sopenharmony_ci *             http://www.samsung.com/
762306a36Sopenharmony_ci */
862306a36Sopenharmony_ci#include <linux/fs.h>
962306a36Sopenharmony_ci#include <linux/f2fs_fs.h>
1062306a36Sopenharmony_ci#include <linux/buffer_head.h>
1162306a36Sopenharmony_ci#include <linux/sched/mm.h>
1262306a36Sopenharmony_ci#include <linux/mpage.h>
1362306a36Sopenharmony_ci#include <linux/writeback.h>
1462306a36Sopenharmony_ci#include <linux/pagevec.h>
1562306a36Sopenharmony_ci#include <linux/blkdev.h>
1662306a36Sopenharmony_ci#include <linux/bio.h>
1762306a36Sopenharmony_ci#include <linux/blk-crypto.h>
1862306a36Sopenharmony_ci#include <linux/swap.h>
1962306a36Sopenharmony_ci#include <linux/prefetch.h>
2062306a36Sopenharmony_ci#include <linux/uio.h>
2162306a36Sopenharmony_ci#include <linux/sched/signal.h>
2262306a36Sopenharmony_ci#include <linux/fiemap.h>
2362306a36Sopenharmony_ci#include <linux/iomap.h>
2462306a36Sopenharmony_ci
2562306a36Sopenharmony_ci#include "f2fs.h"
2662306a36Sopenharmony_ci#include "node.h"
2762306a36Sopenharmony_ci#include "segment.h"
2862306a36Sopenharmony_ci#include "iostat.h"
2962306a36Sopenharmony_ci#include <trace/events/f2fs.h>
3062306a36Sopenharmony_ci
3162306a36Sopenharmony_ci#define NUM_PREALLOC_POST_READ_CTXS	128
3262306a36Sopenharmony_ci
3362306a36Sopenharmony_cistatic struct kmem_cache *bio_post_read_ctx_cache;
3462306a36Sopenharmony_cistatic struct kmem_cache *bio_entry_slab;
3562306a36Sopenharmony_cistatic mempool_t *bio_post_read_ctx_pool;
3662306a36Sopenharmony_cistatic struct bio_set f2fs_bioset;
3762306a36Sopenharmony_ci
3862306a36Sopenharmony_ci#define	F2FS_BIO_POOL_SIZE	NR_CURSEG_TYPE
3962306a36Sopenharmony_ci
4062306a36Sopenharmony_ciint __init f2fs_init_bioset(void)
4162306a36Sopenharmony_ci{
4262306a36Sopenharmony_ci	return bioset_init(&f2fs_bioset, F2FS_BIO_POOL_SIZE,
4362306a36Sopenharmony_ci					0, BIOSET_NEED_BVECS);
4462306a36Sopenharmony_ci}
4562306a36Sopenharmony_ci
4662306a36Sopenharmony_civoid f2fs_destroy_bioset(void)
4762306a36Sopenharmony_ci{
4862306a36Sopenharmony_ci	bioset_exit(&f2fs_bioset);
4962306a36Sopenharmony_ci}
5062306a36Sopenharmony_ci
5162306a36Sopenharmony_cibool f2fs_is_cp_guaranteed(struct page *page)
5262306a36Sopenharmony_ci{
5362306a36Sopenharmony_ci	struct address_space *mapping = page->mapping;
5462306a36Sopenharmony_ci	struct inode *inode;
5562306a36Sopenharmony_ci	struct f2fs_sb_info *sbi;
5662306a36Sopenharmony_ci
5762306a36Sopenharmony_ci	if (!mapping)
5862306a36Sopenharmony_ci		return false;
5962306a36Sopenharmony_ci
6062306a36Sopenharmony_ci	inode = mapping->host;
6162306a36Sopenharmony_ci	sbi = F2FS_I_SB(inode);
6262306a36Sopenharmony_ci
6362306a36Sopenharmony_ci	if (inode->i_ino == F2FS_META_INO(sbi) ||
6462306a36Sopenharmony_ci			inode->i_ino == F2FS_NODE_INO(sbi) ||
6562306a36Sopenharmony_ci			S_ISDIR(inode->i_mode))
6662306a36Sopenharmony_ci		return true;
6762306a36Sopenharmony_ci
6862306a36Sopenharmony_ci	if ((S_ISREG(inode->i_mode) && IS_NOQUOTA(inode)) ||
6962306a36Sopenharmony_ci			page_private_gcing(page))
7062306a36Sopenharmony_ci		return true;
7162306a36Sopenharmony_ci	return false;
7262306a36Sopenharmony_ci}
7362306a36Sopenharmony_ci
7462306a36Sopenharmony_cistatic enum count_type __read_io_type(struct page *page)
7562306a36Sopenharmony_ci{
7662306a36Sopenharmony_ci	struct address_space *mapping = page_file_mapping(page);
7762306a36Sopenharmony_ci
7862306a36Sopenharmony_ci	if (mapping) {
7962306a36Sopenharmony_ci		struct inode *inode = mapping->host;
8062306a36Sopenharmony_ci		struct f2fs_sb_info *sbi = F2FS_I_SB(inode);
8162306a36Sopenharmony_ci
8262306a36Sopenharmony_ci		if (inode->i_ino == F2FS_META_INO(sbi))
8362306a36Sopenharmony_ci			return F2FS_RD_META;
8462306a36Sopenharmony_ci
8562306a36Sopenharmony_ci		if (inode->i_ino == F2FS_NODE_INO(sbi))
8662306a36Sopenharmony_ci			return F2FS_RD_NODE;
8762306a36Sopenharmony_ci	}
8862306a36Sopenharmony_ci	return F2FS_RD_DATA;
8962306a36Sopenharmony_ci}
9062306a36Sopenharmony_ci
9162306a36Sopenharmony_ci/* postprocessing steps for read bios */
9262306a36Sopenharmony_cienum bio_post_read_step {
9362306a36Sopenharmony_ci#ifdef CONFIG_FS_ENCRYPTION
9462306a36Sopenharmony_ci	STEP_DECRYPT	= BIT(0),
9562306a36Sopenharmony_ci#else
9662306a36Sopenharmony_ci	STEP_DECRYPT	= 0,	/* compile out the decryption-related code */
9762306a36Sopenharmony_ci#endif
9862306a36Sopenharmony_ci#ifdef CONFIG_F2FS_FS_COMPRESSION
9962306a36Sopenharmony_ci	STEP_DECOMPRESS	= BIT(1),
10062306a36Sopenharmony_ci#else
10162306a36Sopenharmony_ci	STEP_DECOMPRESS	= 0,	/* compile out the decompression-related code */
10262306a36Sopenharmony_ci#endif
10362306a36Sopenharmony_ci#ifdef CONFIG_FS_VERITY
10462306a36Sopenharmony_ci	STEP_VERITY	= BIT(2),
10562306a36Sopenharmony_ci#else
10662306a36Sopenharmony_ci	STEP_VERITY	= 0,	/* compile out the verity-related code */
10762306a36Sopenharmony_ci#endif
10862306a36Sopenharmony_ci};
10962306a36Sopenharmony_ci
11062306a36Sopenharmony_cistruct bio_post_read_ctx {
11162306a36Sopenharmony_ci	struct bio *bio;
11262306a36Sopenharmony_ci	struct f2fs_sb_info *sbi;
11362306a36Sopenharmony_ci	struct work_struct work;
11462306a36Sopenharmony_ci	unsigned int enabled_steps;
11562306a36Sopenharmony_ci	/*
11662306a36Sopenharmony_ci	 * decompression_attempted keeps track of whether
11762306a36Sopenharmony_ci	 * f2fs_end_read_compressed_page() has been called on the pages in the
11862306a36Sopenharmony_ci	 * bio that belong to a compressed cluster yet.
11962306a36Sopenharmony_ci	 */
12062306a36Sopenharmony_ci	bool decompression_attempted;
12162306a36Sopenharmony_ci	block_t fs_blkaddr;
12262306a36Sopenharmony_ci};
12362306a36Sopenharmony_ci
12462306a36Sopenharmony_ci/*
12562306a36Sopenharmony_ci * Update and unlock a bio's pages, and free the bio.
12662306a36Sopenharmony_ci *
12762306a36Sopenharmony_ci * This marks pages up-to-date only if there was no error in the bio (I/O error,
12862306a36Sopenharmony_ci * decryption error, or verity error), as indicated by bio->bi_status.
12962306a36Sopenharmony_ci *
13062306a36Sopenharmony_ci * "Compressed pages" (pagecache pages backed by a compressed cluster on-disk)
13162306a36Sopenharmony_ci * aren't marked up-to-date here, as decompression is done on a per-compression-
13262306a36Sopenharmony_ci * cluster basis rather than a per-bio basis.  Instead, we only must do two
13362306a36Sopenharmony_ci * things for each compressed page here: call f2fs_end_read_compressed_page()
13462306a36Sopenharmony_ci * with failed=true if an error occurred before it would have normally gotten
13562306a36Sopenharmony_ci * called (i.e., I/O error or decryption error, but *not* verity error), and
13662306a36Sopenharmony_ci * release the bio's reference to the decompress_io_ctx of the page's cluster.
13762306a36Sopenharmony_ci */
13862306a36Sopenharmony_cistatic void f2fs_finish_read_bio(struct bio *bio, bool in_task)
13962306a36Sopenharmony_ci{
14062306a36Sopenharmony_ci	struct bio_vec *bv;
14162306a36Sopenharmony_ci	struct bvec_iter_all iter_all;
14262306a36Sopenharmony_ci	struct bio_post_read_ctx *ctx = bio->bi_private;
14362306a36Sopenharmony_ci
14462306a36Sopenharmony_ci	bio_for_each_segment_all(bv, bio, iter_all) {
14562306a36Sopenharmony_ci		struct page *page = bv->bv_page;
14662306a36Sopenharmony_ci
14762306a36Sopenharmony_ci		if (f2fs_is_compressed_page(page)) {
14862306a36Sopenharmony_ci			if (ctx && !ctx->decompression_attempted)
14962306a36Sopenharmony_ci				f2fs_end_read_compressed_page(page, true, 0,
15062306a36Sopenharmony_ci							in_task);
15162306a36Sopenharmony_ci			f2fs_put_page_dic(page, in_task);
15262306a36Sopenharmony_ci			continue;
15362306a36Sopenharmony_ci		}
15462306a36Sopenharmony_ci
15562306a36Sopenharmony_ci		if (bio->bi_status)
15662306a36Sopenharmony_ci			ClearPageUptodate(page);
15762306a36Sopenharmony_ci		else
15862306a36Sopenharmony_ci			SetPageUptodate(page);
15962306a36Sopenharmony_ci		dec_page_count(F2FS_P_SB(page), __read_io_type(page));
16062306a36Sopenharmony_ci		unlock_page(page);
16162306a36Sopenharmony_ci	}
16262306a36Sopenharmony_ci
16362306a36Sopenharmony_ci	if (ctx)
16462306a36Sopenharmony_ci		mempool_free(ctx, bio_post_read_ctx_pool);
16562306a36Sopenharmony_ci	bio_put(bio);
16662306a36Sopenharmony_ci}
16762306a36Sopenharmony_ci
16862306a36Sopenharmony_cistatic void f2fs_verify_bio(struct work_struct *work)
16962306a36Sopenharmony_ci{
17062306a36Sopenharmony_ci	struct bio_post_read_ctx *ctx =
17162306a36Sopenharmony_ci		container_of(work, struct bio_post_read_ctx, work);
17262306a36Sopenharmony_ci	struct bio *bio = ctx->bio;
17362306a36Sopenharmony_ci	bool may_have_compressed_pages = (ctx->enabled_steps & STEP_DECOMPRESS);
17462306a36Sopenharmony_ci
17562306a36Sopenharmony_ci	/*
17662306a36Sopenharmony_ci	 * fsverity_verify_bio() may call readahead() again, and while verity
17762306a36Sopenharmony_ci	 * will be disabled for this, decryption and/or decompression may still
17862306a36Sopenharmony_ci	 * be needed, resulting in another bio_post_read_ctx being allocated.
17962306a36Sopenharmony_ci	 * So to prevent deadlocks we need to release the current ctx to the
18062306a36Sopenharmony_ci	 * mempool first.  This assumes that verity is the last post-read step.
18162306a36Sopenharmony_ci	 */
18262306a36Sopenharmony_ci	mempool_free(ctx, bio_post_read_ctx_pool);
18362306a36Sopenharmony_ci	bio->bi_private = NULL;
18462306a36Sopenharmony_ci
18562306a36Sopenharmony_ci	/*
18662306a36Sopenharmony_ci	 * Verify the bio's pages with fs-verity.  Exclude compressed pages,
18762306a36Sopenharmony_ci	 * as those were handled separately by f2fs_end_read_compressed_page().
18862306a36Sopenharmony_ci	 */
18962306a36Sopenharmony_ci	if (may_have_compressed_pages) {
19062306a36Sopenharmony_ci		struct bio_vec *bv;
19162306a36Sopenharmony_ci		struct bvec_iter_all iter_all;
19262306a36Sopenharmony_ci
19362306a36Sopenharmony_ci		bio_for_each_segment_all(bv, bio, iter_all) {
19462306a36Sopenharmony_ci			struct page *page = bv->bv_page;
19562306a36Sopenharmony_ci
19662306a36Sopenharmony_ci			if (!f2fs_is_compressed_page(page) &&
19762306a36Sopenharmony_ci			    !fsverity_verify_page(page)) {
19862306a36Sopenharmony_ci				bio->bi_status = BLK_STS_IOERR;
19962306a36Sopenharmony_ci				break;
20062306a36Sopenharmony_ci			}
20162306a36Sopenharmony_ci		}
20262306a36Sopenharmony_ci	} else {
20362306a36Sopenharmony_ci		fsverity_verify_bio(bio);
20462306a36Sopenharmony_ci	}
20562306a36Sopenharmony_ci
20662306a36Sopenharmony_ci	f2fs_finish_read_bio(bio, true);
20762306a36Sopenharmony_ci}
20862306a36Sopenharmony_ci
20962306a36Sopenharmony_ci/*
21062306a36Sopenharmony_ci * If the bio's data needs to be verified with fs-verity, then enqueue the
21162306a36Sopenharmony_ci * verity work for the bio.  Otherwise finish the bio now.
21262306a36Sopenharmony_ci *
21362306a36Sopenharmony_ci * Note that to avoid deadlocks, the verity work can't be done on the
21462306a36Sopenharmony_ci * decryption/decompression workqueue.  This is because verifying the data pages
21562306a36Sopenharmony_ci * can involve reading verity metadata pages from the file, and these verity
21662306a36Sopenharmony_ci * metadata pages may be encrypted and/or compressed.
21762306a36Sopenharmony_ci */
21862306a36Sopenharmony_cistatic void f2fs_verify_and_finish_bio(struct bio *bio, bool in_task)
21962306a36Sopenharmony_ci{
22062306a36Sopenharmony_ci	struct bio_post_read_ctx *ctx = bio->bi_private;
22162306a36Sopenharmony_ci
22262306a36Sopenharmony_ci	if (ctx && (ctx->enabled_steps & STEP_VERITY)) {
22362306a36Sopenharmony_ci		INIT_WORK(&ctx->work, f2fs_verify_bio);
22462306a36Sopenharmony_ci		fsverity_enqueue_verify_work(&ctx->work);
22562306a36Sopenharmony_ci	} else {
22662306a36Sopenharmony_ci		f2fs_finish_read_bio(bio, in_task);
22762306a36Sopenharmony_ci	}
22862306a36Sopenharmony_ci}
22962306a36Sopenharmony_ci
23062306a36Sopenharmony_ci/*
23162306a36Sopenharmony_ci * Handle STEP_DECOMPRESS by decompressing any compressed clusters whose last
23262306a36Sopenharmony_ci * remaining page was read by @ctx->bio.
23362306a36Sopenharmony_ci *
23462306a36Sopenharmony_ci * Note that a bio may span clusters (even a mix of compressed and uncompressed
23562306a36Sopenharmony_ci * clusters) or be for just part of a cluster.  STEP_DECOMPRESS just indicates
23662306a36Sopenharmony_ci * that the bio includes at least one compressed page.  The actual decompression
23762306a36Sopenharmony_ci * is done on a per-cluster basis, not a per-bio basis.
23862306a36Sopenharmony_ci */
23962306a36Sopenharmony_cistatic void f2fs_handle_step_decompress(struct bio_post_read_ctx *ctx,
24062306a36Sopenharmony_ci		bool in_task)
24162306a36Sopenharmony_ci{
24262306a36Sopenharmony_ci	struct bio_vec *bv;
24362306a36Sopenharmony_ci	struct bvec_iter_all iter_all;
24462306a36Sopenharmony_ci	bool all_compressed = true;
24562306a36Sopenharmony_ci	block_t blkaddr = ctx->fs_blkaddr;
24662306a36Sopenharmony_ci
24762306a36Sopenharmony_ci	bio_for_each_segment_all(bv, ctx->bio, iter_all) {
24862306a36Sopenharmony_ci		struct page *page = bv->bv_page;
24962306a36Sopenharmony_ci
25062306a36Sopenharmony_ci		if (f2fs_is_compressed_page(page))
25162306a36Sopenharmony_ci			f2fs_end_read_compressed_page(page, false, blkaddr,
25262306a36Sopenharmony_ci						      in_task);
25362306a36Sopenharmony_ci		else
25462306a36Sopenharmony_ci			all_compressed = false;
25562306a36Sopenharmony_ci
25662306a36Sopenharmony_ci		blkaddr++;
25762306a36Sopenharmony_ci	}
25862306a36Sopenharmony_ci
25962306a36Sopenharmony_ci	ctx->decompression_attempted = true;
26062306a36Sopenharmony_ci
26162306a36Sopenharmony_ci	/*
26262306a36Sopenharmony_ci	 * Optimization: if all the bio's pages are compressed, then scheduling
26362306a36Sopenharmony_ci	 * the per-bio verity work is unnecessary, as verity will be fully
26462306a36Sopenharmony_ci	 * handled at the compression cluster level.
26562306a36Sopenharmony_ci	 */
26662306a36Sopenharmony_ci	if (all_compressed)
26762306a36Sopenharmony_ci		ctx->enabled_steps &= ~STEP_VERITY;
26862306a36Sopenharmony_ci}
26962306a36Sopenharmony_ci
27062306a36Sopenharmony_cistatic void f2fs_post_read_work(struct work_struct *work)
27162306a36Sopenharmony_ci{
27262306a36Sopenharmony_ci	struct bio_post_read_ctx *ctx =
27362306a36Sopenharmony_ci		container_of(work, struct bio_post_read_ctx, work);
27462306a36Sopenharmony_ci	struct bio *bio = ctx->bio;
27562306a36Sopenharmony_ci
27662306a36Sopenharmony_ci	if ((ctx->enabled_steps & STEP_DECRYPT) && !fscrypt_decrypt_bio(bio)) {
27762306a36Sopenharmony_ci		f2fs_finish_read_bio(bio, true);
27862306a36Sopenharmony_ci		return;
27962306a36Sopenharmony_ci	}
28062306a36Sopenharmony_ci
28162306a36Sopenharmony_ci	if (ctx->enabled_steps & STEP_DECOMPRESS)
28262306a36Sopenharmony_ci		f2fs_handle_step_decompress(ctx, true);
28362306a36Sopenharmony_ci
28462306a36Sopenharmony_ci	f2fs_verify_and_finish_bio(bio, true);
28562306a36Sopenharmony_ci}
28662306a36Sopenharmony_ci
28762306a36Sopenharmony_cistatic void f2fs_read_end_io(struct bio *bio)
28862306a36Sopenharmony_ci{
28962306a36Sopenharmony_ci	struct f2fs_sb_info *sbi = F2FS_P_SB(bio_first_page_all(bio));
29062306a36Sopenharmony_ci	struct bio_post_read_ctx *ctx;
29162306a36Sopenharmony_ci	bool intask = in_task();
29262306a36Sopenharmony_ci
29362306a36Sopenharmony_ci	iostat_update_and_unbind_ctx(bio);
29462306a36Sopenharmony_ci	ctx = bio->bi_private;
29562306a36Sopenharmony_ci
29662306a36Sopenharmony_ci	if (time_to_inject(sbi, FAULT_READ_IO))
29762306a36Sopenharmony_ci		bio->bi_status = BLK_STS_IOERR;
29862306a36Sopenharmony_ci
29962306a36Sopenharmony_ci	if (bio->bi_status) {
30062306a36Sopenharmony_ci		f2fs_finish_read_bio(bio, intask);
30162306a36Sopenharmony_ci		return;
30262306a36Sopenharmony_ci	}
30362306a36Sopenharmony_ci
30462306a36Sopenharmony_ci	if (ctx) {
30562306a36Sopenharmony_ci		unsigned int enabled_steps = ctx->enabled_steps &
30662306a36Sopenharmony_ci					(STEP_DECRYPT | STEP_DECOMPRESS);
30762306a36Sopenharmony_ci
30862306a36Sopenharmony_ci		/*
30962306a36Sopenharmony_ci		 * If we have only decompression step between decompression and
31062306a36Sopenharmony_ci		 * decrypt, we don't need post processing for this.
31162306a36Sopenharmony_ci		 */
31262306a36Sopenharmony_ci		if (enabled_steps == STEP_DECOMPRESS &&
31362306a36Sopenharmony_ci				!f2fs_low_mem_mode(sbi)) {
31462306a36Sopenharmony_ci			f2fs_handle_step_decompress(ctx, intask);
31562306a36Sopenharmony_ci		} else if (enabled_steps) {
31662306a36Sopenharmony_ci			INIT_WORK(&ctx->work, f2fs_post_read_work);
31762306a36Sopenharmony_ci			queue_work(ctx->sbi->post_read_wq, &ctx->work);
31862306a36Sopenharmony_ci			return;
31962306a36Sopenharmony_ci		}
32062306a36Sopenharmony_ci	}
32162306a36Sopenharmony_ci
32262306a36Sopenharmony_ci	f2fs_verify_and_finish_bio(bio, intask);
32362306a36Sopenharmony_ci}
32462306a36Sopenharmony_ci
32562306a36Sopenharmony_cistatic void f2fs_write_end_io(struct bio *bio)
32662306a36Sopenharmony_ci{
32762306a36Sopenharmony_ci	struct f2fs_sb_info *sbi;
32862306a36Sopenharmony_ci	struct bio_vec *bvec;
32962306a36Sopenharmony_ci	struct bvec_iter_all iter_all;
33062306a36Sopenharmony_ci
33162306a36Sopenharmony_ci	iostat_update_and_unbind_ctx(bio);
33262306a36Sopenharmony_ci	sbi = bio->bi_private;
33362306a36Sopenharmony_ci
33462306a36Sopenharmony_ci	if (time_to_inject(sbi, FAULT_WRITE_IO))
33562306a36Sopenharmony_ci		bio->bi_status = BLK_STS_IOERR;
33662306a36Sopenharmony_ci
33762306a36Sopenharmony_ci	bio_for_each_segment_all(bvec, bio, iter_all) {
33862306a36Sopenharmony_ci		struct page *page = bvec->bv_page;
33962306a36Sopenharmony_ci		enum count_type type = WB_DATA_TYPE(page, false);
34062306a36Sopenharmony_ci
34162306a36Sopenharmony_ci		if (page_private_dummy(page)) {
34262306a36Sopenharmony_ci			clear_page_private_dummy(page);
34362306a36Sopenharmony_ci			unlock_page(page);
34462306a36Sopenharmony_ci			mempool_free(page, sbi->write_io_dummy);
34562306a36Sopenharmony_ci
34662306a36Sopenharmony_ci			if (unlikely(bio->bi_status))
34762306a36Sopenharmony_ci				f2fs_stop_checkpoint(sbi, true,
34862306a36Sopenharmony_ci						STOP_CP_REASON_WRITE_FAIL);
34962306a36Sopenharmony_ci			continue;
35062306a36Sopenharmony_ci		}
35162306a36Sopenharmony_ci
35262306a36Sopenharmony_ci		fscrypt_finalize_bounce_page(&page);
35362306a36Sopenharmony_ci
35462306a36Sopenharmony_ci#ifdef CONFIG_F2FS_FS_COMPRESSION
35562306a36Sopenharmony_ci		if (f2fs_is_compressed_page(page)) {
35662306a36Sopenharmony_ci			f2fs_compress_write_end_io(bio, page);
35762306a36Sopenharmony_ci			continue;
35862306a36Sopenharmony_ci		}
35962306a36Sopenharmony_ci#endif
36062306a36Sopenharmony_ci
36162306a36Sopenharmony_ci		if (unlikely(bio->bi_status)) {
36262306a36Sopenharmony_ci			mapping_set_error(page->mapping, -EIO);
36362306a36Sopenharmony_ci			if (type == F2FS_WB_CP_DATA)
36462306a36Sopenharmony_ci				f2fs_stop_checkpoint(sbi, true,
36562306a36Sopenharmony_ci						STOP_CP_REASON_WRITE_FAIL);
36662306a36Sopenharmony_ci		}
36762306a36Sopenharmony_ci
36862306a36Sopenharmony_ci		f2fs_bug_on(sbi, page->mapping == NODE_MAPPING(sbi) &&
36962306a36Sopenharmony_ci					page->index != nid_of_node(page));
37062306a36Sopenharmony_ci
37162306a36Sopenharmony_ci		dec_page_count(sbi, type);
37262306a36Sopenharmony_ci		if (f2fs_in_warm_node_list(sbi, page))
37362306a36Sopenharmony_ci			f2fs_del_fsync_node_entry(sbi, page);
37462306a36Sopenharmony_ci		clear_page_private_gcing(page);
37562306a36Sopenharmony_ci		end_page_writeback(page);
37662306a36Sopenharmony_ci	}
37762306a36Sopenharmony_ci	if (!get_pages(sbi, F2FS_WB_CP_DATA) &&
37862306a36Sopenharmony_ci				wq_has_sleeper(&sbi->cp_wait))
37962306a36Sopenharmony_ci		wake_up(&sbi->cp_wait);
38062306a36Sopenharmony_ci
38162306a36Sopenharmony_ci	bio_put(bio);
38262306a36Sopenharmony_ci}
38362306a36Sopenharmony_ci
38462306a36Sopenharmony_ci#ifdef CONFIG_BLK_DEV_ZONED
38562306a36Sopenharmony_cistatic void f2fs_zone_write_end_io(struct bio *bio)
38662306a36Sopenharmony_ci{
38762306a36Sopenharmony_ci	struct f2fs_bio_info *io = (struct f2fs_bio_info *)bio->bi_private;
38862306a36Sopenharmony_ci
38962306a36Sopenharmony_ci	bio->bi_private = io->bi_private;
39062306a36Sopenharmony_ci	complete(&io->zone_wait);
39162306a36Sopenharmony_ci	f2fs_write_end_io(bio);
39262306a36Sopenharmony_ci}
39362306a36Sopenharmony_ci#endif
39462306a36Sopenharmony_ci
39562306a36Sopenharmony_cistruct block_device *f2fs_target_device(struct f2fs_sb_info *sbi,
39662306a36Sopenharmony_ci		block_t blk_addr, sector_t *sector)
39762306a36Sopenharmony_ci{
39862306a36Sopenharmony_ci	struct block_device *bdev = sbi->sb->s_bdev;
39962306a36Sopenharmony_ci	int i;
40062306a36Sopenharmony_ci
40162306a36Sopenharmony_ci	if (f2fs_is_multi_device(sbi)) {
40262306a36Sopenharmony_ci		for (i = 0; i < sbi->s_ndevs; i++) {
40362306a36Sopenharmony_ci			if (FDEV(i).start_blk <= blk_addr &&
40462306a36Sopenharmony_ci			    FDEV(i).end_blk >= blk_addr) {
40562306a36Sopenharmony_ci				blk_addr -= FDEV(i).start_blk;
40662306a36Sopenharmony_ci				bdev = FDEV(i).bdev;
40762306a36Sopenharmony_ci				break;
40862306a36Sopenharmony_ci			}
40962306a36Sopenharmony_ci		}
41062306a36Sopenharmony_ci	}
41162306a36Sopenharmony_ci
41262306a36Sopenharmony_ci	if (sector)
41362306a36Sopenharmony_ci		*sector = SECTOR_FROM_BLOCK(blk_addr);
41462306a36Sopenharmony_ci	return bdev;
41562306a36Sopenharmony_ci}
41662306a36Sopenharmony_ci
41762306a36Sopenharmony_ciint f2fs_target_device_index(struct f2fs_sb_info *sbi, block_t blkaddr)
41862306a36Sopenharmony_ci{
41962306a36Sopenharmony_ci	int i;
42062306a36Sopenharmony_ci
42162306a36Sopenharmony_ci	if (!f2fs_is_multi_device(sbi))
42262306a36Sopenharmony_ci		return 0;
42362306a36Sopenharmony_ci
42462306a36Sopenharmony_ci	for (i = 0; i < sbi->s_ndevs; i++)
42562306a36Sopenharmony_ci		if (FDEV(i).start_blk <= blkaddr && FDEV(i).end_blk >= blkaddr)
42662306a36Sopenharmony_ci			return i;
42762306a36Sopenharmony_ci	return 0;
42862306a36Sopenharmony_ci}
42962306a36Sopenharmony_ci
43062306a36Sopenharmony_cistatic blk_opf_t f2fs_io_flags(struct f2fs_io_info *fio)
43162306a36Sopenharmony_ci{
43262306a36Sopenharmony_ci	unsigned int temp_mask = GENMASK(NR_TEMP_TYPE - 1, 0);
43362306a36Sopenharmony_ci	unsigned int fua_flag, meta_flag, io_flag;
43462306a36Sopenharmony_ci	blk_opf_t op_flags = 0;
43562306a36Sopenharmony_ci
43662306a36Sopenharmony_ci	if (fio->op != REQ_OP_WRITE)
43762306a36Sopenharmony_ci		return 0;
43862306a36Sopenharmony_ci	if (fio->type == DATA)
43962306a36Sopenharmony_ci		io_flag = fio->sbi->data_io_flag;
44062306a36Sopenharmony_ci	else if (fio->type == NODE)
44162306a36Sopenharmony_ci		io_flag = fio->sbi->node_io_flag;
44262306a36Sopenharmony_ci	else
44362306a36Sopenharmony_ci		return 0;
44462306a36Sopenharmony_ci
44562306a36Sopenharmony_ci	fua_flag = io_flag & temp_mask;
44662306a36Sopenharmony_ci	meta_flag = (io_flag >> NR_TEMP_TYPE) & temp_mask;
44762306a36Sopenharmony_ci
44862306a36Sopenharmony_ci	/*
44962306a36Sopenharmony_ci	 * data/node io flag bits per temp:
45062306a36Sopenharmony_ci	 *      REQ_META     |      REQ_FUA      |
45162306a36Sopenharmony_ci	 *    5 |    4 |   3 |    2 |    1 |   0 |
45262306a36Sopenharmony_ci	 * Cold | Warm | Hot | Cold | Warm | Hot |
45362306a36Sopenharmony_ci	 */
45462306a36Sopenharmony_ci	if (BIT(fio->temp) & meta_flag)
45562306a36Sopenharmony_ci		op_flags |= REQ_META;
45662306a36Sopenharmony_ci	if (BIT(fio->temp) & fua_flag)
45762306a36Sopenharmony_ci		op_flags |= REQ_FUA;
45862306a36Sopenharmony_ci	return op_flags;
45962306a36Sopenharmony_ci}
46062306a36Sopenharmony_ci
46162306a36Sopenharmony_cistatic struct bio *__bio_alloc(struct f2fs_io_info *fio, int npages)
46262306a36Sopenharmony_ci{
46362306a36Sopenharmony_ci	struct f2fs_sb_info *sbi = fio->sbi;
46462306a36Sopenharmony_ci	struct block_device *bdev;
46562306a36Sopenharmony_ci	sector_t sector;
46662306a36Sopenharmony_ci	struct bio *bio;
46762306a36Sopenharmony_ci
46862306a36Sopenharmony_ci	bdev = f2fs_target_device(sbi, fio->new_blkaddr, &sector);
46962306a36Sopenharmony_ci	bio = bio_alloc_bioset(bdev, npages,
47062306a36Sopenharmony_ci				fio->op | fio->op_flags | f2fs_io_flags(fio),
47162306a36Sopenharmony_ci				GFP_NOIO, &f2fs_bioset);
47262306a36Sopenharmony_ci	bio->bi_iter.bi_sector = sector;
47362306a36Sopenharmony_ci	if (is_read_io(fio->op)) {
47462306a36Sopenharmony_ci		bio->bi_end_io = f2fs_read_end_io;
47562306a36Sopenharmony_ci		bio->bi_private = NULL;
47662306a36Sopenharmony_ci	} else {
47762306a36Sopenharmony_ci		bio->bi_end_io = f2fs_write_end_io;
47862306a36Sopenharmony_ci		bio->bi_private = sbi;
47962306a36Sopenharmony_ci	}
48062306a36Sopenharmony_ci	iostat_alloc_and_bind_ctx(sbi, bio, NULL);
48162306a36Sopenharmony_ci
48262306a36Sopenharmony_ci	if (fio->io_wbc)
48362306a36Sopenharmony_ci		wbc_init_bio(fio->io_wbc, bio);
48462306a36Sopenharmony_ci
48562306a36Sopenharmony_ci	return bio;
48662306a36Sopenharmony_ci}
48762306a36Sopenharmony_ci
48862306a36Sopenharmony_cistatic void f2fs_set_bio_crypt_ctx(struct bio *bio, const struct inode *inode,
48962306a36Sopenharmony_ci				  pgoff_t first_idx,
49062306a36Sopenharmony_ci				  const struct f2fs_io_info *fio,
49162306a36Sopenharmony_ci				  gfp_t gfp_mask)
49262306a36Sopenharmony_ci{
49362306a36Sopenharmony_ci	/*
49462306a36Sopenharmony_ci	 * The f2fs garbage collector sets ->encrypted_page when it wants to
49562306a36Sopenharmony_ci	 * read/write raw data without encryption.
49662306a36Sopenharmony_ci	 */
49762306a36Sopenharmony_ci	if (!fio || !fio->encrypted_page)
49862306a36Sopenharmony_ci		fscrypt_set_bio_crypt_ctx(bio, inode, first_idx, gfp_mask);
49962306a36Sopenharmony_ci}
50062306a36Sopenharmony_ci
50162306a36Sopenharmony_cistatic bool f2fs_crypt_mergeable_bio(struct bio *bio, const struct inode *inode,
50262306a36Sopenharmony_ci				     pgoff_t next_idx,
50362306a36Sopenharmony_ci				     const struct f2fs_io_info *fio)
50462306a36Sopenharmony_ci{
50562306a36Sopenharmony_ci	/*
50662306a36Sopenharmony_ci	 * The f2fs garbage collector sets ->encrypted_page when it wants to
50762306a36Sopenharmony_ci	 * read/write raw data without encryption.
50862306a36Sopenharmony_ci	 */
50962306a36Sopenharmony_ci	if (fio && fio->encrypted_page)
51062306a36Sopenharmony_ci		return !bio_has_crypt_ctx(bio);
51162306a36Sopenharmony_ci
51262306a36Sopenharmony_ci	return fscrypt_mergeable_bio(bio, inode, next_idx);
51362306a36Sopenharmony_ci}
51462306a36Sopenharmony_ci
51562306a36Sopenharmony_civoid f2fs_submit_read_bio(struct f2fs_sb_info *sbi, struct bio *bio,
51662306a36Sopenharmony_ci				 enum page_type type)
51762306a36Sopenharmony_ci{
51862306a36Sopenharmony_ci	WARN_ON_ONCE(!is_read_io(bio_op(bio)));
51962306a36Sopenharmony_ci	trace_f2fs_submit_read_bio(sbi->sb, type, bio);
52062306a36Sopenharmony_ci
52162306a36Sopenharmony_ci	iostat_update_submit_ctx(bio, type);
52262306a36Sopenharmony_ci	submit_bio(bio);
52362306a36Sopenharmony_ci}
52462306a36Sopenharmony_ci
52562306a36Sopenharmony_cistatic void f2fs_align_write_bio(struct f2fs_sb_info *sbi, struct bio *bio)
52662306a36Sopenharmony_ci{
52762306a36Sopenharmony_ci	unsigned int start =
52862306a36Sopenharmony_ci		(bio->bi_iter.bi_size >> F2FS_BLKSIZE_BITS) % F2FS_IO_SIZE(sbi);
52962306a36Sopenharmony_ci
53062306a36Sopenharmony_ci	if (start == 0)
53162306a36Sopenharmony_ci		return;
53262306a36Sopenharmony_ci
53362306a36Sopenharmony_ci	/* fill dummy pages */
53462306a36Sopenharmony_ci	for (; start < F2FS_IO_SIZE(sbi); start++) {
53562306a36Sopenharmony_ci		struct page *page =
53662306a36Sopenharmony_ci			mempool_alloc(sbi->write_io_dummy,
53762306a36Sopenharmony_ci				      GFP_NOIO | __GFP_NOFAIL);
53862306a36Sopenharmony_ci		f2fs_bug_on(sbi, !page);
53962306a36Sopenharmony_ci
54062306a36Sopenharmony_ci		lock_page(page);
54162306a36Sopenharmony_ci
54262306a36Sopenharmony_ci		zero_user_segment(page, 0, PAGE_SIZE);
54362306a36Sopenharmony_ci		set_page_private_dummy(page);
54462306a36Sopenharmony_ci
54562306a36Sopenharmony_ci		if (bio_add_page(bio, page, PAGE_SIZE, 0) < PAGE_SIZE)
54662306a36Sopenharmony_ci			f2fs_bug_on(sbi, 1);
54762306a36Sopenharmony_ci	}
54862306a36Sopenharmony_ci}
54962306a36Sopenharmony_ci
55062306a36Sopenharmony_cistatic void f2fs_submit_write_bio(struct f2fs_sb_info *sbi, struct bio *bio,
55162306a36Sopenharmony_ci				  enum page_type type)
55262306a36Sopenharmony_ci{
55362306a36Sopenharmony_ci	WARN_ON_ONCE(is_read_io(bio_op(bio)));
55462306a36Sopenharmony_ci
55562306a36Sopenharmony_ci	if (type == DATA || type == NODE) {
55662306a36Sopenharmony_ci		if (f2fs_lfs_mode(sbi) && current->plug)
55762306a36Sopenharmony_ci			blk_finish_plug(current->plug);
55862306a36Sopenharmony_ci
55962306a36Sopenharmony_ci		if (F2FS_IO_ALIGNED(sbi)) {
56062306a36Sopenharmony_ci			f2fs_align_write_bio(sbi, bio);
56162306a36Sopenharmony_ci			/*
56262306a36Sopenharmony_ci			 * In the NODE case, we lose next block address chain.
56362306a36Sopenharmony_ci			 * So, we need to do checkpoint in f2fs_sync_file.
56462306a36Sopenharmony_ci			 */
56562306a36Sopenharmony_ci			if (type == NODE)
56662306a36Sopenharmony_ci				set_sbi_flag(sbi, SBI_NEED_CP);
56762306a36Sopenharmony_ci		}
56862306a36Sopenharmony_ci	}
56962306a36Sopenharmony_ci
57062306a36Sopenharmony_ci	trace_f2fs_submit_write_bio(sbi->sb, type, bio);
57162306a36Sopenharmony_ci	iostat_update_submit_ctx(bio, type);
57262306a36Sopenharmony_ci	submit_bio(bio);
57362306a36Sopenharmony_ci}
57462306a36Sopenharmony_ci
57562306a36Sopenharmony_cistatic void __submit_merged_bio(struct f2fs_bio_info *io)
57662306a36Sopenharmony_ci{
57762306a36Sopenharmony_ci	struct f2fs_io_info *fio = &io->fio;
57862306a36Sopenharmony_ci
57962306a36Sopenharmony_ci	if (!io->bio)
58062306a36Sopenharmony_ci		return;
58162306a36Sopenharmony_ci
58262306a36Sopenharmony_ci	if (is_read_io(fio->op)) {
58362306a36Sopenharmony_ci		trace_f2fs_prepare_read_bio(io->sbi->sb, fio->type, io->bio);
58462306a36Sopenharmony_ci		f2fs_submit_read_bio(io->sbi, io->bio, fio->type);
58562306a36Sopenharmony_ci	} else {
58662306a36Sopenharmony_ci		trace_f2fs_prepare_write_bio(io->sbi->sb, fio->type, io->bio);
58762306a36Sopenharmony_ci		f2fs_submit_write_bio(io->sbi, io->bio, fio->type);
58862306a36Sopenharmony_ci	}
58962306a36Sopenharmony_ci	io->bio = NULL;
59062306a36Sopenharmony_ci}
59162306a36Sopenharmony_ci
59262306a36Sopenharmony_cistatic bool __has_merged_page(struct bio *bio, struct inode *inode,
59362306a36Sopenharmony_ci						struct page *page, nid_t ino)
59462306a36Sopenharmony_ci{
59562306a36Sopenharmony_ci	struct bio_vec *bvec;
59662306a36Sopenharmony_ci	struct bvec_iter_all iter_all;
59762306a36Sopenharmony_ci
59862306a36Sopenharmony_ci	if (!bio)
59962306a36Sopenharmony_ci		return false;
60062306a36Sopenharmony_ci
60162306a36Sopenharmony_ci	if (!inode && !page && !ino)
60262306a36Sopenharmony_ci		return true;
60362306a36Sopenharmony_ci
60462306a36Sopenharmony_ci	bio_for_each_segment_all(bvec, bio, iter_all) {
60562306a36Sopenharmony_ci		struct page *target = bvec->bv_page;
60662306a36Sopenharmony_ci
60762306a36Sopenharmony_ci		if (fscrypt_is_bounce_page(target)) {
60862306a36Sopenharmony_ci			target = fscrypt_pagecache_page(target);
60962306a36Sopenharmony_ci			if (IS_ERR(target))
61062306a36Sopenharmony_ci				continue;
61162306a36Sopenharmony_ci		}
61262306a36Sopenharmony_ci		if (f2fs_is_compressed_page(target)) {
61362306a36Sopenharmony_ci			target = f2fs_compress_control_page(target);
61462306a36Sopenharmony_ci			if (IS_ERR(target))
61562306a36Sopenharmony_ci				continue;
61662306a36Sopenharmony_ci		}
61762306a36Sopenharmony_ci
61862306a36Sopenharmony_ci		if (inode && inode == target->mapping->host)
61962306a36Sopenharmony_ci			return true;
62062306a36Sopenharmony_ci		if (page && page == target)
62162306a36Sopenharmony_ci			return true;
62262306a36Sopenharmony_ci		if (ino && ino == ino_of_node(target))
62362306a36Sopenharmony_ci			return true;
62462306a36Sopenharmony_ci	}
62562306a36Sopenharmony_ci
62662306a36Sopenharmony_ci	return false;
62762306a36Sopenharmony_ci}
62862306a36Sopenharmony_ci
62962306a36Sopenharmony_ciint f2fs_init_write_merge_io(struct f2fs_sb_info *sbi)
63062306a36Sopenharmony_ci{
63162306a36Sopenharmony_ci	int i;
63262306a36Sopenharmony_ci
63362306a36Sopenharmony_ci	for (i = 0; i < NR_PAGE_TYPE; i++) {
63462306a36Sopenharmony_ci		int n = (i == META) ? 1 : NR_TEMP_TYPE;
63562306a36Sopenharmony_ci		int j;
63662306a36Sopenharmony_ci
63762306a36Sopenharmony_ci		sbi->write_io[i] = f2fs_kmalloc(sbi,
63862306a36Sopenharmony_ci				array_size(n, sizeof(struct f2fs_bio_info)),
63962306a36Sopenharmony_ci				GFP_KERNEL);
64062306a36Sopenharmony_ci		if (!sbi->write_io[i])
64162306a36Sopenharmony_ci			return -ENOMEM;
64262306a36Sopenharmony_ci
64362306a36Sopenharmony_ci		for (j = HOT; j < n; j++) {
64462306a36Sopenharmony_ci			init_f2fs_rwsem(&sbi->write_io[i][j].io_rwsem);
64562306a36Sopenharmony_ci			sbi->write_io[i][j].sbi = sbi;
64662306a36Sopenharmony_ci			sbi->write_io[i][j].bio = NULL;
64762306a36Sopenharmony_ci			spin_lock_init(&sbi->write_io[i][j].io_lock);
64862306a36Sopenharmony_ci			INIT_LIST_HEAD(&sbi->write_io[i][j].io_list);
64962306a36Sopenharmony_ci			INIT_LIST_HEAD(&sbi->write_io[i][j].bio_list);
65062306a36Sopenharmony_ci			init_f2fs_rwsem(&sbi->write_io[i][j].bio_list_lock);
65162306a36Sopenharmony_ci#ifdef CONFIG_BLK_DEV_ZONED
65262306a36Sopenharmony_ci			init_completion(&sbi->write_io[i][j].zone_wait);
65362306a36Sopenharmony_ci			sbi->write_io[i][j].zone_pending_bio = NULL;
65462306a36Sopenharmony_ci			sbi->write_io[i][j].bi_private = NULL;
65562306a36Sopenharmony_ci#endif
65662306a36Sopenharmony_ci		}
65762306a36Sopenharmony_ci	}
65862306a36Sopenharmony_ci
65962306a36Sopenharmony_ci	return 0;
66062306a36Sopenharmony_ci}
66162306a36Sopenharmony_ci
66262306a36Sopenharmony_cistatic void __f2fs_submit_merged_write(struct f2fs_sb_info *sbi,
66362306a36Sopenharmony_ci				enum page_type type, enum temp_type temp)
66462306a36Sopenharmony_ci{
66562306a36Sopenharmony_ci	enum page_type btype = PAGE_TYPE_OF_BIO(type);
66662306a36Sopenharmony_ci	struct f2fs_bio_info *io = sbi->write_io[btype] + temp;
66762306a36Sopenharmony_ci
66862306a36Sopenharmony_ci	f2fs_down_write(&io->io_rwsem);
66962306a36Sopenharmony_ci
67062306a36Sopenharmony_ci	if (!io->bio)
67162306a36Sopenharmony_ci		goto unlock_out;
67262306a36Sopenharmony_ci
67362306a36Sopenharmony_ci	/* change META to META_FLUSH in the checkpoint procedure */
67462306a36Sopenharmony_ci	if (type >= META_FLUSH) {
67562306a36Sopenharmony_ci		io->fio.type = META_FLUSH;
67662306a36Sopenharmony_ci		io->bio->bi_opf |= REQ_META | REQ_PRIO | REQ_SYNC;
67762306a36Sopenharmony_ci		if (!test_opt(sbi, NOBARRIER))
67862306a36Sopenharmony_ci			io->bio->bi_opf |= REQ_PREFLUSH | REQ_FUA;
67962306a36Sopenharmony_ci	}
68062306a36Sopenharmony_ci	__submit_merged_bio(io);
68162306a36Sopenharmony_ciunlock_out:
68262306a36Sopenharmony_ci	f2fs_up_write(&io->io_rwsem);
68362306a36Sopenharmony_ci}
68462306a36Sopenharmony_ci
68562306a36Sopenharmony_cistatic void __submit_merged_write_cond(struct f2fs_sb_info *sbi,
68662306a36Sopenharmony_ci				struct inode *inode, struct page *page,
68762306a36Sopenharmony_ci				nid_t ino, enum page_type type, bool force)
68862306a36Sopenharmony_ci{
68962306a36Sopenharmony_ci	enum temp_type temp;
69062306a36Sopenharmony_ci	bool ret = true;
69162306a36Sopenharmony_ci
69262306a36Sopenharmony_ci	for (temp = HOT; temp < NR_TEMP_TYPE; temp++) {
69362306a36Sopenharmony_ci		if (!force)	{
69462306a36Sopenharmony_ci			enum page_type btype = PAGE_TYPE_OF_BIO(type);
69562306a36Sopenharmony_ci			struct f2fs_bio_info *io = sbi->write_io[btype] + temp;
69662306a36Sopenharmony_ci
69762306a36Sopenharmony_ci			f2fs_down_read(&io->io_rwsem);
69862306a36Sopenharmony_ci			ret = __has_merged_page(io->bio, inode, page, ino);
69962306a36Sopenharmony_ci			f2fs_up_read(&io->io_rwsem);
70062306a36Sopenharmony_ci		}
70162306a36Sopenharmony_ci		if (ret)
70262306a36Sopenharmony_ci			__f2fs_submit_merged_write(sbi, type, temp);
70362306a36Sopenharmony_ci
70462306a36Sopenharmony_ci		/* TODO: use HOT temp only for meta pages now. */
70562306a36Sopenharmony_ci		if (type >= META)
70662306a36Sopenharmony_ci			break;
70762306a36Sopenharmony_ci	}
70862306a36Sopenharmony_ci}
70962306a36Sopenharmony_ci
71062306a36Sopenharmony_civoid f2fs_submit_merged_write(struct f2fs_sb_info *sbi, enum page_type type)
71162306a36Sopenharmony_ci{
71262306a36Sopenharmony_ci	__submit_merged_write_cond(sbi, NULL, NULL, 0, type, true);
71362306a36Sopenharmony_ci}
71462306a36Sopenharmony_ci
71562306a36Sopenharmony_civoid f2fs_submit_merged_write_cond(struct f2fs_sb_info *sbi,
71662306a36Sopenharmony_ci				struct inode *inode, struct page *page,
71762306a36Sopenharmony_ci				nid_t ino, enum page_type type)
71862306a36Sopenharmony_ci{
71962306a36Sopenharmony_ci	__submit_merged_write_cond(sbi, inode, page, ino, type, false);
72062306a36Sopenharmony_ci}
72162306a36Sopenharmony_ci
72262306a36Sopenharmony_civoid f2fs_flush_merged_writes(struct f2fs_sb_info *sbi)
72362306a36Sopenharmony_ci{
72462306a36Sopenharmony_ci	f2fs_submit_merged_write(sbi, DATA);
72562306a36Sopenharmony_ci	f2fs_submit_merged_write(sbi, NODE);
72662306a36Sopenharmony_ci	f2fs_submit_merged_write(sbi, META);
72762306a36Sopenharmony_ci}
72862306a36Sopenharmony_ci
72962306a36Sopenharmony_ci/*
73062306a36Sopenharmony_ci * Fill the locked page with data located in the block address.
73162306a36Sopenharmony_ci * A caller needs to unlock the page on failure.
73262306a36Sopenharmony_ci */
73362306a36Sopenharmony_ciint f2fs_submit_page_bio(struct f2fs_io_info *fio)
73462306a36Sopenharmony_ci{
73562306a36Sopenharmony_ci	struct bio *bio;
73662306a36Sopenharmony_ci	struct page *page = fio->encrypted_page ?
73762306a36Sopenharmony_ci			fio->encrypted_page : fio->page;
73862306a36Sopenharmony_ci
73962306a36Sopenharmony_ci	if (!f2fs_is_valid_blkaddr(fio->sbi, fio->new_blkaddr,
74062306a36Sopenharmony_ci			fio->is_por ? META_POR : (__is_meta_io(fio) ?
74162306a36Sopenharmony_ci			META_GENERIC : DATA_GENERIC_ENHANCE))) {
74262306a36Sopenharmony_ci		f2fs_handle_error(fio->sbi, ERROR_INVALID_BLKADDR);
74362306a36Sopenharmony_ci		return -EFSCORRUPTED;
74462306a36Sopenharmony_ci	}
74562306a36Sopenharmony_ci
74662306a36Sopenharmony_ci	trace_f2fs_submit_page_bio(page, fio);
74762306a36Sopenharmony_ci
74862306a36Sopenharmony_ci	/* Allocate a new bio */
74962306a36Sopenharmony_ci	bio = __bio_alloc(fio, 1);
75062306a36Sopenharmony_ci
75162306a36Sopenharmony_ci	f2fs_set_bio_crypt_ctx(bio, fio->page->mapping->host,
75262306a36Sopenharmony_ci			       fio->page->index, fio, GFP_NOIO);
75362306a36Sopenharmony_ci
75462306a36Sopenharmony_ci	if (bio_add_page(bio, page, PAGE_SIZE, 0) < PAGE_SIZE) {
75562306a36Sopenharmony_ci		bio_put(bio);
75662306a36Sopenharmony_ci		return -EFAULT;
75762306a36Sopenharmony_ci	}
75862306a36Sopenharmony_ci
75962306a36Sopenharmony_ci	if (fio->io_wbc && !is_read_io(fio->op))
76062306a36Sopenharmony_ci		wbc_account_cgroup_owner(fio->io_wbc, fio->page, PAGE_SIZE);
76162306a36Sopenharmony_ci
76262306a36Sopenharmony_ci	inc_page_count(fio->sbi, is_read_io(fio->op) ?
76362306a36Sopenharmony_ci			__read_io_type(page) : WB_DATA_TYPE(fio->page, false));
76462306a36Sopenharmony_ci
76562306a36Sopenharmony_ci	if (is_read_io(bio_op(bio)))
76662306a36Sopenharmony_ci		f2fs_submit_read_bio(fio->sbi, bio, fio->type);
76762306a36Sopenharmony_ci	else
76862306a36Sopenharmony_ci		f2fs_submit_write_bio(fio->sbi, bio, fio->type);
76962306a36Sopenharmony_ci	return 0;
77062306a36Sopenharmony_ci}
77162306a36Sopenharmony_ci
77262306a36Sopenharmony_cistatic bool page_is_mergeable(struct f2fs_sb_info *sbi, struct bio *bio,
77362306a36Sopenharmony_ci				block_t last_blkaddr, block_t cur_blkaddr)
77462306a36Sopenharmony_ci{
77562306a36Sopenharmony_ci	if (unlikely(sbi->max_io_bytes &&
77662306a36Sopenharmony_ci			bio->bi_iter.bi_size >= sbi->max_io_bytes))
77762306a36Sopenharmony_ci		return false;
77862306a36Sopenharmony_ci	if (last_blkaddr + 1 != cur_blkaddr)
77962306a36Sopenharmony_ci		return false;
78062306a36Sopenharmony_ci	return bio->bi_bdev == f2fs_target_device(sbi, cur_blkaddr, NULL);
78162306a36Sopenharmony_ci}
78262306a36Sopenharmony_ci
78362306a36Sopenharmony_cistatic bool io_type_is_mergeable(struct f2fs_bio_info *io,
78462306a36Sopenharmony_ci						struct f2fs_io_info *fio)
78562306a36Sopenharmony_ci{
78662306a36Sopenharmony_ci	if (io->fio.op != fio->op)
78762306a36Sopenharmony_ci		return false;
78862306a36Sopenharmony_ci	return io->fio.op_flags == fio->op_flags;
78962306a36Sopenharmony_ci}
79062306a36Sopenharmony_ci
79162306a36Sopenharmony_cistatic bool io_is_mergeable(struct f2fs_sb_info *sbi, struct bio *bio,
79262306a36Sopenharmony_ci					struct f2fs_bio_info *io,
79362306a36Sopenharmony_ci					struct f2fs_io_info *fio,
79462306a36Sopenharmony_ci					block_t last_blkaddr,
79562306a36Sopenharmony_ci					block_t cur_blkaddr)
79662306a36Sopenharmony_ci{
79762306a36Sopenharmony_ci	if (F2FS_IO_ALIGNED(sbi) && (fio->type == DATA || fio->type == NODE)) {
79862306a36Sopenharmony_ci		unsigned int filled_blocks =
79962306a36Sopenharmony_ci				F2FS_BYTES_TO_BLK(bio->bi_iter.bi_size);
80062306a36Sopenharmony_ci		unsigned int io_size = F2FS_IO_SIZE(sbi);
80162306a36Sopenharmony_ci		unsigned int left_vecs = bio->bi_max_vecs - bio->bi_vcnt;
80262306a36Sopenharmony_ci
80362306a36Sopenharmony_ci		/* IOs in bio is aligned and left space of vectors is not enough */
80462306a36Sopenharmony_ci		if (!(filled_blocks % io_size) && left_vecs < io_size)
80562306a36Sopenharmony_ci			return false;
80662306a36Sopenharmony_ci	}
80762306a36Sopenharmony_ci	if (!page_is_mergeable(sbi, bio, last_blkaddr, cur_blkaddr))
80862306a36Sopenharmony_ci		return false;
80962306a36Sopenharmony_ci	return io_type_is_mergeable(io, fio);
81062306a36Sopenharmony_ci}
81162306a36Sopenharmony_ci
81262306a36Sopenharmony_cistatic void add_bio_entry(struct f2fs_sb_info *sbi, struct bio *bio,
81362306a36Sopenharmony_ci				struct page *page, enum temp_type temp)
81462306a36Sopenharmony_ci{
81562306a36Sopenharmony_ci	struct f2fs_bio_info *io = sbi->write_io[DATA] + temp;
81662306a36Sopenharmony_ci	struct bio_entry *be;
81762306a36Sopenharmony_ci
81862306a36Sopenharmony_ci	be = f2fs_kmem_cache_alloc(bio_entry_slab, GFP_NOFS, true, NULL);
81962306a36Sopenharmony_ci	be->bio = bio;
82062306a36Sopenharmony_ci	bio_get(bio);
82162306a36Sopenharmony_ci
82262306a36Sopenharmony_ci	if (bio_add_page(bio, page, PAGE_SIZE, 0) != PAGE_SIZE)
82362306a36Sopenharmony_ci		f2fs_bug_on(sbi, 1);
82462306a36Sopenharmony_ci
82562306a36Sopenharmony_ci	f2fs_down_write(&io->bio_list_lock);
82662306a36Sopenharmony_ci	list_add_tail(&be->list, &io->bio_list);
82762306a36Sopenharmony_ci	f2fs_up_write(&io->bio_list_lock);
82862306a36Sopenharmony_ci}
82962306a36Sopenharmony_ci
83062306a36Sopenharmony_cistatic void del_bio_entry(struct bio_entry *be)
83162306a36Sopenharmony_ci{
83262306a36Sopenharmony_ci	list_del(&be->list);
83362306a36Sopenharmony_ci	kmem_cache_free(bio_entry_slab, be);
83462306a36Sopenharmony_ci}
83562306a36Sopenharmony_ci
83662306a36Sopenharmony_cistatic int add_ipu_page(struct f2fs_io_info *fio, struct bio **bio,
83762306a36Sopenharmony_ci							struct page *page)
83862306a36Sopenharmony_ci{
83962306a36Sopenharmony_ci	struct f2fs_sb_info *sbi = fio->sbi;
84062306a36Sopenharmony_ci	enum temp_type temp;
84162306a36Sopenharmony_ci	bool found = false;
84262306a36Sopenharmony_ci	int ret = -EAGAIN;
84362306a36Sopenharmony_ci
84462306a36Sopenharmony_ci	for (temp = HOT; temp < NR_TEMP_TYPE && !found; temp++) {
84562306a36Sopenharmony_ci		struct f2fs_bio_info *io = sbi->write_io[DATA] + temp;
84662306a36Sopenharmony_ci		struct list_head *head = &io->bio_list;
84762306a36Sopenharmony_ci		struct bio_entry *be;
84862306a36Sopenharmony_ci
84962306a36Sopenharmony_ci		f2fs_down_write(&io->bio_list_lock);
85062306a36Sopenharmony_ci		list_for_each_entry(be, head, list) {
85162306a36Sopenharmony_ci			if (be->bio != *bio)
85262306a36Sopenharmony_ci				continue;
85362306a36Sopenharmony_ci
85462306a36Sopenharmony_ci			found = true;
85562306a36Sopenharmony_ci
85662306a36Sopenharmony_ci			f2fs_bug_on(sbi, !page_is_mergeable(sbi, *bio,
85762306a36Sopenharmony_ci							    *fio->last_block,
85862306a36Sopenharmony_ci							    fio->new_blkaddr));
85962306a36Sopenharmony_ci			if (f2fs_crypt_mergeable_bio(*bio,
86062306a36Sopenharmony_ci					fio->page->mapping->host,
86162306a36Sopenharmony_ci					fio->page->index, fio) &&
86262306a36Sopenharmony_ci			    bio_add_page(*bio, page, PAGE_SIZE, 0) ==
86362306a36Sopenharmony_ci					PAGE_SIZE) {
86462306a36Sopenharmony_ci				ret = 0;
86562306a36Sopenharmony_ci				break;
86662306a36Sopenharmony_ci			}
86762306a36Sopenharmony_ci
86862306a36Sopenharmony_ci			/* page can't be merged into bio; submit the bio */
86962306a36Sopenharmony_ci			del_bio_entry(be);
87062306a36Sopenharmony_ci			f2fs_submit_write_bio(sbi, *bio, DATA);
87162306a36Sopenharmony_ci			break;
87262306a36Sopenharmony_ci		}
87362306a36Sopenharmony_ci		f2fs_up_write(&io->bio_list_lock);
87462306a36Sopenharmony_ci	}
87562306a36Sopenharmony_ci
87662306a36Sopenharmony_ci	if (ret) {
87762306a36Sopenharmony_ci		bio_put(*bio);
87862306a36Sopenharmony_ci		*bio = NULL;
87962306a36Sopenharmony_ci	}
88062306a36Sopenharmony_ci
88162306a36Sopenharmony_ci	return ret;
88262306a36Sopenharmony_ci}
88362306a36Sopenharmony_ci
88462306a36Sopenharmony_civoid f2fs_submit_merged_ipu_write(struct f2fs_sb_info *sbi,
88562306a36Sopenharmony_ci					struct bio **bio, struct page *page)
88662306a36Sopenharmony_ci{
88762306a36Sopenharmony_ci	enum temp_type temp;
88862306a36Sopenharmony_ci	bool found = false;
88962306a36Sopenharmony_ci	struct bio *target = bio ? *bio : NULL;
89062306a36Sopenharmony_ci
89162306a36Sopenharmony_ci	f2fs_bug_on(sbi, !target && !page);
89262306a36Sopenharmony_ci
89362306a36Sopenharmony_ci	for (temp = HOT; temp < NR_TEMP_TYPE && !found; temp++) {
89462306a36Sopenharmony_ci		struct f2fs_bio_info *io = sbi->write_io[DATA] + temp;
89562306a36Sopenharmony_ci		struct list_head *head = &io->bio_list;
89662306a36Sopenharmony_ci		struct bio_entry *be;
89762306a36Sopenharmony_ci
89862306a36Sopenharmony_ci		if (list_empty(head))
89962306a36Sopenharmony_ci			continue;
90062306a36Sopenharmony_ci
90162306a36Sopenharmony_ci		f2fs_down_read(&io->bio_list_lock);
90262306a36Sopenharmony_ci		list_for_each_entry(be, head, list) {
90362306a36Sopenharmony_ci			if (target)
90462306a36Sopenharmony_ci				found = (target == be->bio);
90562306a36Sopenharmony_ci			else
90662306a36Sopenharmony_ci				found = __has_merged_page(be->bio, NULL,
90762306a36Sopenharmony_ci								page, 0);
90862306a36Sopenharmony_ci			if (found)
90962306a36Sopenharmony_ci				break;
91062306a36Sopenharmony_ci		}
91162306a36Sopenharmony_ci		f2fs_up_read(&io->bio_list_lock);
91262306a36Sopenharmony_ci
91362306a36Sopenharmony_ci		if (!found)
91462306a36Sopenharmony_ci			continue;
91562306a36Sopenharmony_ci
91662306a36Sopenharmony_ci		found = false;
91762306a36Sopenharmony_ci
91862306a36Sopenharmony_ci		f2fs_down_write(&io->bio_list_lock);
91962306a36Sopenharmony_ci		list_for_each_entry(be, head, list) {
92062306a36Sopenharmony_ci			if (target)
92162306a36Sopenharmony_ci				found = (target == be->bio);
92262306a36Sopenharmony_ci			else
92362306a36Sopenharmony_ci				found = __has_merged_page(be->bio, NULL,
92462306a36Sopenharmony_ci								page, 0);
92562306a36Sopenharmony_ci			if (found) {
92662306a36Sopenharmony_ci				target = be->bio;
92762306a36Sopenharmony_ci				del_bio_entry(be);
92862306a36Sopenharmony_ci				break;
92962306a36Sopenharmony_ci			}
93062306a36Sopenharmony_ci		}
93162306a36Sopenharmony_ci		f2fs_up_write(&io->bio_list_lock);
93262306a36Sopenharmony_ci	}
93362306a36Sopenharmony_ci
93462306a36Sopenharmony_ci	if (found)
93562306a36Sopenharmony_ci		f2fs_submit_write_bio(sbi, target, DATA);
93662306a36Sopenharmony_ci	if (bio && *bio) {
93762306a36Sopenharmony_ci		bio_put(*bio);
93862306a36Sopenharmony_ci		*bio = NULL;
93962306a36Sopenharmony_ci	}
94062306a36Sopenharmony_ci}
94162306a36Sopenharmony_ci
94262306a36Sopenharmony_ciint f2fs_merge_page_bio(struct f2fs_io_info *fio)
94362306a36Sopenharmony_ci{
94462306a36Sopenharmony_ci	struct bio *bio = *fio->bio;
94562306a36Sopenharmony_ci	struct page *page = fio->encrypted_page ?
94662306a36Sopenharmony_ci			fio->encrypted_page : fio->page;
94762306a36Sopenharmony_ci
94862306a36Sopenharmony_ci	if (!f2fs_is_valid_blkaddr(fio->sbi, fio->new_blkaddr,
94962306a36Sopenharmony_ci			__is_meta_io(fio) ? META_GENERIC : DATA_GENERIC)) {
95062306a36Sopenharmony_ci		f2fs_handle_error(fio->sbi, ERROR_INVALID_BLKADDR);
95162306a36Sopenharmony_ci		return -EFSCORRUPTED;
95262306a36Sopenharmony_ci	}
95362306a36Sopenharmony_ci
95462306a36Sopenharmony_ci	trace_f2fs_submit_page_bio(page, fio);
95562306a36Sopenharmony_ci
95662306a36Sopenharmony_ci	if (bio && !page_is_mergeable(fio->sbi, bio, *fio->last_block,
95762306a36Sopenharmony_ci						fio->new_blkaddr))
95862306a36Sopenharmony_ci		f2fs_submit_merged_ipu_write(fio->sbi, &bio, NULL);
95962306a36Sopenharmony_cialloc_new:
96062306a36Sopenharmony_ci	if (!bio) {
96162306a36Sopenharmony_ci		bio = __bio_alloc(fio, BIO_MAX_VECS);
96262306a36Sopenharmony_ci		f2fs_set_bio_crypt_ctx(bio, fio->page->mapping->host,
96362306a36Sopenharmony_ci				       fio->page->index, fio, GFP_NOIO);
96462306a36Sopenharmony_ci
96562306a36Sopenharmony_ci		add_bio_entry(fio->sbi, bio, page, fio->temp);
96662306a36Sopenharmony_ci	} else {
96762306a36Sopenharmony_ci		if (add_ipu_page(fio, &bio, page))
96862306a36Sopenharmony_ci			goto alloc_new;
96962306a36Sopenharmony_ci	}
97062306a36Sopenharmony_ci
97162306a36Sopenharmony_ci	if (fio->io_wbc)
97262306a36Sopenharmony_ci		wbc_account_cgroup_owner(fio->io_wbc, fio->page, PAGE_SIZE);
97362306a36Sopenharmony_ci
97462306a36Sopenharmony_ci	inc_page_count(fio->sbi, WB_DATA_TYPE(page, false));
97562306a36Sopenharmony_ci
97662306a36Sopenharmony_ci	*fio->last_block = fio->new_blkaddr;
97762306a36Sopenharmony_ci	*fio->bio = bio;
97862306a36Sopenharmony_ci
97962306a36Sopenharmony_ci	return 0;
98062306a36Sopenharmony_ci}
98162306a36Sopenharmony_ci
98262306a36Sopenharmony_ci#ifdef CONFIG_BLK_DEV_ZONED
98362306a36Sopenharmony_cistatic bool is_end_zone_blkaddr(struct f2fs_sb_info *sbi, block_t blkaddr)
98462306a36Sopenharmony_ci{
98562306a36Sopenharmony_ci	int devi = 0;
98662306a36Sopenharmony_ci
98762306a36Sopenharmony_ci	if (f2fs_is_multi_device(sbi)) {
98862306a36Sopenharmony_ci		devi = f2fs_target_device_index(sbi, blkaddr);
98962306a36Sopenharmony_ci		if (blkaddr < FDEV(devi).start_blk ||
99062306a36Sopenharmony_ci		    blkaddr > FDEV(devi).end_blk) {
99162306a36Sopenharmony_ci			f2fs_err(sbi, "Invalid block %x", blkaddr);
99262306a36Sopenharmony_ci			return false;
99362306a36Sopenharmony_ci		}
99462306a36Sopenharmony_ci		blkaddr -= FDEV(devi).start_blk;
99562306a36Sopenharmony_ci	}
99662306a36Sopenharmony_ci	return bdev_zoned_model(FDEV(devi).bdev) == BLK_ZONED_HM &&
99762306a36Sopenharmony_ci		f2fs_blkz_is_seq(sbi, devi, blkaddr) &&
99862306a36Sopenharmony_ci		(blkaddr % sbi->blocks_per_blkz == sbi->blocks_per_blkz - 1);
99962306a36Sopenharmony_ci}
100062306a36Sopenharmony_ci#endif
100162306a36Sopenharmony_ci
100262306a36Sopenharmony_civoid f2fs_submit_page_write(struct f2fs_io_info *fio)
100362306a36Sopenharmony_ci{
100462306a36Sopenharmony_ci	struct f2fs_sb_info *sbi = fio->sbi;
100562306a36Sopenharmony_ci	enum page_type btype = PAGE_TYPE_OF_BIO(fio->type);
100662306a36Sopenharmony_ci	struct f2fs_bio_info *io = sbi->write_io[btype] + fio->temp;
100762306a36Sopenharmony_ci	struct page *bio_page;
100862306a36Sopenharmony_ci	enum count_type type;
100962306a36Sopenharmony_ci
101062306a36Sopenharmony_ci	f2fs_bug_on(sbi, is_read_io(fio->op));
101162306a36Sopenharmony_ci
101262306a36Sopenharmony_ci	f2fs_down_write(&io->io_rwsem);
101362306a36Sopenharmony_cinext:
101462306a36Sopenharmony_ci#ifdef CONFIG_BLK_DEV_ZONED
101562306a36Sopenharmony_ci	if (f2fs_sb_has_blkzoned(sbi) && btype < META && io->zone_pending_bio) {
101662306a36Sopenharmony_ci		wait_for_completion_io(&io->zone_wait);
101762306a36Sopenharmony_ci		bio_put(io->zone_pending_bio);
101862306a36Sopenharmony_ci		io->zone_pending_bio = NULL;
101962306a36Sopenharmony_ci		io->bi_private = NULL;
102062306a36Sopenharmony_ci	}
102162306a36Sopenharmony_ci#endif
102262306a36Sopenharmony_ci
102362306a36Sopenharmony_ci	if (fio->in_list) {
102462306a36Sopenharmony_ci		spin_lock(&io->io_lock);
102562306a36Sopenharmony_ci		if (list_empty(&io->io_list)) {
102662306a36Sopenharmony_ci			spin_unlock(&io->io_lock);
102762306a36Sopenharmony_ci			goto out;
102862306a36Sopenharmony_ci		}
102962306a36Sopenharmony_ci		fio = list_first_entry(&io->io_list,
103062306a36Sopenharmony_ci						struct f2fs_io_info, list);
103162306a36Sopenharmony_ci		list_del(&fio->list);
103262306a36Sopenharmony_ci		spin_unlock(&io->io_lock);
103362306a36Sopenharmony_ci	}
103462306a36Sopenharmony_ci
103562306a36Sopenharmony_ci	verify_fio_blkaddr(fio);
103662306a36Sopenharmony_ci
103762306a36Sopenharmony_ci	if (fio->encrypted_page)
103862306a36Sopenharmony_ci		bio_page = fio->encrypted_page;
103962306a36Sopenharmony_ci	else if (fio->compressed_page)
104062306a36Sopenharmony_ci		bio_page = fio->compressed_page;
104162306a36Sopenharmony_ci	else
104262306a36Sopenharmony_ci		bio_page = fio->page;
104362306a36Sopenharmony_ci
104462306a36Sopenharmony_ci	/* set submitted = true as a return value */
104562306a36Sopenharmony_ci	fio->submitted = 1;
104662306a36Sopenharmony_ci
104762306a36Sopenharmony_ci	type = WB_DATA_TYPE(bio_page, fio->compressed_page);
104862306a36Sopenharmony_ci	inc_page_count(sbi, type);
104962306a36Sopenharmony_ci
105062306a36Sopenharmony_ci	if (io->bio &&
105162306a36Sopenharmony_ci	    (!io_is_mergeable(sbi, io->bio, io, fio, io->last_block_in_bio,
105262306a36Sopenharmony_ci			      fio->new_blkaddr) ||
105362306a36Sopenharmony_ci	     !f2fs_crypt_mergeable_bio(io->bio, fio->page->mapping->host,
105462306a36Sopenharmony_ci				       bio_page->index, fio)))
105562306a36Sopenharmony_ci		__submit_merged_bio(io);
105662306a36Sopenharmony_cialloc_new:
105762306a36Sopenharmony_ci	if (io->bio == NULL) {
105862306a36Sopenharmony_ci		if (F2FS_IO_ALIGNED(sbi) &&
105962306a36Sopenharmony_ci				(fio->type == DATA || fio->type == NODE) &&
106062306a36Sopenharmony_ci				fio->new_blkaddr & F2FS_IO_SIZE_MASK(sbi)) {
106162306a36Sopenharmony_ci			dec_page_count(sbi, WB_DATA_TYPE(bio_page,
106262306a36Sopenharmony_ci						fio->compressed_page));
106362306a36Sopenharmony_ci			fio->retry = 1;
106462306a36Sopenharmony_ci			goto skip;
106562306a36Sopenharmony_ci		}
106662306a36Sopenharmony_ci		io->bio = __bio_alloc(fio, BIO_MAX_VECS);
106762306a36Sopenharmony_ci		f2fs_set_bio_crypt_ctx(io->bio, fio->page->mapping->host,
106862306a36Sopenharmony_ci				       bio_page->index, fio, GFP_NOIO);
106962306a36Sopenharmony_ci		io->fio = *fio;
107062306a36Sopenharmony_ci	}
107162306a36Sopenharmony_ci
107262306a36Sopenharmony_ci	if (bio_add_page(io->bio, bio_page, PAGE_SIZE, 0) < PAGE_SIZE) {
107362306a36Sopenharmony_ci		__submit_merged_bio(io);
107462306a36Sopenharmony_ci		goto alloc_new;
107562306a36Sopenharmony_ci	}
107662306a36Sopenharmony_ci
107762306a36Sopenharmony_ci	if (fio->io_wbc)
107862306a36Sopenharmony_ci		wbc_account_cgroup_owner(fio->io_wbc, fio->page, PAGE_SIZE);
107962306a36Sopenharmony_ci
108062306a36Sopenharmony_ci	io->last_block_in_bio = fio->new_blkaddr;
108162306a36Sopenharmony_ci
108262306a36Sopenharmony_ci	trace_f2fs_submit_page_write(fio->page, fio);
108362306a36Sopenharmony_ci#ifdef CONFIG_BLK_DEV_ZONED
108462306a36Sopenharmony_ci	if (f2fs_sb_has_blkzoned(sbi) && btype < META &&
108562306a36Sopenharmony_ci			is_end_zone_blkaddr(sbi, fio->new_blkaddr)) {
108662306a36Sopenharmony_ci		bio_get(io->bio);
108762306a36Sopenharmony_ci		reinit_completion(&io->zone_wait);
108862306a36Sopenharmony_ci		io->bi_private = io->bio->bi_private;
108962306a36Sopenharmony_ci		io->bio->bi_private = io;
109062306a36Sopenharmony_ci		io->bio->bi_end_io = f2fs_zone_write_end_io;
109162306a36Sopenharmony_ci		io->zone_pending_bio = io->bio;
109262306a36Sopenharmony_ci		__submit_merged_bio(io);
109362306a36Sopenharmony_ci	}
109462306a36Sopenharmony_ci#endif
109562306a36Sopenharmony_ciskip:
109662306a36Sopenharmony_ci	if (fio->in_list)
109762306a36Sopenharmony_ci		goto next;
109862306a36Sopenharmony_ciout:
109962306a36Sopenharmony_ci	if (is_sbi_flag_set(sbi, SBI_IS_SHUTDOWN) ||
110062306a36Sopenharmony_ci				!f2fs_is_checkpoint_ready(sbi))
110162306a36Sopenharmony_ci		__submit_merged_bio(io);
110262306a36Sopenharmony_ci	f2fs_up_write(&io->io_rwsem);
110362306a36Sopenharmony_ci}
110462306a36Sopenharmony_ci
110562306a36Sopenharmony_cistatic struct bio *f2fs_grab_read_bio(struct inode *inode, block_t blkaddr,
110662306a36Sopenharmony_ci				      unsigned nr_pages, blk_opf_t op_flag,
110762306a36Sopenharmony_ci				      pgoff_t first_idx, bool for_write)
110862306a36Sopenharmony_ci{
110962306a36Sopenharmony_ci	struct f2fs_sb_info *sbi = F2FS_I_SB(inode);
111062306a36Sopenharmony_ci	struct bio *bio;
111162306a36Sopenharmony_ci	struct bio_post_read_ctx *ctx = NULL;
111262306a36Sopenharmony_ci	unsigned int post_read_steps = 0;
111362306a36Sopenharmony_ci	sector_t sector;
111462306a36Sopenharmony_ci	struct block_device *bdev = f2fs_target_device(sbi, blkaddr, &sector);
111562306a36Sopenharmony_ci
111662306a36Sopenharmony_ci	bio = bio_alloc_bioset(bdev, bio_max_segs(nr_pages),
111762306a36Sopenharmony_ci			       REQ_OP_READ | op_flag,
111862306a36Sopenharmony_ci			       for_write ? GFP_NOIO : GFP_KERNEL, &f2fs_bioset);
111962306a36Sopenharmony_ci	if (!bio)
112062306a36Sopenharmony_ci		return ERR_PTR(-ENOMEM);
112162306a36Sopenharmony_ci	bio->bi_iter.bi_sector = sector;
112262306a36Sopenharmony_ci	f2fs_set_bio_crypt_ctx(bio, inode, first_idx, NULL, GFP_NOFS);
112362306a36Sopenharmony_ci	bio->bi_end_io = f2fs_read_end_io;
112462306a36Sopenharmony_ci
112562306a36Sopenharmony_ci	if (fscrypt_inode_uses_fs_layer_crypto(inode))
112662306a36Sopenharmony_ci		post_read_steps |= STEP_DECRYPT;
112762306a36Sopenharmony_ci
112862306a36Sopenharmony_ci	if (f2fs_need_verity(inode, first_idx))
112962306a36Sopenharmony_ci		post_read_steps |= STEP_VERITY;
113062306a36Sopenharmony_ci
113162306a36Sopenharmony_ci	/*
113262306a36Sopenharmony_ci	 * STEP_DECOMPRESS is handled specially, since a compressed file might
113362306a36Sopenharmony_ci	 * contain both compressed and uncompressed clusters.  We'll allocate a
113462306a36Sopenharmony_ci	 * bio_post_read_ctx if the file is compressed, but the caller is
113562306a36Sopenharmony_ci	 * responsible for enabling STEP_DECOMPRESS if it's actually needed.
113662306a36Sopenharmony_ci	 */
113762306a36Sopenharmony_ci
113862306a36Sopenharmony_ci	if (post_read_steps || f2fs_compressed_file(inode)) {
113962306a36Sopenharmony_ci		/* Due to the mempool, this never fails. */
114062306a36Sopenharmony_ci		ctx = mempool_alloc(bio_post_read_ctx_pool, GFP_NOFS);
114162306a36Sopenharmony_ci		ctx->bio = bio;
114262306a36Sopenharmony_ci		ctx->sbi = sbi;
114362306a36Sopenharmony_ci		ctx->enabled_steps = post_read_steps;
114462306a36Sopenharmony_ci		ctx->fs_blkaddr = blkaddr;
114562306a36Sopenharmony_ci		ctx->decompression_attempted = false;
114662306a36Sopenharmony_ci		bio->bi_private = ctx;
114762306a36Sopenharmony_ci	}
114862306a36Sopenharmony_ci	iostat_alloc_and_bind_ctx(sbi, bio, ctx);
114962306a36Sopenharmony_ci
115062306a36Sopenharmony_ci	return bio;
115162306a36Sopenharmony_ci}
115262306a36Sopenharmony_ci
115362306a36Sopenharmony_ci/* This can handle encryption stuffs */
115462306a36Sopenharmony_cistatic int f2fs_submit_page_read(struct inode *inode, struct page *page,
115562306a36Sopenharmony_ci				 block_t blkaddr, blk_opf_t op_flags,
115662306a36Sopenharmony_ci				 bool for_write)
115762306a36Sopenharmony_ci{
115862306a36Sopenharmony_ci	struct f2fs_sb_info *sbi = F2FS_I_SB(inode);
115962306a36Sopenharmony_ci	struct bio *bio;
116062306a36Sopenharmony_ci
116162306a36Sopenharmony_ci	bio = f2fs_grab_read_bio(inode, blkaddr, 1, op_flags,
116262306a36Sopenharmony_ci					page->index, for_write);
116362306a36Sopenharmony_ci	if (IS_ERR(bio))
116462306a36Sopenharmony_ci		return PTR_ERR(bio);
116562306a36Sopenharmony_ci
116662306a36Sopenharmony_ci	/* wait for GCed page writeback via META_MAPPING */
116762306a36Sopenharmony_ci	f2fs_wait_on_block_writeback(inode, blkaddr);
116862306a36Sopenharmony_ci
116962306a36Sopenharmony_ci	if (bio_add_page(bio, page, PAGE_SIZE, 0) < PAGE_SIZE) {
117062306a36Sopenharmony_ci		iostat_update_and_unbind_ctx(bio);
117162306a36Sopenharmony_ci		if (bio->bi_private)
117262306a36Sopenharmony_ci			mempool_free(bio->bi_private, bio_post_read_ctx_pool);
117362306a36Sopenharmony_ci		bio_put(bio);
117462306a36Sopenharmony_ci		return -EFAULT;
117562306a36Sopenharmony_ci	}
117662306a36Sopenharmony_ci	inc_page_count(sbi, F2FS_RD_DATA);
117762306a36Sopenharmony_ci	f2fs_update_iostat(sbi, NULL, FS_DATA_READ_IO, F2FS_BLKSIZE);
117862306a36Sopenharmony_ci	f2fs_submit_read_bio(sbi, bio, DATA);
117962306a36Sopenharmony_ci	return 0;
118062306a36Sopenharmony_ci}
118162306a36Sopenharmony_ci
118262306a36Sopenharmony_cistatic void __set_data_blkaddr(struct dnode_of_data *dn, block_t blkaddr)
118362306a36Sopenharmony_ci{
118462306a36Sopenharmony_ci	__le32 *addr = get_dnode_addr(dn->inode, dn->node_page);
118562306a36Sopenharmony_ci
118662306a36Sopenharmony_ci	dn->data_blkaddr = blkaddr;
118762306a36Sopenharmony_ci	addr[dn->ofs_in_node] = cpu_to_le32(dn->data_blkaddr);
118862306a36Sopenharmony_ci}
118962306a36Sopenharmony_ci
119062306a36Sopenharmony_ci/*
119162306a36Sopenharmony_ci * Lock ordering for the change of data block address:
119262306a36Sopenharmony_ci * ->data_page
119362306a36Sopenharmony_ci *  ->node_page
119462306a36Sopenharmony_ci *    update block addresses in the node page
119562306a36Sopenharmony_ci */
119662306a36Sopenharmony_civoid f2fs_set_data_blkaddr(struct dnode_of_data *dn, block_t blkaddr)
119762306a36Sopenharmony_ci{
119862306a36Sopenharmony_ci	f2fs_wait_on_page_writeback(dn->node_page, NODE, true, true);
119962306a36Sopenharmony_ci	__set_data_blkaddr(dn, blkaddr);
120062306a36Sopenharmony_ci	if (set_page_dirty(dn->node_page))
120162306a36Sopenharmony_ci		dn->node_changed = true;
120262306a36Sopenharmony_ci}
120362306a36Sopenharmony_ci
120462306a36Sopenharmony_civoid f2fs_update_data_blkaddr(struct dnode_of_data *dn, block_t blkaddr)
120562306a36Sopenharmony_ci{
120662306a36Sopenharmony_ci	f2fs_set_data_blkaddr(dn, blkaddr);
120762306a36Sopenharmony_ci	f2fs_update_read_extent_cache(dn);
120862306a36Sopenharmony_ci}
120962306a36Sopenharmony_ci
121062306a36Sopenharmony_ci/* dn->ofs_in_node will be returned with up-to-date last block pointer */
121162306a36Sopenharmony_ciint f2fs_reserve_new_blocks(struct dnode_of_data *dn, blkcnt_t count)
121262306a36Sopenharmony_ci{
121362306a36Sopenharmony_ci	struct f2fs_sb_info *sbi = F2FS_I_SB(dn->inode);
121462306a36Sopenharmony_ci	int err;
121562306a36Sopenharmony_ci
121662306a36Sopenharmony_ci	if (!count)
121762306a36Sopenharmony_ci		return 0;
121862306a36Sopenharmony_ci
121962306a36Sopenharmony_ci	if (unlikely(is_inode_flag_set(dn->inode, FI_NO_ALLOC)))
122062306a36Sopenharmony_ci		return -EPERM;
122162306a36Sopenharmony_ci	err = inc_valid_block_count(sbi, dn->inode, &count, true);
122262306a36Sopenharmony_ci	if (unlikely(err))
122362306a36Sopenharmony_ci		return err;
122462306a36Sopenharmony_ci
122562306a36Sopenharmony_ci	trace_f2fs_reserve_new_blocks(dn->inode, dn->nid,
122662306a36Sopenharmony_ci						dn->ofs_in_node, count);
122762306a36Sopenharmony_ci
122862306a36Sopenharmony_ci	f2fs_wait_on_page_writeback(dn->node_page, NODE, true, true);
122962306a36Sopenharmony_ci
123062306a36Sopenharmony_ci	for (; count > 0; dn->ofs_in_node++) {
123162306a36Sopenharmony_ci		block_t blkaddr = f2fs_data_blkaddr(dn);
123262306a36Sopenharmony_ci
123362306a36Sopenharmony_ci		if (blkaddr == NULL_ADDR) {
123462306a36Sopenharmony_ci			__set_data_blkaddr(dn, NEW_ADDR);
123562306a36Sopenharmony_ci			count--;
123662306a36Sopenharmony_ci		}
123762306a36Sopenharmony_ci	}
123862306a36Sopenharmony_ci
123962306a36Sopenharmony_ci	if (set_page_dirty(dn->node_page))
124062306a36Sopenharmony_ci		dn->node_changed = true;
124162306a36Sopenharmony_ci	return 0;
124262306a36Sopenharmony_ci}
124362306a36Sopenharmony_ci
124462306a36Sopenharmony_ci/* Should keep dn->ofs_in_node unchanged */
124562306a36Sopenharmony_ciint f2fs_reserve_new_block(struct dnode_of_data *dn)
124662306a36Sopenharmony_ci{
124762306a36Sopenharmony_ci	unsigned int ofs_in_node = dn->ofs_in_node;
124862306a36Sopenharmony_ci	int ret;
124962306a36Sopenharmony_ci
125062306a36Sopenharmony_ci	ret = f2fs_reserve_new_blocks(dn, 1);
125162306a36Sopenharmony_ci	dn->ofs_in_node = ofs_in_node;
125262306a36Sopenharmony_ci	return ret;
125362306a36Sopenharmony_ci}
125462306a36Sopenharmony_ci
125562306a36Sopenharmony_ciint f2fs_reserve_block(struct dnode_of_data *dn, pgoff_t index)
125662306a36Sopenharmony_ci{
125762306a36Sopenharmony_ci	bool need_put = dn->inode_page ? false : true;
125862306a36Sopenharmony_ci	int err;
125962306a36Sopenharmony_ci
126062306a36Sopenharmony_ci	err = f2fs_get_dnode_of_data(dn, index, ALLOC_NODE);
126162306a36Sopenharmony_ci	if (err)
126262306a36Sopenharmony_ci		return err;
126362306a36Sopenharmony_ci
126462306a36Sopenharmony_ci	if (dn->data_blkaddr == NULL_ADDR)
126562306a36Sopenharmony_ci		err = f2fs_reserve_new_block(dn);
126662306a36Sopenharmony_ci	if (err || need_put)
126762306a36Sopenharmony_ci		f2fs_put_dnode(dn);
126862306a36Sopenharmony_ci	return err;
126962306a36Sopenharmony_ci}
127062306a36Sopenharmony_ci
127162306a36Sopenharmony_cistruct page *f2fs_get_read_data_page(struct inode *inode, pgoff_t index,
127262306a36Sopenharmony_ci				     blk_opf_t op_flags, bool for_write,
127362306a36Sopenharmony_ci				     pgoff_t *next_pgofs)
127462306a36Sopenharmony_ci{
127562306a36Sopenharmony_ci	struct address_space *mapping = inode->i_mapping;
127662306a36Sopenharmony_ci	struct dnode_of_data dn;
127762306a36Sopenharmony_ci	struct page *page;
127862306a36Sopenharmony_ci	int err;
127962306a36Sopenharmony_ci
128062306a36Sopenharmony_ci	page = f2fs_grab_cache_page(mapping, index, for_write);
128162306a36Sopenharmony_ci	if (!page)
128262306a36Sopenharmony_ci		return ERR_PTR(-ENOMEM);
128362306a36Sopenharmony_ci
128462306a36Sopenharmony_ci	if (f2fs_lookup_read_extent_cache_block(inode, index,
128562306a36Sopenharmony_ci						&dn.data_blkaddr)) {
128662306a36Sopenharmony_ci		if (!f2fs_is_valid_blkaddr(F2FS_I_SB(inode), dn.data_blkaddr,
128762306a36Sopenharmony_ci						DATA_GENERIC_ENHANCE_READ)) {
128862306a36Sopenharmony_ci			err = -EFSCORRUPTED;
128962306a36Sopenharmony_ci			f2fs_handle_error(F2FS_I_SB(inode),
129062306a36Sopenharmony_ci						ERROR_INVALID_BLKADDR);
129162306a36Sopenharmony_ci			goto put_err;
129262306a36Sopenharmony_ci		}
129362306a36Sopenharmony_ci		goto got_it;
129462306a36Sopenharmony_ci	}
129562306a36Sopenharmony_ci
129662306a36Sopenharmony_ci	set_new_dnode(&dn, inode, NULL, NULL, 0);
129762306a36Sopenharmony_ci	err = f2fs_get_dnode_of_data(&dn, index, LOOKUP_NODE);
129862306a36Sopenharmony_ci	if (err) {
129962306a36Sopenharmony_ci		if (err == -ENOENT && next_pgofs)
130062306a36Sopenharmony_ci			*next_pgofs = f2fs_get_next_page_offset(&dn, index);
130162306a36Sopenharmony_ci		goto put_err;
130262306a36Sopenharmony_ci	}
130362306a36Sopenharmony_ci	f2fs_put_dnode(&dn);
130462306a36Sopenharmony_ci
130562306a36Sopenharmony_ci	if (unlikely(dn.data_blkaddr == NULL_ADDR)) {
130662306a36Sopenharmony_ci		err = -ENOENT;
130762306a36Sopenharmony_ci		if (next_pgofs)
130862306a36Sopenharmony_ci			*next_pgofs = index + 1;
130962306a36Sopenharmony_ci		goto put_err;
131062306a36Sopenharmony_ci	}
131162306a36Sopenharmony_ci	if (dn.data_blkaddr != NEW_ADDR &&
131262306a36Sopenharmony_ci			!f2fs_is_valid_blkaddr(F2FS_I_SB(inode),
131362306a36Sopenharmony_ci						dn.data_blkaddr,
131462306a36Sopenharmony_ci						DATA_GENERIC_ENHANCE)) {
131562306a36Sopenharmony_ci		err = -EFSCORRUPTED;
131662306a36Sopenharmony_ci		f2fs_handle_error(F2FS_I_SB(inode),
131762306a36Sopenharmony_ci					ERROR_INVALID_BLKADDR);
131862306a36Sopenharmony_ci		goto put_err;
131962306a36Sopenharmony_ci	}
132062306a36Sopenharmony_cigot_it:
132162306a36Sopenharmony_ci	if (PageUptodate(page)) {
132262306a36Sopenharmony_ci		unlock_page(page);
132362306a36Sopenharmony_ci		return page;
132462306a36Sopenharmony_ci	}
132562306a36Sopenharmony_ci
132662306a36Sopenharmony_ci	/*
132762306a36Sopenharmony_ci	 * A new dentry page is allocated but not able to be written, since its
132862306a36Sopenharmony_ci	 * new inode page couldn't be allocated due to -ENOSPC.
132962306a36Sopenharmony_ci	 * In such the case, its blkaddr can be remained as NEW_ADDR.
133062306a36Sopenharmony_ci	 * see, f2fs_add_link -> f2fs_get_new_data_page ->
133162306a36Sopenharmony_ci	 * f2fs_init_inode_metadata.
133262306a36Sopenharmony_ci	 */
133362306a36Sopenharmony_ci	if (dn.data_blkaddr == NEW_ADDR) {
133462306a36Sopenharmony_ci		zero_user_segment(page, 0, PAGE_SIZE);
133562306a36Sopenharmony_ci		if (!PageUptodate(page))
133662306a36Sopenharmony_ci			SetPageUptodate(page);
133762306a36Sopenharmony_ci		unlock_page(page);
133862306a36Sopenharmony_ci		return page;
133962306a36Sopenharmony_ci	}
134062306a36Sopenharmony_ci
134162306a36Sopenharmony_ci	err = f2fs_submit_page_read(inode, page, dn.data_blkaddr,
134262306a36Sopenharmony_ci						op_flags, for_write);
134362306a36Sopenharmony_ci	if (err)
134462306a36Sopenharmony_ci		goto put_err;
134562306a36Sopenharmony_ci	return page;
134662306a36Sopenharmony_ci
134762306a36Sopenharmony_ciput_err:
134862306a36Sopenharmony_ci	f2fs_put_page(page, 1);
134962306a36Sopenharmony_ci	return ERR_PTR(err);
135062306a36Sopenharmony_ci}
135162306a36Sopenharmony_ci
135262306a36Sopenharmony_cistruct page *f2fs_find_data_page(struct inode *inode, pgoff_t index,
135362306a36Sopenharmony_ci					pgoff_t *next_pgofs)
135462306a36Sopenharmony_ci{
135562306a36Sopenharmony_ci	struct address_space *mapping = inode->i_mapping;
135662306a36Sopenharmony_ci	struct page *page;
135762306a36Sopenharmony_ci
135862306a36Sopenharmony_ci	page = find_get_page(mapping, index);
135962306a36Sopenharmony_ci	if (page && PageUptodate(page))
136062306a36Sopenharmony_ci		return page;
136162306a36Sopenharmony_ci	f2fs_put_page(page, 0);
136262306a36Sopenharmony_ci
136362306a36Sopenharmony_ci	page = f2fs_get_read_data_page(inode, index, 0, false, next_pgofs);
136462306a36Sopenharmony_ci	if (IS_ERR(page))
136562306a36Sopenharmony_ci		return page;
136662306a36Sopenharmony_ci
136762306a36Sopenharmony_ci	if (PageUptodate(page))
136862306a36Sopenharmony_ci		return page;
136962306a36Sopenharmony_ci
137062306a36Sopenharmony_ci	wait_on_page_locked(page);
137162306a36Sopenharmony_ci	if (unlikely(!PageUptodate(page))) {
137262306a36Sopenharmony_ci		f2fs_put_page(page, 0);
137362306a36Sopenharmony_ci		return ERR_PTR(-EIO);
137462306a36Sopenharmony_ci	}
137562306a36Sopenharmony_ci	return page;
137662306a36Sopenharmony_ci}
137762306a36Sopenharmony_ci
137862306a36Sopenharmony_ci/*
137962306a36Sopenharmony_ci * If it tries to access a hole, return an error.
138062306a36Sopenharmony_ci * Because, the callers, functions in dir.c and GC, should be able to know
138162306a36Sopenharmony_ci * whether this page exists or not.
138262306a36Sopenharmony_ci */
138362306a36Sopenharmony_cistruct page *f2fs_get_lock_data_page(struct inode *inode, pgoff_t index,
138462306a36Sopenharmony_ci							bool for_write)
138562306a36Sopenharmony_ci{
138662306a36Sopenharmony_ci	struct address_space *mapping = inode->i_mapping;
138762306a36Sopenharmony_ci	struct page *page;
138862306a36Sopenharmony_ci
138962306a36Sopenharmony_ci	page = f2fs_get_read_data_page(inode, index, 0, for_write, NULL);
139062306a36Sopenharmony_ci	if (IS_ERR(page))
139162306a36Sopenharmony_ci		return page;
139262306a36Sopenharmony_ci
139362306a36Sopenharmony_ci	/* wait for read completion */
139462306a36Sopenharmony_ci	lock_page(page);
139562306a36Sopenharmony_ci	if (unlikely(page->mapping != mapping || !PageUptodate(page))) {
139662306a36Sopenharmony_ci		f2fs_put_page(page, 1);
139762306a36Sopenharmony_ci		return ERR_PTR(-EIO);
139862306a36Sopenharmony_ci	}
139962306a36Sopenharmony_ci	return page;
140062306a36Sopenharmony_ci}
140162306a36Sopenharmony_ci
140262306a36Sopenharmony_ci/*
140362306a36Sopenharmony_ci * Caller ensures that this data page is never allocated.
140462306a36Sopenharmony_ci * A new zero-filled data page is allocated in the page cache.
140562306a36Sopenharmony_ci *
140662306a36Sopenharmony_ci * Also, caller should grab and release a rwsem by calling f2fs_lock_op() and
140762306a36Sopenharmony_ci * f2fs_unlock_op().
140862306a36Sopenharmony_ci * Note that, ipage is set only by make_empty_dir, and if any error occur,
140962306a36Sopenharmony_ci * ipage should be released by this function.
141062306a36Sopenharmony_ci */
141162306a36Sopenharmony_cistruct page *f2fs_get_new_data_page(struct inode *inode,
141262306a36Sopenharmony_ci		struct page *ipage, pgoff_t index, bool new_i_size)
141362306a36Sopenharmony_ci{
141462306a36Sopenharmony_ci	struct address_space *mapping = inode->i_mapping;
141562306a36Sopenharmony_ci	struct page *page;
141662306a36Sopenharmony_ci	struct dnode_of_data dn;
141762306a36Sopenharmony_ci	int err;
141862306a36Sopenharmony_ci
141962306a36Sopenharmony_ci	page = f2fs_grab_cache_page(mapping, index, true);
142062306a36Sopenharmony_ci	if (!page) {
142162306a36Sopenharmony_ci		/*
142262306a36Sopenharmony_ci		 * before exiting, we should make sure ipage will be released
142362306a36Sopenharmony_ci		 * if any error occur.
142462306a36Sopenharmony_ci		 */
142562306a36Sopenharmony_ci		f2fs_put_page(ipage, 1);
142662306a36Sopenharmony_ci		return ERR_PTR(-ENOMEM);
142762306a36Sopenharmony_ci	}
142862306a36Sopenharmony_ci
142962306a36Sopenharmony_ci	set_new_dnode(&dn, inode, ipage, NULL, 0);
143062306a36Sopenharmony_ci	err = f2fs_reserve_block(&dn, index);
143162306a36Sopenharmony_ci	if (err) {
143262306a36Sopenharmony_ci		f2fs_put_page(page, 1);
143362306a36Sopenharmony_ci		return ERR_PTR(err);
143462306a36Sopenharmony_ci	}
143562306a36Sopenharmony_ci	if (!ipage)
143662306a36Sopenharmony_ci		f2fs_put_dnode(&dn);
143762306a36Sopenharmony_ci
143862306a36Sopenharmony_ci	if (PageUptodate(page))
143962306a36Sopenharmony_ci		goto got_it;
144062306a36Sopenharmony_ci
144162306a36Sopenharmony_ci	if (dn.data_blkaddr == NEW_ADDR) {
144262306a36Sopenharmony_ci		zero_user_segment(page, 0, PAGE_SIZE);
144362306a36Sopenharmony_ci		if (!PageUptodate(page))
144462306a36Sopenharmony_ci			SetPageUptodate(page);
144562306a36Sopenharmony_ci	} else {
144662306a36Sopenharmony_ci		f2fs_put_page(page, 1);
144762306a36Sopenharmony_ci
144862306a36Sopenharmony_ci		/* if ipage exists, blkaddr should be NEW_ADDR */
144962306a36Sopenharmony_ci		f2fs_bug_on(F2FS_I_SB(inode), ipage);
145062306a36Sopenharmony_ci		page = f2fs_get_lock_data_page(inode, index, true);
145162306a36Sopenharmony_ci		if (IS_ERR(page))
145262306a36Sopenharmony_ci			return page;
145362306a36Sopenharmony_ci	}
145462306a36Sopenharmony_cigot_it:
145562306a36Sopenharmony_ci	if (new_i_size && i_size_read(inode) <
145662306a36Sopenharmony_ci				((loff_t)(index + 1) << PAGE_SHIFT))
145762306a36Sopenharmony_ci		f2fs_i_size_write(inode, ((loff_t)(index + 1) << PAGE_SHIFT));
145862306a36Sopenharmony_ci	return page;
145962306a36Sopenharmony_ci}
146062306a36Sopenharmony_ci
146162306a36Sopenharmony_cistatic int __allocate_data_block(struct dnode_of_data *dn, int seg_type)
146262306a36Sopenharmony_ci{
146362306a36Sopenharmony_ci	struct f2fs_sb_info *sbi = F2FS_I_SB(dn->inode);
146462306a36Sopenharmony_ci	struct f2fs_summary sum;
146562306a36Sopenharmony_ci	struct node_info ni;
146662306a36Sopenharmony_ci	block_t old_blkaddr;
146762306a36Sopenharmony_ci	blkcnt_t count = 1;
146862306a36Sopenharmony_ci	int err;
146962306a36Sopenharmony_ci
147062306a36Sopenharmony_ci	if (unlikely(is_inode_flag_set(dn->inode, FI_NO_ALLOC)))
147162306a36Sopenharmony_ci		return -EPERM;
147262306a36Sopenharmony_ci
147362306a36Sopenharmony_ci	err = f2fs_get_node_info(sbi, dn->nid, &ni, false);
147462306a36Sopenharmony_ci	if (err)
147562306a36Sopenharmony_ci		return err;
147662306a36Sopenharmony_ci
147762306a36Sopenharmony_ci	dn->data_blkaddr = f2fs_data_blkaddr(dn);
147862306a36Sopenharmony_ci	if (dn->data_blkaddr == NULL_ADDR) {
147962306a36Sopenharmony_ci		err = inc_valid_block_count(sbi, dn->inode, &count, true);
148062306a36Sopenharmony_ci		if (unlikely(err))
148162306a36Sopenharmony_ci			return err;
148262306a36Sopenharmony_ci	}
148362306a36Sopenharmony_ci
148462306a36Sopenharmony_ci	set_summary(&sum, dn->nid, dn->ofs_in_node, ni.version);
148562306a36Sopenharmony_ci	old_blkaddr = dn->data_blkaddr;
148662306a36Sopenharmony_ci	f2fs_allocate_data_block(sbi, NULL, old_blkaddr, &dn->data_blkaddr,
148762306a36Sopenharmony_ci				&sum, seg_type, NULL);
148862306a36Sopenharmony_ci	if (GET_SEGNO(sbi, old_blkaddr) != NULL_SEGNO)
148962306a36Sopenharmony_ci		f2fs_invalidate_internal_cache(sbi, old_blkaddr);
149062306a36Sopenharmony_ci
149162306a36Sopenharmony_ci	f2fs_update_data_blkaddr(dn, dn->data_blkaddr);
149262306a36Sopenharmony_ci	return 0;
149362306a36Sopenharmony_ci}
149462306a36Sopenharmony_ci
149562306a36Sopenharmony_cistatic void f2fs_map_lock(struct f2fs_sb_info *sbi, int flag)
149662306a36Sopenharmony_ci{
149762306a36Sopenharmony_ci	if (flag == F2FS_GET_BLOCK_PRE_AIO)
149862306a36Sopenharmony_ci		f2fs_down_read(&sbi->node_change);
149962306a36Sopenharmony_ci	else
150062306a36Sopenharmony_ci		f2fs_lock_op(sbi);
150162306a36Sopenharmony_ci}
150262306a36Sopenharmony_ci
150362306a36Sopenharmony_cistatic void f2fs_map_unlock(struct f2fs_sb_info *sbi, int flag)
150462306a36Sopenharmony_ci{
150562306a36Sopenharmony_ci	if (flag == F2FS_GET_BLOCK_PRE_AIO)
150662306a36Sopenharmony_ci		f2fs_up_read(&sbi->node_change);
150762306a36Sopenharmony_ci	else
150862306a36Sopenharmony_ci		f2fs_unlock_op(sbi);
150962306a36Sopenharmony_ci}
151062306a36Sopenharmony_ci
151162306a36Sopenharmony_ciint f2fs_get_block_locked(struct dnode_of_data *dn, pgoff_t index)
151262306a36Sopenharmony_ci{
151362306a36Sopenharmony_ci	struct f2fs_sb_info *sbi = F2FS_I_SB(dn->inode);
151462306a36Sopenharmony_ci	int err = 0;
151562306a36Sopenharmony_ci
151662306a36Sopenharmony_ci	f2fs_map_lock(sbi, F2FS_GET_BLOCK_PRE_AIO);
151762306a36Sopenharmony_ci	if (!f2fs_lookup_read_extent_cache_block(dn->inode, index,
151862306a36Sopenharmony_ci						&dn->data_blkaddr))
151962306a36Sopenharmony_ci		err = f2fs_reserve_block(dn, index);
152062306a36Sopenharmony_ci	f2fs_map_unlock(sbi, F2FS_GET_BLOCK_PRE_AIO);
152162306a36Sopenharmony_ci
152262306a36Sopenharmony_ci	return err;
152362306a36Sopenharmony_ci}
152462306a36Sopenharmony_ci
152562306a36Sopenharmony_cistatic int f2fs_map_no_dnode(struct inode *inode,
152662306a36Sopenharmony_ci		struct f2fs_map_blocks *map, struct dnode_of_data *dn,
152762306a36Sopenharmony_ci		pgoff_t pgoff)
152862306a36Sopenharmony_ci{
152962306a36Sopenharmony_ci	struct f2fs_sb_info *sbi = F2FS_I_SB(inode);
153062306a36Sopenharmony_ci
153162306a36Sopenharmony_ci	/*
153262306a36Sopenharmony_ci	 * There is one exceptional case that read_node_page() may return
153362306a36Sopenharmony_ci	 * -ENOENT due to filesystem has been shutdown or cp_error, return
153462306a36Sopenharmony_ci	 * -EIO in that case.
153562306a36Sopenharmony_ci	 */
153662306a36Sopenharmony_ci	if (map->m_may_create &&
153762306a36Sopenharmony_ci	    (is_sbi_flag_set(sbi, SBI_IS_SHUTDOWN) || f2fs_cp_error(sbi)))
153862306a36Sopenharmony_ci		return -EIO;
153962306a36Sopenharmony_ci
154062306a36Sopenharmony_ci	if (map->m_next_pgofs)
154162306a36Sopenharmony_ci		*map->m_next_pgofs = f2fs_get_next_page_offset(dn, pgoff);
154262306a36Sopenharmony_ci	if (map->m_next_extent)
154362306a36Sopenharmony_ci		*map->m_next_extent = f2fs_get_next_page_offset(dn, pgoff);
154462306a36Sopenharmony_ci	return 0;
154562306a36Sopenharmony_ci}
154662306a36Sopenharmony_ci
154762306a36Sopenharmony_cistatic bool f2fs_map_blocks_cached(struct inode *inode,
154862306a36Sopenharmony_ci		struct f2fs_map_blocks *map, int flag)
154962306a36Sopenharmony_ci{
155062306a36Sopenharmony_ci	struct f2fs_sb_info *sbi = F2FS_I_SB(inode);
155162306a36Sopenharmony_ci	unsigned int maxblocks = map->m_len;
155262306a36Sopenharmony_ci	pgoff_t pgoff = (pgoff_t)map->m_lblk;
155362306a36Sopenharmony_ci	struct extent_info ei = {};
155462306a36Sopenharmony_ci
155562306a36Sopenharmony_ci	if (!f2fs_lookup_read_extent_cache(inode, pgoff, &ei))
155662306a36Sopenharmony_ci		return false;
155762306a36Sopenharmony_ci
155862306a36Sopenharmony_ci	map->m_pblk = ei.blk + pgoff - ei.fofs;
155962306a36Sopenharmony_ci	map->m_len = min((pgoff_t)maxblocks, ei.fofs + ei.len - pgoff);
156062306a36Sopenharmony_ci	map->m_flags = F2FS_MAP_MAPPED;
156162306a36Sopenharmony_ci	if (map->m_next_extent)
156262306a36Sopenharmony_ci		*map->m_next_extent = pgoff + map->m_len;
156362306a36Sopenharmony_ci
156462306a36Sopenharmony_ci	/* for hardware encryption, but to avoid potential issue in future */
156562306a36Sopenharmony_ci	if (flag == F2FS_GET_BLOCK_DIO)
156662306a36Sopenharmony_ci		f2fs_wait_on_block_writeback_range(inode,
156762306a36Sopenharmony_ci					map->m_pblk, map->m_len);
156862306a36Sopenharmony_ci
156962306a36Sopenharmony_ci	if (f2fs_allow_multi_device_dio(sbi, flag)) {
157062306a36Sopenharmony_ci		int bidx = f2fs_target_device_index(sbi, map->m_pblk);
157162306a36Sopenharmony_ci		struct f2fs_dev_info *dev = &sbi->devs[bidx];
157262306a36Sopenharmony_ci
157362306a36Sopenharmony_ci		map->m_bdev = dev->bdev;
157462306a36Sopenharmony_ci		map->m_pblk -= dev->start_blk;
157562306a36Sopenharmony_ci		map->m_len = min(map->m_len, dev->end_blk + 1 - map->m_pblk);
157662306a36Sopenharmony_ci	} else {
157762306a36Sopenharmony_ci		map->m_bdev = inode->i_sb->s_bdev;
157862306a36Sopenharmony_ci	}
157962306a36Sopenharmony_ci	return true;
158062306a36Sopenharmony_ci}
158162306a36Sopenharmony_ci
158262306a36Sopenharmony_ci/*
158362306a36Sopenharmony_ci * f2fs_map_blocks() tries to find or build mapping relationship which
158462306a36Sopenharmony_ci * maps continuous logical blocks to physical blocks, and return such
158562306a36Sopenharmony_ci * info via f2fs_map_blocks structure.
158662306a36Sopenharmony_ci */
158762306a36Sopenharmony_ciint f2fs_map_blocks(struct inode *inode, struct f2fs_map_blocks *map, int flag)
158862306a36Sopenharmony_ci{
158962306a36Sopenharmony_ci	unsigned int maxblocks = map->m_len;
159062306a36Sopenharmony_ci	struct dnode_of_data dn;
159162306a36Sopenharmony_ci	struct f2fs_sb_info *sbi = F2FS_I_SB(inode);
159262306a36Sopenharmony_ci	int mode = map->m_may_create ? ALLOC_NODE : LOOKUP_NODE;
159362306a36Sopenharmony_ci	pgoff_t pgofs, end_offset, end;
159462306a36Sopenharmony_ci	int err = 0, ofs = 1;
159562306a36Sopenharmony_ci	unsigned int ofs_in_node, last_ofs_in_node;
159662306a36Sopenharmony_ci	blkcnt_t prealloc;
159762306a36Sopenharmony_ci	block_t blkaddr;
159862306a36Sopenharmony_ci	unsigned int start_pgofs;
159962306a36Sopenharmony_ci	int bidx = 0;
160062306a36Sopenharmony_ci	bool is_hole;
160162306a36Sopenharmony_ci
160262306a36Sopenharmony_ci	if (!maxblocks)
160362306a36Sopenharmony_ci		return 0;
160462306a36Sopenharmony_ci
160562306a36Sopenharmony_ci	if (!map->m_may_create && f2fs_map_blocks_cached(inode, map, flag))
160662306a36Sopenharmony_ci		goto out;
160762306a36Sopenharmony_ci
160862306a36Sopenharmony_ci	map->m_bdev = inode->i_sb->s_bdev;
160962306a36Sopenharmony_ci	map->m_multidev_dio =
161062306a36Sopenharmony_ci		f2fs_allow_multi_device_dio(F2FS_I_SB(inode), flag);
161162306a36Sopenharmony_ci
161262306a36Sopenharmony_ci	map->m_len = 0;
161362306a36Sopenharmony_ci	map->m_flags = 0;
161462306a36Sopenharmony_ci
161562306a36Sopenharmony_ci	/* it only supports block size == page size */
161662306a36Sopenharmony_ci	pgofs =	(pgoff_t)map->m_lblk;
161762306a36Sopenharmony_ci	end = pgofs + maxblocks;
161862306a36Sopenharmony_ci
161962306a36Sopenharmony_cinext_dnode:
162062306a36Sopenharmony_ci	if (map->m_may_create)
162162306a36Sopenharmony_ci		f2fs_map_lock(sbi, flag);
162262306a36Sopenharmony_ci
162362306a36Sopenharmony_ci	/* When reading holes, we need its node page */
162462306a36Sopenharmony_ci	set_new_dnode(&dn, inode, NULL, NULL, 0);
162562306a36Sopenharmony_ci	err = f2fs_get_dnode_of_data(&dn, pgofs, mode);
162662306a36Sopenharmony_ci	if (err) {
162762306a36Sopenharmony_ci		if (flag == F2FS_GET_BLOCK_BMAP)
162862306a36Sopenharmony_ci			map->m_pblk = 0;
162962306a36Sopenharmony_ci		if (err == -ENOENT)
163062306a36Sopenharmony_ci			err = f2fs_map_no_dnode(inode, map, &dn, pgofs);
163162306a36Sopenharmony_ci		goto unlock_out;
163262306a36Sopenharmony_ci	}
163362306a36Sopenharmony_ci
163462306a36Sopenharmony_ci	start_pgofs = pgofs;
163562306a36Sopenharmony_ci	prealloc = 0;
163662306a36Sopenharmony_ci	last_ofs_in_node = ofs_in_node = dn.ofs_in_node;
163762306a36Sopenharmony_ci	end_offset = ADDRS_PER_PAGE(dn.node_page, inode);
163862306a36Sopenharmony_ci
163962306a36Sopenharmony_cinext_block:
164062306a36Sopenharmony_ci	blkaddr = f2fs_data_blkaddr(&dn);
164162306a36Sopenharmony_ci	is_hole = !__is_valid_data_blkaddr(blkaddr);
164262306a36Sopenharmony_ci	if (!is_hole &&
164362306a36Sopenharmony_ci	    !f2fs_is_valid_blkaddr(sbi, blkaddr, DATA_GENERIC_ENHANCE)) {
164462306a36Sopenharmony_ci		err = -EFSCORRUPTED;
164562306a36Sopenharmony_ci		f2fs_handle_error(sbi, ERROR_INVALID_BLKADDR);
164662306a36Sopenharmony_ci		goto sync_out;
164762306a36Sopenharmony_ci	}
164862306a36Sopenharmony_ci
164962306a36Sopenharmony_ci	/* use out-place-update for direct IO under LFS mode */
165062306a36Sopenharmony_ci	if (map->m_may_create &&
165162306a36Sopenharmony_ci	    (is_hole || (f2fs_lfs_mode(sbi) && flag == F2FS_GET_BLOCK_DIO))) {
165262306a36Sopenharmony_ci		if (unlikely(f2fs_cp_error(sbi))) {
165362306a36Sopenharmony_ci			err = -EIO;
165462306a36Sopenharmony_ci			goto sync_out;
165562306a36Sopenharmony_ci		}
165662306a36Sopenharmony_ci
165762306a36Sopenharmony_ci		switch (flag) {
165862306a36Sopenharmony_ci		case F2FS_GET_BLOCK_PRE_AIO:
165962306a36Sopenharmony_ci			if (blkaddr == NULL_ADDR) {
166062306a36Sopenharmony_ci				prealloc++;
166162306a36Sopenharmony_ci				last_ofs_in_node = dn.ofs_in_node;
166262306a36Sopenharmony_ci			}
166362306a36Sopenharmony_ci			break;
166462306a36Sopenharmony_ci		case F2FS_GET_BLOCK_PRE_DIO:
166562306a36Sopenharmony_ci		case F2FS_GET_BLOCK_DIO:
166662306a36Sopenharmony_ci			err = __allocate_data_block(&dn, map->m_seg_type);
166762306a36Sopenharmony_ci			if (err)
166862306a36Sopenharmony_ci				goto sync_out;
166962306a36Sopenharmony_ci			if (flag == F2FS_GET_BLOCK_PRE_DIO)
167062306a36Sopenharmony_ci				file_need_truncate(inode);
167162306a36Sopenharmony_ci			set_inode_flag(inode, FI_APPEND_WRITE);
167262306a36Sopenharmony_ci			break;
167362306a36Sopenharmony_ci		default:
167462306a36Sopenharmony_ci			WARN_ON_ONCE(1);
167562306a36Sopenharmony_ci			err = -EIO;
167662306a36Sopenharmony_ci			goto sync_out;
167762306a36Sopenharmony_ci		}
167862306a36Sopenharmony_ci
167962306a36Sopenharmony_ci		blkaddr = dn.data_blkaddr;
168062306a36Sopenharmony_ci		if (is_hole)
168162306a36Sopenharmony_ci			map->m_flags |= F2FS_MAP_NEW;
168262306a36Sopenharmony_ci	} else if (is_hole) {
168362306a36Sopenharmony_ci		if (f2fs_compressed_file(inode) &&
168462306a36Sopenharmony_ci		    f2fs_sanity_check_cluster(&dn) &&
168562306a36Sopenharmony_ci		    (flag != F2FS_GET_BLOCK_FIEMAP ||
168662306a36Sopenharmony_ci		     IS_ENABLED(CONFIG_F2FS_CHECK_FS))) {
168762306a36Sopenharmony_ci			err = -EFSCORRUPTED;
168862306a36Sopenharmony_ci			f2fs_handle_error(sbi,
168962306a36Sopenharmony_ci					ERROR_CORRUPTED_CLUSTER);
169062306a36Sopenharmony_ci			goto sync_out;
169162306a36Sopenharmony_ci		}
169262306a36Sopenharmony_ci
169362306a36Sopenharmony_ci		switch (flag) {
169462306a36Sopenharmony_ci		case F2FS_GET_BLOCK_PRECACHE:
169562306a36Sopenharmony_ci			goto sync_out;
169662306a36Sopenharmony_ci		case F2FS_GET_BLOCK_BMAP:
169762306a36Sopenharmony_ci			map->m_pblk = 0;
169862306a36Sopenharmony_ci			goto sync_out;
169962306a36Sopenharmony_ci		case F2FS_GET_BLOCK_FIEMAP:
170062306a36Sopenharmony_ci			if (blkaddr == NULL_ADDR) {
170162306a36Sopenharmony_ci				if (map->m_next_pgofs)
170262306a36Sopenharmony_ci					*map->m_next_pgofs = pgofs + 1;
170362306a36Sopenharmony_ci				goto sync_out;
170462306a36Sopenharmony_ci			}
170562306a36Sopenharmony_ci			break;
170662306a36Sopenharmony_ci		default:
170762306a36Sopenharmony_ci			/* for defragment case */
170862306a36Sopenharmony_ci			if (map->m_next_pgofs)
170962306a36Sopenharmony_ci				*map->m_next_pgofs = pgofs + 1;
171062306a36Sopenharmony_ci			goto sync_out;
171162306a36Sopenharmony_ci		}
171262306a36Sopenharmony_ci	}
171362306a36Sopenharmony_ci
171462306a36Sopenharmony_ci	if (flag == F2FS_GET_BLOCK_PRE_AIO)
171562306a36Sopenharmony_ci		goto skip;
171662306a36Sopenharmony_ci
171762306a36Sopenharmony_ci	if (map->m_multidev_dio)
171862306a36Sopenharmony_ci		bidx = f2fs_target_device_index(sbi, blkaddr);
171962306a36Sopenharmony_ci
172062306a36Sopenharmony_ci	if (map->m_len == 0) {
172162306a36Sopenharmony_ci		/* reserved delalloc block should be mapped for fiemap. */
172262306a36Sopenharmony_ci		if (blkaddr == NEW_ADDR)
172362306a36Sopenharmony_ci			map->m_flags |= F2FS_MAP_DELALLOC;
172462306a36Sopenharmony_ci		map->m_flags |= F2FS_MAP_MAPPED;
172562306a36Sopenharmony_ci
172662306a36Sopenharmony_ci		map->m_pblk = blkaddr;
172762306a36Sopenharmony_ci		map->m_len = 1;
172862306a36Sopenharmony_ci
172962306a36Sopenharmony_ci		if (map->m_multidev_dio)
173062306a36Sopenharmony_ci			map->m_bdev = FDEV(bidx).bdev;
173162306a36Sopenharmony_ci	} else if ((map->m_pblk != NEW_ADDR &&
173262306a36Sopenharmony_ci			blkaddr == (map->m_pblk + ofs)) ||
173362306a36Sopenharmony_ci			(map->m_pblk == NEW_ADDR && blkaddr == NEW_ADDR) ||
173462306a36Sopenharmony_ci			flag == F2FS_GET_BLOCK_PRE_DIO) {
173562306a36Sopenharmony_ci		if (map->m_multidev_dio && map->m_bdev != FDEV(bidx).bdev)
173662306a36Sopenharmony_ci			goto sync_out;
173762306a36Sopenharmony_ci		ofs++;
173862306a36Sopenharmony_ci		map->m_len++;
173962306a36Sopenharmony_ci	} else {
174062306a36Sopenharmony_ci		goto sync_out;
174162306a36Sopenharmony_ci	}
174262306a36Sopenharmony_ci
174362306a36Sopenharmony_ciskip:
174462306a36Sopenharmony_ci	dn.ofs_in_node++;
174562306a36Sopenharmony_ci	pgofs++;
174662306a36Sopenharmony_ci
174762306a36Sopenharmony_ci	/* preallocate blocks in batch for one dnode page */
174862306a36Sopenharmony_ci	if (flag == F2FS_GET_BLOCK_PRE_AIO &&
174962306a36Sopenharmony_ci			(pgofs == end || dn.ofs_in_node == end_offset)) {
175062306a36Sopenharmony_ci
175162306a36Sopenharmony_ci		dn.ofs_in_node = ofs_in_node;
175262306a36Sopenharmony_ci		err = f2fs_reserve_new_blocks(&dn, prealloc);
175362306a36Sopenharmony_ci		if (err)
175462306a36Sopenharmony_ci			goto sync_out;
175562306a36Sopenharmony_ci
175662306a36Sopenharmony_ci		map->m_len += dn.ofs_in_node - ofs_in_node;
175762306a36Sopenharmony_ci		if (prealloc && dn.ofs_in_node != last_ofs_in_node + 1) {
175862306a36Sopenharmony_ci			err = -ENOSPC;
175962306a36Sopenharmony_ci			goto sync_out;
176062306a36Sopenharmony_ci		}
176162306a36Sopenharmony_ci		dn.ofs_in_node = end_offset;
176262306a36Sopenharmony_ci	}
176362306a36Sopenharmony_ci
176462306a36Sopenharmony_ci	if (pgofs >= end)
176562306a36Sopenharmony_ci		goto sync_out;
176662306a36Sopenharmony_ci	else if (dn.ofs_in_node < end_offset)
176762306a36Sopenharmony_ci		goto next_block;
176862306a36Sopenharmony_ci
176962306a36Sopenharmony_ci	if (flag == F2FS_GET_BLOCK_PRECACHE) {
177062306a36Sopenharmony_ci		if (map->m_flags & F2FS_MAP_MAPPED) {
177162306a36Sopenharmony_ci			unsigned int ofs = start_pgofs - map->m_lblk;
177262306a36Sopenharmony_ci
177362306a36Sopenharmony_ci			f2fs_update_read_extent_cache_range(&dn,
177462306a36Sopenharmony_ci				start_pgofs, map->m_pblk + ofs,
177562306a36Sopenharmony_ci				map->m_len - ofs);
177662306a36Sopenharmony_ci		}
177762306a36Sopenharmony_ci	}
177862306a36Sopenharmony_ci
177962306a36Sopenharmony_ci	f2fs_put_dnode(&dn);
178062306a36Sopenharmony_ci
178162306a36Sopenharmony_ci	if (map->m_may_create) {
178262306a36Sopenharmony_ci		f2fs_map_unlock(sbi, flag);
178362306a36Sopenharmony_ci		f2fs_balance_fs(sbi, dn.node_changed);
178462306a36Sopenharmony_ci	}
178562306a36Sopenharmony_ci	goto next_dnode;
178662306a36Sopenharmony_ci
178762306a36Sopenharmony_cisync_out:
178862306a36Sopenharmony_ci
178962306a36Sopenharmony_ci	if (flag == F2FS_GET_BLOCK_DIO && map->m_flags & F2FS_MAP_MAPPED) {
179062306a36Sopenharmony_ci		/*
179162306a36Sopenharmony_ci		 * for hardware encryption, but to avoid potential issue
179262306a36Sopenharmony_ci		 * in future
179362306a36Sopenharmony_ci		 */
179462306a36Sopenharmony_ci		f2fs_wait_on_block_writeback_range(inode,
179562306a36Sopenharmony_ci						map->m_pblk, map->m_len);
179662306a36Sopenharmony_ci
179762306a36Sopenharmony_ci		if (map->m_multidev_dio) {
179862306a36Sopenharmony_ci			block_t blk_addr = map->m_pblk;
179962306a36Sopenharmony_ci
180062306a36Sopenharmony_ci			bidx = f2fs_target_device_index(sbi, map->m_pblk);
180162306a36Sopenharmony_ci
180262306a36Sopenharmony_ci			map->m_bdev = FDEV(bidx).bdev;
180362306a36Sopenharmony_ci			map->m_pblk -= FDEV(bidx).start_blk;
180462306a36Sopenharmony_ci
180562306a36Sopenharmony_ci			if (map->m_may_create)
180662306a36Sopenharmony_ci				f2fs_update_device_state(sbi, inode->i_ino,
180762306a36Sopenharmony_ci							blk_addr, map->m_len);
180862306a36Sopenharmony_ci
180962306a36Sopenharmony_ci			f2fs_bug_on(sbi, blk_addr + map->m_len >
181062306a36Sopenharmony_ci						FDEV(bidx).end_blk + 1);
181162306a36Sopenharmony_ci		}
181262306a36Sopenharmony_ci	}
181362306a36Sopenharmony_ci
181462306a36Sopenharmony_ci	if (flag == F2FS_GET_BLOCK_PRECACHE) {
181562306a36Sopenharmony_ci		if (map->m_flags & F2FS_MAP_MAPPED) {
181662306a36Sopenharmony_ci			unsigned int ofs = start_pgofs - map->m_lblk;
181762306a36Sopenharmony_ci
181862306a36Sopenharmony_ci			f2fs_update_read_extent_cache_range(&dn,
181962306a36Sopenharmony_ci				start_pgofs, map->m_pblk + ofs,
182062306a36Sopenharmony_ci				map->m_len - ofs);
182162306a36Sopenharmony_ci		}
182262306a36Sopenharmony_ci		if (map->m_next_extent)
182362306a36Sopenharmony_ci			*map->m_next_extent = pgofs + 1;
182462306a36Sopenharmony_ci	}
182562306a36Sopenharmony_ci	f2fs_put_dnode(&dn);
182662306a36Sopenharmony_ciunlock_out:
182762306a36Sopenharmony_ci	if (map->m_may_create) {
182862306a36Sopenharmony_ci		f2fs_map_unlock(sbi, flag);
182962306a36Sopenharmony_ci		f2fs_balance_fs(sbi, dn.node_changed);
183062306a36Sopenharmony_ci	}
183162306a36Sopenharmony_ciout:
183262306a36Sopenharmony_ci	trace_f2fs_map_blocks(inode, map, flag, err);
183362306a36Sopenharmony_ci	return err;
183462306a36Sopenharmony_ci}
183562306a36Sopenharmony_ci
183662306a36Sopenharmony_cibool f2fs_overwrite_io(struct inode *inode, loff_t pos, size_t len)
183762306a36Sopenharmony_ci{
183862306a36Sopenharmony_ci	struct f2fs_map_blocks map;
183962306a36Sopenharmony_ci	block_t last_lblk;
184062306a36Sopenharmony_ci	int err;
184162306a36Sopenharmony_ci
184262306a36Sopenharmony_ci	if (pos + len > i_size_read(inode))
184362306a36Sopenharmony_ci		return false;
184462306a36Sopenharmony_ci
184562306a36Sopenharmony_ci	map.m_lblk = F2FS_BYTES_TO_BLK(pos);
184662306a36Sopenharmony_ci	map.m_next_pgofs = NULL;
184762306a36Sopenharmony_ci	map.m_next_extent = NULL;
184862306a36Sopenharmony_ci	map.m_seg_type = NO_CHECK_TYPE;
184962306a36Sopenharmony_ci	map.m_may_create = false;
185062306a36Sopenharmony_ci	last_lblk = F2FS_BLK_ALIGN(pos + len);
185162306a36Sopenharmony_ci
185262306a36Sopenharmony_ci	while (map.m_lblk < last_lblk) {
185362306a36Sopenharmony_ci		map.m_len = last_lblk - map.m_lblk;
185462306a36Sopenharmony_ci		err = f2fs_map_blocks(inode, &map, F2FS_GET_BLOCK_DEFAULT);
185562306a36Sopenharmony_ci		if (err || map.m_len == 0)
185662306a36Sopenharmony_ci			return false;
185762306a36Sopenharmony_ci		map.m_lblk += map.m_len;
185862306a36Sopenharmony_ci	}
185962306a36Sopenharmony_ci	return true;
186062306a36Sopenharmony_ci}
186162306a36Sopenharmony_ci
186262306a36Sopenharmony_cistatic inline u64 bytes_to_blks(struct inode *inode, u64 bytes)
186362306a36Sopenharmony_ci{
186462306a36Sopenharmony_ci	return (bytes >> inode->i_blkbits);
186562306a36Sopenharmony_ci}
186662306a36Sopenharmony_ci
186762306a36Sopenharmony_cistatic inline u64 blks_to_bytes(struct inode *inode, u64 blks)
186862306a36Sopenharmony_ci{
186962306a36Sopenharmony_ci	return (blks << inode->i_blkbits);
187062306a36Sopenharmony_ci}
187162306a36Sopenharmony_ci
187262306a36Sopenharmony_cistatic int f2fs_xattr_fiemap(struct inode *inode,
187362306a36Sopenharmony_ci				struct fiemap_extent_info *fieinfo)
187462306a36Sopenharmony_ci{
187562306a36Sopenharmony_ci	struct f2fs_sb_info *sbi = F2FS_I_SB(inode);
187662306a36Sopenharmony_ci	struct page *page;
187762306a36Sopenharmony_ci	struct node_info ni;
187862306a36Sopenharmony_ci	__u64 phys = 0, len;
187962306a36Sopenharmony_ci	__u32 flags;
188062306a36Sopenharmony_ci	nid_t xnid = F2FS_I(inode)->i_xattr_nid;
188162306a36Sopenharmony_ci	int err = 0;
188262306a36Sopenharmony_ci
188362306a36Sopenharmony_ci	if (f2fs_has_inline_xattr(inode)) {
188462306a36Sopenharmony_ci		int offset;
188562306a36Sopenharmony_ci
188662306a36Sopenharmony_ci		page = f2fs_grab_cache_page(NODE_MAPPING(sbi),
188762306a36Sopenharmony_ci						inode->i_ino, false);
188862306a36Sopenharmony_ci		if (!page)
188962306a36Sopenharmony_ci			return -ENOMEM;
189062306a36Sopenharmony_ci
189162306a36Sopenharmony_ci		err = f2fs_get_node_info(sbi, inode->i_ino, &ni, false);
189262306a36Sopenharmony_ci		if (err) {
189362306a36Sopenharmony_ci			f2fs_put_page(page, 1);
189462306a36Sopenharmony_ci			return err;
189562306a36Sopenharmony_ci		}
189662306a36Sopenharmony_ci
189762306a36Sopenharmony_ci		phys = blks_to_bytes(inode, ni.blk_addr);
189862306a36Sopenharmony_ci		offset = offsetof(struct f2fs_inode, i_addr) +
189962306a36Sopenharmony_ci					sizeof(__le32) * (DEF_ADDRS_PER_INODE -
190062306a36Sopenharmony_ci					get_inline_xattr_addrs(inode));
190162306a36Sopenharmony_ci
190262306a36Sopenharmony_ci		phys += offset;
190362306a36Sopenharmony_ci		len = inline_xattr_size(inode);
190462306a36Sopenharmony_ci
190562306a36Sopenharmony_ci		f2fs_put_page(page, 1);
190662306a36Sopenharmony_ci
190762306a36Sopenharmony_ci		flags = FIEMAP_EXTENT_DATA_INLINE | FIEMAP_EXTENT_NOT_ALIGNED;
190862306a36Sopenharmony_ci
190962306a36Sopenharmony_ci		if (!xnid)
191062306a36Sopenharmony_ci			flags |= FIEMAP_EXTENT_LAST;
191162306a36Sopenharmony_ci
191262306a36Sopenharmony_ci		err = fiemap_fill_next_extent(fieinfo, 0, phys, len, flags);
191362306a36Sopenharmony_ci		trace_f2fs_fiemap(inode, 0, phys, len, flags, err);
191462306a36Sopenharmony_ci		if (err)
191562306a36Sopenharmony_ci			return err;
191662306a36Sopenharmony_ci	}
191762306a36Sopenharmony_ci
191862306a36Sopenharmony_ci	if (xnid) {
191962306a36Sopenharmony_ci		page = f2fs_grab_cache_page(NODE_MAPPING(sbi), xnid, false);
192062306a36Sopenharmony_ci		if (!page)
192162306a36Sopenharmony_ci			return -ENOMEM;
192262306a36Sopenharmony_ci
192362306a36Sopenharmony_ci		err = f2fs_get_node_info(sbi, xnid, &ni, false);
192462306a36Sopenharmony_ci		if (err) {
192562306a36Sopenharmony_ci			f2fs_put_page(page, 1);
192662306a36Sopenharmony_ci			return err;
192762306a36Sopenharmony_ci		}
192862306a36Sopenharmony_ci
192962306a36Sopenharmony_ci		phys = blks_to_bytes(inode, ni.blk_addr);
193062306a36Sopenharmony_ci		len = inode->i_sb->s_blocksize;
193162306a36Sopenharmony_ci
193262306a36Sopenharmony_ci		f2fs_put_page(page, 1);
193362306a36Sopenharmony_ci
193462306a36Sopenharmony_ci		flags = FIEMAP_EXTENT_LAST;
193562306a36Sopenharmony_ci	}
193662306a36Sopenharmony_ci
193762306a36Sopenharmony_ci	if (phys) {
193862306a36Sopenharmony_ci		err = fiemap_fill_next_extent(fieinfo, 0, phys, len, flags);
193962306a36Sopenharmony_ci		trace_f2fs_fiemap(inode, 0, phys, len, flags, err);
194062306a36Sopenharmony_ci	}
194162306a36Sopenharmony_ci
194262306a36Sopenharmony_ci	return (err < 0 ? err : 0);
194362306a36Sopenharmony_ci}
194462306a36Sopenharmony_ci
194562306a36Sopenharmony_cistatic loff_t max_inode_blocks(struct inode *inode)
194662306a36Sopenharmony_ci{
194762306a36Sopenharmony_ci	loff_t result = ADDRS_PER_INODE(inode);
194862306a36Sopenharmony_ci	loff_t leaf_count = ADDRS_PER_BLOCK(inode);
194962306a36Sopenharmony_ci
195062306a36Sopenharmony_ci	/* two direct node blocks */
195162306a36Sopenharmony_ci	result += (leaf_count * 2);
195262306a36Sopenharmony_ci
195362306a36Sopenharmony_ci	/* two indirect node blocks */
195462306a36Sopenharmony_ci	leaf_count *= NIDS_PER_BLOCK;
195562306a36Sopenharmony_ci	result += (leaf_count * 2);
195662306a36Sopenharmony_ci
195762306a36Sopenharmony_ci	/* one double indirect node block */
195862306a36Sopenharmony_ci	leaf_count *= NIDS_PER_BLOCK;
195962306a36Sopenharmony_ci	result += leaf_count;
196062306a36Sopenharmony_ci
196162306a36Sopenharmony_ci	return result;
196262306a36Sopenharmony_ci}
196362306a36Sopenharmony_ci
196462306a36Sopenharmony_ciint f2fs_fiemap(struct inode *inode, struct fiemap_extent_info *fieinfo,
196562306a36Sopenharmony_ci		u64 start, u64 len)
196662306a36Sopenharmony_ci{
196762306a36Sopenharmony_ci	struct f2fs_map_blocks map;
196862306a36Sopenharmony_ci	sector_t start_blk, last_blk;
196962306a36Sopenharmony_ci	pgoff_t next_pgofs;
197062306a36Sopenharmony_ci	u64 logical = 0, phys = 0, size = 0;
197162306a36Sopenharmony_ci	u32 flags = 0;
197262306a36Sopenharmony_ci	int ret = 0;
197362306a36Sopenharmony_ci	bool compr_cluster = false, compr_appended;
197462306a36Sopenharmony_ci	unsigned int cluster_size = F2FS_I(inode)->i_cluster_size;
197562306a36Sopenharmony_ci	unsigned int count_in_cluster = 0;
197662306a36Sopenharmony_ci	loff_t maxbytes;
197762306a36Sopenharmony_ci
197862306a36Sopenharmony_ci	if (fieinfo->fi_flags & FIEMAP_FLAG_CACHE) {
197962306a36Sopenharmony_ci		ret = f2fs_precache_extents(inode);
198062306a36Sopenharmony_ci		if (ret)
198162306a36Sopenharmony_ci			return ret;
198262306a36Sopenharmony_ci	}
198362306a36Sopenharmony_ci
198462306a36Sopenharmony_ci	ret = fiemap_prep(inode, fieinfo, start, &len, FIEMAP_FLAG_XATTR);
198562306a36Sopenharmony_ci	if (ret)
198662306a36Sopenharmony_ci		return ret;
198762306a36Sopenharmony_ci
198862306a36Sopenharmony_ci	inode_lock(inode);
198962306a36Sopenharmony_ci
199062306a36Sopenharmony_ci	maxbytes = max_file_blocks(inode) << F2FS_BLKSIZE_BITS;
199162306a36Sopenharmony_ci	if (start > maxbytes) {
199262306a36Sopenharmony_ci		ret = -EFBIG;
199362306a36Sopenharmony_ci		goto out;
199462306a36Sopenharmony_ci	}
199562306a36Sopenharmony_ci
199662306a36Sopenharmony_ci	if (len > maxbytes || (maxbytes - len) < start)
199762306a36Sopenharmony_ci		len = maxbytes - start;
199862306a36Sopenharmony_ci
199962306a36Sopenharmony_ci	if (fieinfo->fi_flags & FIEMAP_FLAG_XATTR) {
200062306a36Sopenharmony_ci		ret = f2fs_xattr_fiemap(inode, fieinfo);
200162306a36Sopenharmony_ci		goto out;
200262306a36Sopenharmony_ci	}
200362306a36Sopenharmony_ci
200462306a36Sopenharmony_ci	if (f2fs_has_inline_data(inode) || f2fs_has_inline_dentry(inode)) {
200562306a36Sopenharmony_ci		ret = f2fs_inline_data_fiemap(inode, fieinfo, start, len);
200662306a36Sopenharmony_ci		if (ret != -EAGAIN)
200762306a36Sopenharmony_ci			goto out;
200862306a36Sopenharmony_ci	}
200962306a36Sopenharmony_ci
201062306a36Sopenharmony_ci	if (bytes_to_blks(inode, len) == 0)
201162306a36Sopenharmony_ci		len = blks_to_bytes(inode, 1);
201262306a36Sopenharmony_ci
201362306a36Sopenharmony_ci	start_blk = bytes_to_blks(inode, start);
201462306a36Sopenharmony_ci	last_blk = bytes_to_blks(inode, start + len - 1);
201562306a36Sopenharmony_ci
201662306a36Sopenharmony_cinext:
201762306a36Sopenharmony_ci	memset(&map, 0, sizeof(map));
201862306a36Sopenharmony_ci	map.m_lblk = start_blk;
201962306a36Sopenharmony_ci	map.m_len = bytes_to_blks(inode, len);
202062306a36Sopenharmony_ci	map.m_next_pgofs = &next_pgofs;
202162306a36Sopenharmony_ci	map.m_seg_type = NO_CHECK_TYPE;
202262306a36Sopenharmony_ci
202362306a36Sopenharmony_ci	if (compr_cluster) {
202462306a36Sopenharmony_ci		map.m_lblk += 1;
202562306a36Sopenharmony_ci		map.m_len = cluster_size - count_in_cluster;
202662306a36Sopenharmony_ci	}
202762306a36Sopenharmony_ci
202862306a36Sopenharmony_ci	ret = f2fs_map_blocks(inode, &map, F2FS_GET_BLOCK_FIEMAP);
202962306a36Sopenharmony_ci	if (ret)
203062306a36Sopenharmony_ci		goto out;
203162306a36Sopenharmony_ci
203262306a36Sopenharmony_ci	/* HOLE */
203362306a36Sopenharmony_ci	if (!compr_cluster && !(map.m_flags & F2FS_MAP_FLAGS)) {
203462306a36Sopenharmony_ci		start_blk = next_pgofs;
203562306a36Sopenharmony_ci
203662306a36Sopenharmony_ci		if (blks_to_bytes(inode, start_blk) < blks_to_bytes(inode,
203762306a36Sopenharmony_ci						max_inode_blocks(inode)))
203862306a36Sopenharmony_ci			goto prep_next;
203962306a36Sopenharmony_ci
204062306a36Sopenharmony_ci		flags |= FIEMAP_EXTENT_LAST;
204162306a36Sopenharmony_ci	}
204262306a36Sopenharmony_ci
204362306a36Sopenharmony_ci	compr_appended = false;
204462306a36Sopenharmony_ci	/* In a case of compressed cluster, append this to the last extent */
204562306a36Sopenharmony_ci	if (compr_cluster && ((map.m_flags & F2FS_MAP_DELALLOC) ||
204662306a36Sopenharmony_ci			!(map.m_flags & F2FS_MAP_FLAGS))) {
204762306a36Sopenharmony_ci		compr_appended = true;
204862306a36Sopenharmony_ci		goto skip_fill;
204962306a36Sopenharmony_ci	}
205062306a36Sopenharmony_ci
205162306a36Sopenharmony_ci	if (size) {
205262306a36Sopenharmony_ci		flags |= FIEMAP_EXTENT_MERGED;
205362306a36Sopenharmony_ci		if (IS_ENCRYPTED(inode))
205462306a36Sopenharmony_ci			flags |= FIEMAP_EXTENT_DATA_ENCRYPTED;
205562306a36Sopenharmony_ci
205662306a36Sopenharmony_ci		ret = fiemap_fill_next_extent(fieinfo, logical,
205762306a36Sopenharmony_ci				phys, size, flags);
205862306a36Sopenharmony_ci		trace_f2fs_fiemap(inode, logical, phys, size, flags, ret);
205962306a36Sopenharmony_ci		if (ret)
206062306a36Sopenharmony_ci			goto out;
206162306a36Sopenharmony_ci		size = 0;
206262306a36Sopenharmony_ci	}
206362306a36Sopenharmony_ci
206462306a36Sopenharmony_ci	if (start_blk > last_blk)
206562306a36Sopenharmony_ci		goto out;
206662306a36Sopenharmony_ci
206762306a36Sopenharmony_ciskip_fill:
206862306a36Sopenharmony_ci	if (map.m_pblk == COMPRESS_ADDR) {
206962306a36Sopenharmony_ci		compr_cluster = true;
207062306a36Sopenharmony_ci		count_in_cluster = 1;
207162306a36Sopenharmony_ci	} else if (compr_appended) {
207262306a36Sopenharmony_ci		unsigned int appended_blks = cluster_size -
207362306a36Sopenharmony_ci						count_in_cluster + 1;
207462306a36Sopenharmony_ci		size += blks_to_bytes(inode, appended_blks);
207562306a36Sopenharmony_ci		start_blk += appended_blks;
207662306a36Sopenharmony_ci		compr_cluster = false;
207762306a36Sopenharmony_ci	} else {
207862306a36Sopenharmony_ci		logical = blks_to_bytes(inode, start_blk);
207962306a36Sopenharmony_ci		phys = __is_valid_data_blkaddr(map.m_pblk) ?
208062306a36Sopenharmony_ci			blks_to_bytes(inode, map.m_pblk) : 0;
208162306a36Sopenharmony_ci		size = blks_to_bytes(inode, map.m_len);
208262306a36Sopenharmony_ci		flags = 0;
208362306a36Sopenharmony_ci
208462306a36Sopenharmony_ci		if (compr_cluster) {
208562306a36Sopenharmony_ci			flags = FIEMAP_EXTENT_ENCODED;
208662306a36Sopenharmony_ci			count_in_cluster += map.m_len;
208762306a36Sopenharmony_ci			if (count_in_cluster == cluster_size) {
208862306a36Sopenharmony_ci				compr_cluster = false;
208962306a36Sopenharmony_ci				size += blks_to_bytes(inode, 1);
209062306a36Sopenharmony_ci			}
209162306a36Sopenharmony_ci		} else if (map.m_flags & F2FS_MAP_DELALLOC) {
209262306a36Sopenharmony_ci			flags = FIEMAP_EXTENT_UNWRITTEN;
209362306a36Sopenharmony_ci		}
209462306a36Sopenharmony_ci
209562306a36Sopenharmony_ci		start_blk += bytes_to_blks(inode, size);
209662306a36Sopenharmony_ci	}
209762306a36Sopenharmony_ci
209862306a36Sopenharmony_ciprep_next:
209962306a36Sopenharmony_ci	cond_resched();
210062306a36Sopenharmony_ci	if (fatal_signal_pending(current))
210162306a36Sopenharmony_ci		ret = -EINTR;
210262306a36Sopenharmony_ci	else
210362306a36Sopenharmony_ci		goto next;
210462306a36Sopenharmony_ciout:
210562306a36Sopenharmony_ci	if (ret == 1)
210662306a36Sopenharmony_ci		ret = 0;
210762306a36Sopenharmony_ci
210862306a36Sopenharmony_ci	inode_unlock(inode);
210962306a36Sopenharmony_ci	return ret;
211062306a36Sopenharmony_ci}
211162306a36Sopenharmony_ci
211262306a36Sopenharmony_cistatic inline loff_t f2fs_readpage_limit(struct inode *inode)
211362306a36Sopenharmony_ci{
211462306a36Sopenharmony_ci	if (IS_ENABLED(CONFIG_FS_VERITY) && IS_VERITY(inode))
211562306a36Sopenharmony_ci		return inode->i_sb->s_maxbytes;
211662306a36Sopenharmony_ci
211762306a36Sopenharmony_ci	return i_size_read(inode);
211862306a36Sopenharmony_ci}
211962306a36Sopenharmony_ci
212062306a36Sopenharmony_cistatic int f2fs_read_single_page(struct inode *inode, struct page *page,
212162306a36Sopenharmony_ci					unsigned nr_pages,
212262306a36Sopenharmony_ci					struct f2fs_map_blocks *map,
212362306a36Sopenharmony_ci					struct bio **bio_ret,
212462306a36Sopenharmony_ci					sector_t *last_block_in_bio,
212562306a36Sopenharmony_ci					bool is_readahead)
212662306a36Sopenharmony_ci{
212762306a36Sopenharmony_ci	struct bio *bio = *bio_ret;
212862306a36Sopenharmony_ci	const unsigned blocksize = blks_to_bytes(inode, 1);
212962306a36Sopenharmony_ci	sector_t block_in_file;
213062306a36Sopenharmony_ci	sector_t last_block;
213162306a36Sopenharmony_ci	sector_t last_block_in_file;
213262306a36Sopenharmony_ci	sector_t block_nr;
213362306a36Sopenharmony_ci	int ret = 0;
213462306a36Sopenharmony_ci
213562306a36Sopenharmony_ci	block_in_file = (sector_t)page_index(page);
213662306a36Sopenharmony_ci	last_block = block_in_file + nr_pages;
213762306a36Sopenharmony_ci	last_block_in_file = bytes_to_blks(inode,
213862306a36Sopenharmony_ci			f2fs_readpage_limit(inode) + blocksize - 1);
213962306a36Sopenharmony_ci	if (last_block > last_block_in_file)
214062306a36Sopenharmony_ci		last_block = last_block_in_file;
214162306a36Sopenharmony_ci
214262306a36Sopenharmony_ci	/* just zeroing out page which is beyond EOF */
214362306a36Sopenharmony_ci	if (block_in_file >= last_block)
214462306a36Sopenharmony_ci		goto zero_out;
214562306a36Sopenharmony_ci	/*
214662306a36Sopenharmony_ci	 * Map blocks using the previous result first.
214762306a36Sopenharmony_ci	 */
214862306a36Sopenharmony_ci	if ((map->m_flags & F2FS_MAP_MAPPED) &&
214962306a36Sopenharmony_ci			block_in_file > map->m_lblk &&
215062306a36Sopenharmony_ci			block_in_file < (map->m_lblk + map->m_len))
215162306a36Sopenharmony_ci		goto got_it;
215262306a36Sopenharmony_ci
215362306a36Sopenharmony_ci	/*
215462306a36Sopenharmony_ci	 * Then do more f2fs_map_blocks() calls until we are
215562306a36Sopenharmony_ci	 * done with this page.
215662306a36Sopenharmony_ci	 */
215762306a36Sopenharmony_ci	map->m_lblk = block_in_file;
215862306a36Sopenharmony_ci	map->m_len = last_block - block_in_file;
215962306a36Sopenharmony_ci
216062306a36Sopenharmony_ci	ret = f2fs_map_blocks(inode, map, F2FS_GET_BLOCK_DEFAULT);
216162306a36Sopenharmony_ci	if (ret)
216262306a36Sopenharmony_ci		goto out;
216362306a36Sopenharmony_cigot_it:
216462306a36Sopenharmony_ci	if ((map->m_flags & F2FS_MAP_MAPPED)) {
216562306a36Sopenharmony_ci		block_nr = map->m_pblk + block_in_file - map->m_lblk;
216662306a36Sopenharmony_ci		SetPageMappedToDisk(page);
216762306a36Sopenharmony_ci
216862306a36Sopenharmony_ci		if (!f2fs_is_valid_blkaddr(F2FS_I_SB(inode), block_nr,
216962306a36Sopenharmony_ci						DATA_GENERIC_ENHANCE_READ)) {
217062306a36Sopenharmony_ci			ret = -EFSCORRUPTED;
217162306a36Sopenharmony_ci			f2fs_handle_error(F2FS_I_SB(inode),
217262306a36Sopenharmony_ci						ERROR_INVALID_BLKADDR);
217362306a36Sopenharmony_ci			goto out;
217462306a36Sopenharmony_ci		}
217562306a36Sopenharmony_ci	} else {
217662306a36Sopenharmony_cizero_out:
217762306a36Sopenharmony_ci		zero_user_segment(page, 0, PAGE_SIZE);
217862306a36Sopenharmony_ci		if (f2fs_need_verity(inode, page->index) &&
217962306a36Sopenharmony_ci		    !fsverity_verify_page(page)) {
218062306a36Sopenharmony_ci			ret = -EIO;
218162306a36Sopenharmony_ci			goto out;
218262306a36Sopenharmony_ci		}
218362306a36Sopenharmony_ci		if (!PageUptodate(page))
218462306a36Sopenharmony_ci			SetPageUptodate(page);
218562306a36Sopenharmony_ci		unlock_page(page);
218662306a36Sopenharmony_ci		goto out;
218762306a36Sopenharmony_ci	}
218862306a36Sopenharmony_ci
218962306a36Sopenharmony_ci	/*
219062306a36Sopenharmony_ci	 * This page will go to BIO.  Do we need to send this
219162306a36Sopenharmony_ci	 * BIO off first?
219262306a36Sopenharmony_ci	 */
219362306a36Sopenharmony_ci	if (bio && (!page_is_mergeable(F2FS_I_SB(inode), bio,
219462306a36Sopenharmony_ci				       *last_block_in_bio, block_nr) ||
219562306a36Sopenharmony_ci		    !f2fs_crypt_mergeable_bio(bio, inode, page->index, NULL))) {
219662306a36Sopenharmony_cisubmit_and_realloc:
219762306a36Sopenharmony_ci		f2fs_submit_read_bio(F2FS_I_SB(inode), bio, DATA);
219862306a36Sopenharmony_ci		bio = NULL;
219962306a36Sopenharmony_ci	}
220062306a36Sopenharmony_ci	if (bio == NULL) {
220162306a36Sopenharmony_ci		bio = f2fs_grab_read_bio(inode, block_nr, nr_pages,
220262306a36Sopenharmony_ci				is_readahead ? REQ_RAHEAD : 0, page->index,
220362306a36Sopenharmony_ci				false);
220462306a36Sopenharmony_ci		if (IS_ERR(bio)) {
220562306a36Sopenharmony_ci			ret = PTR_ERR(bio);
220662306a36Sopenharmony_ci			bio = NULL;
220762306a36Sopenharmony_ci			goto out;
220862306a36Sopenharmony_ci		}
220962306a36Sopenharmony_ci	}
221062306a36Sopenharmony_ci
221162306a36Sopenharmony_ci	/*
221262306a36Sopenharmony_ci	 * If the page is under writeback, we need to wait for
221362306a36Sopenharmony_ci	 * its completion to see the correct decrypted data.
221462306a36Sopenharmony_ci	 */
221562306a36Sopenharmony_ci	f2fs_wait_on_block_writeback(inode, block_nr);
221662306a36Sopenharmony_ci
221762306a36Sopenharmony_ci	if (bio_add_page(bio, page, blocksize, 0) < blocksize)
221862306a36Sopenharmony_ci		goto submit_and_realloc;
221962306a36Sopenharmony_ci
222062306a36Sopenharmony_ci	inc_page_count(F2FS_I_SB(inode), F2FS_RD_DATA);
222162306a36Sopenharmony_ci	f2fs_update_iostat(F2FS_I_SB(inode), NULL, FS_DATA_READ_IO,
222262306a36Sopenharmony_ci							F2FS_BLKSIZE);
222362306a36Sopenharmony_ci	*last_block_in_bio = block_nr;
222462306a36Sopenharmony_ciout:
222562306a36Sopenharmony_ci	*bio_ret = bio;
222662306a36Sopenharmony_ci	return ret;
222762306a36Sopenharmony_ci}
222862306a36Sopenharmony_ci
222962306a36Sopenharmony_ci#ifdef CONFIG_F2FS_FS_COMPRESSION
223062306a36Sopenharmony_ciint f2fs_read_multi_pages(struct compress_ctx *cc, struct bio **bio_ret,
223162306a36Sopenharmony_ci				unsigned nr_pages, sector_t *last_block_in_bio,
223262306a36Sopenharmony_ci				bool is_readahead, bool for_write)
223362306a36Sopenharmony_ci{
223462306a36Sopenharmony_ci	struct dnode_of_data dn;
223562306a36Sopenharmony_ci	struct inode *inode = cc->inode;
223662306a36Sopenharmony_ci	struct f2fs_sb_info *sbi = F2FS_I_SB(inode);
223762306a36Sopenharmony_ci	struct bio *bio = *bio_ret;
223862306a36Sopenharmony_ci	unsigned int start_idx = cc->cluster_idx << cc->log_cluster_size;
223962306a36Sopenharmony_ci	sector_t last_block_in_file;
224062306a36Sopenharmony_ci	const unsigned blocksize = blks_to_bytes(inode, 1);
224162306a36Sopenharmony_ci	struct decompress_io_ctx *dic = NULL;
224262306a36Sopenharmony_ci	struct extent_info ei = {};
224362306a36Sopenharmony_ci	bool from_dnode = true;
224462306a36Sopenharmony_ci	int i;
224562306a36Sopenharmony_ci	int ret = 0;
224662306a36Sopenharmony_ci
224762306a36Sopenharmony_ci	f2fs_bug_on(sbi, f2fs_cluster_is_empty(cc));
224862306a36Sopenharmony_ci
224962306a36Sopenharmony_ci	last_block_in_file = bytes_to_blks(inode,
225062306a36Sopenharmony_ci			f2fs_readpage_limit(inode) + blocksize - 1);
225162306a36Sopenharmony_ci
225262306a36Sopenharmony_ci	/* get rid of pages beyond EOF */
225362306a36Sopenharmony_ci	for (i = 0; i < cc->cluster_size; i++) {
225462306a36Sopenharmony_ci		struct page *page = cc->rpages[i];
225562306a36Sopenharmony_ci
225662306a36Sopenharmony_ci		if (!page)
225762306a36Sopenharmony_ci			continue;
225862306a36Sopenharmony_ci		if ((sector_t)page->index >= last_block_in_file) {
225962306a36Sopenharmony_ci			zero_user_segment(page, 0, PAGE_SIZE);
226062306a36Sopenharmony_ci			if (!PageUptodate(page))
226162306a36Sopenharmony_ci				SetPageUptodate(page);
226262306a36Sopenharmony_ci		} else if (!PageUptodate(page)) {
226362306a36Sopenharmony_ci			continue;
226462306a36Sopenharmony_ci		}
226562306a36Sopenharmony_ci		unlock_page(page);
226662306a36Sopenharmony_ci		if (for_write)
226762306a36Sopenharmony_ci			put_page(page);
226862306a36Sopenharmony_ci		cc->rpages[i] = NULL;
226962306a36Sopenharmony_ci		cc->nr_rpages--;
227062306a36Sopenharmony_ci	}
227162306a36Sopenharmony_ci
227262306a36Sopenharmony_ci	/* we are done since all pages are beyond EOF */
227362306a36Sopenharmony_ci	if (f2fs_cluster_is_empty(cc))
227462306a36Sopenharmony_ci		goto out;
227562306a36Sopenharmony_ci
227662306a36Sopenharmony_ci	if (f2fs_lookup_read_extent_cache(inode, start_idx, &ei))
227762306a36Sopenharmony_ci		from_dnode = false;
227862306a36Sopenharmony_ci
227962306a36Sopenharmony_ci	if (!from_dnode)
228062306a36Sopenharmony_ci		goto skip_reading_dnode;
228162306a36Sopenharmony_ci
228262306a36Sopenharmony_ci	set_new_dnode(&dn, inode, NULL, NULL, 0);
228362306a36Sopenharmony_ci	ret = f2fs_get_dnode_of_data(&dn, start_idx, LOOKUP_NODE);
228462306a36Sopenharmony_ci	if (ret)
228562306a36Sopenharmony_ci		goto out;
228662306a36Sopenharmony_ci
228762306a36Sopenharmony_ci	if (unlikely(f2fs_cp_error(sbi))) {
228862306a36Sopenharmony_ci		ret = -EIO;
228962306a36Sopenharmony_ci		goto out_put_dnode;
229062306a36Sopenharmony_ci	}
229162306a36Sopenharmony_ci	f2fs_bug_on(sbi, dn.data_blkaddr != COMPRESS_ADDR);
229262306a36Sopenharmony_ci
229362306a36Sopenharmony_ciskip_reading_dnode:
229462306a36Sopenharmony_ci	for (i = 1; i < cc->cluster_size; i++) {
229562306a36Sopenharmony_ci		block_t blkaddr;
229662306a36Sopenharmony_ci
229762306a36Sopenharmony_ci		blkaddr = from_dnode ? data_blkaddr(dn.inode, dn.node_page,
229862306a36Sopenharmony_ci					dn.ofs_in_node + i) :
229962306a36Sopenharmony_ci					ei.blk + i - 1;
230062306a36Sopenharmony_ci
230162306a36Sopenharmony_ci		if (!__is_valid_data_blkaddr(blkaddr))
230262306a36Sopenharmony_ci			break;
230362306a36Sopenharmony_ci
230462306a36Sopenharmony_ci		if (!f2fs_is_valid_blkaddr(sbi, blkaddr, DATA_GENERIC)) {
230562306a36Sopenharmony_ci			ret = -EFAULT;
230662306a36Sopenharmony_ci			goto out_put_dnode;
230762306a36Sopenharmony_ci		}
230862306a36Sopenharmony_ci		cc->nr_cpages++;
230962306a36Sopenharmony_ci
231062306a36Sopenharmony_ci		if (!from_dnode && i >= ei.c_len)
231162306a36Sopenharmony_ci			break;
231262306a36Sopenharmony_ci	}
231362306a36Sopenharmony_ci
231462306a36Sopenharmony_ci	/* nothing to decompress */
231562306a36Sopenharmony_ci	if (cc->nr_cpages == 0) {
231662306a36Sopenharmony_ci		ret = 0;
231762306a36Sopenharmony_ci		goto out_put_dnode;
231862306a36Sopenharmony_ci	}
231962306a36Sopenharmony_ci
232062306a36Sopenharmony_ci	dic = f2fs_alloc_dic(cc);
232162306a36Sopenharmony_ci	if (IS_ERR(dic)) {
232262306a36Sopenharmony_ci		ret = PTR_ERR(dic);
232362306a36Sopenharmony_ci		goto out_put_dnode;
232462306a36Sopenharmony_ci	}
232562306a36Sopenharmony_ci
232662306a36Sopenharmony_ci	for (i = 0; i < cc->nr_cpages; i++) {
232762306a36Sopenharmony_ci		struct page *page = dic->cpages[i];
232862306a36Sopenharmony_ci		block_t blkaddr;
232962306a36Sopenharmony_ci		struct bio_post_read_ctx *ctx;
233062306a36Sopenharmony_ci
233162306a36Sopenharmony_ci		blkaddr = from_dnode ? data_blkaddr(dn.inode, dn.node_page,
233262306a36Sopenharmony_ci					dn.ofs_in_node + i + 1) :
233362306a36Sopenharmony_ci					ei.blk + i;
233462306a36Sopenharmony_ci
233562306a36Sopenharmony_ci		f2fs_wait_on_block_writeback(inode, blkaddr);
233662306a36Sopenharmony_ci
233762306a36Sopenharmony_ci		if (f2fs_load_compressed_page(sbi, page, blkaddr)) {
233862306a36Sopenharmony_ci			if (atomic_dec_and_test(&dic->remaining_pages)) {
233962306a36Sopenharmony_ci				f2fs_decompress_cluster(dic, true);
234062306a36Sopenharmony_ci				break;
234162306a36Sopenharmony_ci			}
234262306a36Sopenharmony_ci			continue;
234362306a36Sopenharmony_ci		}
234462306a36Sopenharmony_ci
234562306a36Sopenharmony_ci		if (bio && (!page_is_mergeable(sbi, bio,
234662306a36Sopenharmony_ci					*last_block_in_bio, blkaddr) ||
234762306a36Sopenharmony_ci		    !f2fs_crypt_mergeable_bio(bio, inode, page->index, NULL))) {
234862306a36Sopenharmony_cisubmit_and_realloc:
234962306a36Sopenharmony_ci			f2fs_submit_read_bio(sbi, bio, DATA);
235062306a36Sopenharmony_ci			bio = NULL;
235162306a36Sopenharmony_ci		}
235262306a36Sopenharmony_ci
235362306a36Sopenharmony_ci		if (!bio) {
235462306a36Sopenharmony_ci			bio = f2fs_grab_read_bio(inode, blkaddr, nr_pages,
235562306a36Sopenharmony_ci					is_readahead ? REQ_RAHEAD : 0,
235662306a36Sopenharmony_ci					page->index, for_write);
235762306a36Sopenharmony_ci			if (IS_ERR(bio)) {
235862306a36Sopenharmony_ci				ret = PTR_ERR(bio);
235962306a36Sopenharmony_ci				f2fs_decompress_end_io(dic, ret, true);
236062306a36Sopenharmony_ci				f2fs_put_dnode(&dn);
236162306a36Sopenharmony_ci				*bio_ret = NULL;
236262306a36Sopenharmony_ci				return ret;
236362306a36Sopenharmony_ci			}
236462306a36Sopenharmony_ci		}
236562306a36Sopenharmony_ci
236662306a36Sopenharmony_ci		if (bio_add_page(bio, page, blocksize, 0) < blocksize)
236762306a36Sopenharmony_ci			goto submit_and_realloc;
236862306a36Sopenharmony_ci
236962306a36Sopenharmony_ci		ctx = get_post_read_ctx(bio);
237062306a36Sopenharmony_ci		ctx->enabled_steps |= STEP_DECOMPRESS;
237162306a36Sopenharmony_ci		refcount_inc(&dic->refcnt);
237262306a36Sopenharmony_ci
237362306a36Sopenharmony_ci		inc_page_count(sbi, F2FS_RD_DATA);
237462306a36Sopenharmony_ci		f2fs_update_iostat(sbi, inode, FS_DATA_READ_IO, F2FS_BLKSIZE);
237562306a36Sopenharmony_ci		*last_block_in_bio = blkaddr;
237662306a36Sopenharmony_ci	}
237762306a36Sopenharmony_ci
237862306a36Sopenharmony_ci	if (from_dnode)
237962306a36Sopenharmony_ci		f2fs_put_dnode(&dn);
238062306a36Sopenharmony_ci
238162306a36Sopenharmony_ci	*bio_ret = bio;
238262306a36Sopenharmony_ci	return 0;
238362306a36Sopenharmony_ci
238462306a36Sopenharmony_ciout_put_dnode:
238562306a36Sopenharmony_ci	if (from_dnode)
238662306a36Sopenharmony_ci		f2fs_put_dnode(&dn);
238762306a36Sopenharmony_ciout:
238862306a36Sopenharmony_ci	for (i = 0; i < cc->cluster_size; i++) {
238962306a36Sopenharmony_ci		if (cc->rpages[i]) {
239062306a36Sopenharmony_ci			ClearPageUptodate(cc->rpages[i]);
239162306a36Sopenharmony_ci			unlock_page(cc->rpages[i]);
239262306a36Sopenharmony_ci		}
239362306a36Sopenharmony_ci	}
239462306a36Sopenharmony_ci	*bio_ret = bio;
239562306a36Sopenharmony_ci	return ret;
239662306a36Sopenharmony_ci}
239762306a36Sopenharmony_ci#endif
239862306a36Sopenharmony_ci
239962306a36Sopenharmony_ci/*
240062306a36Sopenharmony_ci * This function was originally taken from fs/mpage.c, and customized for f2fs.
240162306a36Sopenharmony_ci * Major change was from block_size == page_size in f2fs by default.
240262306a36Sopenharmony_ci */
240362306a36Sopenharmony_cistatic int f2fs_mpage_readpages(struct inode *inode,
240462306a36Sopenharmony_ci		struct readahead_control *rac, struct page *page)
240562306a36Sopenharmony_ci{
240662306a36Sopenharmony_ci	struct bio *bio = NULL;
240762306a36Sopenharmony_ci	sector_t last_block_in_bio = 0;
240862306a36Sopenharmony_ci	struct f2fs_map_blocks map;
240962306a36Sopenharmony_ci#ifdef CONFIG_F2FS_FS_COMPRESSION
241062306a36Sopenharmony_ci	struct compress_ctx cc = {
241162306a36Sopenharmony_ci		.inode = inode,
241262306a36Sopenharmony_ci		.log_cluster_size = F2FS_I(inode)->i_log_cluster_size,
241362306a36Sopenharmony_ci		.cluster_size = F2FS_I(inode)->i_cluster_size,
241462306a36Sopenharmony_ci		.cluster_idx = NULL_CLUSTER,
241562306a36Sopenharmony_ci		.rpages = NULL,
241662306a36Sopenharmony_ci		.cpages = NULL,
241762306a36Sopenharmony_ci		.nr_rpages = 0,
241862306a36Sopenharmony_ci		.nr_cpages = 0,
241962306a36Sopenharmony_ci	};
242062306a36Sopenharmony_ci	pgoff_t nc_cluster_idx = NULL_CLUSTER;
242162306a36Sopenharmony_ci#endif
242262306a36Sopenharmony_ci	unsigned nr_pages = rac ? readahead_count(rac) : 1;
242362306a36Sopenharmony_ci	unsigned max_nr_pages = nr_pages;
242462306a36Sopenharmony_ci	int ret = 0;
242562306a36Sopenharmony_ci
242662306a36Sopenharmony_ci	map.m_pblk = 0;
242762306a36Sopenharmony_ci	map.m_lblk = 0;
242862306a36Sopenharmony_ci	map.m_len = 0;
242962306a36Sopenharmony_ci	map.m_flags = 0;
243062306a36Sopenharmony_ci	map.m_next_pgofs = NULL;
243162306a36Sopenharmony_ci	map.m_next_extent = NULL;
243262306a36Sopenharmony_ci	map.m_seg_type = NO_CHECK_TYPE;
243362306a36Sopenharmony_ci	map.m_may_create = false;
243462306a36Sopenharmony_ci
243562306a36Sopenharmony_ci	for (; nr_pages; nr_pages--) {
243662306a36Sopenharmony_ci		if (rac) {
243762306a36Sopenharmony_ci			page = readahead_page(rac);
243862306a36Sopenharmony_ci			prefetchw(&page->flags);
243962306a36Sopenharmony_ci		}
244062306a36Sopenharmony_ci
244162306a36Sopenharmony_ci#ifdef CONFIG_F2FS_FS_COMPRESSION
244262306a36Sopenharmony_ci		if (f2fs_compressed_file(inode)) {
244362306a36Sopenharmony_ci			/* there are remained compressed pages, submit them */
244462306a36Sopenharmony_ci			if (!f2fs_cluster_can_merge_page(&cc, page->index)) {
244562306a36Sopenharmony_ci				ret = f2fs_read_multi_pages(&cc, &bio,
244662306a36Sopenharmony_ci							max_nr_pages,
244762306a36Sopenharmony_ci							&last_block_in_bio,
244862306a36Sopenharmony_ci							rac != NULL, false);
244962306a36Sopenharmony_ci				f2fs_destroy_compress_ctx(&cc, false);
245062306a36Sopenharmony_ci				if (ret)
245162306a36Sopenharmony_ci					goto set_error_page;
245262306a36Sopenharmony_ci			}
245362306a36Sopenharmony_ci			if (cc.cluster_idx == NULL_CLUSTER) {
245462306a36Sopenharmony_ci				if (nc_cluster_idx ==
245562306a36Sopenharmony_ci					page->index >> cc.log_cluster_size) {
245662306a36Sopenharmony_ci					goto read_single_page;
245762306a36Sopenharmony_ci				}
245862306a36Sopenharmony_ci
245962306a36Sopenharmony_ci				ret = f2fs_is_compressed_cluster(inode, page->index);
246062306a36Sopenharmony_ci				if (ret < 0)
246162306a36Sopenharmony_ci					goto set_error_page;
246262306a36Sopenharmony_ci				else if (!ret) {
246362306a36Sopenharmony_ci					nc_cluster_idx =
246462306a36Sopenharmony_ci						page->index >> cc.log_cluster_size;
246562306a36Sopenharmony_ci					goto read_single_page;
246662306a36Sopenharmony_ci				}
246762306a36Sopenharmony_ci
246862306a36Sopenharmony_ci				nc_cluster_idx = NULL_CLUSTER;
246962306a36Sopenharmony_ci			}
247062306a36Sopenharmony_ci			ret = f2fs_init_compress_ctx(&cc);
247162306a36Sopenharmony_ci			if (ret)
247262306a36Sopenharmony_ci				goto set_error_page;
247362306a36Sopenharmony_ci
247462306a36Sopenharmony_ci			f2fs_compress_ctx_add_page(&cc, page);
247562306a36Sopenharmony_ci
247662306a36Sopenharmony_ci			goto next_page;
247762306a36Sopenharmony_ci		}
247862306a36Sopenharmony_ciread_single_page:
247962306a36Sopenharmony_ci#endif
248062306a36Sopenharmony_ci
248162306a36Sopenharmony_ci		ret = f2fs_read_single_page(inode, page, max_nr_pages, &map,
248262306a36Sopenharmony_ci					&bio, &last_block_in_bio, rac);
248362306a36Sopenharmony_ci		if (ret) {
248462306a36Sopenharmony_ci#ifdef CONFIG_F2FS_FS_COMPRESSION
248562306a36Sopenharmony_ciset_error_page:
248662306a36Sopenharmony_ci#endif
248762306a36Sopenharmony_ci			zero_user_segment(page, 0, PAGE_SIZE);
248862306a36Sopenharmony_ci			unlock_page(page);
248962306a36Sopenharmony_ci		}
249062306a36Sopenharmony_ci#ifdef CONFIG_F2FS_FS_COMPRESSION
249162306a36Sopenharmony_cinext_page:
249262306a36Sopenharmony_ci#endif
249362306a36Sopenharmony_ci		if (rac)
249462306a36Sopenharmony_ci			put_page(page);
249562306a36Sopenharmony_ci
249662306a36Sopenharmony_ci#ifdef CONFIG_F2FS_FS_COMPRESSION
249762306a36Sopenharmony_ci		if (f2fs_compressed_file(inode)) {
249862306a36Sopenharmony_ci			/* last page */
249962306a36Sopenharmony_ci			if (nr_pages == 1 && !f2fs_cluster_is_empty(&cc)) {
250062306a36Sopenharmony_ci				ret = f2fs_read_multi_pages(&cc, &bio,
250162306a36Sopenharmony_ci							max_nr_pages,
250262306a36Sopenharmony_ci							&last_block_in_bio,
250362306a36Sopenharmony_ci							rac != NULL, false);
250462306a36Sopenharmony_ci				f2fs_destroy_compress_ctx(&cc, false);
250562306a36Sopenharmony_ci			}
250662306a36Sopenharmony_ci		}
250762306a36Sopenharmony_ci#endif
250862306a36Sopenharmony_ci	}
250962306a36Sopenharmony_ci	if (bio)
251062306a36Sopenharmony_ci		f2fs_submit_read_bio(F2FS_I_SB(inode), bio, DATA);
251162306a36Sopenharmony_ci	return ret;
251262306a36Sopenharmony_ci}
251362306a36Sopenharmony_ci
251462306a36Sopenharmony_cistatic int f2fs_read_data_folio(struct file *file, struct folio *folio)
251562306a36Sopenharmony_ci{
251662306a36Sopenharmony_ci	struct page *page = &folio->page;
251762306a36Sopenharmony_ci	struct inode *inode = page_file_mapping(page)->host;
251862306a36Sopenharmony_ci	int ret = -EAGAIN;
251962306a36Sopenharmony_ci
252062306a36Sopenharmony_ci	trace_f2fs_readpage(page, DATA);
252162306a36Sopenharmony_ci
252262306a36Sopenharmony_ci	if (!f2fs_is_compress_backend_ready(inode)) {
252362306a36Sopenharmony_ci		unlock_page(page);
252462306a36Sopenharmony_ci		return -EOPNOTSUPP;
252562306a36Sopenharmony_ci	}
252662306a36Sopenharmony_ci
252762306a36Sopenharmony_ci	/* If the file has inline data, try to read it directly */
252862306a36Sopenharmony_ci	if (f2fs_has_inline_data(inode))
252962306a36Sopenharmony_ci		ret = f2fs_read_inline_data(inode, page);
253062306a36Sopenharmony_ci	if (ret == -EAGAIN)
253162306a36Sopenharmony_ci		ret = f2fs_mpage_readpages(inode, NULL, page);
253262306a36Sopenharmony_ci	return ret;
253362306a36Sopenharmony_ci}
253462306a36Sopenharmony_ci
253562306a36Sopenharmony_cistatic void f2fs_readahead(struct readahead_control *rac)
253662306a36Sopenharmony_ci{
253762306a36Sopenharmony_ci	struct inode *inode = rac->mapping->host;
253862306a36Sopenharmony_ci
253962306a36Sopenharmony_ci	trace_f2fs_readpages(inode, readahead_index(rac), readahead_count(rac));
254062306a36Sopenharmony_ci
254162306a36Sopenharmony_ci	if (!f2fs_is_compress_backend_ready(inode))
254262306a36Sopenharmony_ci		return;
254362306a36Sopenharmony_ci
254462306a36Sopenharmony_ci	/* If the file has inline data, skip readahead */
254562306a36Sopenharmony_ci	if (f2fs_has_inline_data(inode))
254662306a36Sopenharmony_ci		return;
254762306a36Sopenharmony_ci
254862306a36Sopenharmony_ci	f2fs_mpage_readpages(inode, rac, NULL);
254962306a36Sopenharmony_ci}
255062306a36Sopenharmony_ci
255162306a36Sopenharmony_ciint f2fs_encrypt_one_page(struct f2fs_io_info *fio)
255262306a36Sopenharmony_ci{
255362306a36Sopenharmony_ci	struct inode *inode = fio->page->mapping->host;
255462306a36Sopenharmony_ci	struct page *mpage, *page;
255562306a36Sopenharmony_ci	gfp_t gfp_flags = GFP_NOFS;
255662306a36Sopenharmony_ci
255762306a36Sopenharmony_ci	if (!f2fs_encrypted_file(inode))
255862306a36Sopenharmony_ci		return 0;
255962306a36Sopenharmony_ci
256062306a36Sopenharmony_ci	page = fio->compressed_page ? fio->compressed_page : fio->page;
256162306a36Sopenharmony_ci
256262306a36Sopenharmony_ci	if (fscrypt_inode_uses_inline_crypto(inode))
256362306a36Sopenharmony_ci		return 0;
256462306a36Sopenharmony_ci
256562306a36Sopenharmony_ciretry_encrypt:
256662306a36Sopenharmony_ci	fio->encrypted_page = fscrypt_encrypt_pagecache_blocks(page,
256762306a36Sopenharmony_ci					PAGE_SIZE, 0, gfp_flags);
256862306a36Sopenharmony_ci	if (IS_ERR(fio->encrypted_page)) {
256962306a36Sopenharmony_ci		/* flush pending IOs and wait for a while in the ENOMEM case */
257062306a36Sopenharmony_ci		if (PTR_ERR(fio->encrypted_page) == -ENOMEM) {
257162306a36Sopenharmony_ci			f2fs_flush_merged_writes(fio->sbi);
257262306a36Sopenharmony_ci			memalloc_retry_wait(GFP_NOFS);
257362306a36Sopenharmony_ci			gfp_flags |= __GFP_NOFAIL;
257462306a36Sopenharmony_ci			goto retry_encrypt;
257562306a36Sopenharmony_ci		}
257662306a36Sopenharmony_ci		return PTR_ERR(fio->encrypted_page);
257762306a36Sopenharmony_ci	}
257862306a36Sopenharmony_ci
257962306a36Sopenharmony_ci	mpage = find_lock_page(META_MAPPING(fio->sbi), fio->old_blkaddr);
258062306a36Sopenharmony_ci	if (mpage) {
258162306a36Sopenharmony_ci		if (PageUptodate(mpage))
258262306a36Sopenharmony_ci			memcpy(page_address(mpage),
258362306a36Sopenharmony_ci				page_address(fio->encrypted_page), PAGE_SIZE);
258462306a36Sopenharmony_ci		f2fs_put_page(mpage, 1);
258562306a36Sopenharmony_ci	}
258662306a36Sopenharmony_ci	return 0;
258762306a36Sopenharmony_ci}
258862306a36Sopenharmony_ci
258962306a36Sopenharmony_cistatic inline bool check_inplace_update_policy(struct inode *inode,
259062306a36Sopenharmony_ci				struct f2fs_io_info *fio)
259162306a36Sopenharmony_ci{
259262306a36Sopenharmony_ci	struct f2fs_sb_info *sbi = F2FS_I_SB(inode);
259362306a36Sopenharmony_ci
259462306a36Sopenharmony_ci	if (IS_F2FS_IPU_HONOR_OPU_WRITE(sbi) &&
259562306a36Sopenharmony_ci	    is_inode_flag_set(inode, FI_OPU_WRITE))
259662306a36Sopenharmony_ci		return false;
259762306a36Sopenharmony_ci	if (IS_F2FS_IPU_FORCE(sbi))
259862306a36Sopenharmony_ci		return true;
259962306a36Sopenharmony_ci	if (IS_F2FS_IPU_SSR(sbi) && f2fs_need_SSR(sbi))
260062306a36Sopenharmony_ci		return true;
260162306a36Sopenharmony_ci	if (IS_F2FS_IPU_UTIL(sbi) && utilization(sbi) > SM_I(sbi)->min_ipu_util)
260262306a36Sopenharmony_ci		return true;
260362306a36Sopenharmony_ci	if (IS_F2FS_IPU_SSR_UTIL(sbi) && f2fs_need_SSR(sbi) &&
260462306a36Sopenharmony_ci	    utilization(sbi) > SM_I(sbi)->min_ipu_util)
260562306a36Sopenharmony_ci		return true;
260662306a36Sopenharmony_ci
260762306a36Sopenharmony_ci	/*
260862306a36Sopenharmony_ci	 * IPU for rewrite async pages
260962306a36Sopenharmony_ci	 */
261062306a36Sopenharmony_ci	if (IS_F2FS_IPU_ASYNC(sbi) && fio && fio->op == REQ_OP_WRITE &&
261162306a36Sopenharmony_ci	    !(fio->op_flags & REQ_SYNC) && !IS_ENCRYPTED(inode))
261262306a36Sopenharmony_ci		return true;
261362306a36Sopenharmony_ci
261462306a36Sopenharmony_ci	/* this is only set during fdatasync */
261562306a36Sopenharmony_ci	if (IS_F2FS_IPU_FSYNC(sbi) && is_inode_flag_set(inode, FI_NEED_IPU))
261662306a36Sopenharmony_ci		return true;
261762306a36Sopenharmony_ci
261862306a36Sopenharmony_ci	if (unlikely(fio && is_sbi_flag_set(sbi, SBI_CP_DISABLED) &&
261962306a36Sopenharmony_ci			!f2fs_is_checkpointed_data(sbi, fio->old_blkaddr)))
262062306a36Sopenharmony_ci		return true;
262162306a36Sopenharmony_ci
262262306a36Sopenharmony_ci	return false;
262362306a36Sopenharmony_ci}
262462306a36Sopenharmony_ci
262562306a36Sopenharmony_cibool f2fs_should_update_inplace(struct inode *inode, struct f2fs_io_info *fio)
262662306a36Sopenharmony_ci{
262762306a36Sopenharmony_ci	/* swap file is migrating in aligned write mode */
262862306a36Sopenharmony_ci	if (is_inode_flag_set(inode, FI_ALIGNED_WRITE))
262962306a36Sopenharmony_ci		return false;
263062306a36Sopenharmony_ci
263162306a36Sopenharmony_ci	if (f2fs_is_pinned_file(inode))
263262306a36Sopenharmony_ci		return true;
263362306a36Sopenharmony_ci
263462306a36Sopenharmony_ci	/* if this is cold file, we should overwrite to avoid fragmentation */
263562306a36Sopenharmony_ci	if (file_is_cold(inode) && !is_inode_flag_set(inode, FI_OPU_WRITE))
263662306a36Sopenharmony_ci		return true;
263762306a36Sopenharmony_ci
263862306a36Sopenharmony_ci	return check_inplace_update_policy(inode, fio);
263962306a36Sopenharmony_ci}
264062306a36Sopenharmony_ci
264162306a36Sopenharmony_cibool f2fs_should_update_outplace(struct inode *inode, struct f2fs_io_info *fio)
264262306a36Sopenharmony_ci{
264362306a36Sopenharmony_ci	struct f2fs_sb_info *sbi = F2FS_I_SB(inode);
264462306a36Sopenharmony_ci
264562306a36Sopenharmony_ci	/* The below cases were checked when setting it. */
264662306a36Sopenharmony_ci	if (f2fs_is_pinned_file(inode))
264762306a36Sopenharmony_ci		return false;
264862306a36Sopenharmony_ci	if (fio && is_sbi_flag_set(sbi, SBI_NEED_FSCK))
264962306a36Sopenharmony_ci		return true;
265062306a36Sopenharmony_ci	if (f2fs_lfs_mode(sbi))
265162306a36Sopenharmony_ci		return true;
265262306a36Sopenharmony_ci	if (S_ISDIR(inode->i_mode))
265362306a36Sopenharmony_ci		return true;
265462306a36Sopenharmony_ci	if (IS_NOQUOTA(inode))
265562306a36Sopenharmony_ci		return true;
265662306a36Sopenharmony_ci	if (f2fs_is_atomic_file(inode))
265762306a36Sopenharmony_ci		return true;
265862306a36Sopenharmony_ci
265962306a36Sopenharmony_ci	/* swap file is migrating in aligned write mode */
266062306a36Sopenharmony_ci	if (is_inode_flag_set(inode, FI_ALIGNED_WRITE))
266162306a36Sopenharmony_ci		return true;
266262306a36Sopenharmony_ci
266362306a36Sopenharmony_ci	if (is_inode_flag_set(inode, FI_OPU_WRITE))
266462306a36Sopenharmony_ci		return true;
266562306a36Sopenharmony_ci
266662306a36Sopenharmony_ci	if (fio) {
266762306a36Sopenharmony_ci		if (page_private_gcing(fio->page))
266862306a36Sopenharmony_ci			return true;
266962306a36Sopenharmony_ci		if (page_private_dummy(fio->page))
267062306a36Sopenharmony_ci			return true;
267162306a36Sopenharmony_ci		if (unlikely(is_sbi_flag_set(sbi, SBI_CP_DISABLED) &&
267262306a36Sopenharmony_ci			f2fs_is_checkpointed_data(sbi, fio->old_blkaddr)))
267362306a36Sopenharmony_ci			return true;
267462306a36Sopenharmony_ci	}
267562306a36Sopenharmony_ci	return false;
267662306a36Sopenharmony_ci}
267762306a36Sopenharmony_ci
267862306a36Sopenharmony_cistatic inline bool need_inplace_update(struct f2fs_io_info *fio)
267962306a36Sopenharmony_ci{
268062306a36Sopenharmony_ci	struct inode *inode = fio->page->mapping->host;
268162306a36Sopenharmony_ci
268262306a36Sopenharmony_ci	if (f2fs_should_update_outplace(inode, fio))
268362306a36Sopenharmony_ci		return false;
268462306a36Sopenharmony_ci
268562306a36Sopenharmony_ci	return f2fs_should_update_inplace(inode, fio);
268662306a36Sopenharmony_ci}
268762306a36Sopenharmony_ci
268862306a36Sopenharmony_ciint f2fs_do_write_data_page(struct f2fs_io_info *fio)
268962306a36Sopenharmony_ci{
269062306a36Sopenharmony_ci	struct page *page = fio->page;
269162306a36Sopenharmony_ci	struct inode *inode = page->mapping->host;
269262306a36Sopenharmony_ci	struct dnode_of_data dn;
269362306a36Sopenharmony_ci	struct node_info ni;
269462306a36Sopenharmony_ci	bool ipu_force = false;
269562306a36Sopenharmony_ci	int err = 0;
269662306a36Sopenharmony_ci
269762306a36Sopenharmony_ci	/* Use COW inode to make dnode_of_data for atomic write */
269862306a36Sopenharmony_ci	if (f2fs_is_atomic_file(inode))
269962306a36Sopenharmony_ci		set_new_dnode(&dn, F2FS_I(inode)->cow_inode, NULL, NULL, 0);
270062306a36Sopenharmony_ci	else
270162306a36Sopenharmony_ci		set_new_dnode(&dn, inode, NULL, NULL, 0);
270262306a36Sopenharmony_ci
270362306a36Sopenharmony_ci	if (need_inplace_update(fio) &&
270462306a36Sopenharmony_ci	    f2fs_lookup_read_extent_cache_block(inode, page->index,
270562306a36Sopenharmony_ci						&fio->old_blkaddr)) {
270662306a36Sopenharmony_ci		if (!f2fs_is_valid_blkaddr(fio->sbi, fio->old_blkaddr,
270762306a36Sopenharmony_ci						DATA_GENERIC_ENHANCE)) {
270862306a36Sopenharmony_ci			f2fs_handle_error(fio->sbi,
270962306a36Sopenharmony_ci						ERROR_INVALID_BLKADDR);
271062306a36Sopenharmony_ci			return -EFSCORRUPTED;
271162306a36Sopenharmony_ci		}
271262306a36Sopenharmony_ci
271362306a36Sopenharmony_ci		ipu_force = true;
271462306a36Sopenharmony_ci		fio->need_lock = LOCK_DONE;
271562306a36Sopenharmony_ci		goto got_it;
271662306a36Sopenharmony_ci	}
271762306a36Sopenharmony_ci
271862306a36Sopenharmony_ci	/* Deadlock due to between page->lock and f2fs_lock_op */
271962306a36Sopenharmony_ci	if (fio->need_lock == LOCK_REQ && !f2fs_trylock_op(fio->sbi))
272062306a36Sopenharmony_ci		return -EAGAIN;
272162306a36Sopenharmony_ci
272262306a36Sopenharmony_ci	err = f2fs_get_dnode_of_data(&dn, page->index, LOOKUP_NODE);
272362306a36Sopenharmony_ci	if (err)
272462306a36Sopenharmony_ci		goto out;
272562306a36Sopenharmony_ci
272662306a36Sopenharmony_ci	fio->old_blkaddr = dn.data_blkaddr;
272762306a36Sopenharmony_ci
272862306a36Sopenharmony_ci	/* This page is already truncated */
272962306a36Sopenharmony_ci	if (fio->old_blkaddr == NULL_ADDR) {
273062306a36Sopenharmony_ci		ClearPageUptodate(page);
273162306a36Sopenharmony_ci		clear_page_private_gcing(page);
273262306a36Sopenharmony_ci		goto out_writepage;
273362306a36Sopenharmony_ci	}
273462306a36Sopenharmony_cigot_it:
273562306a36Sopenharmony_ci	if (__is_valid_data_blkaddr(fio->old_blkaddr) &&
273662306a36Sopenharmony_ci		!f2fs_is_valid_blkaddr(fio->sbi, fio->old_blkaddr,
273762306a36Sopenharmony_ci						DATA_GENERIC_ENHANCE)) {
273862306a36Sopenharmony_ci		err = -EFSCORRUPTED;
273962306a36Sopenharmony_ci		f2fs_handle_error(fio->sbi, ERROR_INVALID_BLKADDR);
274062306a36Sopenharmony_ci		goto out_writepage;
274162306a36Sopenharmony_ci	}
274262306a36Sopenharmony_ci
274362306a36Sopenharmony_ci	/* wait for GCed page writeback via META_MAPPING */
274462306a36Sopenharmony_ci	if (fio->post_read)
274562306a36Sopenharmony_ci		f2fs_wait_on_block_writeback(inode, fio->old_blkaddr);
274662306a36Sopenharmony_ci
274762306a36Sopenharmony_ci	/*
274862306a36Sopenharmony_ci	 * If current allocation needs SSR,
274962306a36Sopenharmony_ci	 * it had better in-place writes for updated data.
275062306a36Sopenharmony_ci	 */
275162306a36Sopenharmony_ci	if (ipu_force ||
275262306a36Sopenharmony_ci		(__is_valid_data_blkaddr(fio->old_blkaddr) &&
275362306a36Sopenharmony_ci					need_inplace_update(fio))) {
275462306a36Sopenharmony_ci		err = f2fs_encrypt_one_page(fio);
275562306a36Sopenharmony_ci		if (err)
275662306a36Sopenharmony_ci			goto out_writepage;
275762306a36Sopenharmony_ci
275862306a36Sopenharmony_ci		set_page_writeback(page);
275962306a36Sopenharmony_ci		f2fs_put_dnode(&dn);
276062306a36Sopenharmony_ci		if (fio->need_lock == LOCK_REQ)
276162306a36Sopenharmony_ci			f2fs_unlock_op(fio->sbi);
276262306a36Sopenharmony_ci		err = f2fs_inplace_write_data(fio);
276362306a36Sopenharmony_ci		if (err) {
276462306a36Sopenharmony_ci			if (fscrypt_inode_uses_fs_layer_crypto(inode))
276562306a36Sopenharmony_ci				fscrypt_finalize_bounce_page(&fio->encrypted_page);
276662306a36Sopenharmony_ci			if (PageWriteback(page))
276762306a36Sopenharmony_ci				end_page_writeback(page);
276862306a36Sopenharmony_ci		} else {
276962306a36Sopenharmony_ci			set_inode_flag(inode, FI_UPDATE_WRITE);
277062306a36Sopenharmony_ci		}
277162306a36Sopenharmony_ci		trace_f2fs_do_write_data_page(fio->page, IPU);
277262306a36Sopenharmony_ci		return err;
277362306a36Sopenharmony_ci	}
277462306a36Sopenharmony_ci
277562306a36Sopenharmony_ci	if (fio->need_lock == LOCK_RETRY) {
277662306a36Sopenharmony_ci		if (!f2fs_trylock_op(fio->sbi)) {
277762306a36Sopenharmony_ci			err = -EAGAIN;
277862306a36Sopenharmony_ci			goto out_writepage;
277962306a36Sopenharmony_ci		}
278062306a36Sopenharmony_ci		fio->need_lock = LOCK_REQ;
278162306a36Sopenharmony_ci	}
278262306a36Sopenharmony_ci
278362306a36Sopenharmony_ci	err = f2fs_get_node_info(fio->sbi, dn.nid, &ni, false);
278462306a36Sopenharmony_ci	if (err)
278562306a36Sopenharmony_ci		goto out_writepage;
278662306a36Sopenharmony_ci
278762306a36Sopenharmony_ci	fio->version = ni.version;
278862306a36Sopenharmony_ci
278962306a36Sopenharmony_ci	err = f2fs_encrypt_one_page(fio);
279062306a36Sopenharmony_ci	if (err)
279162306a36Sopenharmony_ci		goto out_writepage;
279262306a36Sopenharmony_ci
279362306a36Sopenharmony_ci	set_page_writeback(page);
279462306a36Sopenharmony_ci
279562306a36Sopenharmony_ci	if (fio->compr_blocks && fio->old_blkaddr == COMPRESS_ADDR)
279662306a36Sopenharmony_ci		f2fs_i_compr_blocks_update(inode, fio->compr_blocks - 1, false);
279762306a36Sopenharmony_ci
279862306a36Sopenharmony_ci	/* LFS mode write path */
279962306a36Sopenharmony_ci	f2fs_outplace_write_data(&dn, fio);
280062306a36Sopenharmony_ci	trace_f2fs_do_write_data_page(page, OPU);
280162306a36Sopenharmony_ci	set_inode_flag(inode, FI_APPEND_WRITE);
280262306a36Sopenharmony_ciout_writepage:
280362306a36Sopenharmony_ci	f2fs_put_dnode(&dn);
280462306a36Sopenharmony_ciout:
280562306a36Sopenharmony_ci	if (fio->need_lock == LOCK_REQ)
280662306a36Sopenharmony_ci		f2fs_unlock_op(fio->sbi);
280762306a36Sopenharmony_ci	return err;
280862306a36Sopenharmony_ci}
280962306a36Sopenharmony_ci
281062306a36Sopenharmony_ciint f2fs_write_single_data_page(struct page *page, int *submitted,
281162306a36Sopenharmony_ci				struct bio **bio,
281262306a36Sopenharmony_ci				sector_t *last_block,
281362306a36Sopenharmony_ci				struct writeback_control *wbc,
281462306a36Sopenharmony_ci				enum iostat_type io_type,
281562306a36Sopenharmony_ci				int compr_blocks,
281662306a36Sopenharmony_ci				bool allow_balance)
281762306a36Sopenharmony_ci{
281862306a36Sopenharmony_ci	struct inode *inode = page->mapping->host;
281962306a36Sopenharmony_ci	struct f2fs_sb_info *sbi = F2FS_I_SB(inode);
282062306a36Sopenharmony_ci	loff_t i_size = i_size_read(inode);
282162306a36Sopenharmony_ci	const pgoff_t end_index = ((unsigned long long)i_size)
282262306a36Sopenharmony_ci							>> PAGE_SHIFT;
282362306a36Sopenharmony_ci	loff_t psize = (loff_t)(page->index + 1) << PAGE_SHIFT;
282462306a36Sopenharmony_ci	unsigned offset = 0;
282562306a36Sopenharmony_ci	bool need_balance_fs = false;
282662306a36Sopenharmony_ci	bool quota_inode = IS_NOQUOTA(inode);
282762306a36Sopenharmony_ci	int err = 0;
282862306a36Sopenharmony_ci	struct f2fs_io_info fio = {
282962306a36Sopenharmony_ci		.sbi = sbi,
283062306a36Sopenharmony_ci		.ino = inode->i_ino,
283162306a36Sopenharmony_ci		.type = DATA,
283262306a36Sopenharmony_ci		.op = REQ_OP_WRITE,
283362306a36Sopenharmony_ci		.op_flags = wbc_to_write_flags(wbc),
283462306a36Sopenharmony_ci		.old_blkaddr = NULL_ADDR,
283562306a36Sopenharmony_ci		.page = page,
283662306a36Sopenharmony_ci		.encrypted_page = NULL,
283762306a36Sopenharmony_ci		.submitted = 0,
283862306a36Sopenharmony_ci		.compr_blocks = compr_blocks,
283962306a36Sopenharmony_ci		.need_lock = compr_blocks ? LOCK_DONE : LOCK_RETRY,
284062306a36Sopenharmony_ci		.post_read = f2fs_post_read_required(inode) ? 1 : 0,
284162306a36Sopenharmony_ci		.io_type = io_type,
284262306a36Sopenharmony_ci		.io_wbc = wbc,
284362306a36Sopenharmony_ci		.bio = bio,
284462306a36Sopenharmony_ci		.last_block = last_block,
284562306a36Sopenharmony_ci	};
284662306a36Sopenharmony_ci
284762306a36Sopenharmony_ci	trace_f2fs_writepage(page, DATA);
284862306a36Sopenharmony_ci
284962306a36Sopenharmony_ci	/* we should bypass data pages to proceed the kworker jobs */
285062306a36Sopenharmony_ci	if (unlikely(f2fs_cp_error(sbi))) {
285162306a36Sopenharmony_ci		mapping_set_error(page->mapping, -EIO);
285262306a36Sopenharmony_ci		/*
285362306a36Sopenharmony_ci		 * don't drop any dirty dentry pages for keeping lastest
285462306a36Sopenharmony_ci		 * directory structure.
285562306a36Sopenharmony_ci		 */
285662306a36Sopenharmony_ci		if (S_ISDIR(inode->i_mode) &&
285762306a36Sopenharmony_ci				!is_sbi_flag_set(sbi, SBI_IS_CLOSE))
285862306a36Sopenharmony_ci			goto redirty_out;
285962306a36Sopenharmony_ci
286062306a36Sopenharmony_ci		/* keep data pages in remount-ro mode */
286162306a36Sopenharmony_ci		if (F2FS_OPTION(sbi).errors == MOUNT_ERRORS_READONLY)
286262306a36Sopenharmony_ci			goto redirty_out;
286362306a36Sopenharmony_ci		goto out;
286462306a36Sopenharmony_ci	}
286562306a36Sopenharmony_ci
286662306a36Sopenharmony_ci	if (unlikely(is_sbi_flag_set(sbi, SBI_POR_DOING)))
286762306a36Sopenharmony_ci		goto redirty_out;
286862306a36Sopenharmony_ci
286962306a36Sopenharmony_ci	if (page->index < end_index ||
287062306a36Sopenharmony_ci			f2fs_verity_in_progress(inode) ||
287162306a36Sopenharmony_ci			compr_blocks)
287262306a36Sopenharmony_ci		goto write;
287362306a36Sopenharmony_ci
287462306a36Sopenharmony_ci	/*
287562306a36Sopenharmony_ci	 * If the offset is out-of-range of file size,
287662306a36Sopenharmony_ci	 * this page does not have to be written to disk.
287762306a36Sopenharmony_ci	 */
287862306a36Sopenharmony_ci	offset = i_size & (PAGE_SIZE - 1);
287962306a36Sopenharmony_ci	if ((page->index >= end_index + 1) || !offset)
288062306a36Sopenharmony_ci		goto out;
288162306a36Sopenharmony_ci
288262306a36Sopenharmony_ci	zero_user_segment(page, offset, PAGE_SIZE);
288362306a36Sopenharmony_ciwrite:
288462306a36Sopenharmony_ci	/* Dentry/quota blocks are controlled by checkpoint */
288562306a36Sopenharmony_ci	if (S_ISDIR(inode->i_mode) || quota_inode) {
288662306a36Sopenharmony_ci		/*
288762306a36Sopenharmony_ci		 * We need to wait for node_write to avoid block allocation during
288862306a36Sopenharmony_ci		 * checkpoint. This can only happen to quota writes which can cause
288962306a36Sopenharmony_ci		 * the below discard race condition.
289062306a36Sopenharmony_ci		 */
289162306a36Sopenharmony_ci		if (quota_inode)
289262306a36Sopenharmony_ci			f2fs_down_read(&sbi->node_write);
289362306a36Sopenharmony_ci
289462306a36Sopenharmony_ci		fio.need_lock = LOCK_DONE;
289562306a36Sopenharmony_ci		err = f2fs_do_write_data_page(&fio);
289662306a36Sopenharmony_ci
289762306a36Sopenharmony_ci		if (quota_inode)
289862306a36Sopenharmony_ci			f2fs_up_read(&sbi->node_write);
289962306a36Sopenharmony_ci
290062306a36Sopenharmony_ci		goto done;
290162306a36Sopenharmony_ci	}
290262306a36Sopenharmony_ci
290362306a36Sopenharmony_ci	if (!wbc->for_reclaim)
290462306a36Sopenharmony_ci		need_balance_fs = true;
290562306a36Sopenharmony_ci	else if (has_not_enough_free_secs(sbi, 0, 0))
290662306a36Sopenharmony_ci		goto redirty_out;
290762306a36Sopenharmony_ci	else
290862306a36Sopenharmony_ci		set_inode_flag(inode, FI_HOT_DATA);
290962306a36Sopenharmony_ci
291062306a36Sopenharmony_ci	err = -EAGAIN;
291162306a36Sopenharmony_ci	if (f2fs_has_inline_data(inode)) {
291262306a36Sopenharmony_ci		err = f2fs_write_inline_data(inode, page);
291362306a36Sopenharmony_ci		if (!err)
291462306a36Sopenharmony_ci			goto out;
291562306a36Sopenharmony_ci	}
291662306a36Sopenharmony_ci
291762306a36Sopenharmony_ci	if (err == -EAGAIN) {
291862306a36Sopenharmony_ci		err = f2fs_do_write_data_page(&fio);
291962306a36Sopenharmony_ci		if (err == -EAGAIN) {
292062306a36Sopenharmony_ci			f2fs_bug_on(sbi, compr_blocks);
292162306a36Sopenharmony_ci			fio.need_lock = LOCK_REQ;
292262306a36Sopenharmony_ci			err = f2fs_do_write_data_page(&fio);
292362306a36Sopenharmony_ci		}
292462306a36Sopenharmony_ci	}
292562306a36Sopenharmony_ci
292662306a36Sopenharmony_ci	if (err) {
292762306a36Sopenharmony_ci		file_set_keep_isize(inode);
292862306a36Sopenharmony_ci	} else {
292962306a36Sopenharmony_ci		spin_lock(&F2FS_I(inode)->i_size_lock);
293062306a36Sopenharmony_ci		if (F2FS_I(inode)->last_disk_size < psize)
293162306a36Sopenharmony_ci			F2FS_I(inode)->last_disk_size = psize;
293262306a36Sopenharmony_ci		spin_unlock(&F2FS_I(inode)->i_size_lock);
293362306a36Sopenharmony_ci	}
293462306a36Sopenharmony_ci
293562306a36Sopenharmony_cidone:
293662306a36Sopenharmony_ci	if (err && err != -ENOENT)
293762306a36Sopenharmony_ci		goto redirty_out;
293862306a36Sopenharmony_ci
293962306a36Sopenharmony_ciout:
294062306a36Sopenharmony_ci	inode_dec_dirty_pages(inode);
294162306a36Sopenharmony_ci	if (err) {
294262306a36Sopenharmony_ci		ClearPageUptodate(page);
294362306a36Sopenharmony_ci		clear_page_private_gcing(page);
294462306a36Sopenharmony_ci	}
294562306a36Sopenharmony_ci
294662306a36Sopenharmony_ci	if (wbc->for_reclaim) {
294762306a36Sopenharmony_ci		f2fs_submit_merged_write_cond(sbi, NULL, page, 0, DATA);
294862306a36Sopenharmony_ci		clear_inode_flag(inode, FI_HOT_DATA);
294962306a36Sopenharmony_ci		f2fs_remove_dirty_inode(inode);
295062306a36Sopenharmony_ci		submitted = NULL;
295162306a36Sopenharmony_ci	}
295262306a36Sopenharmony_ci	unlock_page(page);
295362306a36Sopenharmony_ci	if (!S_ISDIR(inode->i_mode) && !IS_NOQUOTA(inode) &&
295462306a36Sopenharmony_ci			!F2FS_I(inode)->wb_task && allow_balance)
295562306a36Sopenharmony_ci		f2fs_balance_fs(sbi, need_balance_fs);
295662306a36Sopenharmony_ci
295762306a36Sopenharmony_ci	if (unlikely(f2fs_cp_error(sbi))) {
295862306a36Sopenharmony_ci		f2fs_submit_merged_write(sbi, DATA);
295962306a36Sopenharmony_ci		if (bio && *bio)
296062306a36Sopenharmony_ci			f2fs_submit_merged_ipu_write(sbi, bio, NULL);
296162306a36Sopenharmony_ci		submitted = NULL;
296262306a36Sopenharmony_ci	}
296362306a36Sopenharmony_ci
296462306a36Sopenharmony_ci	if (submitted)
296562306a36Sopenharmony_ci		*submitted = fio.submitted;
296662306a36Sopenharmony_ci
296762306a36Sopenharmony_ci	return 0;
296862306a36Sopenharmony_ci
296962306a36Sopenharmony_ciredirty_out:
297062306a36Sopenharmony_ci	redirty_page_for_writepage(wbc, page);
297162306a36Sopenharmony_ci	/*
297262306a36Sopenharmony_ci	 * pageout() in MM translates EAGAIN, so calls handle_write_error()
297362306a36Sopenharmony_ci	 * -> mapping_set_error() -> set_bit(AS_EIO, ...).
297462306a36Sopenharmony_ci	 * file_write_and_wait_range() will see EIO error, which is critical
297562306a36Sopenharmony_ci	 * to return value of fsync() followed by atomic_write failure to user.
297662306a36Sopenharmony_ci	 */
297762306a36Sopenharmony_ci	if (!err || wbc->for_reclaim)
297862306a36Sopenharmony_ci		return AOP_WRITEPAGE_ACTIVATE;
297962306a36Sopenharmony_ci	unlock_page(page);
298062306a36Sopenharmony_ci	return err;
298162306a36Sopenharmony_ci}
298262306a36Sopenharmony_ci
298362306a36Sopenharmony_cistatic int f2fs_write_data_page(struct page *page,
298462306a36Sopenharmony_ci					struct writeback_control *wbc)
298562306a36Sopenharmony_ci{
298662306a36Sopenharmony_ci#ifdef CONFIG_F2FS_FS_COMPRESSION
298762306a36Sopenharmony_ci	struct inode *inode = page->mapping->host;
298862306a36Sopenharmony_ci
298962306a36Sopenharmony_ci	if (unlikely(f2fs_cp_error(F2FS_I_SB(inode))))
299062306a36Sopenharmony_ci		goto out;
299162306a36Sopenharmony_ci
299262306a36Sopenharmony_ci	if (f2fs_compressed_file(inode)) {
299362306a36Sopenharmony_ci		if (f2fs_is_compressed_cluster(inode, page->index)) {
299462306a36Sopenharmony_ci			redirty_page_for_writepage(wbc, page);
299562306a36Sopenharmony_ci			return AOP_WRITEPAGE_ACTIVATE;
299662306a36Sopenharmony_ci		}
299762306a36Sopenharmony_ci	}
299862306a36Sopenharmony_ciout:
299962306a36Sopenharmony_ci#endif
300062306a36Sopenharmony_ci
300162306a36Sopenharmony_ci	return f2fs_write_single_data_page(page, NULL, NULL, NULL,
300262306a36Sopenharmony_ci						wbc, FS_DATA_IO, 0, true);
300362306a36Sopenharmony_ci}
300462306a36Sopenharmony_ci
300562306a36Sopenharmony_ci/*
300662306a36Sopenharmony_ci * This function was copied from write_cache_pages from mm/page-writeback.c.
300762306a36Sopenharmony_ci * The major change is making write step of cold data page separately from
300862306a36Sopenharmony_ci * warm/hot data page.
300962306a36Sopenharmony_ci */
301062306a36Sopenharmony_cistatic int f2fs_write_cache_pages(struct address_space *mapping,
301162306a36Sopenharmony_ci					struct writeback_control *wbc,
301262306a36Sopenharmony_ci					enum iostat_type io_type)
301362306a36Sopenharmony_ci{
301462306a36Sopenharmony_ci	int ret = 0;
301562306a36Sopenharmony_ci	int done = 0, retry = 0;
301662306a36Sopenharmony_ci	struct page *pages_local[F2FS_ONSTACK_PAGES];
301762306a36Sopenharmony_ci	struct page **pages = pages_local;
301862306a36Sopenharmony_ci	struct folio_batch fbatch;
301962306a36Sopenharmony_ci	struct f2fs_sb_info *sbi = F2FS_M_SB(mapping);
302062306a36Sopenharmony_ci	struct bio *bio = NULL;
302162306a36Sopenharmony_ci	sector_t last_block;
302262306a36Sopenharmony_ci#ifdef CONFIG_F2FS_FS_COMPRESSION
302362306a36Sopenharmony_ci	struct inode *inode = mapping->host;
302462306a36Sopenharmony_ci	struct compress_ctx cc = {
302562306a36Sopenharmony_ci		.inode = inode,
302662306a36Sopenharmony_ci		.log_cluster_size = F2FS_I(inode)->i_log_cluster_size,
302762306a36Sopenharmony_ci		.cluster_size = F2FS_I(inode)->i_cluster_size,
302862306a36Sopenharmony_ci		.cluster_idx = NULL_CLUSTER,
302962306a36Sopenharmony_ci		.rpages = NULL,
303062306a36Sopenharmony_ci		.nr_rpages = 0,
303162306a36Sopenharmony_ci		.cpages = NULL,
303262306a36Sopenharmony_ci		.valid_nr_cpages = 0,
303362306a36Sopenharmony_ci		.rbuf = NULL,
303462306a36Sopenharmony_ci		.cbuf = NULL,
303562306a36Sopenharmony_ci		.rlen = PAGE_SIZE * F2FS_I(inode)->i_cluster_size,
303662306a36Sopenharmony_ci		.private = NULL,
303762306a36Sopenharmony_ci	};
303862306a36Sopenharmony_ci#endif
303962306a36Sopenharmony_ci	int nr_folios, p, idx;
304062306a36Sopenharmony_ci	int nr_pages;
304162306a36Sopenharmony_ci	unsigned int max_pages = F2FS_ONSTACK_PAGES;
304262306a36Sopenharmony_ci	pgoff_t index;
304362306a36Sopenharmony_ci	pgoff_t end;		/* Inclusive */
304462306a36Sopenharmony_ci	pgoff_t done_index;
304562306a36Sopenharmony_ci	int range_whole = 0;
304662306a36Sopenharmony_ci	xa_mark_t tag;
304762306a36Sopenharmony_ci	int nwritten = 0;
304862306a36Sopenharmony_ci	int submitted = 0;
304962306a36Sopenharmony_ci	int i;
305062306a36Sopenharmony_ci
305162306a36Sopenharmony_ci#ifdef CONFIG_F2FS_FS_COMPRESSION
305262306a36Sopenharmony_ci	if (f2fs_compressed_file(inode) &&
305362306a36Sopenharmony_ci		1 << cc.log_cluster_size > F2FS_ONSTACK_PAGES) {
305462306a36Sopenharmony_ci		pages = f2fs_kzalloc(sbi, sizeof(struct page *) <<
305562306a36Sopenharmony_ci				cc.log_cluster_size, GFP_NOFS | __GFP_NOFAIL);
305662306a36Sopenharmony_ci		max_pages = 1 << cc.log_cluster_size;
305762306a36Sopenharmony_ci	}
305862306a36Sopenharmony_ci#endif
305962306a36Sopenharmony_ci
306062306a36Sopenharmony_ci	folio_batch_init(&fbatch);
306162306a36Sopenharmony_ci
306262306a36Sopenharmony_ci	if (get_dirty_pages(mapping->host) <=
306362306a36Sopenharmony_ci				SM_I(F2FS_M_SB(mapping))->min_hot_blocks)
306462306a36Sopenharmony_ci		set_inode_flag(mapping->host, FI_HOT_DATA);
306562306a36Sopenharmony_ci	else
306662306a36Sopenharmony_ci		clear_inode_flag(mapping->host, FI_HOT_DATA);
306762306a36Sopenharmony_ci
306862306a36Sopenharmony_ci	if (wbc->range_cyclic) {
306962306a36Sopenharmony_ci		index = mapping->writeback_index; /* prev offset */
307062306a36Sopenharmony_ci		end = -1;
307162306a36Sopenharmony_ci	} else {
307262306a36Sopenharmony_ci		index = wbc->range_start >> PAGE_SHIFT;
307362306a36Sopenharmony_ci		end = wbc->range_end >> PAGE_SHIFT;
307462306a36Sopenharmony_ci		if (wbc->range_start == 0 && wbc->range_end == LLONG_MAX)
307562306a36Sopenharmony_ci			range_whole = 1;
307662306a36Sopenharmony_ci	}
307762306a36Sopenharmony_ci	if (wbc->sync_mode == WB_SYNC_ALL || wbc->tagged_writepages)
307862306a36Sopenharmony_ci		tag = PAGECACHE_TAG_TOWRITE;
307962306a36Sopenharmony_ci	else
308062306a36Sopenharmony_ci		tag = PAGECACHE_TAG_DIRTY;
308162306a36Sopenharmony_ciretry:
308262306a36Sopenharmony_ci	retry = 0;
308362306a36Sopenharmony_ci	if (wbc->sync_mode == WB_SYNC_ALL || wbc->tagged_writepages)
308462306a36Sopenharmony_ci		tag_pages_for_writeback(mapping, index, end);
308562306a36Sopenharmony_ci	done_index = index;
308662306a36Sopenharmony_ci	while (!done && !retry && (index <= end)) {
308762306a36Sopenharmony_ci		nr_pages = 0;
308862306a36Sopenharmony_ciagain:
308962306a36Sopenharmony_ci		nr_folios = filemap_get_folios_tag(mapping, &index, end,
309062306a36Sopenharmony_ci				tag, &fbatch);
309162306a36Sopenharmony_ci		if (nr_folios == 0) {
309262306a36Sopenharmony_ci			if (nr_pages)
309362306a36Sopenharmony_ci				goto write;
309462306a36Sopenharmony_ci			break;
309562306a36Sopenharmony_ci		}
309662306a36Sopenharmony_ci
309762306a36Sopenharmony_ci		for (i = 0; i < nr_folios; i++) {
309862306a36Sopenharmony_ci			struct folio *folio = fbatch.folios[i];
309962306a36Sopenharmony_ci
310062306a36Sopenharmony_ci			idx = 0;
310162306a36Sopenharmony_ci			p = folio_nr_pages(folio);
310262306a36Sopenharmony_ciadd_more:
310362306a36Sopenharmony_ci			pages[nr_pages] = folio_page(folio, idx);
310462306a36Sopenharmony_ci			folio_get(folio);
310562306a36Sopenharmony_ci			if (++nr_pages == max_pages) {
310662306a36Sopenharmony_ci				index = folio->index + idx + 1;
310762306a36Sopenharmony_ci				folio_batch_release(&fbatch);
310862306a36Sopenharmony_ci				goto write;
310962306a36Sopenharmony_ci			}
311062306a36Sopenharmony_ci			if (++idx < p)
311162306a36Sopenharmony_ci				goto add_more;
311262306a36Sopenharmony_ci		}
311362306a36Sopenharmony_ci		folio_batch_release(&fbatch);
311462306a36Sopenharmony_ci		goto again;
311562306a36Sopenharmony_ciwrite:
311662306a36Sopenharmony_ci		for (i = 0; i < nr_pages; i++) {
311762306a36Sopenharmony_ci			struct page *page = pages[i];
311862306a36Sopenharmony_ci			struct folio *folio = page_folio(page);
311962306a36Sopenharmony_ci			bool need_readd;
312062306a36Sopenharmony_cireadd:
312162306a36Sopenharmony_ci			need_readd = false;
312262306a36Sopenharmony_ci#ifdef CONFIG_F2FS_FS_COMPRESSION
312362306a36Sopenharmony_ci			if (f2fs_compressed_file(inode)) {
312462306a36Sopenharmony_ci				void *fsdata = NULL;
312562306a36Sopenharmony_ci				struct page *pagep;
312662306a36Sopenharmony_ci				int ret2;
312762306a36Sopenharmony_ci
312862306a36Sopenharmony_ci				ret = f2fs_init_compress_ctx(&cc);
312962306a36Sopenharmony_ci				if (ret) {
313062306a36Sopenharmony_ci					done = 1;
313162306a36Sopenharmony_ci					break;
313262306a36Sopenharmony_ci				}
313362306a36Sopenharmony_ci
313462306a36Sopenharmony_ci				if (!f2fs_cluster_can_merge_page(&cc,
313562306a36Sopenharmony_ci								folio->index)) {
313662306a36Sopenharmony_ci					ret = f2fs_write_multi_pages(&cc,
313762306a36Sopenharmony_ci						&submitted, wbc, io_type);
313862306a36Sopenharmony_ci					if (!ret)
313962306a36Sopenharmony_ci						need_readd = true;
314062306a36Sopenharmony_ci					goto result;
314162306a36Sopenharmony_ci				}
314262306a36Sopenharmony_ci
314362306a36Sopenharmony_ci				if (unlikely(f2fs_cp_error(sbi)))
314462306a36Sopenharmony_ci					goto lock_folio;
314562306a36Sopenharmony_ci
314662306a36Sopenharmony_ci				if (!f2fs_cluster_is_empty(&cc))
314762306a36Sopenharmony_ci					goto lock_folio;
314862306a36Sopenharmony_ci
314962306a36Sopenharmony_ci				if (f2fs_all_cluster_page_ready(&cc,
315062306a36Sopenharmony_ci					pages, i, nr_pages, true))
315162306a36Sopenharmony_ci					goto lock_folio;
315262306a36Sopenharmony_ci
315362306a36Sopenharmony_ci				ret2 = f2fs_prepare_compress_overwrite(
315462306a36Sopenharmony_ci							inode, &pagep,
315562306a36Sopenharmony_ci							folio->index, &fsdata);
315662306a36Sopenharmony_ci				if (ret2 < 0) {
315762306a36Sopenharmony_ci					ret = ret2;
315862306a36Sopenharmony_ci					done = 1;
315962306a36Sopenharmony_ci					break;
316062306a36Sopenharmony_ci				} else if (ret2 &&
316162306a36Sopenharmony_ci					(!f2fs_compress_write_end(inode,
316262306a36Sopenharmony_ci						fsdata, folio->index, 1) ||
316362306a36Sopenharmony_ci					 !f2fs_all_cluster_page_ready(&cc,
316462306a36Sopenharmony_ci						pages, i, nr_pages,
316562306a36Sopenharmony_ci						false))) {
316662306a36Sopenharmony_ci					retry = 1;
316762306a36Sopenharmony_ci					break;
316862306a36Sopenharmony_ci				}
316962306a36Sopenharmony_ci			}
317062306a36Sopenharmony_ci#endif
317162306a36Sopenharmony_ci			/* give a priority to WB_SYNC threads */
317262306a36Sopenharmony_ci			if (atomic_read(&sbi->wb_sync_req[DATA]) &&
317362306a36Sopenharmony_ci					wbc->sync_mode == WB_SYNC_NONE) {
317462306a36Sopenharmony_ci				done = 1;
317562306a36Sopenharmony_ci				break;
317662306a36Sopenharmony_ci			}
317762306a36Sopenharmony_ci#ifdef CONFIG_F2FS_FS_COMPRESSION
317862306a36Sopenharmony_cilock_folio:
317962306a36Sopenharmony_ci#endif
318062306a36Sopenharmony_ci			done_index = folio->index;
318162306a36Sopenharmony_ciretry_write:
318262306a36Sopenharmony_ci			folio_lock(folio);
318362306a36Sopenharmony_ci
318462306a36Sopenharmony_ci			if (unlikely(folio->mapping != mapping)) {
318562306a36Sopenharmony_cicontinue_unlock:
318662306a36Sopenharmony_ci				folio_unlock(folio);
318762306a36Sopenharmony_ci				continue;
318862306a36Sopenharmony_ci			}
318962306a36Sopenharmony_ci
319062306a36Sopenharmony_ci			if (!folio_test_dirty(folio)) {
319162306a36Sopenharmony_ci				/* someone wrote it for us */
319262306a36Sopenharmony_ci				goto continue_unlock;
319362306a36Sopenharmony_ci			}
319462306a36Sopenharmony_ci
319562306a36Sopenharmony_ci			if (folio_test_writeback(folio)) {
319662306a36Sopenharmony_ci				if (wbc->sync_mode == WB_SYNC_NONE)
319762306a36Sopenharmony_ci					goto continue_unlock;
319862306a36Sopenharmony_ci				f2fs_wait_on_page_writeback(&folio->page, DATA, true, true);
319962306a36Sopenharmony_ci			}
320062306a36Sopenharmony_ci
320162306a36Sopenharmony_ci			if (!folio_clear_dirty_for_io(folio))
320262306a36Sopenharmony_ci				goto continue_unlock;
320362306a36Sopenharmony_ci
320462306a36Sopenharmony_ci#ifdef CONFIG_F2FS_FS_COMPRESSION
320562306a36Sopenharmony_ci			if (f2fs_compressed_file(inode)) {
320662306a36Sopenharmony_ci				folio_get(folio);
320762306a36Sopenharmony_ci				f2fs_compress_ctx_add_page(&cc, &folio->page);
320862306a36Sopenharmony_ci				continue;
320962306a36Sopenharmony_ci			}
321062306a36Sopenharmony_ci#endif
321162306a36Sopenharmony_ci			ret = f2fs_write_single_data_page(&folio->page,
321262306a36Sopenharmony_ci					&submitted, &bio, &last_block,
321362306a36Sopenharmony_ci					wbc, io_type, 0, true);
321462306a36Sopenharmony_ci			if (ret == AOP_WRITEPAGE_ACTIVATE)
321562306a36Sopenharmony_ci				folio_unlock(folio);
321662306a36Sopenharmony_ci#ifdef CONFIG_F2FS_FS_COMPRESSION
321762306a36Sopenharmony_ciresult:
321862306a36Sopenharmony_ci#endif
321962306a36Sopenharmony_ci			nwritten += submitted;
322062306a36Sopenharmony_ci			wbc->nr_to_write -= submitted;
322162306a36Sopenharmony_ci
322262306a36Sopenharmony_ci			if (unlikely(ret)) {
322362306a36Sopenharmony_ci				/*
322462306a36Sopenharmony_ci				 * keep nr_to_write, since vfs uses this to
322562306a36Sopenharmony_ci				 * get # of written pages.
322662306a36Sopenharmony_ci				 */
322762306a36Sopenharmony_ci				if (ret == AOP_WRITEPAGE_ACTIVATE) {
322862306a36Sopenharmony_ci					ret = 0;
322962306a36Sopenharmony_ci					goto next;
323062306a36Sopenharmony_ci				} else if (ret == -EAGAIN) {
323162306a36Sopenharmony_ci					ret = 0;
323262306a36Sopenharmony_ci					if (wbc->sync_mode == WB_SYNC_ALL) {
323362306a36Sopenharmony_ci						f2fs_io_schedule_timeout(
323462306a36Sopenharmony_ci							DEFAULT_IO_TIMEOUT);
323562306a36Sopenharmony_ci						goto retry_write;
323662306a36Sopenharmony_ci					}
323762306a36Sopenharmony_ci					goto next;
323862306a36Sopenharmony_ci				}
323962306a36Sopenharmony_ci				done_index = folio_next_index(folio);
324062306a36Sopenharmony_ci				done = 1;
324162306a36Sopenharmony_ci				break;
324262306a36Sopenharmony_ci			}
324362306a36Sopenharmony_ci
324462306a36Sopenharmony_ci			if (wbc->nr_to_write <= 0 &&
324562306a36Sopenharmony_ci					wbc->sync_mode == WB_SYNC_NONE) {
324662306a36Sopenharmony_ci				done = 1;
324762306a36Sopenharmony_ci				break;
324862306a36Sopenharmony_ci			}
324962306a36Sopenharmony_cinext:
325062306a36Sopenharmony_ci			if (need_readd)
325162306a36Sopenharmony_ci				goto readd;
325262306a36Sopenharmony_ci		}
325362306a36Sopenharmony_ci		release_pages(pages, nr_pages);
325462306a36Sopenharmony_ci		cond_resched();
325562306a36Sopenharmony_ci	}
325662306a36Sopenharmony_ci#ifdef CONFIG_F2FS_FS_COMPRESSION
325762306a36Sopenharmony_ci	/* flush remained pages in compress cluster */
325862306a36Sopenharmony_ci	if (f2fs_compressed_file(inode) && !f2fs_cluster_is_empty(&cc)) {
325962306a36Sopenharmony_ci		ret = f2fs_write_multi_pages(&cc, &submitted, wbc, io_type);
326062306a36Sopenharmony_ci		nwritten += submitted;
326162306a36Sopenharmony_ci		wbc->nr_to_write -= submitted;
326262306a36Sopenharmony_ci		if (ret) {
326362306a36Sopenharmony_ci			done = 1;
326462306a36Sopenharmony_ci			retry = 0;
326562306a36Sopenharmony_ci		}
326662306a36Sopenharmony_ci	}
326762306a36Sopenharmony_ci	if (f2fs_compressed_file(inode))
326862306a36Sopenharmony_ci		f2fs_destroy_compress_ctx(&cc, false);
326962306a36Sopenharmony_ci#endif
327062306a36Sopenharmony_ci	if (retry) {
327162306a36Sopenharmony_ci		index = 0;
327262306a36Sopenharmony_ci		end = -1;
327362306a36Sopenharmony_ci		goto retry;
327462306a36Sopenharmony_ci	}
327562306a36Sopenharmony_ci	if (wbc->range_cyclic && !done)
327662306a36Sopenharmony_ci		done_index = 0;
327762306a36Sopenharmony_ci	if (wbc->range_cyclic || (range_whole && wbc->nr_to_write > 0))
327862306a36Sopenharmony_ci		mapping->writeback_index = done_index;
327962306a36Sopenharmony_ci
328062306a36Sopenharmony_ci	if (nwritten)
328162306a36Sopenharmony_ci		f2fs_submit_merged_write_cond(F2FS_M_SB(mapping), mapping->host,
328262306a36Sopenharmony_ci								NULL, 0, DATA);
328362306a36Sopenharmony_ci	/* submit cached bio of IPU write */
328462306a36Sopenharmony_ci	if (bio)
328562306a36Sopenharmony_ci		f2fs_submit_merged_ipu_write(sbi, &bio, NULL);
328662306a36Sopenharmony_ci
328762306a36Sopenharmony_ci#ifdef CONFIG_F2FS_FS_COMPRESSION
328862306a36Sopenharmony_ci	if (pages != pages_local)
328962306a36Sopenharmony_ci		kfree(pages);
329062306a36Sopenharmony_ci#endif
329162306a36Sopenharmony_ci
329262306a36Sopenharmony_ci	return ret;
329362306a36Sopenharmony_ci}
329462306a36Sopenharmony_ci
329562306a36Sopenharmony_cistatic inline bool __should_serialize_io(struct inode *inode,
329662306a36Sopenharmony_ci					struct writeback_control *wbc)
329762306a36Sopenharmony_ci{
329862306a36Sopenharmony_ci	/* to avoid deadlock in path of data flush */
329962306a36Sopenharmony_ci	if (F2FS_I(inode)->wb_task)
330062306a36Sopenharmony_ci		return false;
330162306a36Sopenharmony_ci
330262306a36Sopenharmony_ci	if (!S_ISREG(inode->i_mode))
330362306a36Sopenharmony_ci		return false;
330462306a36Sopenharmony_ci	if (IS_NOQUOTA(inode))
330562306a36Sopenharmony_ci		return false;
330662306a36Sopenharmony_ci
330762306a36Sopenharmony_ci	if (f2fs_need_compress_data(inode))
330862306a36Sopenharmony_ci		return true;
330962306a36Sopenharmony_ci	if (wbc->sync_mode != WB_SYNC_ALL)
331062306a36Sopenharmony_ci		return true;
331162306a36Sopenharmony_ci	if (get_dirty_pages(inode) >= SM_I(F2FS_I_SB(inode))->min_seq_blocks)
331262306a36Sopenharmony_ci		return true;
331362306a36Sopenharmony_ci	return false;
331462306a36Sopenharmony_ci}
331562306a36Sopenharmony_ci
331662306a36Sopenharmony_cistatic int __f2fs_write_data_pages(struct address_space *mapping,
331762306a36Sopenharmony_ci						struct writeback_control *wbc,
331862306a36Sopenharmony_ci						enum iostat_type io_type)
331962306a36Sopenharmony_ci{
332062306a36Sopenharmony_ci	struct inode *inode = mapping->host;
332162306a36Sopenharmony_ci	struct f2fs_sb_info *sbi = F2FS_I_SB(inode);
332262306a36Sopenharmony_ci	struct blk_plug plug;
332362306a36Sopenharmony_ci	int ret;
332462306a36Sopenharmony_ci	bool locked = false;
332562306a36Sopenharmony_ci
332662306a36Sopenharmony_ci	/* deal with chardevs and other special file */
332762306a36Sopenharmony_ci	if (!mapping->a_ops->writepage)
332862306a36Sopenharmony_ci		return 0;
332962306a36Sopenharmony_ci
333062306a36Sopenharmony_ci	/* skip writing if there is no dirty page in this inode */
333162306a36Sopenharmony_ci	if (!get_dirty_pages(inode) && wbc->sync_mode == WB_SYNC_NONE)
333262306a36Sopenharmony_ci		return 0;
333362306a36Sopenharmony_ci
333462306a36Sopenharmony_ci	/* during POR, we don't need to trigger writepage at all. */
333562306a36Sopenharmony_ci	if (unlikely(is_sbi_flag_set(sbi, SBI_POR_DOING)))
333662306a36Sopenharmony_ci		goto skip_write;
333762306a36Sopenharmony_ci
333862306a36Sopenharmony_ci	if ((S_ISDIR(inode->i_mode) || IS_NOQUOTA(inode)) &&
333962306a36Sopenharmony_ci			wbc->sync_mode == WB_SYNC_NONE &&
334062306a36Sopenharmony_ci			get_dirty_pages(inode) < nr_pages_to_skip(sbi, DATA) &&
334162306a36Sopenharmony_ci			f2fs_available_free_memory(sbi, DIRTY_DENTS))
334262306a36Sopenharmony_ci		goto skip_write;
334362306a36Sopenharmony_ci
334462306a36Sopenharmony_ci	/* skip writing in file defragment preparing stage */
334562306a36Sopenharmony_ci	if (is_inode_flag_set(inode, FI_SKIP_WRITES))
334662306a36Sopenharmony_ci		goto skip_write;
334762306a36Sopenharmony_ci
334862306a36Sopenharmony_ci	trace_f2fs_writepages(mapping->host, wbc, DATA);
334962306a36Sopenharmony_ci
335062306a36Sopenharmony_ci	/* to avoid spliting IOs due to mixed WB_SYNC_ALL and WB_SYNC_NONE */
335162306a36Sopenharmony_ci	if (wbc->sync_mode == WB_SYNC_ALL)
335262306a36Sopenharmony_ci		atomic_inc(&sbi->wb_sync_req[DATA]);
335362306a36Sopenharmony_ci	else if (atomic_read(&sbi->wb_sync_req[DATA])) {
335462306a36Sopenharmony_ci		/* to avoid potential deadlock */
335562306a36Sopenharmony_ci		if (current->plug)
335662306a36Sopenharmony_ci			blk_finish_plug(current->plug);
335762306a36Sopenharmony_ci		goto skip_write;
335862306a36Sopenharmony_ci	}
335962306a36Sopenharmony_ci
336062306a36Sopenharmony_ci	if (__should_serialize_io(inode, wbc)) {
336162306a36Sopenharmony_ci		mutex_lock(&sbi->writepages);
336262306a36Sopenharmony_ci		locked = true;
336362306a36Sopenharmony_ci	}
336462306a36Sopenharmony_ci
336562306a36Sopenharmony_ci	blk_start_plug(&plug);
336662306a36Sopenharmony_ci	ret = f2fs_write_cache_pages(mapping, wbc, io_type);
336762306a36Sopenharmony_ci	blk_finish_plug(&plug);
336862306a36Sopenharmony_ci
336962306a36Sopenharmony_ci	if (locked)
337062306a36Sopenharmony_ci		mutex_unlock(&sbi->writepages);
337162306a36Sopenharmony_ci
337262306a36Sopenharmony_ci	if (wbc->sync_mode == WB_SYNC_ALL)
337362306a36Sopenharmony_ci		atomic_dec(&sbi->wb_sync_req[DATA]);
337462306a36Sopenharmony_ci	/*
337562306a36Sopenharmony_ci	 * if some pages were truncated, we cannot guarantee its mapping->host
337662306a36Sopenharmony_ci	 * to detect pending bios.
337762306a36Sopenharmony_ci	 */
337862306a36Sopenharmony_ci
337962306a36Sopenharmony_ci	f2fs_remove_dirty_inode(inode);
338062306a36Sopenharmony_ci	return ret;
338162306a36Sopenharmony_ci
338262306a36Sopenharmony_ciskip_write:
338362306a36Sopenharmony_ci	wbc->pages_skipped += get_dirty_pages(inode);
338462306a36Sopenharmony_ci	trace_f2fs_writepages(mapping->host, wbc, DATA);
338562306a36Sopenharmony_ci	return 0;
338662306a36Sopenharmony_ci}
338762306a36Sopenharmony_ci
338862306a36Sopenharmony_cistatic int f2fs_write_data_pages(struct address_space *mapping,
338962306a36Sopenharmony_ci			    struct writeback_control *wbc)
339062306a36Sopenharmony_ci{
339162306a36Sopenharmony_ci	struct inode *inode = mapping->host;
339262306a36Sopenharmony_ci
339362306a36Sopenharmony_ci	return __f2fs_write_data_pages(mapping, wbc,
339462306a36Sopenharmony_ci			F2FS_I(inode)->cp_task == current ?
339562306a36Sopenharmony_ci			FS_CP_DATA_IO : FS_DATA_IO);
339662306a36Sopenharmony_ci}
339762306a36Sopenharmony_ci
339862306a36Sopenharmony_civoid f2fs_write_failed(struct inode *inode, loff_t to)
339962306a36Sopenharmony_ci{
340062306a36Sopenharmony_ci	loff_t i_size = i_size_read(inode);
340162306a36Sopenharmony_ci
340262306a36Sopenharmony_ci	if (IS_NOQUOTA(inode))
340362306a36Sopenharmony_ci		return;
340462306a36Sopenharmony_ci
340562306a36Sopenharmony_ci	/* In the fs-verity case, f2fs_end_enable_verity() does the truncate */
340662306a36Sopenharmony_ci	if (to > i_size && !f2fs_verity_in_progress(inode)) {
340762306a36Sopenharmony_ci		f2fs_down_write(&F2FS_I(inode)->i_gc_rwsem[WRITE]);
340862306a36Sopenharmony_ci		filemap_invalidate_lock(inode->i_mapping);
340962306a36Sopenharmony_ci
341062306a36Sopenharmony_ci		truncate_pagecache(inode, i_size);
341162306a36Sopenharmony_ci		f2fs_truncate_blocks(inode, i_size, true);
341262306a36Sopenharmony_ci
341362306a36Sopenharmony_ci		filemap_invalidate_unlock(inode->i_mapping);
341462306a36Sopenharmony_ci		f2fs_up_write(&F2FS_I(inode)->i_gc_rwsem[WRITE]);
341562306a36Sopenharmony_ci	}
341662306a36Sopenharmony_ci}
341762306a36Sopenharmony_ci
341862306a36Sopenharmony_cistatic int prepare_write_begin(struct f2fs_sb_info *sbi,
341962306a36Sopenharmony_ci			struct page *page, loff_t pos, unsigned len,
342062306a36Sopenharmony_ci			block_t *blk_addr, bool *node_changed)
342162306a36Sopenharmony_ci{
342262306a36Sopenharmony_ci	struct inode *inode = page->mapping->host;
342362306a36Sopenharmony_ci	pgoff_t index = page->index;
342462306a36Sopenharmony_ci	struct dnode_of_data dn;
342562306a36Sopenharmony_ci	struct page *ipage;
342662306a36Sopenharmony_ci	bool locked = false;
342762306a36Sopenharmony_ci	int flag = F2FS_GET_BLOCK_PRE_AIO;
342862306a36Sopenharmony_ci	int err = 0;
342962306a36Sopenharmony_ci
343062306a36Sopenharmony_ci	/*
343162306a36Sopenharmony_ci	 * If a whole page is being written and we already preallocated all the
343262306a36Sopenharmony_ci	 * blocks, then there is no need to get a block address now.
343362306a36Sopenharmony_ci	 */
343462306a36Sopenharmony_ci	if (len == PAGE_SIZE && is_inode_flag_set(inode, FI_PREALLOCATED_ALL))
343562306a36Sopenharmony_ci		return 0;
343662306a36Sopenharmony_ci
343762306a36Sopenharmony_ci	/* f2fs_lock_op avoids race between write CP and convert_inline_page */
343862306a36Sopenharmony_ci	if (f2fs_has_inline_data(inode)) {
343962306a36Sopenharmony_ci		if (pos + len > MAX_INLINE_DATA(inode))
344062306a36Sopenharmony_ci			flag = F2FS_GET_BLOCK_DEFAULT;
344162306a36Sopenharmony_ci		f2fs_map_lock(sbi, flag);
344262306a36Sopenharmony_ci		locked = true;
344362306a36Sopenharmony_ci	} else if ((pos & PAGE_MASK) >= i_size_read(inode)) {
344462306a36Sopenharmony_ci		f2fs_map_lock(sbi, flag);
344562306a36Sopenharmony_ci		locked = true;
344662306a36Sopenharmony_ci	}
344762306a36Sopenharmony_ci
344862306a36Sopenharmony_cirestart:
344962306a36Sopenharmony_ci	/* check inline_data */
345062306a36Sopenharmony_ci	ipage = f2fs_get_node_page(sbi, inode->i_ino);
345162306a36Sopenharmony_ci	if (IS_ERR(ipage)) {
345262306a36Sopenharmony_ci		err = PTR_ERR(ipage);
345362306a36Sopenharmony_ci		goto unlock_out;
345462306a36Sopenharmony_ci	}
345562306a36Sopenharmony_ci
345662306a36Sopenharmony_ci	set_new_dnode(&dn, inode, ipage, ipage, 0);
345762306a36Sopenharmony_ci
345862306a36Sopenharmony_ci	if (f2fs_has_inline_data(inode)) {
345962306a36Sopenharmony_ci		if (pos + len <= MAX_INLINE_DATA(inode)) {
346062306a36Sopenharmony_ci			f2fs_do_read_inline_data(page, ipage);
346162306a36Sopenharmony_ci			set_inode_flag(inode, FI_DATA_EXIST);
346262306a36Sopenharmony_ci			if (inode->i_nlink)
346362306a36Sopenharmony_ci				set_page_private_inline(ipage);
346462306a36Sopenharmony_ci			goto out;
346562306a36Sopenharmony_ci		}
346662306a36Sopenharmony_ci		err = f2fs_convert_inline_page(&dn, page);
346762306a36Sopenharmony_ci		if (err || dn.data_blkaddr != NULL_ADDR)
346862306a36Sopenharmony_ci			goto out;
346962306a36Sopenharmony_ci	}
347062306a36Sopenharmony_ci
347162306a36Sopenharmony_ci	if (!f2fs_lookup_read_extent_cache_block(inode, index,
347262306a36Sopenharmony_ci						 &dn.data_blkaddr)) {
347362306a36Sopenharmony_ci		if (locked) {
347462306a36Sopenharmony_ci			err = f2fs_reserve_block(&dn, index);
347562306a36Sopenharmony_ci			goto out;
347662306a36Sopenharmony_ci		}
347762306a36Sopenharmony_ci
347862306a36Sopenharmony_ci		/* hole case */
347962306a36Sopenharmony_ci		err = f2fs_get_dnode_of_data(&dn, index, LOOKUP_NODE);
348062306a36Sopenharmony_ci		if (!err && dn.data_blkaddr != NULL_ADDR)
348162306a36Sopenharmony_ci			goto out;
348262306a36Sopenharmony_ci		f2fs_put_dnode(&dn);
348362306a36Sopenharmony_ci		f2fs_map_lock(sbi, F2FS_GET_BLOCK_PRE_AIO);
348462306a36Sopenharmony_ci		WARN_ON(flag != F2FS_GET_BLOCK_PRE_AIO);
348562306a36Sopenharmony_ci		locked = true;
348662306a36Sopenharmony_ci		goto restart;
348762306a36Sopenharmony_ci	}
348862306a36Sopenharmony_ciout:
348962306a36Sopenharmony_ci	if (!err) {
349062306a36Sopenharmony_ci		/* convert_inline_page can make node_changed */
349162306a36Sopenharmony_ci		*blk_addr = dn.data_blkaddr;
349262306a36Sopenharmony_ci		*node_changed = dn.node_changed;
349362306a36Sopenharmony_ci	}
349462306a36Sopenharmony_ci	f2fs_put_dnode(&dn);
349562306a36Sopenharmony_ciunlock_out:
349662306a36Sopenharmony_ci	if (locked)
349762306a36Sopenharmony_ci		f2fs_map_unlock(sbi, flag);
349862306a36Sopenharmony_ci	return err;
349962306a36Sopenharmony_ci}
350062306a36Sopenharmony_ci
350162306a36Sopenharmony_cistatic int __find_data_block(struct inode *inode, pgoff_t index,
350262306a36Sopenharmony_ci				block_t *blk_addr)
350362306a36Sopenharmony_ci{
350462306a36Sopenharmony_ci	struct dnode_of_data dn;
350562306a36Sopenharmony_ci	struct page *ipage;
350662306a36Sopenharmony_ci	int err = 0;
350762306a36Sopenharmony_ci
350862306a36Sopenharmony_ci	ipage = f2fs_get_node_page(F2FS_I_SB(inode), inode->i_ino);
350962306a36Sopenharmony_ci	if (IS_ERR(ipage))
351062306a36Sopenharmony_ci		return PTR_ERR(ipage);
351162306a36Sopenharmony_ci
351262306a36Sopenharmony_ci	set_new_dnode(&dn, inode, ipage, ipage, 0);
351362306a36Sopenharmony_ci
351462306a36Sopenharmony_ci	if (!f2fs_lookup_read_extent_cache_block(inode, index,
351562306a36Sopenharmony_ci						 &dn.data_blkaddr)) {
351662306a36Sopenharmony_ci		/* hole case */
351762306a36Sopenharmony_ci		err = f2fs_get_dnode_of_data(&dn, index, LOOKUP_NODE);
351862306a36Sopenharmony_ci		if (err) {
351962306a36Sopenharmony_ci			dn.data_blkaddr = NULL_ADDR;
352062306a36Sopenharmony_ci			err = 0;
352162306a36Sopenharmony_ci		}
352262306a36Sopenharmony_ci	}
352362306a36Sopenharmony_ci	*blk_addr = dn.data_blkaddr;
352462306a36Sopenharmony_ci	f2fs_put_dnode(&dn);
352562306a36Sopenharmony_ci	return err;
352662306a36Sopenharmony_ci}
352762306a36Sopenharmony_ci
352862306a36Sopenharmony_cistatic int __reserve_data_block(struct inode *inode, pgoff_t index,
352962306a36Sopenharmony_ci				block_t *blk_addr, bool *node_changed)
353062306a36Sopenharmony_ci{
353162306a36Sopenharmony_ci	struct f2fs_sb_info *sbi = F2FS_I_SB(inode);
353262306a36Sopenharmony_ci	struct dnode_of_data dn;
353362306a36Sopenharmony_ci	struct page *ipage;
353462306a36Sopenharmony_ci	int err = 0;
353562306a36Sopenharmony_ci
353662306a36Sopenharmony_ci	f2fs_map_lock(sbi, F2FS_GET_BLOCK_PRE_AIO);
353762306a36Sopenharmony_ci
353862306a36Sopenharmony_ci	ipage = f2fs_get_node_page(sbi, inode->i_ino);
353962306a36Sopenharmony_ci	if (IS_ERR(ipage)) {
354062306a36Sopenharmony_ci		err = PTR_ERR(ipage);
354162306a36Sopenharmony_ci		goto unlock_out;
354262306a36Sopenharmony_ci	}
354362306a36Sopenharmony_ci	set_new_dnode(&dn, inode, ipage, ipage, 0);
354462306a36Sopenharmony_ci
354562306a36Sopenharmony_ci	if (!f2fs_lookup_read_extent_cache_block(dn.inode, index,
354662306a36Sopenharmony_ci						&dn.data_blkaddr))
354762306a36Sopenharmony_ci		err = f2fs_reserve_block(&dn, index);
354862306a36Sopenharmony_ci
354962306a36Sopenharmony_ci	*blk_addr = dn.data_blkaddr;
355062306a36Sopenharmony_ci	*node_changed = dn.node_changed;
355162306a36Sopenharmony_ci	f2fs_put_dnode(&dn);
355262306a36Sopenharmony_ci
355362306a36Sopenharmony_ciunlock_out:
355462306a36Sopenharmony_ci	f2fs_map_unlock(sbi, F2FS_GET_BLOCK_PRE_AIO);
355562306a36Sopenharmony_ci	return err;
355662306a36Sopenharmony_ci}
355762306a36Sopenharmony_ci
355862306a36Sopenharmony_cistatic int prepare_atomic_write_begin(struct f2fs_sb_info *sbi,
355962306a36Sopenharmony_ci			struct page *page, loff_t pos, unsigned int len,
356062306a36Sopenharmony_ci			block_t *blk_addr, bool *node_changed, bool *use_cow)
356162306a36Sopenharmony_ci{
356262306a36Sopenharmony_ci	struct inode *inode = page->mapping->host;
356362306a36Sopenharmony_ci	struct inode *cow_inode = F2FS_I(inode)->cow_inode;
356462306a36Sopenharmony_ci	pgoff_t index = page->index;
356562306a36Sopenharmony_ci	int err = 0;
356662306a36Sopenharmony_ci	block_t ori_blk_addr = NULL_ADDR;
356762306a36Sopenharmony_ci
356862306a36Sopenharmony_ci	/* If pos is beyond the end of file, reserve a new block in COW inode */
356962306a36Sopenharmony_ci	if ((pos & PAGE_MASK) >= i_size_read(inode))
357062306a36Sopenharmony_ci		goto reserve_block;
357162306a36Sopenharmony_ci
357262306a36Sopenharmony_ci	/* Look for the block in COW inode first */
357362306a36Sopenharmony_ci	err = __find_data_block(cow_inode, index, blk_addr);
357462306a36Sopenharmony_ci	if (err) {
357562306a36Sopenharmony_ci		return err;
357662306a36Sopenharmony_ci	} else if (*blk_addr != NULL_ADDR) {
357762306a36Sopenharmony_ci		*use_cow = true;
357862306a36Sopenharmony_ci		return 0;
357962306a36Sopenharmony_ci	}
358062306a36Sopenharmony_ci
358162306a36Sopenharmony_ci	if (is_inode_flag_set(inode, FI_ATOMIC_REPLACE))
358262306a36Sopenharmony_ci		goto reserve_block;
358362306a36Sopenharmony_ci
358462306a36Sopenharmony_ci	/* Look for the block in the original inode */
358562306a36Sopenharmony_ci	err = __find_data_block(inode, index, &ori_blk_addr);
358662306a36Sopenharmony_ci	if (err)
358762306a36Sopenharmony_ci		return err;
358862306a36Sopenharmony_ci
358962306a36Sopenharmony_cireserve_block:
359062306a36Sopenharmony_ci	/* Finally, we should reserve a new block in COW inode for the update */
359162306a36Sopenharmony_ci	err = __reserve_data_block(cow_inode, index, blk_addr, node_changed);
359262306a36Sopenharmony_ci	if (err)
359362306a36Sopenharmony_ci		return err;
359462306a36Sopenharmony_ci	inc_atomic_write_cnt(inode);
359562306a36Sopenharmony_ci
359662306a36Sopenharmony_ci	if (ori_blk_addr != NULL_ADDR)
359762306a36Sopenharmony_ci		*blk_addr = ori_blk_addr;
359862306a36Sopenharmony_ci	return 0;
359962306a36Sopenharmony_ci}
360062306a36Sopenharmony_ci
360162306a36Sopenharmony_cistatic int f2fs_write_begin(struct file *file, struct address_space *mapping,
360262306a36Sopenharmony_ci		loff_t pos, unsigned len, struct page **pagep, void **fsdata)
360362306a36Sopenharmony_ci{
360462306a36Sopenharmony_ci	struct inode *inode = mapping->host;
360562306a36Sopenharmony_ci	struct f2fs_sb_info *sbi = F2FS_I_SB(inode);
360662306a36Sopenharmony_ci	struct page *page = NULL;
360762306a36Sopenharmony_ci	pgoff_t index = ((unsigned long long) pos) >> PAGE_SHIFT;
360862306a36Sopenharmony_ci	bool need_balance = false;
360962306a36Sopenharmony_ci	bool use_cow = false;
361062306a36Sopenharmony_ci	block_t blkaddr = NULL_ADDR;
361162306a36Sopenharmony_ci	int err = 0;
361262306a36Sopenharmony_ci
361362306a36Sopenharmony_ci	trace_f2fs_write_begin(inode, pos, len);
361462306a36Sopenharmony_ci
361562306a36Sopenharmony_ci	if (!f2fs_is_checkpoint_ready(sbi)) {
361662306a36Sopenharmony_ci		err = -ENOSPC;
361762306a36Sopenharmony_ci		goto fail;
361862306a36Sopenharmony_ci	}
361962306a36Sopenharmony_ci
362062306a36Sopenharmony_ci	/*
362162306a36Sopenharmony_ci	 * We should check this at this moment to avoid deadlock on inode page
362262306a36Sopenharmony_ci	 * and #0 page. The locking rule for inline_data conversion should be:
362362306a36Sopenharmony_ci	 * lock_page(page #0) -> lock_page(inode_page)
362462306a36Sopenharmony_ci	 */
362562306a36Sopenharmony_ci	if (index != 0) {
362662306a36Sopenharmony_ci		err = f2fs_convert_inline_inode(inode);
362762306a36Sopenharmony_ci		if (err)
362862306a36Sopenharmony_ci			goto fail;
362962306a36Sopenharmony_ci	}
363062306a36Sopenharmony_ci
363162306a36Sopenharmony_ci#ifdef CONFIG_F2FS_FS_COMPRESSION
363262306a36Sopenharmony_ci	if (f2fs_compressed_file(inode)) {
363362306a36Sopenharmony_ci		int ret;
363462306a36Sopenharmony_ci
363562306a36Sopenharmony_ci		*fsdata = NULL;
363662306a36Sopenharmony_ci
363762306a36Sopenharmony_ci		if (len == PAGE_SIZE && !(f2fs_is_atomic_file(inode)))
363862306a36Sopenharmony_ci			goto repeat;
363962306a36Sopenharmony_ci
364062306a36Sopenharmony_ci		ret = f2fs_prepare_compress_overwrite(inode, pagep,
364162306a36Sopenharmony_ci							index, fsdata);
364262306a36Sopenharmony_ci		if (ret < 0) {
364362306a36Sopenharmony_ci			err = ret;
364462306a36Sopenharmony_ci			goto fail;
364562306a36Sopenharmony_ci		} else if (ret) {
364662306a36Sopenharmony_ci			return 0;
364762306a36Sopenharmony_ci		}
364862306a36Sopenharmony_ci	}
364962306a36Sopenharmony_ci#endif
365062306a36Sopenharmony_ci
365162306a36Sopenharmony_cirepeat:
365262306a36Sopenharmony_ci	/*
365362306a36Sopenharmony_ci	 * Do not use grab_cache_page_write_begin() to avoid deadlock due to
365462306a36Sopenharmony_ci	 * wait_for_stable_page. Will wait that below with our IO control.
365562306a36Sopenharmony_ci	 */
365662306a36Sopenharmony_ci	page = f2fs_pagecache_get_page(mapping, index,
365762306a36Sopenharmony_ci				FGP_LOCK | FGP_WRITE | FGP_CREAT, GFP_NOFS);
365862306a36Sopenharmony_ci	if (!page) {
365962306a36Sopenharmony_ci		err = -ENOMEM;
366062306a36Sopenharmony_ci		goto fail;
366162306a36Sopenharmony_ci	}
366262306a36Sopenharmony_ci
366362306a36Sopenharmony_ci	/* TODO: cluster can be compressed due to race with .writepage */
366462306a36Sopenharmony_ci
366562306a36Sopenharmony_ci	*pagep = page;
366662306a36Sopenharmony_ci
366762306a36Sopenharmony_ci	if (f2fs_is_atomic_file(inode))
366862306a36Sopenharmony_ci		err = prepare_atomic_write_begin(sbi, page, pos, len,
366962306a36Sopenharmony_ci					&blkaddr, &need_balance, &use_cow);
367062306a36Sopenharmony_ci	else
367162306a36Sopenharmony_ci		err = prepare_write_begin(sbi, page, pos, len,
367262306a36Sopenharmony_ci					&blkaddr, &need_balance);
367362306a36Sopenharmony_ci	if (err)
367462306a36Sopenharmony_ci		goto fail;
367562306a36Sopenharmony_ci
367662306a36Sopenharmony_ci	if (need_balance && !IS_NOQUOTA(inode) &&
367762306a36Sopenharmony_ci			has_not_enough_free_secs(sbi, 0, 0)) {
367862306a36Sopenharmony_ci		unlock_page(page);
367962306a36Sopenharmony_ci		f2fs_balance_fs(sbi, true);
368062306a36Sopenharmony_ci		lock_page(page);
368162306a36Sopenharmony_ci		if (page->mapping != mapping) {
368262306a36Sopenharmony_ci			/* The page got truncated from under us */
368362306a36Sopenharmony_ci			f2fs_put_page(page, 1);
368462306a36Sopenharmony_ci			goto repeat;
368562306a36Sopenharmony_ci		}
368662306a36Sopenharmony_ci	}
368762306a36Sopenharmony_ci
368862306a36Sopenharmony_ci	f2fs_wait_on_page_writeback(page, DATA, false, true);
368962306a36Sopenharmony_ci
369062306a36Sopenharmony_ci	if (len == PAGE_SIZE || PageUptodate(page))
369162306a36Sopenharmony_ci		return 0;
369262306a36Sopenharmony_ci
369362306a36Sopenharmony_ci	if (!(pos & (PAGE_SIZE - 1)) && (pos + len) >= i_size_read(inode) &&
369462306a36Sopenharmony_ci	    !f2fs_verity_in_progress(inode)) {
369562306a36Sopenharmony_ci		zero_user_segment(page, len, PAGE_SIZE);
369662306a36Sopenharmony_ci		return 0;
369762306a36Sopenharmony_ci	}
369862306a36Sopenharmony_ci
369962306a36Sopenharmony_ci	if (blkaddr == NEW_ADDR) {
370062306a36Sopenharmony_ci		zero_user_segment(page, 0, PAGE_SIZE);
370162306a36Sopenharmony_ci		SetPageUptodate(page);
370262306a36Sopenharmony_ci	} else {
370362306a36Sopenharmony_ci		if (!f2fs_is_valid_blkaddr(sbi, blkaddr,
370462306a36Sopenharmony_ci				DATA_GENERIC_ENHANCE_READ)) {
370562306a36Sopenharmony_ci			err = -EFSCORRUPTED;
370662306a36Sopenharmony_ci			f2fs_handle_error(sbi, ERROR_INVALID_BLKADDR);
370762306a36Sopenharmony_ci			goto fail;
370862306a36Sopenharmony_ci		}
370962306a36Sopenharmony_ci		err = f2fs_submit_page_read(use_cow ?
371062306a36Sopenharmony_ci				F2FS_I(inode)->cow_inode : inode, page,
371162306a36Sopenharmony_ci				blkaddr, 0, true);
371262306a36Sopenharmony_ci		if (err)
371362306a36Sopenharmony_ci			goto fail;
371462306a36Sopenharmony_ci
371562306a36Sopenharmony_ci		lock_page(page);
371662306a36Sopenharmony_ci		if (unlikely(page->mapping != mapping)) {
371762306a36Sopenharmony_ci			f2fs_put_page(page, 1);
371862306a36Sopenharmony_ci			goto repeat;
371962306a36Sopenharmony_ci		}
372062306a36Sopenharmony_ci		if (unlikely(!PageUptodate(page))) {
372162306a36Sopenharmony_ci			err = -EIO;
372262306a36Sopenharmony_ci			goto fail;
372362306a36Sopenharmony_ci		}
372462306a36Sopenharmony_ci	}
372562306a36Sopenharmony_ci	return 0;
372662306a36Sopenharmony_ci
372762306a36Sopenharmony_cifail:
372862306a36Sopenharmony_ci	f2fs_put_page(page, 1);
372962306a36Sopenharmony_ci	f2fs_write_failed(inode, pos + len);
373062306a36Sopenharmony_ci	return err;
373162306a36Sopenharmony_ci}
373262306a36Sopenharmony_ci
373362306a36Sopenharmony_cistatic int f2fs_write_end(struct file *file,
373462306a36Sopenharmony_ci			struct address_space *mapping,
373562306a36Sopenharmony_ci			loff_t pos, unsigned len, unsigned copied,
373662306a36Sopenharmony_ci			struct page *page, void *fsdata)
373762306a36Sopenharmony_ci{
373862306a36Sopenharmony_ci	struct inode *inode = page->mapping->host;
373962306a36Sopenharmony_ci
374062306a36Sopenharmony_ci	trace_f2fs_write_end(inode, pos, len, copied);
374162306a36Sopenharmony_ci
374262306a36Sopenharmony_ci	/*
374362306a36Sopenharmony_ci	 * This should be come from len == PAGE_SIZE, and we expect copied
374462306a36Sopenharmony_ci	 * should be PAGE_SIZE. Otherwise, we treat it with zero copied and
374562306a36Sopenharmony_ci	 * let generic_perform_write() try to copy data again through copied=0.
374662306a36Sopenharmony_ci	 */
374762306a36Sopenharmony_ci	if (!PageUptodate(page)) {
374862306a36Sopenharmony_ci		if (unlikely(copied != len))
374962306a36Sopenharmony_ci			copied = 0;
375062306a36Sopenharmony_ci		else
375162306a36Sopenharmony_ci			SetPageUptodate(page);
375262306a36Sopenharmony_ci	}
375362306a36Sopenharmony_ci
375462306a36Sopenharmony_ci#ifdef CONFIG_F2FS_FS_COMPRESSION
375562306a36Sopenharmony_ci	/* overwrite compressed file */
375662306a36Sopenharmony_ci	if (f2fs_compressed_file(inode) && fsdata) {
375762306a36Sopenharmony_ci		f2fs_compress_write_end(inode, fsdata, page->index, copied);
375862306a36Sopenharmony_ci		f2fs_update_time(F2FS_I_SB(inode), REQ_TIME);
375962306a36Sopenharmony_ci
376062306a36Sopenharmony_ci		if (pos + copied > i_size_read(inode) &&
376162306a36Sopenharmony_ci				!f2fs_verity_in_progress(inode))
376262306a36Sopenharmony_ci			f2fs_i_size_write(inode, pos + copied);
376362306a36Sopenharmony_ci		return copied;
376462306a36Sopenharmony_ci	}
376562306a36Sopenharmony_ci#endif
376662306a36Sopenharmony_ci
376762306a36Sopenharmony_ci	if (!copied)
376862306a36Sopenharmony_ci		goto unlock_out;
376962306a36Sopenharmony_ci
377062306a36Sopenharmony_ci	set_page_dirty(page);
377162306a36Sopenharmony_ci
377262306a36Sopenharmony_ci	if (pos + copied > i_size_read(inode) &&
377362306a36Sopenharmony_ci	    !f2fs_verity_in_progress(inode)) {
377462306a36Sopenharmony_ci		f2fs_i_size_write(inode, pos + copied);
377562306a36Sopenharmony_ci		if (f2fs_is_atomic_file(inode))
377662306a36Sopenharmony_ci			f2fs_i_size_write(F2FS_I(inode)->cow_inode,
377762306a36Sopenharmony_ci					pos + copied);
377862306a36Sopenharmony_ci	}
377962306a36Sopenharmony_ciunlock_out:
378062306a36Sopenharmony_ci	f2fs_put_page(page, 1);
378162306a36Sopenharmony_ci	f2fs_update_time(F2FS_I_SB(inode), REQ_TIME);
378262306a36Sopenharmony_ci	return copied;
378362306a36Sopenharmony_ci}
378462306a36Sopenharmony_ci
378562306a36Sopenharmony_civoid f2fs_invalidate_folio(struct folio *folio, size_t offset, size_t length)
378662306a36Sopenharmony_ci{
378762306a36Sopenharmony_ci	struct inode *inode = folio->mapping->host;
378862306a36Sopenharmony_ci	struct f2fs_sb_info *sbi = F2FS_I_SB(inode);
378962306a36Sopenharmony_ci
379062306a36Sopenharmony_ci	if (inode->i_ino >= F2FS_ROOT_INO(sbi) &&
379162306a36Sopenharmony_ci				(offset || length != folio_size(folio)))
379262306a36Sopenharmony_ci		return;
379362306a36Sopenharmony_ci
379462306a36Sopenharmony_ci	if (folio_test_dirty(folio)) {
379562306a36Sopenharmony_ci		if (inode->i_ino == F2FS_META_INO(sbi)) {
379662306a36Sopenharmony_ci			dec_page_count(sbi, F2FS_DIRTY_META);
379762306a36Sopenharmony_ci		} else if (inode->i_ino == F2FS_NODE_INO(sbi)) {
379862306a36Sopenharmony_ci			dec_page_count(sbi, F2FS_DIRTY_NODES);
379962306a36Sopenharmony_ci		} else {
380062306a36Sopenharmony_ci			inode_dec_dirty_pages(inode);
380162306a36Sopenharmony_ci			f2fs_remove_dirty_inode(inode);
380262306a36Sopenharmony_ci		}
380362306a36Sopenharmony_ci	}
380462306a36Sopenharmony_ci	clear_page_private_all(&folio->page);
380562306a36Sopenharmony_ci}
380662306a36Sopenharmony_ci
380762306a36Sopenharmony_cibool f2fs_release_folio(struct folio *folio, gfp_t wait)
380862306a36Sopenharmony_ci{
380962306a36Sopenharmony_ci	/* If this is dirty folio, keep private data */
381062306a36Sopenharmony_ci	if (folio_test_dirty(folio))
381162306a36Sopenharmony_ci		return false;
381262306a36Sopenharmony_ci
381362306a36Sopenharmony_ci	clear_page_private_all(&folio->page);
381462306a36Sopenharmony_ci	return true;
381562306a36Sopenharmony_ci}
381662306a36Sopenharmony_ci
381762306a36Sopenharmony_cistatic bool f2fs_dirty_data_folio(struct address_space *mapping,
381862306a36Sopenharmony_ci		struct folio *folio)
381962306a36Sopenharmony_ci{
382062306a36Sopenharmony_ci	struct inode *inode = mapping->host;
382162306a36Sopenharmony_ci
382262306a36Sopenharmony_ci	trace_f2fs_set_page_dirty(&folio->page, DATA);
382362306a36Sopenharmony_ci
382462306a36Sopenharmony_ci	if (!folio_test_uptodate(folio))
382562306a36Sopenharmony_ci		folio_mark_uptodate(folio);
382662306a36Sopenharmony_ci	BUG_ON(folio_test_swapcache(folio));
382762306a36Sopenharmony_ci
382862306a36Sopenharmony_ci	if (filemap_dirty_folio(mapping, folio)) {
382962306a36Sopenharmony_ci		f2fs_update_dirty_folio(inode, folio);
383062306a36Sopenharmony_ci		return true;
383162306a36Sopenharmony_ci	}
383262306a36Sopenharmony_ci	return false;
383362306a36Sopenharmony_ci}
383462306a36Sopenharmony_ci
383562306a36Sopenharmony_ci
383662306a36Sopenharmony_cistatic sector_t f2fs_bmap_compress(struct inode *inode, sector_t block)
383762306a36Sopenharmony_ci{
383862306a36Sopenharmony_ci#ifdef CONFIG_F2FS_FS_COMPRESSION
383962306a36Sopenharmony_ci	struct dnode_of_data dn;
384062306a36Sopenharmony_ci	sector_t start_idx, blknr = 0;
384162306a36Sopenharmony_ci	int ret;
384262306a36Sopenharmony_ci
384362306a36Sopenharmony_ci	start_idx = round_down(block, F2FS_I(inode)->i_cluster_size);
384462306a36Sopenharmony_ci
384562306a36Sopenharmony_ci	set_new_dnode(&dn, inode, NULL, NULL, 0);
384662306a36Sopenharmony_ci	ret = f2fs_get_dnode_of_data(&dn, start_idx, LOOKUP_NODE);
384762306a36Sopenharmony_ci	if (ret)
384862306a36Sopenharmony_ci		return 0;
384962306a36Sopenharmony_ci
385062306a36Sopenharmony_ci	if (dn.data_blkaddr != COMPRESS_ADDR) {
385162306a36Sopenharmony_ci		dn.ofs_in_node += block - start_idx;
385262306a36Sopenharmony_ci		blknr = f2fs_data_blkaddr(&dn);
385362306a36Sopenharmony_ci		if (!__is_valid_data_blkaddr(blknr))
385462306a36Sopenharmony_ci			blknr = 0;
385562306a36Sopenharmony_ci	}
385662306a36Sopenharmony_ci
385762306a36Sopenharmony_ci	f2fs_put_dnode(&dn);
385862306a36Sopenharmony_ci	return blknr;
385962306a36Sopenharmony_ci#else
386062306a36Sopenharmony_ci	return 0;
386162306a36Sopenharmony_ci#endif
386262306a36Sopenharmony_ci}
386362306a36Sopenharmony_ci
386462306a36Sopenharmony_ci
386562306a36Sopenharmony_cistatic sector_t f2fs_bmap(struct address_space *mapping, sector_t block)
386662306a36Sopenharmony_ci{
386762306a36Sopenharmony_ci	struct inode *inode = mapping->host;
386862306a36Sopenharmony_ci	sector_t blknr = 0;
386962306a36Sopenharmony_ci
387062306a36Sopenharmony_ci	if (f2fs_has_inline_data(inode))
387162306a36Sopenharmony_ci		goto out;
387262306a36Sopenharmony_ci
387362306a36Sopenharmony_ci	/* make sure allocating whole blocks */
387462306a36Sopenharmony_ci	if (mapping_tagged(mapping, PAGECACHE_TAG_DIRTY))
387562306a36Sopenharmony_ci		filemap_write_and_wait(mapping);
387662306a36Sopenharmony_ci
387762306a36Sopenharmony_ci	/* Block number less than F2FS MAX BLOCKS */
387862306a36Sopenharmony_ci	if (unlikely(block >= max_file_blocks(inode)))
387962306a36Sopenharmony_ci		goto out;
388062306a36Sopenharmony_ci
388162306a36Sopenharmony_ci	if (f2fs_compressed_file(inode)) {
388262306a36Sopenharmony_ci		blknr = f2fs_bmap_compress(inode, block);
388362306a36Sopenharmony_ci	} else {
388462306a36Sopenharmony_ci		struct f2fs_map_blocks map;
388562306a36Sopenharmony_ci
388662306a36Sopenharmony_ci		memset(&map, 0, sizeof(map));
388762306a36Sopenharmony_ci		map.m_lblk = block;
388862306a36Sopenharmony_ci		map.m_len = 1;
388962306a36Sopenharmony_ci		map.m_next_pgofs = NULL;
389062306a36Sopenharmony_ci		map.m_seg_type = NO_CHECK_TYPE;
389162306a36Sopenharmony_ci
389262306a36Sopenharmony_ci		if (!f2fs_map_blocks(inode, &map, F2FS_GET_BLOCK_BMAP))
389362306a36Sopenharmony_ci			blknr = map.m_pblk;
389462306a36Sopenharmony_ci	}
389562306a36Sopenharmony_ciout:
389662306a36Sopenharmony_ci	trace_f2fs_bmap(inode, block, blknr);
389762306a36Sopenharmony_ci	return blknr;
389862306a36Sopenharmony_ci}
389962306a36Sopenharmony_ci
390062306a36Sopenharmony_ci#ifdef CONFIG_SWAP
390162306a36Sopenharmony_cistatic int f2fs_migrate_blocks(struct inode *inode, block_t start_blk,
390262306a36Sopenharmony_ci							unsigned int blkcnt)
390362306a36Sopenharmony_ci{
390462306a36Sopenharmony_ci	struct f2fs_sb_info *sbi = F2FS_I_SB(inode);
390562306a36Sopenharmony_ci	unsigned int blkofs;
390662306a36Sopenharmony_ci	unsigned int blk_per_sec = BLKS_PER_SEC(sbi);
390762306a36Sopenharmony_ci	unsigned int secidx = start_blk / blk_per_sec;
390862306a36Sopenharmony_ci	unsigned int end_sec = secidx + blkcnt / blk_per_sec;
390962306a36Sopenharmony_ci	int ret = 0;
391062306a36Sopenharmony_ci
391162306a36Sopenharmony_ci	f2fs_down_write(&F2FS_I(inode)->i_gc_rwsem[WRITE]);
391262306a36Sopenharmony_ci	filemap_invalidate_lock(inode->i_mapping);
391362306a36Sopenharmony_ci
391462306a36Sopenharmony_ci	set_inode_flag(inode, FI_ALIGNED_WRITE);
391562306a36Sopenharmony_ci	set_inode_flag(inode, FI_OPU_WRITE);
391662306a36Sopenharmony_ci
391762306a36Sopenharmony_ci	for (; secidx < end_sec; secidx++) {
391862306a36Sopenharmony_ci		f2fs_down_write(&sbi->pin_sem);
391962306a36Sopenharmony_ci
392062306a36Sopenharmony_ci		f2fs_lock_op(sbi);
392162306a36Sopenharmony_ci		f2fs_allocate_new_section(sbi, CURSEG_COLD_DATA_PINNED, false);
392262306a36Sopenharmony_ci		f2fs_unlock_op(sbi);
392362306a36Sopenharmony_ci
392462306a36Sopenharmony_ci		set_inode_flag(inode, FI_SKIP_WRITES);
392562306a36Sopenharmony_ci
392662306a36Sopenharmony_ci		for (blkofs = 0; blkofs < blk_per_sec; blkofs++) {
392762306a36Sopenharmony_ci			struct page *page;
392862306a36Sopenharmony_ci			unsigned int blkidx = secidx * blk_per_sec + blkofs;
392962306a36Sopenharmony_ci
393062306a36Sopenharmony_ci			page = f2fs_get_lock_data_page(inode, blkidx, true);
393162306a36Sopenharmony_ci			if (IS_ERR(page)) {
393262306a36Sopenharmony_ci				f2fs_up_write(&sbi->pin_sem);
393362306a36Sopenharmony_ci				ret = PTR_ERR(page);
393462306a36Sopenharmony_ci				goto done;
393562306a36Sopenharmony_ci			}
393662306a36Sopenharmony_ci
393762306a36Sopenharmony_ci			set_page_dirty(page);
393862306a36Sopenharmony_ci			f2fs_put_page(page, 1);
393962306a36Sopenharmony_ci		}
394062306a36Sopenharmony_ci
394162306a36Sopenharmony_ci		clear_inode_flag(inode, FI_SKIP_WRITES);
394262306a36Sopenharmony_ci
394362306a36Sopenharmony_ci		ret = filemap_fdatawrite(inode->i_mapping);
394462306a36Sopenharmony_ci
394562306a36Sopenharmony_ci		f2fs_up_write(&sbi->pin_sem);
394662306a36Sopenharmony_ci
394762306a36Sopenharmony_ci		if (ret)
394862306a36Sopenharmony_ci			break;
394962306a36Sopenharmony_ci	}
395062306a36Sopenharmony_ci
395162306a36Sopenharmony_cidone:
395262306a36Sopenharmony_ci	clear_inode_flag(inode, FI_SKIP_WRITES);
395362306a36Sopenharmony_ci	clear_inode_flag(inode, FI_OPU_WRITE);
395462306a36Sopenharmony_ci	clear_inode_flag(inode, FI_ALIGNED_WRITE);
395562306a36Sopenharmony_ci
395662306a36Sopenharmony_ci	filemap_invalidate_unlock(inode->i_mapping);
395762306a36Sopenharmony_ci	f2fs_up_write(&F2FS_I(inode)->i_gc_rwsem[WRITE]);
395862306a36Sopenharmony_ci
395962306a36Sopenharmony_ci	return ret;
396062306a36Sopenharmony_ci}
396162306a36Sopenharmony_ci
396262306a36Sopenharmony_cistatic int check_swap_activate(struct swap_info_struct *sis,
396362306a36Sopenharmony_ci				struct file *swap_file, sector_t *span)
396462306a36Sopenharmony_ci{
396562306a36Sopenharmony_ci	struct address_space *mapping = swap_file->f_mapping;
396662306a36Sopenharmony_ci	struct inode *inode = mapping->host;
396762306a36Sopenharmony_ci	struct f2fs_sb_info *sbi = F2FS_I_SB(inode);
396862306a36Sopenharmony_ci	sector_t cur_lblock;
396962306a36Sopenharmony_ci	sector_t last_lblock;
397062306a36Sopenharmony_ci	sector_t pblock;
397162306a36Sopenharmony_ci	sector_t lowest_pblock = -1;
397262306a36Sopenharmony_ci	sector_t highest_pblock = 0;
397362306a36Sopenharmony_ci	int nr_extents = 0;
397462306a36Sopenharmony_ci	unsigned long nr_pblocks;
397562306a36Sopenharmony_ci	unsigned int blks_per_sec = BLKS_PER_SEC(sbi);
397662306a36Sopenharmony_ci	unsigned int sec_blks_mask = BLKS_PER_SEC(sbi) - 1;
397762306a36Sopenharmony_ci	unsigned int not_aligned = 0;
397862306a36Sopenharmony_ci	int ret = 0;
397962306a36Sopenharmony_ci
398062306a36Sopenharmony_ci	/*
398162306a36Sopenharmony_ci	 * Map all the blocks into the extent list.  This code doesn't try
398262306a36Sopenharmony_ci	 * to be very smart.
398362306a36Sopenharmony_ci	 */
398462306a36Sopenharmony_ci	cur_lblock = 0;
398562306a36Sopenharmony_ci	last_lblock = bytes_to_blks(inode, i_size_read(inode));
398662306a36Sopenharmony_ci
398762306a36Sopenharmony_ci	while (cur_lblock < last_lblock && cur_lblock < sis->max) {
398862306a36Sopenharmony_ci		struct f2fs_map_blocks map;
398962306a36Sopenharmony_ciretry:
399062306a36Sopenharmony_ci		cond_resched();
399162306a36Sopenharmony_ci
399262306a36Sopenharmony_ci		memset(&map, 0, sizeof(map));
399362306a36Sopenharmony_ci		map.m_lblk = cur_lblock;
399462306a36Sopenharmony_ci		map.m_len = last_lblock - cur_lblock;
399562306a36Sopenharmony_ci		map.m_next_pgofs = NULL;
399662306a36Sopenharmony_ci		map.m_next_extent = NULL;
399762306a36Sopenharmony_ci		map.m_seg_type = NO_CHECK_TYPE;
399862306a36Sopenharmony_ci		map.m_may_create = false;
399962306a36Sopenharmony_ci
400062306a36Sopenharmony_ci		ret = f2fs_map_blocks(inode, &map, F2FS_GET_BLOCK_FIEMAP);
400162306a36Sopenharmony_ci		if (ret)
400262306a36Sopenharmony_ci			goto out;
400362306a36Sopenharmony_ci
400462306a36Sopenharmony_ci		/* hole */
400562306a36Sopenharmony_ci		if (!(map.m_flags & F2FS_MAP_FLAGS)) {
400662306a36Sopenharmony_ci			f2fs_err(sbi, "Swapfile has holes");
400762306a36Sopenharmony_ci			ret = -EINVAL;
400862306a36Sopenharmony_ci			goto out;
400962306a36Sopenharmony_ci		}
401062306a36Sopenharmony_ci
401162306a36Sopenharmony_ci		pblock = map.m_pblk;
401262306a36Sopenharmony_ci		nr_pblocks = map.m_len;
401362306a36Sopenharmony_ci
401462306a36Sopenharmony_ci		if ((pblock - SM_I(sbi)->main_blkaddr) & sec_blks_mask ||
401562306a36Sopenharmony_ci				nr_pblocks & sec_blks_mask) {
401662306a36Sopenharmony_ci			not_aligned++;
401762306a36Sopenharmony_ci
401862306a36Sopenharmony_ci			nr_pblocks = roundup(nr_pblocks, blks_per_sec);
401962306a36Sopenharmony_ci			if (cur_lblock + nr_pblocks > sis->max)
402062306a36Sopenharmony_ci				nr_pblocks -= blks_per_sec;
402162306a36Sopenharmony_ci
402262306a36Sopenharmony_ci			if (!nr_pblocks) {
402362306a36Sopenharmony_ci				/* this extent is last one */
402462306a36Sopenharmony_ci				nr_pblocks = map.m_len;
402562306a36Sopenharmony_ci				f2fs_warn(sbi, "Swapfile: last extent is not aligned to section");
402662306a36Sopenharmony_ci				goto next;
402762306a36Sopenharmony_ci			}
402862306a36Sopenharmony_ci
402962306a36Sopenharmony_ci			ret = f2fs_migrate_blocks(inode, cur_lblock,
403062306a36Sopenharmony_ci							nr_pblocks);
403162306a36Sopenharmony_ci			if (ret)
403262306a36Sopenharmony_ci				goto out;
403362306a36Sopenharmony_ci			goto retry;
403462306a36Sopenharmony_ci		}
403562306a36Sopenharmony_cinext:
403662306a36Sopenharmony_ci		if (cur_lblock + nr_pblocks >= sis->max)
403762306a36Sopenharmony_ci			nr_pblocks = sis->max - cur_lblock;
403862306a36Sopenharmony_ci
403962306a36Sopenharmony_ci		if (cur_lblock) {	/* exclude the header page */
404062306a36Sopenharmony_ci			if (pblock < lowest_pblock)
404162306a36Sopenharmony_ci				lowest_pblock = pblock;
404262306a36Sopenharmony_ci			if (pblock + nr_pblocks - 1 > highest_pblock)
404362306a36Sopenharmony_ci				highest_pblock = pblock + nr_pblocks - 1;
404462306a36Sopenharmony_ci		}
404562306a36Sopenharmony_ci
404662306a36Sopenharmony_ci		/*
404762306a36Sopenharmony_ci		 * We found a PAGE_SIZE-length, PAGE_SIZE-aligned run of blocks
404862306a36Sopenharmony_ci		 */
404962306a36Sopenharmony_ci		ret = add_swap_extent(sis, cur_lblock, nr_pblocks, pblock);
405062306a36Sopenharmony_ci		if (ret < 0)
405162306a36Sopenharmony_ci			goto out;
405262306a36Sopenharmony_ci		nr_extents += ret;
405362306a36Sopenharmony_ci		cur_lblock += nr_pblocks;
405462306a36Sopenharmony_ci	}
405562306a36Sopenharmony_ci	ret = nr_extents;
405662306a36Sopenharmony_ci	*span = 1 + highest_pblock - lowest_pblock;
405762306a36Sopenharmony_ci	if (cur_lblock == 0)
405862306a36Sopenharmony_ci		cur_lblock = 1;	/* force Empty message */
405962306a36Sopenharmony_ci	sis->max = cur_lblock;
406062306a36Sopenharmony_ci	sis->pages = cur_lblock - 1;
406162306a36Sopenharmony_ci	sis->highest_bit = cur_lblock - 1;
406262306a36Sopenharmony_ciout:
406362306a36Sopenharmony_ci	if (not_aligned)
406462306a36Sopenharmony_ci		f2fs_warn(sbi, "Swapfile (%u) is not align to section: 1) creat(), 2) ioctl(F2FS_IOC_SET_PIN_FILE), 3) fallocate(%u * N)",
406562306a36Sopenharmony_ci			  not_aligned, blks_per_sec * F2FS_BLKSIZE);
406662306a36Sopenharmony_ci	return ret;
406762306a36Sopenharmony_ci}
406862306a36Sopenharmony_ci
406962306a36Sopenharmony_cistatic int f2fs_swap_activate(struct swap_info_struct *sis, struct file *file,
407062306a36Sopenharmony_ci				sector_t *span)
407162306a36Sopenharmony_ci{
407262306a36Sopenharmony_ci	struct inode *inode = file_inode(file);
407362306a36Sopenharmony_ci	int ret;
407462306a36Sopenharmony_ci
407562306a36Sopenharmony_ci	if (!S_ISREG(inode->i_mode))
407662306a36Sopenharmony_ci		return -EINVAL;
407762306a36Sopenharmony_ci
407862306a36Sopenharmony_ci	if (f2fs_readonly(F2FS_I_SB(inode)->sb))
407962306a36Sopenharmony_ci		return -EROFS;
408062306a36Sopenharmony_ci
408162306a36Sopenharmony_ci	if (f2fs_lfs_mode(F2FS_I_SB(inode))) {
408262306a36Sopenharmony_ci		f2fs_err(F2FS_I_SB(inode),
408362306a36Sopenharmony_ci			"Swapfile not supported in LFS mode");
408462306a36Sopenharmony_ci		return -EINVAL;
408562306a36Sopenharmony_ci	}
408662306a36Sopenharmony_ci
408762306a36Sopenharmony_ci	ret = f2fs_convert_inline_inode(inode);
408862306a36Sopenharmony_ci	if (ret)
408962306a36Sopenharmony_ci		return ret;
409062306a36Sopenharmony_ci
409162306a36Sopenharmony_ci	if (!f2fs_disable_compressed_file(inode))
409262306a36Sopenharmony_ci		return -EINVAL;
409362306a36Sopenharmony_ci
409462306a36Sopenharmony_ci	f2fs_precache_extents(inode);
409562306a36Sopenharmony_ci
409662306a36Sopenharmony_ci	ret = check_swap_activate(sis, file, span);
409762306a36Sopenharmony_ci	if (ret < 0)
409862306a36Sopenharmony_ci		return ret;
409962306a36Sopenharmony_ci
410062306a36Sopenharmony_ci	stat_inc_swapfile_inode(inode);
410162306a36Sopenharmony_ci	set_inode_flag(inode, FI_PIN_FILE);
410262306a36Sopenharmony_ci	f2fs_update_time(F2FS_I_SB(inode), REQ_TIME);
410362306a36Sopenharmony_ci	return ret;
410462306a36Sopenharmony_ci}
410562306a36Sopenharmony_ci
410662306a36Sopenharmony_cistatic void f2fs_swap_deactivate(struct file *file)
410762306a36Sopenharmony_ci{
410862306a36Sopenharmony_ci	struct inode *inode = file_inode(file);
410962306a36Sopenharmony_ci
411062306a36Sopenharmony_ci	stat_dec_swapfile_inode(inode);
411162306a36Sopenharmony_ci	clear_inode_flag(inode, FI_PIN_FILE);
411262306a36Sopenharmony_ci}
411362306a36Sopenharmony_ci#else
411462306a36Sopenharmony_cistatic int f2fs_swap_activate(struct swap_info_struct *sis, struct file *file,
411562306a36Sopenharmony_ci				sector_t *span)
411662306a36Sopenharmony_ci{
411762306a36Sopenharmony_ci	return -EOPNOTSUPP;
411862306a36Sopenharmony_ci}
411962306a36Sopenharmony_ci
412062306a36Sopenharmony_cistatic void f2fs_swap_deactivate(struct file *file)
412162306a36Sopenharmony_ci{
412262306a36Sopenharmony_ci}
412362306a36Sopenharmony_ci#endif
412462306a36Sopenharmony_ci
412562306a36Sopenharmony_ciconst struct address_space_operations f2fs_dblock_aops = {
412662306a36Sopenharmony_ci	.read_folio	= f2fs_read_data_folio,
412762306a36Sopenharmony_ci	.readahead	= f2fs_readahead,
412862306a36Sopenharmony_ci	.writepage	= f2fs_write_data_page,
412962306a36Sopenharmony_ci	.writepages	= f2fs_write_data_pages,
413062306a36Sopenharmony_ci	.write_begin	= f2fs_write_begin,
413162306a36Sopenharmony_ci	.write_end	= f2fs_write_end,
413262306a36Sopenharmony_ci	.dirty_folio	= f2fs_dirty_data_folio,
413362306a36Sopenharmony_ci	.migrate_folio	= filemap_migrate_folio,
413462306a36Sopenharmony_ci	.invalidate_folio = f2fs_invalidate_folio,
413562306a36Sopenharmony_ci	.release_folio	= f2fs_release_folio,
413662306a36Sopenharmony_ci	.bmap		= f2fs_bmap,
413762306a36Sopenharmony_ci	.swap_activate  = f2fs_swap_activate,
413862306a36Sopenharmony_ci	.swap_deactivate = f2fs_swap_deactivate,
413962306a36Sopenharmony_ci};
414062306a36Sopenharmony_ci
414162306a36Sopenharmony_civoid f2fs_clear_page_cache_dirty_tag(struct page *page)
414262306a36Sopenharmony_ci{
414362306a36Sopenharmony_ci	struct address_space *mapping = page_mapping(page);
414462306a36Sopenharmony_ci	unsigned long flags;
414562306a36Sopenharmony_ci
414662306a36Sopenharmony_ci	xa_lock_irqsave(&mapping->i_pages, flags);
414762306a36Sopenharmony_ci	__xa_clear_mark(&mapping->i_pages, page_index(page),
414862306a36Sopenharmony_ci						PAGECACHE_TAG_DIRTY);
414962306a36Sopenharmony_ci	xa_unlock_irqrestore(&mapping->i_pages, flags);
415062306a36Sopenharmony_ci}
415162306a36Sopenharmony_ci
415262306a36Sopenharmony_ciint __init f2fs_init_post_read_processing(void)
415362306a36Sopenharmony_ci{
415462306a36Sopenharmony_ci	bio_post_read_ctx_cache =
415562306a36Sopenharmony_ci		kmem_cache_create("f2fs_bio_post_read_ctx",
415662306a36Sopenharmony_ci				  sizeof(struct bio_post_read_ctx), 0, 0, NULL);
415762306a36Sopenharmony_ci	if (!bio_post_read_ctx_cache)
415862306a36Sopenharmony_ci		goto fail;
415962306a36Sopenharmony_ci	bio_post_read_ctx_pool =
416062306a36Sopenharmony_ci		mempool_create_slab_pool(NUM_PREALLOC_POST_READ_CTXS,
416162306a36Sopenharmony_ci					 bio_post_read_ctx_cache);
416262306a36Sopenharmony_ci	if (!bio_post_read_ctx_pool)
416362306a36Sopenharmony_ci		goto fail_free_cache;
416462306a36Sopenharmony_ci	return 0;
416562306a36Sopenharmony_ci
416662306a36Sopenharmony_cifail_free_cache:
416762306a36Sopenharmony_ci	kmem_cache_destroy(bio_post_read_ctx_cache);
416862306a36Sopenharmony_cifail:
416962306a36Sopenharmony_ci	return -ENOMEM;
417062306a36Sopenharmony_ci}
417162306a36Sopenharmony_ci
417262306a36Sopenharmony_civoid f2fs_destroy_post_read_processing(void)
417362306a36Sopenharmony_ci{
417462306a36Sopenharmony_ci	mempool_destroy(bio_post_read_ctx_pool);
417562306a36Sopenharmony_ci	kmem_cache_destroy(bio_post_read_ctx_cache);
417662306a36Sopenharmony_ci}
417762306a36Sopenharmony_ci
417862306a36Sopenharmony_ciint f2fs_init_post_read_wq(struct f2fs_sb_info *sbi)
417962306a36Sopenharmony_ci{
418062306a36Sopenharmony_ci	if (!f2fs_sb_has_encrypt(sbi) &&
418162306a36Sopenharmony_ci		!f2fs_sb_has_verity(sbi) &&
418262306a36Sopenharmony_ci		!f2fs_sb_has_compression(sbi))
418362306a36Sopenharmony_ci		return 0;
418462306a36Sopenharmony_ci
418562306a36Sopenharmony_ci	sbi->post_read_wq = alloc_workqueue("f2fs_post_read_wq",
418662306a36Sopenharmony_ci						 WQ_UNBOUND | WQ_HIGHPRI,
418762306a36Sopenharmony_ci						 num_online_cpus());
418862306a36Sopenharmony_ci	return sbi->post_read_wq ? 0 : -ENOMEM;
418962306a36Sopenharmony_ci}
419062306a36Sopenharmony_ci
419162306a36Sopenharmony_civoid f2fs_destroy_post_read_wq(struct f2fs_sb_info *sbi)
419262306a36Sopenharmony_ci{
419362306a36Sopenharmony_ci	if (sbi->post_read_wq)
419462306a36Sopenharmony_ci		destroy_workqueue(sbi->post_read_wq);
419562306a36Sopenharmony_ci}
419662306a36Sopenharmony_ci
419762306a36Sopenharmony_ciint __init f2fs_init_bio_entry_cache(void)
419862306a36Sopenharmony_ci{
419962306a36Sopenharmony_ci	bio_entry_slab = f2fs_kmem_cache_create("f2fs_bio_entry_slab",
420062306a36Sopenharmony_ci			sizeof(struct bio_entry));
420162306a36Sopenharmony_ci	return bio_entry_slab ? 0 : -ENOMEM;
420262306a36Sopenharmony_ci}
420362306a36Sopenharmony_ci
420462306a36Sopenharmony_civoid f2fs_destroy_bio_entry_cache(void)
420562306a36Sopenharmony_ci{
420662306a36Sopenharmony_ci	kmem_cache_destroy(bio_entry_slab);
420762306a36Sopenharmony_ci}
420862306a36Sopenharmony_ci
420962306a36Sopenharmony_cistatic int f2fs_iomap_begin(struct inode *inode, loff_t offset, loff_t length,
421062306a36Sopenharmony_ci			    unsigned int flags, struct iomap *iomap,
421162306a36Sopenharmony_ci			    struct iomap *srcmap)
421262306a36Sopenharmony_ci{
421362306a36Sopenharmony_ci	struct f2fs_map_blocks map = {};
421462306a36Sopenharmony_ci	pgoff_t next_pgofs = 0;
421562306a36Sopenharmony_ci	int err;
421662306a36Sopenharmony_ci
421762306a36Sopenharmony_ci	map.m_lblk = bytes_to_blks(inode, offset);
421862306a36Sopenharmony_ci	map.m_len = bytes_to_blks(inode, offset + length - 1) - map.m_lblk + 1;
421962306a36Sopenharmony_ci	map.m_next_pgofs = &next_pgofs;
422062306a36Sopenharmony_ci	map.m_seg_type = f2fs_rw_hint_to_seg_type(inode->i_write_hint);
422162306a36Sopenharmony_ci	if (flags & IOMAP_WRITE)
422262306a36Sopenharmony_ci		map.m_may_create = true;
422362306a36Sopenharmony_ci
422462306a36Sopenharmony_ci	err = f2fs_map_blocks(inode, &map, F2FS_GET_BLOCK_DIO);
422562306a36Sopenharmony_ci	if (err)
422662306a36Sopenharmony_ci		return err;
422762306a36Sopenharmony_ci
422862306a36Sopenharmony_ci	iomap->offset = blks_to_bytes(inode, map.m_lblk);
422962306a36Sopenharmony_ci
423062306a36Sopenharmony_ci	/*
423162306a36Sopenharmony_ci	 * When inline encryption is enabled, sometimes I/O to an encrypted file
423262306a36Sopenharmony_ci	 * has to be broken up to guarantee DUN contiguity.  Handle this by
423362306a36Sopenharmony_ci	 * limiting the length of the mapping returned.
423462306a36Sopenharmony_ci	 */
423562306a36Sopenharmony_ci	map.m_len = fscrypt_limit_io_blocks(inode, map.m_lblk, map.m_len);
423662306a36Sopenharmony_ci
423762306a36Sopenharmony_ci	/*
423862306a36Sopenharmony_ci	 * We should never see delalloc or compressed extents here based on
423962306a36Sopenharmony_ci	 * prior flushing and checks.
424062306a36Sopenharmony_ci	 */
424162306a36Sopenharmony_ci	if (WARN_ON_ONCE(map.m_pblk == NEW_ADDR))
424262306a36Sopenharmony_ci		return -EINVAL;
424362306a36Sopenharmony_ci	if (WARN_ON_ONCE(map.m_pblk == COMPRESS_ADDR))
424462306a36Sopenharmony_ci		return -EINVAL;
424562306a36Sopenharmony_ci
424662306a36Sopenharmony_ci	if (map.m_pblk != NULL_ADDR) {
424762306a36Sopenharmony_ci		iomap->length = blks_to_bytes(inode, map.m_len);
424862306a36Sopenharmony_ci		iomap->type = IOMAP_MAPPED;
424962306a36Sopenharmony_ci		iomap->flags |= IOMAP_F_MERGED;
425062306a36Sopenharmony_ci		iomap->bdev = map.m_bdev;
425162306a36Sopenharmony_ci		iomap->addr = blks_to_bytes(inode, map.m_pblk);
425262306a36Sopenharmony_ci	} else {
425362306a36Sopenharmony_ci		if (flags & IOMAP_WRITE)
425462306a36Sopenharmony_ci			return -ENOTBLK;
425562306a36Sopenharmony_ci		iomap->length = blks_to_bytes(inode, next_pgofs) -
425662306a36Sopenharmony_ci				iomap->offset;
425762306a36Sopenharmony_ci		iomap->type = IOMAP_HOLE;
425862306a36Sopenharmony_ci		iomap->addr = IOMAP_NULL_ADDR;
425962306a36Sopenharmony_ci	}
426062306a36Sopenharmony_ci
426162306a36Sopenharmony_ci	if (map.m_flags & F2FS_MAP_NEW)
426262306a36Sopenharmony_ci		iomap->flags |= IOMAP_F_NEW;
426362306a36Sopenharmony_ci	if ((inode->i_state & I_DIRTY_DATASYNC) ||
426462306a36Sopenharmony_ci	    offset + length > i_size_read(inode))
426562306a36Sopenharmony_ci		iomap->flags |= IOMAP_F_DIRTY;
426662306a36Sopenharmony_ci
426762306a36Sopenharmony_ci	return 0;
426862306a36Sopenharmony_ci}
426962306a36Sopenharmony_ci
427062306a36Sopenharmony_ciconst struct iomap_ops f2fs_iomap_ops = {
427162306a36Sopenharmony_ci	.iomap_begin	= f2fs_iomap_begin,
427262306a36Sopenharmony_ci};
4273