18c2ecf20Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0
28c2ecf20Sopenharmony_ci/*
38c2ecf20Sopenharmony_ci * fs/f2fs/data.c
48c2ecf20Sopenharmony_ci *
58c2ecf20Sopenharmony_ci * Copyright (c) 2012 Samsung Electronics Co., Ltd.
68c2ecf20Sopenharmony_ci *             http://www.samsung.com/
78c2ecf20Sopenharmony_ci */
88c2ecf20Sopenharmony_ci#include <linux/fs.h>
98c2ecf20Sopenharmony_ci#include <linux/f2fs_fs.h>
108c2ecf20Sopenharmony_ci#include <linux/buffer_head.h>
118c2ecf20Sopenharmony_ci#include <linux/mpage.h>
128c2ecf20Sopenharmony_ci#include <linux/writeback.h>
138c2ecf20Sopenharmony_ci#include <linux/backing-dev.h>
148c2ecf20Sopenharmony_ci#include <linux/pagevec.h>
158c2ecf20Sopenharmony_ci#include <linux/blkdev.h>
168c2ecf20Sopenharmony_ci#include <linux/bio.h>
178c2ecf20Sopenharmony_ci#include <linux/blk-crypto.h>
188c2ecf20Sopenharmony_ci#include <linux/swap.h>
198c2ecf20Sopenharmony_ci#include <linux/prefetch.h>
208c2ecf20Sopenharmony_ci#include <linux/uio.h>
218c2ecf20Sopenharmony_ci#include <linux/cleancache.h>
228c2ecf20Sopenharmony_ci#include <linux/sched/signal.h>
238c2ecf20Sopenharmony_ci#include <linux/fiemap.h>
248c2ecf20Sopenharmony_ci
258c2ecf20Sopenharmony_ci#include "f2fs.h"
268c2ecf20Sopenharmony_ci#include "node.h"
278c2ecf20Sopenharmony_ci#include "segment.h"
288c2ecf20Sopenharmony_ci#include "trace.h"
298c2ecf20Sopenharmony_ci#include <trace/events/f2fs.h>
308c2ecf20Sopenharmony_ci
318c2ecf20Sopenharmony_ci#define NUM_PREALLOC_POST_READ_CTXS	128
328c2ecf20Sopenharmony_ci
338c2ecf20Sopenharmony_cistatic struct kmem_cache *bio_post_read_ctx_cache;
348c2ecf20Sopenharmony_cistatic struct kmem_cache *bio_entry_slab;
358c2ecf20Sopenharmony_cistatic mempool_t *bio_post_read_ctx_pool;
368c2ecf20Sopenharmony_cistatic struct bio_set f2fs_bioset;
378c2ecf20Sopenharmony_ci
388c2ecf20Sopenharmony_ci#define	F2FS_BIO_POOL_SIZE	NR_CURSEG_TYPE
398c2ecf20Sopenharmony_ci
408c2ecf20Sopenharmony_ciint __init f2fs_init_bioset(void)
418c2ecf20Sopenharmony_ci{
428c2ecf20Sopenharmony_ci	if (bioset_init(&f2fs_bioset, F2FS_BIO_POOL_SIZE,
438c2ecf20Sopenharmony_ci					0, BIOSET_NEED_BVECS))
448c2ecf20Sopenharmony_ci		return -ENOMEM;
458c2ecf20Sopenharmony_ci	return 0;
468c2ecf20Sopenharmony_ci}
478c2ecf20Sopenharmony_ci
488c2ecf20Sopenharmony_civoid f2fs_destroy_bioset(void)
498c2ecf20Sopenharmony_ci{
508c2ecf20Sopenharmony_ci	bioset_exit(&f2fs_bioset);
518c2ecf20Sopenharmony_ci}
528c2ecf20Sopenharmony_ci
538c2ecf20Sopenharmony_cistatic inline struct bio *__f2fs_bio_alloc(gfp_t gfp_mask,
548c2ecf20Sopenharmony_ci						unsigned int nr_iovecs)
558c2ecf20Sopenharmony_ci{
568c2ecf20Sopenharmony_ci	return bio_alloc_bioset(gfp_mask, nr_iovecs, &f2fs_bioset);
578c2ecf20Sopenharmony_ci}
588c2ecf20Sopenharmony_ci
598c2ecf20Sopenharmony_cistruct bio *f2fs_bio_alloc(struct f2fs_sb_info *sbi, int npages, bool noio)
608c2ecf20Sopenharmony_ci{
618c2ecf20Sopenharmony_ci	if (noio) {
628c2ecf20Sopenharmony_ci		/* No failure on bio allocation */
638c2ecf20Sopenharmony_ci		return __f2fs_bio_alloc(GFP_NOIO, npages);
648c2ecf20Sopenharmony_ci	}
658c2ecf20Sopenharmony_ci
668c2ecf20Sopenharmony_ci	if (time_to_inject(sbi, FAULT_ALLOC_BIO)) {
678c2ecf20Sopenharmony_ci		f2fs_show_injection_info(sbi, FAULT_ALLOC_BIO);
688c2ecf20Sopenharmony_ci		return NULL;
698c2ecf20Sopenharmony_ci	}
708c2ecf20Sopenharmony_ci
718c2ecf20Sopenharmony_ci	return __f2fs_bio_alloc(GFP_KERNEL, npages);
728c2ecf20Sopenharmony_ci}
738c2ecf20Sopenharmony_ci
748c2ecf20Sopenharmony_cistatic bool __is_cp_guaranteed(struct page *page)
758c2ecf20Sopenharmony_ci{
768c2ecf20Sopenharmony_ci	struct address_space *mapping = page->mapping;
778c2ecf20Sopenharmony_ci	struct inode *inode;
788c2ecf20Sopenharmony_ci	struct f2fs_sb_info *sbi;
798c2ecf20Sopenharmony_ci
808c2ecf20Sopenharmony_ci	if (!mapping)
818c2ecf20Sopenharmony_ci		return false;
828c2ecf20Sopenharmony_ci
838c2ecf20Sopenharmony_ci	if (f2fs_is_compressed_page(page))
848c2ecf20Sopenharmony_ci		return false;
858c2ecf20Sopenharmony_ci
868c2ecf20Sopenharmony_ci	inode = mapping->host;
878c2ecf20Sopenharmony_ci	sbi = F2FS_I_SB(inode);
888c2ecf20Sopenharmony_ci
898c2ecf20Sopenharmony_ci	if (inode->i_ino == F2FS_META_INO(sbi) ||
908c2ecf20Sopenharmony_ci			inode->i_ino == F2FS_NODE_INO(sbi) ||
918c2ecf20Sopenharmony_ci			S_ISDIR(inode->i_mode) ||
928c2ecf20Sopenharmony_ci			(S_ISREG(inode->i_mode) &&
938c2ecf20Sopenharmony_ci			(f2fs_is_atomic_file(inode) || IS_NOQUOTA(inode))) ||
948c2ecf20Sopenharmony_ci			is_cold_data(page))
958c2ecf20Sopenharmony_ci		return true;
968c2ecf20Sopenharmony_ci	return false;
978c2ecf20Sopenharmony_ci}
988c2ecf20Sopenharmony_ci
998c2ecf20Sopenharmony_cistatic enum count_type __read_io_type(struct page *page)
1008c2ecf20Sopenharmony_ci{
1018c2ecf20Sopenharmony_ci	struct address_space *mapping = page_file_mapping(page);
1028c2ecf20Sopenharmony_ci
1038c2ecf20Sopenharmony_ci	if (mapping) {
1048c2ecf20Sopenharmony_ci		struct inode *inode = mapping->host;
1058c2ecf20Sopenharmony_ci		struct f2fs_sb_info *sbi = F2FS_I_SB(inode);
1068c2ecf20Sopenharmony_ci
1078c2ecf20Sopenharmony_ci		if (inode->i_ino == F2FS_META_INO(sbi))
1088c2ecf20Sopenharmony_ci			return F2FS_RD_META;
1098c2ecf20Sopenharmony_ci
1108c2ecf20Sopenharmony_ci		if (inode->i_ino == F2FS_NODE_INO(sbi))
1118c2ecf20Sopenharmony_ci			return F2FS_RD_NODE;
1128c2ecf20Sopenharmony_ci	}
1138c2ecf20Sopenharmony_ci	return F2FS_RD_DATA;
1148c2ecf20Sopenharmony_ci}
1158c2ecf20Sopenharmony_ci
1168c2ecf20Sopenharmony_ci/* postprocessing steps for read bios */
1178c2ecf20Sopenharmony_cienum bio_post_read_step {
1188c2ecf20Sopenharmony_ci	STEP_DECRYPT,
1198c2ecf20Sopenharmony_ci	STEP_DECOMPRESS_NOWQ,		/* handle normal cluster data inplace */
1208c2ecf20Sopenharmony_ci	STEP_DECOMPRESS,		/* handle compressed cluster data in workqueue */
1218c2ecf20Sopenharmony_ci	STEP_VERITY,
1228c2ecf20Sopenharmony_ci};
1238c2ecf20Sopenharmony_ci
1248c2ecf20Sopenharmony_cistruct bio_post_read_ctx {
1258c2ecf20Sopenharmony_ci	struct bio *bio;
1268c2ecf20Sopenharmony_ci	struct f2fs_sb_info *sbi;
1278c2ecf20Sopenharmony_ci	struct work_struct work;
1288c2ecf20Sopenharmony_ci	unsigned int enabled_steps;
1298c2ecf20Sopenharmony_ci};
1308c2ecf20Sopenharmony_ci
1318c2ecf20Sopenharmony_cistatic void __read_end_io(struct bio *bio, bool compr, bool verity)
1328c2ecf20Sopenharmony_ci{
1338c2ecf20Sopenharmony_ci	struct page *page;
1348c2ecf20Sopenharmony_ci	struct bio_vec *bv;
1358c2ecf20Sopenharmony_ci	struct bvec_iter_all iter_all;
1368c2ecf20Sopenharmony_ci
1378c2ecf20Sopenharmony_ci	bio_for_each_segment_all(bv, bio, iter_all) {
1388c2ecf20Sopenharmony_ci		page = bv->bv_page;
1398c2ecf20Sopenharmony_ci
1408c2ecf20Sopenharmony_ci#ifdef CONFIG_F2FS_FS_COMPRESSION
1418c2ecf20Sopenharmony_ci		if (compr && f2fs_is_compressed_page(page)) {
1428c2ecf20Sopenharmony_ci			f2fs_decompress_pages(bio, page, verity);
1438c2ecf20Sopenharmony_ci			continue;
1448c2ecf20Sopenharmony_ci		}
1458c2ecf20Sopenharmony_ci		if (verity)
1468c2ecf20Sopenharmony_ci			continue;
1478c2ecf20Sopenharmony_ci#endif
1488c2ecf20Sopenharmony_ci
1498c2ecf20Sopenharmony_ci		/* PG_error was set if any post_read step failed */
1508c2ecf20Sopenharmony_ci		if (bio->bi_status || PageError(page)) {
1518c2ecf20Sopenharmony_ci			ClearPageUptodate(page);
1528c2ecf20Sopenharmony_ci			/* will re-read again later */
1538c2ecf20Sopenharmony_ci			ClearPageError(page);
1548c2ecf20Sopenharmony_ci		} else {
1558c2ecf20Sopenharmony_ci			SetPageUptodate(page);
1568c2ecf20Sopenharmony_ci		}
1578c2ecf20Sopenharmony_ci		dec_page_count(F2FS_P_SB(page), __read_io_type(page));
1588c2ecf20Sopenharmony_ci		unlock_page(page);
1598c2ecf20Sopenharmony_ci	}
1608c2ecf20Sopenharmony_ci}
1618c2ecf20Sopenharmony_ci
1628c2ecf20Sopenharmony_cistatic void f2fs_release_read_bio(struct bio *bio);
1638c2ecf20Sopenharmony_cistatic void __f2fs_read_end_io(struct bio *bio, bool compr, bool verity)
1648c2ecf20Sopenharmony_ci{
1658c2ecf20Sopenharmony_ci	if (!compr)
1668c2ecf20Sopenharmony_ci		__read_end_io(bio, false, verity);
1678c2ecf20Sopenharmony_ci	f2fs_release_read_bio(bio);
1688c2ecf20Sopenharmony_ci}
1698c2ecf20Sopenharmony_ci
1708c2ecf20Sopenharmony_cistatic void f2fs_decompress_bio(struct bio *bio, bool verity)
1718c2ecf20Sopenharmony_ci{
1728c2ecf20Sopenharmony_ci	__read_end_io(bio, true, verity);
1738c2ecf20Sopenharmony_ci}
1748c2ecf20Sopenharmony_ci
1758c2ecf20Sopenharmony_cistatic void bio_post_read_processing(struct bio_post_read_ctx *ctx);
1768c2ecf20Sopenharmony_ci
1778c2ecf20Sopenharmony_cistatic void f2fs_decrypt_work(struct bio_post_read_ctx *ctx)
1788c2ecf20Sopenharmony_ci{
1798c2ecf20Sopenharmony_ci	fscrypt_decrypt_bio(ctx->bio);
1808c2ecf20Sopenharmony_ci}
1818c2ecf20Sopenharmony_ci
1828c2ecf20Sopenharmony_cistatic void f2fs_decompress_work(struct bio_post_read_ctx *ctx)
1838c2ecf20Sopenharmony_ci{
1848c2ecf20Sopenharmony_ci	f2fs_decompress_bio(ctx->bio, ctx->enabled_steps & (1 << STEP_VERITY));
1858c2ecf20Sopenharmony_ci}
1868c2ecf20Sopenharmony_ci
1878c2ecf20Sopenharmony_ci#ifdef CONFIG_F2FS_FS_COMPRESSION
1888c2ecf20Sopenharmony_cistatic void f2fs_verify_pages(struct page **rpages, unsigned int cluster_size)
1898c2ecf20Sopenharmony_ci{
1908c2ecf20Sopenharmony_ci	f2fs_decompress_end_io(rpages, cluster_size, false, true);
1918c2ecf20Sopenharmony_ci}
1928c2ecf20Sopenharmony_ci
1938c2ecf20Sopenharmony_cistatic void f2fs_verify_bio(struct bio *bio)
1948c2ecf20Sopenharmony_ci{
1958c2ecf20Sopenharmony_ci	struct bio_vec *bv;
1968c2ecf20Sopenharmony_ci	struct bvec_iter_all iter_all;
1978c2ecf20Sopenharmony_ci
1988c2ecf20Sopenharmony_ci	bio_for_each_segment_all(bv, bio, iter_all) {
1998c2ecf20Sopenharmony_ci		struct page *page = bv->bv_page;
2008c2ecf20Sopenharmony_ci		struct decompress_io_ctx *dic;
2018c2ecf20Sopenharmony_ci
2028c2ecf20Sopenharmony_ci		dic = (struct decompress_io_ctx *)page_private(page);
2038c2ecf20Sopenharmony_ci
2048c2ecf20Sopenharmony_ci		if (dic) {
2058c2ecf20Sopenharmony_ci			if (atomic_dec_return(&dic->verity_pages))
2068c2ecf20Sopenharmony_ci				continue;
2078c2ecf20Sopenharmony_ci			f2fs_verify_pages(dic->rpages,
2088c2ecf20Sopenharmony_ci						dic->cluster_size);
2098c2ecf20Sopenharmony_ci			f2fs_free_dic(dic);
2108c2ecf20Sopenharmony_ci			continue;
2118c2ecf20Sopenharmony_ci		}
2128c2ecf20Sopenharmony_ci
2138c2ecf20Sopenharmony_ci		if (bio->bi_status || PageError(page))
2148c2ecf20Sopenharmony_ci			goto clear_uptodate;
2158c2ecf20Sopenharmony_ci
2168c2ecf20Sopenharmony_ci		if (fsverity_verify_page(page)) {
2178c2ecf20Sopenharmony_ci			SetPageUptodate(page);
2188c2ecf20Sopenharmony_ci			goto unlock;
2198c2ecf20Sopenharmony_ci		}
2208c2ecf20Sopenharmony_ciclear_uptodate:
2218c2ecf20Sopenharmony_ci		ClearPageUptodate(page);
2228c2ecf20Sopenharmony_ci		ClearPageError(page);
2238c2ecf20Sopenharmony_ciunlock:
2248c2ecf20Sopenharmony_ci		dec_page_count(F2FS_P_SB(page), __read_io_type(page));
2258c2ecf20Sopenharmony_ci		unlock_page(page);
2268c2ecf20Sopenharmony_ci	}
2278c2ecf20Sopenharmony_ci}
2288c2ecf20Sopenharmony_ci#endif
2298c2ecf20Sopenharmony_ci
2308c2ecf20Sopenharmony_cistatic void f2fs_verity_work(struct work_struct *work)
2318c2ecf20Sopenharmony_ci{
2328c2ecf20Sopenharmony_ci	struct bio_post_read_ctx *ctx =
2338c2ecf20Sopenharmony_ci		container_of(work, struct bio_post_read_ctx, work);
2348c2ecf20Sopenharmony_ci	struct bio *bio = ctx->bio;
2358c2ecf20Sopenharmony_ci#ifdef CONFIG_F2FS_FS_COMPRESSION
2368c2ecf20Sopenharmony_ci	unsigned int enabled_steps = ctx->enabled_steps;
2378c2ecf20Sopenharmony_ci#endif
2388c2ecf20Sopenharmony_ci
2398c2ecf20Sopenharmony_ci	/*
2408c2ecf20Sopenharmony_ci	 * fsverity_verify_bio() may call readpages() again, and while verity
2418c2ecf20Sopenharmony_ci	 * will be disabled for this, decryption may still be needed, resulting
2428c2ecf20Sopenharmony_ci	 * in another bio_post_read_ctx being allocated.  So to prevent
2438c2ecf20Sopenharmony_ci	 * deadlocks we need to release the current ctx to the mempool first.
2448c2ecf20Sopenharmony_ci	 * This assumes that verity is the last post-read step.
2458c2ecf20Sopenharmony_ci	 */
2468c2ecf20Sopenharmony_ci	mempool_free(ctx, bio_post_read_ctx_pool);
2478c2ecf20Sopenharmony_ci	bio->bi_private = NULL;
2488c2ecf20Sopenharmony_ci
2498c2ecf20Sopenharmony_ci#ifdef CONFIG_F2FS_FS_COMPRESSION
2508c2ecf20Sopenharmony_ci	/* previous step is decompression */
2518c2ecf20Sopenharmony_ci	if (enabled_steps & (1 << STEP_DECOMPRESS)) {
2528c2ecf20Sopenharmony_ci		f2fs_verify_bio(bio);
2538c2ecf20Sopenharmony_ci		f2fs_release_read_bio(bio);
2548c2ecf20Sopenharmony_ci		return;
2558c2ecf20Sopenharmony_ci	}
2568c2ecf20Sopenharmony_ci#endif
2578c2ecf20Sopenharmony_ci
2588c2ecf20Sopenharmony_ci	fsverity_verify_bio(bio);
2598c2ecf20Sopenharmony_ci	__f2fs_read_end_io(bio, false, false);
2608c2ecf20Sopenharmony_ci}
2618c2ecf20Sopenharmony_ci
2628c2ecf20Sopenharmony_cistatic void f2fs_post_read_work(struct work_struct *work)
2638c2ecf20Sopenharmony_ci{
2648c2ecf20Sopenharmony_ci	struct bio_post_read_ctx *ctx =
2658c2ecf20Sopenharmony_ci		container_of(work, struct bio_post_read_ctx, work);
2668c2ecf20Sopenharmony_ci
2678c2ecf20Sopenharmony_ci	if (ctx->enabled_steps & (1 << STEP_DECRYPT))
2688c2ecf20Sopenharmony_ci		f2fs_decrypt_work(ctx);
2698c2ecf20Sopenharmony_ci
2708c2ecf20Sopenharmony_ci	if (ctx->enabled_steps & (1 << STEP_DECOMPRESS))
2718c2ecf20Sopenharmony_ci		f2fs_decompress_work(ctx);
2728c2ecf20Sopenharmony_ci
2738c2ecf20Sopenharmony_ci	if (ctx->enabled_steps & (1 << STEP_VERITY)) {
2748c2ecf20Sopenharmony_ci		INIT_WORK(&ctx->work, f2fs_verity_work);
2758c2ecf20Sopenharmony_ci		fsverity_enqueue_verify_work(&ctx->work);
2768c2ecf20Sopenharmony_ci		return;
2778c2ecf20Sopenharmony_ci	}
2788c2ecf20Sopenharmony_ci
2798c2ecf20Sopenharmony_ci	__f2fs_read_end_io(ctx->bio,
2808c2ecf20Sopenharmony_ci		ctx->enabled_steps & (1 << STEP_DECOMPRESS), false);
2818c2ecf20Sopenharmony_ci}
2828c2ecf20Sopenharmony_ci
2838c2ecf20Sopenharmony_cistatic void f2fs_enqueue_post_read_work(struct f2fs_sb_info *sbi,
2848c2ecf20Sopenharmony_ci						struct work_struct *work)
2858c2ecf20Sopenharmony_ci{
2868c2ecf20Sopenharmony_ci	queue_work(sbi->post_read_wq, work);
2878c2ecf20Sopenharmony_ci}
2888c2ecf20Sopenharmony_ci
2898c2ecf20Sopenharmony_cistatic void bio_post_read_processing(struct bio_post_read_ctx *ctx)
2908c2ecf20Sopenharmony_ci{
2918c2ecf20Sopenharmony_ci	/*
2928c2ecf20Sopenharmony_ci	 * We use different work queues for decryption and for verity because
2938c2ecf20Sopenharmony_ci	 * verity may require reading metadata pages that need decryption, and
2948c2ecf20Sopenharmony_ci	 * we shouldn't recurse to the same workqueue.
2958c2ecf20Sopenharmony_ci	 */
2968c2ecf20Sopenharmony_ci
2978c2ecf20Sopenharmony_ci	if (ctx->enabled_steps & (1 << STEP_DECRYPT) ||
2988c2ecf20Sopenharmony_ci		ctx->enabled_steps & (1 << STEP_DECOMPRESS)) {
2998c2ecf20Sopenharmony_ci		INIT_WORK(&ctx->work, f2fs_post_read_work);
3008c2ecf20Sopenharmony_ci		f2fs_enqueue_post_read_work(ctx->sbi, &ctx->work);
3018c2ecf20Sopenharmony_ci		return;
3028c2ecf20Sopenharmony_ci	}
3038c2ecf20Sopenharmony_ci
3048c2ecf20Sopenharmony_ci	if (ctx->enabled_steps & (1 << STEP_VERITY)) {
3058c2ecf20Sopenharmony_ci		INIT_WORK(&ctx->work, f2fs_verity_work);
3068c2ecf20Sopenharmony_ci		fsverity_enqueue_verify_work(&ctx->work);
3078c2ecf20Sopenharmony_ci		return;
3088c2ecf20Sopenharmony_ci	}
3098c2ecf20Sopenharmony_ci
3108c2ecf20Sopenharmony_ci	__f2fs_read_end_io(ctx->bio, false, false);
3118c2ecf20Sopenharmony_ci}
3128c2ecf20Sopenharmony_ci
3138c2ecf20Sopenharmony_cistatic bool f2fs_bio_post_read_required(struct bio *bio)
3148c2ecf20Sopenharmony_ci{
3158c2ecf20Sopenharmony_ci	return bio->bi_private;
3168c2ecf20Sopenharmony_ci}
3178c2ecf20Sopenharmony_ci
3188c2ecf20Sopenharmony_cistatic void f2fs_read_end_io(struct bio *bio)
3198c2ecf20Sopenharmony_ci{
3208c2ecf20Sopenharmony_ci	struct f2fs_sb_info *sbi = F2FS_P_SB(bio_first_page_all(bio));
3218c2ecf20Sopenharmony_ci
3228c2ecf20Sopenharmony_ci	if (time_to_inject(sbi, FAULT_READ_IO)) {
3238c2ecf20Sopenharmony_ci		f2fs_show_injection_info(sbi, FAULT_READ_IO);
3248c2ecf20Sopenharmony_ci		bio->bi_status = BLK_STS_IOERR;
3258c2ecf20Sopenharmony_ci	}
3268c2ecf20Sopenharmony_ci
3278c2ecf20Sopenharmony_ci	if (f2fs_bio_post_read_required(bio)) {
3288c2ecf20Sopenharmony_ci		struct bio_post_read_ctx *ctx = bio->bi_private;
3298c2ecf20Sopenharmony_ci
3308c2ecf20Sopenharmony_ci		bio_post_read_processing(ctx);
3318c2ecf20Sopenharmony_ci		return;
3328c2ecf20Sopenharmony_ci	}
3338c2ecf20Sopenharmony_ci
3348c2ecf20Sopenharmony_ci	__f2fs_read_end_io(bio, false, false);
3358c2ecf20Sopenharmony_ci}
3368c2ecf20Sopenharmony_ci
3378c2ecf20Sopenharmony_cistatic void f2fs_write_end_io(struct bio *bio)
3388c2ecf20Sopenharmony_ci{
3398c2ecf20Sopenharmony_ci	struct f2fs_sb_info *sbi = bio->bi_private;
3408c2ecf20Sopenharmony_ci	struct bio_vec *bvec;
3418c2ecf20Sopenharmony_ci	struct bvec_iter_all iter_all;
3428c2ecf20Sopenharmony_ci
3438c2ecf20Sopenharmony_ci	if (time_to_inject(sbi, FAULT_WRITE_IO)) {
3448c2ecf20Sopenharmony_ci		f2fs_show_injection_info(sbi, FAULT_WRITE_IO);
3458c2ecf20Sopenharmony_ci		bio->bi_status = BLK_STS_IOERR;
3468c2ecf20Sopenharmony_ci	}
3478c2ecf20Sopenharmony_ci
3488c2ecf20Sopenharmony_ci	bio_for_each_segment_all(bvec, bio, iter_all) {
3498c2ecf20Sopenharmony_ci		struct page *page = bvec->bv_page;
3508c2ecf20Sopenharmony_ci		enum count_type type = WB_DATA_TYPE(page);
3518c2ecf20Sopenharmony_ci
3528c2ecf20Sopenharmony_ci		if (IS_DUMMY_WRITTEN_PAGE(page)) {
3538c2ecf20Sopenharmony_ci			set_page_private(page, (unsigned long)NULL);
3548c2ecf20Sopenharmony_ci			ClearPagePrivate(page);
3558c2ecf20Sopenharmony_ci			unlock_page(page);
3568c2ecf20Sopenharmony_ci			mempool_free(page, sbi->write_io_dummy);
3578c2ecf20Sopenharmony_ci
3588c2ecf20Sopenharmony_ci			if (unlikely(bio->bi_status))
3598c2ecf20Sopenharmony_ci				f2fs_stop_checkpoint(sbi, true);
3608c2ecf20Sopenharmony_ci			continue;
3618c2ecf20Sopenharmony_ci		}
3628c2ecf20Sopenharmony_ci
3638c2ecf20Sopenharmony_ci		fscrypt_finalize_bounce_page(&page);
3648c2ecf20Sopenharmony_ci
3658c2ecf20Sopenharmony_ci#ifdef CONFIG_F2FS_FS_COMPRESSION
3668c2ecf20Sopenharmony_ci		if (f2fs_is_compressed_page(page)) {
3678c2ecf20Sopenharmony_ci			f2fs_compress_write_end_io(bio, page);
3688c2ecf20Sopenharmony_ci			continue;
3698c2ecf20Sopenharmony_ci		}
3708c2ecf20Sopenharmony_ci#endif
3718c2ecf20Sopenharmony_ci
3728c2ecf20Sopenharmony_ci		if (unlikely(bio->bi_status)) {
3738c2ecf20Sopenharmony_ci			mapping_set_error(page->mapping, -EIO);
3748c2ecf20Sopenharmony_ci			if (type == F2FS_WB_CP_DATA)
3758c2ecf20Sopenharmony_ci				f2fs_stop_checkpoint(sbi, true);
3768c2ecf20Sopenharmony_ci		}
3778c2ecf20Sopenharmony_ci
3788c2ecf20Sopenharmony_ci		f2fs_bug_on(sbi, page->mapping == NODE_MAPPING(sbi) &&
3798c2ecf20Sopenharmony_ci					page->index != nid_of_node(page));
3808c2ecf20Sopenharmony_ci
3818c2ecf20Sopenharmony_ci		dec_page_count(sbi, type);
3828c2ecf20Sopenharmony_ci		if (f2fs_in_warm_node_list(sbi, page))
3838c2ecf20Sopenharmony_ci			f2fs_del_fsync_node_entry(sbi, page);
3848c2ecf20Sopenharmony_ci		clear_cold_data(page);
3858c2ecf20Sopenharmony_ci		end_page_writeback(page);
3868c2ecf20Sopenharmony_ci	}
3878c2ecf20Sopenharmony_ci	if (!get_pages(sbi, F2FS_WB_CP_DATA) &&
3888c2ecf20Sopenharmony_ci				wq_has_sleeper(&sbi->cp_wait))
3898c2ecf20Sopenharmony_ci		wake_up(&sbi->cp_wait);
3908c2ecf20Sopenharmony_ci
3918c2ecf20Sopenharmony_ci	bio_put(bio);
3928c2ecf20Sopenharmony_ci}
3938c2ecf20Sopenharmony_ci
3948c2ecf20Sopenharmony_cistruct block_device *f2fs_target_device(struct f2fs_sb_info *sbi,
3958c2ecf20Sopenharmony_ci				block_t blk_addr, struct bio *bio)
3968c2ecf20Sopenharmony_ci{
3978c2ecf20Sopenharmony_ci	struct block_device *bdev = sbi->sb->s_bdev;
3988c2ecf20Sopenharmony_ci	int i;
3998c2ecf20Sopenharmony_ci
4008c2ecf20Sopenharmony_ci	if (f2fs_is_multi_device(sbi)) {
4018c2ecf20Sopenharmony_ci		for (i = 0; i < sbi->s_ndevs; i++) {
4028c2ecf20Sopenharmony_ci			if (FDEV(i).start_blk <= blk_addr &&
4038c2ecf20Sopenharmony_ci			    FDEV(i).end_blk >= blk_addr) {
4048c2ecf20Sopenharmony_ci				blk_addr -= FDEV(i).start_blk;
4058c2ecf20Sopenharmony_ci				bdev = FDEV(i).bdev;
4068c2ecf20Sopenharmony_ci				break;
4078c2ecf20Sopenharmony_ci			}
4088c2ecf20Sopenharmony_ci		}
4098c2ecf20Sopenharmony_ci	}
4108c2ecf20Sopenharmony_ci	if (bio) {
4118c2ecf20Sopenharmony_ci		bio_set_dev(bio, bdev);
4128c2ecf20Sopenharmony_ci		bio->bi_iter.bi_sector = SECTOR_FROM_BLOCK(blk_addr);
4138c2ecf20Sopenharmony_ci	}
4148c2ecf20Sopenharmony_ci	return bdev;
4158c2ecf20Sopenharmony_ci}
4168c2ecf20Sopenharmony_ci
4178c2ecf20Sopenharmony_ciint f2fs_target_device_index(struct f2fs_sb_info *sbi, block_t blkaddr)
4188c2ecf20Sopenharmony_ci{
4198c2ecf20Sopenharmony_ci	int i;
4208c2ecf20Sopenharmony_ci
4218c2ecf20Sopenharmony_ci	if (!f2fs_is_multi_device(sbi))
4228c2ecf20Sopenharmony_ci		return 0;
4238c2ecf20Sopenharmony_ci
4248c2ecf20Sopenharmony_ci	for (i = 0; i < sbi->s_ndevs; i++)
4258c2ecf20Sopenharmony_ci		if (FDEV(i).start_blk <= blkaddr && FDEV(i).end_blk >= blkaddr)
4268c2ecf20Sopenharmony_ci			return i;
4278c2ecf20Sopenharmony_ci	return 0;
4288c2ecf20Sopenharmony_ci}
4298c2ecf20Sopenharmony_ci
4308c2ecf20Sopenharmony_ci/*
4318c2ecf20Sopenharmony_ci * Return true, if pre_bio's bdev is same as its target device.
4328c2ecf20Sopenharmony_ci */
4338c2ecf20Sopenharmony_cistatic bool __same_bdev(struct f2fs_sb_info *sbi,
4348c2ecf20Sopenharmony_ci				block_t blk_addr, struct bio *bio)
4358c2ecf20Sopenharmony_ci{
4368c2ecf20Sopenharmony_ci	struct block_device *b = f2fs_target_device(sbi, blk_addr, NULL);
4378c2ecf20Sopenharmony_ci	return bio->bi_disk == b->bd_disk && bio->bi_partno == b->bd_partno;
4388c2ecf20Sopenharmony_ci}
4398c2ecf20Sopenharmony_ci
4408c2ecf20Sopenharmony_cistatic struct bio *__bio_alloc(struct f2fs_io_info *fio, int npages)
4418c2ecf20Sopenharmony_ci{
4428c2ecf20Sopenharmony_ci	struct f2fs_sb_info *sbi = fio->sbi;
4438c2ecf20Sopenharmony_ci	struct bio *bio;
4448c2ecf20Sopenharmony_ci
4458c2ecf20Sopenharmony_ci	bio = f2fs_bio_alloc(sbi, npages, true);
4468c2ecf20Sopenharmony_ci
4478c2ecf20Sopenharmony_ci	f2fs_target_device(sbi, fio->new_blkaddr, bio);
4488c2ecf20Sopenharmony_ci	if (is_read_io(fio->op)) {
4498c2ecf20Sopenharmony_ci		bio->bi_end_io = f2fs_read_end_io;
4508c2ecf20Sopenharmony_ci		bio->bi_private = NULL;
4518c2ecf20Sopenharmony_ci	} else {
4528c2ecf20Sopenharmony_ci		bio->bi_end_io = f2fs_write_end_io;
4538c2ecf20Sopenharmony_ci		bio->bi_private = sbi;
4548c2ecf20Sopenharmony_ci		bio->bi_write_hint = f2fs_io_type_to_rw_hint(sbi,
4558c2ecf20Sopenharmony_ci						fio->type, fio->temp);
4568c2ecf20Sopenharmony_ci	}
4578c2ecf20Sopenharmony_ci	if (fio->io_wbc)
4588c2ecf20Sopenharmony_ci		wbc_init_bio(fio->io_wbc, bio);
4598c2ecf20Sopenharmony_ci
4608c2ecf20Sopenharmony_ci	return bio;
4618c2ecf20Sopenharmony_ci}
4628c2ecf20Sopenharmony_ci
4638c2ecf20Sopenharmony_cistatic void f2fs_set_bio_crypt_ctx(struct bio *bio, const struct inode *inode,
4648c2ecf20Sopenharmony_ci				  pgoff_t first_idx,
4658c2ecf20Sopenharmony_ci				  const struct f2fs_io_info *fio,
4668c2ecf20Sopenharmony_ci				  gfp_t gfp_mask)
4678c2ecf20Sopenharmony_ci{
4688c2ecf20Sopenharmony_ci	/*
4698c2ecf20Sopenharmony_ci	 * The f2fs garbage collector sets ->encrypted_page when it wants to
4708c2ecf20Sopenharmony_ci	 * read/write raw data without encryption.
4718c2ecf20Sopenharmony_ci	 */
4728c2ecf20Sopenharmony_ci	if (!fio || !fio->encrypted_page)
4738c2ecf20Sopenharmony_ci		fscrypt_set_bio_crypt_ctx(bio, inode, first_idx, gfp_mask);
4748c2ecf20Sopenharmony_ci}
4758c2ecf20Sopenharmony_ci
4768c2ecf20Sopenharmony_cistatic bool f2fs_crypt_mergeable_bio(struct bio *bio, const struct inode *inode,
4778c2ecf20Sopenharmony_ci				     pgoff_t next_idx,
4788c2ecf20Sopenharmony_ci				     const struct f2fs_io_info *fio)
4798c2ecf20Sopenharmony_ci{
4808c2ecf20Sopenharmony_ci	/*
4818c2ecf20Sopenharmony_ci	 * The f2fs garbage collector sets ->encrypted_page when it wants to
4828c2ecf20Sopenharmony_ci	 * read/write raw data without encryption.
4838c2ecf20Sopenharmony_ci	 */
4848c2ecf20Sopenharmony_ci	if (fio && fio->encrypted_page)
4858c2ecf20Sopenharmony_ci		return !bio_has_crypt_ctx(bio);
4868c2ecf20Sopenharmony_ci
4878c2ecf20Sopenharmony_ci	return fscrypt_mergeable_bio(bio, inode, next_idx);
4888c2ecf20Sopenharmony_ci}
4898c2ecf20Sopenharmony_ci
4908c2ecf20Sopenharmony_cistatic inline void __submit_bio(struct f2fs_sb_info *sbi,
4918c2ecf20Sopenharmony_ci				struct bio *bio, enum page_type type)
4928c2ecf20Sopenharmony_ci{
4938c2ecf20Sopenharmony_ci	if (!is_read_io(bio_op(bio))) {
4948c2ecf20Sopenharmony_ci		unsigned int start;
4958c2ecf20Sopenharmony_ci
4968c2ecf20Sopenharmony_ci		if (type != DATA && type != NODE)
4978c2ecf20Sopenharmony_ci			goto submit_io;
4988c2ecf20Sopenharmony_ci
4998c2ecf20Sopenharmony_ci		if (f2fs_lfs_mode(sbi) && current->plug)
5008c2ecf20Sopenharmony_ci			blk_finish_plug(current->plug);
5018c2ecf20Sopenharmony_ci
5028c2ecf20Sopenharmony_ci		if (!F2FS_IO_ALIGNED(sbi))
5038c2ecf20Sopenharmony_ci			goto submit_io;
5048c2ecf20Sopenharmony_ci
5058c2ecf20Sopenharmony_ci		start = bio->bi_iter.bi_size >> F2FS_BLKSIZE_BITS;
5068c2ecf20Sopenharmony_ci		start %= F2FS_IO_SIZE(sbi);
5078c2ecf20Sopenharmony_ci
5088c2ecf20Sopenharmony_ci		if (start == 0)
5098c2ecf20Sopenharmony_ci			goto submit_io;
5108c2ecf20Sopenharmony_ci
5118c2ecf20Sopenharmony_ci		/* fill dummy pages */
5128c2ecf20Sopenharmony_ci		for (; start < F2FS_IO_SIZE(sbi); start++) {
5138c2ecf20Sopenharmony_ci			struct page *page =
5148c2ecf20Sopenharmony_ci				mempool_alloc(sbi->write_io_dummy,
5158c2ecf20Sopenharmony_ci					      GFP_NOIO | __GFP_NOFAIL);
5168c2ecf20Sopenharmony_ci			f2fs_bug_on(sbi, !page);
5178c2ecf20Sopenharmony_ci
5188c2ecf20Sopenharmony_ci			zero_user_segment(page, 0, PAGE_SIZE);
5198c2ecf20Sopenharmony_ci			SetPagePrivate(page);
5208c2ecf20Sopenharmony_ci			set_page_private(page, DUMMY_WRITTEN_PAGE);
5218c2ecf20Sopenharmony_ci			lock_page(page);
5228c2ecf20Sopenharmony_ci			if (bio_add_page(bio, page, PAGE_SIZE, 0) < PAGE_SIZE)
5238c2ecf20Sopenharmony_ci				f2fs_bug_on(sbi, 1);
5248c2ecf20Sopenharmony_ci		}
5258c2ecf20Sopenharmony_ci		/*
5268c2ecf20Sopenharmony_ci		 * In the NODE case, we lose next block address chain. So, we
5278c2ecf20Sopenharmony_ci		 * need to do checkpoint in f2fs_sync_file.
5288c2ecf20Sopenharmony_ci		 */
5298c2ecf20Sopenharmony_ci		if (type == NODE)
5308c2ecf20Sopenharmony_ci			set_sbi_flag(sbi, SBI_NEED_CP);
5318c2ecf20Sopenharmony_ci	}
5328c2ecf20Sopenharmony_cisubmit_io:
5338c2ecf20Sopenharmony_ci	if (is_read_io(bio_op(bio)))
5348c2ecf20Sopenharmony_ci		trace_f2fs_submit_read_bio(sbi->sb, type, bio);
5358c2ecf20Sopenharmony_ci	else
5368c2ecf20Sopenharmony_ci		trace_f2fs_submit_write_bio(sbi->sb, type, bio);
5378c2ecf20Sopenharmony_ci	submit_bio(bio);
5388c2ecf20Sopenharmony_ci}
5398c2ecf20Sopenharmony_ci
5408c2ecf20Sopenharmony_civoid f2fs_submit_bio(struct f2fs_sb_info *sbi,
5418c2ecf20Sopenharmony_ci				struct bio *bio, enum page_type type)
5428c2ecf20Sopenharmony_ci{
5438c2ecf20Sopenharmony_ci	__submit_bio(sbi, bio, type);
5448c2ecf20Sopenharmony_ci}
5458c2ecf20Sopenharmony_ci
5468c2ecf20Sopenharmony_cistatic void __attach_io_flag(struct f2fs_io_info *fio)
5478c2ecf20Sopenharmony_ci{
5488c2ecf20Sopenharmony_ci	struct f2fs_sb_info *sbi = fio->sbi;
5498c2ecf20Sopenharmony_ci	unsigned int temp_mask = (1 << NR_TEMP_TYPE) - 1;
5508c2ecf20Sopenharmony_ci	unsigned int io_flag, fua_flag, meta_flag;
5518c2ecf20Sopenharmony_ci
5528c2ecf20Sopenharmony_ci	if (fio->type == DATA)
5538c2ecf20Sopenharmony_ci		io_flag = sbi->data_io_flag;
5548c2ecf20Sopenharmony_ci	else if (fio->type == NODE)
5558c2ecf20Sopenharmony_ci		io_flag = sbi->node_io_flag;
5568c2ecf20Sopenharmony_ci	else
5578c2ecf20Sopenharmony_ci		return;
5588c2ecf20Sopenharmony_ci
5598c2ecf20Sopenharmony_ci	fua_flag = io_flag & temp_mask;
5608c2ecf20Sopenharmony_ci	meta_flag = (io_flag >> NR_TEMP_TYPE) & temp_mask;
5618c2ecf20Sopenharmony_ci
5628c2ecf20Sopenharmony_ci	/*
5638c2ecf20Sopenharmony_ci	 * data/node io flag bits per temp:
5648c2ecf20Sopenharmony_ci	 *      REQ_META     |      REQ_FUA      |
5658c2ecf20Sopenharmony_ci	 *    5 |    4 |   3 |    2 |    1 |   0 |
5668c2ecf20Sopenharmony_ci	 * Cold | Warm | Hot | Cold | Warm | Hot |
5678c2ecf20Sopenharmony_ci	 */
5688c2ecf20Sopenharmony_ci	if ((1 << fio->temp) & meta_flag)
5698c2ecf20Sopenharmony_ci		fio->op_flags |= REQ_META;
5708c2ecf20Sopenharmony_ci	if ((1 << fio->temp) & fua_flag)
5718c2ecf20Sopenharmony_ci		fio->op_flags |= REQ_FUA;
5728c2ecf20Sopenharmony_ci}
5738c2ecf20Sopenharmony_ci
5748c2ecf20Sopenharmony_cistatic void __submit_merged_bio(struct f2fs_bio_info *io)
5758c2ecf20Sopenharmony_ci{
5768c2ecf20Sopenharmony_ci	struct f2fs_io_info *fio = &io->fio;
5778c2ecf20Sopenharmony_ci
5788c2ecf20Sopenharmony_ci	if (!io->bio)
5798c2ecf20Sopenharmony_ci		return;
5808c2ecf20Sopenharmony_ci
5818c2ecf20Sopenharmony_ci	__attach_io_flag(fio);
5828c2ecf20Sopenharmony_ci	bio_set_op_attrs(io->bio, fio->op, fio->op_flags);
5838c2ecf20Sopenharmony_ci
5848c2ecf20Sopenharmony_ci	if (is_read_io(fio->op))
5858c2ecf20Sopenharmony_ci		trace_f2fs_prepare_read_bio(io->sbi->sb, fio->type, io->bio);
5868c2ecf20Sopenharmony_ci	else
5878c2ecf20Sopenharmony_ci		trace_f2fs_prepare_write_bio(io->sbi->sb, fio->type, io->bio);
5888c2ecf20Sopenharmony_ci
5898c2ecf20Sopenharmony_ci	__submit_bio(io->sbi, io->bio, fio->type);
5908c2ecf20Sopenharmony_ci	io->bio = NULL;
5918c2ecf20Sopenharmony_ci}
5928c2ecf20Sopenharmony_ci
5938c2ecf20Sopenharmony_cistatic bool __has_merged_page(struct bio *bio, struct inode *inode,
5948c2ecf20Sopenharmony_ci						struct page *page, nid_t ino)
5958c2ecf20Sopenharmony_ci{
5968c2ecf20Sopenharmony_ci	struct bio_vec *bvec;
5978c2ecf20Sopenharmony_ci	struct bvec_iter_all iter_all;
5988c2ecf20Sopenharmony_ci
5998c2ecf20Sopenharmony_ci	if (!bio)
6008c2ecf20Sopenharmony_ci		return false;
6018c2ecf20Sopenharmony_ci
6028c2ecf20Sopenharmony_ci	if (!inode && !page && !ino)
6038c2ecf20Sopenharmony_ci		return true;
6048c2ecf20Sopenharmony_ci
6058c2ecf20Sopenharmony_ci	bio_for_each_segment_all(bvec, bio, iter_all) {
6068c2ecf20Sopenharmony_ci		struct page *target = bvec->bv_page;
6078c2ecf20Sopenharmony_ci
6088c2ecf20Sopenharmony_ci		if (fscrypt_is_bounce_page(target)) {
6098c2ecf20Sopenharmony_ci			target = fscrypt_pagecache_page(target);
6108c2ecf20Sopenharmony_ci			if (IS_ERR(target))
6118c2ecf20Sopenharmony_ci				continue;
6128c2ecf20Sopenharmony_ci		}
6138c2ecf20Sopenharmony_ci		if (f2fs_is_compressed_page(target)) {
6148c2ecf20Sopenharmony_ci			target = f2fs_compress_control_page(target);
6158c2ecf20Sopenharmony_ci			if (IS_ERR(target))
6168c2ecf20Sopenharmony_ci				continue;
6178c2ecf20Sopenharmony_ci		}
6188c2ecf20Sopenharmony_ci
6198c2ecf20Sopenharmony_ci		if (inode && inode == target->mapping->host)
6208c2ecf20Sopenharmony_ci			return true;
6218c2ecf20Sopenharmony_ci		if (page && page == target)
6228c2ecf20Sopenharmony_ci			return true;
6238c2ecf20Sopenharmony_ci		if (ino && ino == ino_of_node(target))
6248c2ecf20Sopenharmony_ci			return true;
6258c2ecf20Sopenharmony_ci	}
6268c2ecf20Sopenharmony_ci
6278c2ecf20Sopenharmony_ci	return false;
6288c2ecf20Sopenharmony_ci}
6298c2ecf20Sopenharmony_ci
6308c2ecf20Sopenharmony_cistatic void __f2fs_submit_merged_write(struct f2fs_sb_info *sbi,
6318c2ecf20Sopenharmony_ci				enum page_type type, enum temp_type temp)
6328c2ecf20Sopenharmony_ci{
6338c2ecf20Sopenharmony_ci	enum page_type btype = PAGE_TYPE_OF_BIO(type);
6348c2ecf20Sopenharmony_ci	struct f2fs_bio_info *io = sbi->write_io[btype] + temp;
6358c2ecf20Sopenharmony_ci
6368c2ecf20Sopenharmony_ci	down_write(&io->io_rwsem);
6378c2ecf20Sopenharmony_ci
6388c2ecf20Sopenharmony_ci	/* change META to META_FLUSH in the checkpoint procedure */
6398c2ecf20Sopenharmony_ci	if (type >= META_FLUSH) {
6408c2ecf20Sopenharmony_ci		io->fio.type = META_FLUSH;
6418c2ecf20Sopenharmony_ci		io->fio.op = REQ_OP_WRITE;
6428c2ecf20Sopenharmony_ci		io->fio.op_flags = REQ_META | REQ_PRIO | REQ_SYNC;
6438c2ecf20Sopenharmony_ci		if (!test_opt(sbi, NOBARRIER))
6448c2ecf20Sopenharmony_ci			io->fio.op_flags |= REQ_PREFLUSH | REQ_FUA;
6458c2ecf20Sopenharmony_ci	}
6468c2ecf20Sopenharmony_ci	__submit_merged_bio(io);
6478c2ecf20Sopenharmony_ci	up_write(&io->io_rwsem);
6488c2ecf20Sopenharmony_ci}
6498c2ecf20Sopenharmony_ci
6508c2ecf20Sopenharmony_cistatic void __submit_merged_write_cond(struct f2fs_sb_info *sbi,
6518c2ecf20Sopenharmony_ci				struct inode *inode, struct page *page,
6528c2ecf20Sopenharmony_ci				nid_t ino, enum page_type type, bool force)
6538c2ecf20Sopenharmony_ci{
6548c2ecf20Sopenharmony_ci	enum temp_type temp;
6558c2ecf20Sopenharmony_ci	bool ret = true;
6568c2ecf20Sopenharmony_ci
6578c2ecf20Sopenharmony_ci	for (temp = HOT; temp < NR_TEMP_TYPE; temp++) {
6588c2ecf20Sopenharmony_ci		if (!force)	{
6598c2ecf20Sopenharmony_ci			enum page_type btype = PAGE_TYPE_OF_BIO(type);
6608c2ecf20Sopenharmony_ci			struct f2fs_bio_info *io = sbi->write_io[btype] + temp;
6618c2ecf20Sopenharmony_ci
6628c2ecf20Sopenharmony_ci			down_read(&io->io_rwsem);
6638c2ecf20Sopenharmony_ci			ret = __has_merged_page(io->bio, inode, page, ino);
6648c2ecf20Sopenharmony_ci			up_read(&io->io_rwsem);
6658c2ecf20Sopenharmony_ci		}
6668c2ecf20Sopenharmony_ci		if (ret)
6678c2ecf20Sopenharmony_ci			__f2fs_submit_merged_write(sbi, type, temp);
6688c2ecf20Sopenharmony_ci
6698c2ecf20Sopenharmony_ci		/* TODO: use HOT temp only for meta pages now. */
6708c2ecf20Sopenharmony_ci		if (type >= META)
6718c2ecf20Sopenharmony_ci			break;
6728c2ecf20Sopenharmony_ci	}
6738c2ecf20Sopenharmony_ci}
6748c2ecf20Sopenharmony_ci
6758c2ecf20Sopenharmony_civoid f2fs_submit_merged_write(struct f2fs_sb_info *sbi, enum page_type type)
6768c2ecf20Sopenharmony_ci{
6778c2ecf20Sopenharmony_ci	__submit_merged_write_cond(sbi, NULL, NULL, 0, type, true);
6788c2ecf20Sopenharmony_ci}
6798c2ecf20Sopenharmony_ci
6808c2ecf20Sopenharmony_civoid f2fs_submit_merged_write_cond(struct f2fs_sb_info *sbi,
6818c2ecf20Sopenharmony_ci				struct inode *inode, struct page *page,
6828c2ecf20Sopenharmony_ci				nid_t ino, enum page_type type)
6838c2ecf20Sopenharmony_ci{
6848c2ecf20Sopenharmony_ci	__submit_merged_write_cond(sbi, inode, page, ino, type, false);
6858c2ecf20Sopenharmony_ci}
6868c2ecf20Sopenharmony_ci
6878c2ecf20Sopenharmony_civoid f2fs_flush_merged_writes(struct f2fs_sb_info *sbi)
6888c2ecf20Sopenharmony_ci{
6898c2ecf20Sopenharmony_ci	f2fs_submit_merged_write(sbi, DATA);
6908c2ecf20Sopenharmony_ci	f2fs_submit_merged_write(sbi, NODE);
6918c2ecf20Sopenharmony_ci	f2fs_submit_merged_write(sbi, META);
6928c2ecf20Sopenharmony_ci}
6938c2ecf20Sopenharmony_ci
6948c2ecf20Sopenharmony_ci/*
6958c2ecf20Sopenharmony_ci * Fill the locked page with data located in the block address.
6968c2ecf20Sopenharmony_ci * A caller needs to unlock the page on failure.
6978c2ecf20Sopenharmony_ci */
6988c2ecf20Sopenharmony_ciint f2fs_submit_page_bio(struct f2fs_io_info *fio)
6998c2ecf20Sopenharmony_ci{
7008c2ecf20Sopenharmony_ci	struct bio *bio;
7018c2ecf20Sopenharmony_ci	struct page *page = fio->encrypted_page ?
7028c2ecf20Sopenharmony_ci			fio->encrypted_page : fio->page;
7038c2ecf20Sopenharmony_ci
7048c2ecf20Sopenharmony_ci	if (!f2fs_is_valid_blkaddr(fio->sbi, fio->new_blkaddr,
7058c2ecf20Sopenharmony_ci			fio->is_por ? META_POR : (__is_meta_io(fio) ?
7068c2ecf20Sopenharmony_ci			META_GENERIC : DATA_GENERIC_ENHANCE)))
7078c2ecf20Sopenharmony_ci		return -EFSCORRUPTED;
7088c2ecf20Sopenharmony_ci
7098c2ecf20Sopenharmony_ci	trace_f2fs_submit_page_bio(page, fio);
7108c2ecf20Sopenharmony_ci	f2fs_trace_ios(fio, 0);
7118c2ecf20Sopenharmony_ci
7128c2ecf20Sopenharmony_ci	/* Allocate a new bio */
7138c2ecf20Sopenharmony_ci	bio = __bio_alloc(fio, 1);
7148c2ecf20Sopenharmony_ci
7158c2ecf20Sopenharmony_ci	f2fs_set_bio_crypt_ctx(bio, fio->page->mapping->host,
7168c2ecf20Sopenharmony_ci			       fio->page->index, fio, GFP_NOIO);
7178c2ecf20Sopenharmony_ci
7188c2ecf20Sopenharmony_ci	if (bio_add_page(bio, page, PAGE_SIZE, 0) < PAGE_SIZE) {
7198c2ecf20Sopenharmony_ci		bio_put(bio);
7208c2ecf20Sopenharmony_ci		return -EFAULT;
7218c2ecf20Sopenharmony_ci	}
7228c2ecf20Sopenharmony_ci
7238c2ecf20Sopenharmony_ci	if (fio->io_wbc && !is_read_io(fio->op))
7248c2ecf20Sopenharmony_ci		wbc_account_cgroup_owner(fio->io_wbc, fio->page, PAGE_SIZE);
7258c2ecf20Sopenharmony_ci
7268c2ecf20Sopenharmony_ci	__attach_io_flag(fio);
7278c2ecf20Sopenharmony_ci	bio_set_op_attrs(bio, fio->op, fio->op_flags);
7288c2ecf20Sopenharmony_ci
7298c2ecf20Sopenharmony_ci	inc_page_count(fio->sbi, is_read_io(fio->op) ?
7308c2ecf20Sopenharmony_ci			__read_io_type(page): WB_DATA_TYPE(fio->page));
7318c2ecf20Sopenharmony_ci
7328c2ecf20Sopenharmony_ci	__submit_bio(fio->sbi, bio, fio->type);
7338c2ecf20Sopenharmony_ci	return 0;
7348c2ecf20Sopenharmony_ci}
7358c2ecf20Sopenharmony_ci
7368c2ecf20Sopenharmony_cistatic bool page_is_mergeable(struct f2fs_sb_info *sbi, struct bio *bio,
7378c2ecf20Sopenharmony_ci				block_t last_blkaddr, block_t cur_blkaddr)
7388c2ecf20Sopenharmony_ci{
7398c2ecf20Sopenharmony_ci	if (last_blkaddr + 1 != cur_blkaddr)
7408c2ecf20Sopenharmony_ci		return false;
7418c2ecf20Sopenharmony_ci	return __same_bdev(sbi, cur_blkaddr, bio);
7428c2ecf20Sopenharmony_ci}
7438c2ecf20Sopenharmony_ci
7448c2ecf20Sopenharmony_cistatic bool io_type_is_mergeable(struct f2fs_bio_info *io,
7458c2ecf20Sopenharmony_ci						struct f2fs_io_info *fio)
7468c2ecf20Sopenharmony_ci{
7478c2ecf20Sopenharmony_ci	if (io->fio.op != fio->op)
7488c2ecf20Sopenharmony_ci		return false;
7498c2ecf20Sopenharmony_ci	return io->fio.op_flags == fio->op_flags;
7508c2ecf20Sopenharmony_ci}
7518c2ecf20Sopenharmony_ci
7528c2ecf20Sopenharmony_cistatic bool io_is_mergeable(struct f2fs_sb_info *sbi, struct bio *bio,
7538c2ecf20Sopenharmony_ci					struct f2fs_bio_info *io,
7548c2ecf20Sopenharmony_ci					struct f2fs_io_info *fio,
7558c2ecf20Sopenharmony_ci					block_t last_blkaddr,
7568c2ecf20Sopenharmony_ci					block_t cur_blkaddr)
7578c2ecf20Sopenharmony_ci{
7588c2ecf20Sopenharmony_ci	if (F2FS_IO_ALIGNED(sbi) && (fio->type == DATA || fio->type == NODE)) {
7598c2ecf20Sopenharmony_ci		unsigned int filled_blocks =
7608c2ecf20Sopenharmony_ci				F2FS_BYTES_TO_BLK(bio->bi_iter.bi_size);
7618c2ecf20Sopenharmony_ci		unsigned int io_size = F2FS_IO_SIZE(sbi);
7628c2ecf20Sopenharmony_ci		unsigned int left_vecs = bio->bi_max_vecs - bio->bi_vcnt;
7638c2ecf20Sopenharmony_ci
7648c2ecf20Sopenharmony_ci		/* IOs in bio is aligned and left space of vectors is not enough */
7658c2ecf20Sopenharmony_ci		if (!(filled_blocks % io_size) && left_vecs < io_size)
7668c2ecf20Sopenharmony_ci			return false;
7678c2ecf20Sopenharmony_ci	}
7688c2ecf20Sopenharmony_ci	if (!page_is_mergeable(sbi, bio, last_blkaddr, cur_blkaddr))
7698c2ecf20Sopenharmony_ci		return false;
7708c2ecf20Sopenharmony_ci	return io_type_is_mergeable(io, fio);
7718c2ecf20Sopenharmony_ci}
7728c2ecf20Sopenharmony_ci
7738c2ecf20Sopenharmony_cistatic void add_bio_entry(struct f2fs_sb_info *sbi, struct bio *bio,
7748c2ecf20Sopenharmony_ci				struct page *page, enum temp_type temp)
7758c2ecf20Sopenharmony_ci{
7768c2ecf20Sopenharmony_ci	struct f2fs_bio_info *io = sbi->write_io[DATA] + temp;
7778c2ecf20Sopenharmony_ci	struct bio_entry *be;
7788c2ecf20Sopenharmony_ci
7798c2ecf20Sopenharmony_ci	be = f2fs_kmem_cache_alloc(bio_entry_slab, GFP_NOFS);
7808c2ecf20Sopenharmony_ci	be->bio = bio;
7818c2ecf20Sopenharmony_ci	bio_get(bio);
7828c2ecf20Sopenharmony_ci
7838c2ecf20Sopenharmony_ci	if (bio_add_page(bio, page, PAGE_SIZE, 0) != PAGE_SIZE)
7848c2ecf20Sopenharmony_ci		f2fs_bug_on(sbi, 1);
7858c2ecf20Sopenharmony_ci
7868c2ecf20Sopenharmony_ci	down_write(&io->bio_list_lock);
7878c2ecf20Sopenharmony_ci	list_add_tail(&be->list, &io->bio_list);
7888c2ecf20Sopenharmony_ci	up_write(&io->bio_list_lock);
7898c2ecf20Sopenharmony_ci}
7908c2ecf20Sopenharmony_ci
7918c2ecf20Sopenharmony_cistatic void del_bio_entry(struct bio_entry *be)
7928c2ecf20Sopenharmony_ci{
7938c2ecf20Sopenharmony_ci	list_del(&be->list);
7948c2ecf20Sopenharmony_ci	kmem_cache_free(bio_entry_slab, be);
7958c2ecf20Sopenharmony_ci}
7968c2ecf20Sopenharmony_ci
7978c2ecf20Sopenharmony_cistatic int add_ipu_page(struct f2fs_io_info *fio, struct bio **bio,
7988c2ecf20Sopenharmony_ci							struct page *page)
7998c2ecf20Sopenharmony_ci{
8008c2ecf20Sopenharmony_ci	struct f2fs_sb_info *sbi = fio->sbi;
8018c2ecf20Sopenharmony_ci	enum temp_type temp;
8028c2ecf20Sopenharmony_ci	bool found = false;
8038c2ecf20Sopenharmony_ci	int ret = -EAGAIN;
8048c2ecf20Sopenharmony_ci
8058c2ecf20Sopenharmony_ci	for (temp = HOT; temp < NR_TEMP_TYPE && !found; temp++) {
8068c2ecf20Sopenharmony_ci		struct f2fs_bio_info *io = sbi->write_io[DATA] + temp;
8078c2ecf20Sopenharmony_ci		struct list_head *head = &io->bio_list;
8088c2ecf20Sopenharmony_ci		struct bio_entry *be;
8098c2ecf20Sopenharmony_ci
8108c2ecf20Sopenharmony_ci		down_write(&io->bio_list_lock);
8118c2ecf20Sopenharmony_ci		list_for_each_entry(be, head, list) {
8128c2ecf20Sopenharmony_ci			if (be->bio != *bio)
8138c2ecf20Sopenharmony_ci				continue;
8148c2ecf20Sopenharmony_ci
8158c2ecf20Sopenharmony_ci			found = true;
8168c2ecf20Sopenharmony_ci
8178c2ecf20Sopenharmony_ci			f2fs_bug_on(sbi, !page_is_mergeable(sbi, *bio,
8188c2ecf20Sopenharmony_ci							    *fio->last_block,
8198c2ecf20Sopenharmony_ci							    fio->new_blkaddr));
8208c2ecf20Sopenharmony_ci			if (f2fs_crypt_mergeable_bio(*bio,
8218c2ecf20Sopenharmony_ci					fio->page->mapping->host,
8228c2ecf20Sopenharmony_ci					fio->page->index, fio) &&
8238c2ecf20Sopenharmony_ci			    bio_add_page(*bio, page, PAGE_SIZE, 0) ==
8248c2ecf20Sopenharmony_ci					PAGE_SIZE) {
8258c2ecf20Sopenharmony_ci				ret = 0;
8268c2ecf20Sopenharmony_ci				break;
8278c2ecf20Sopenharmony_ci			}
8288c2ecf20Sopenharmony_ci
8298c2ecf20Sopenharmony_ci			/* page can't be merged into bio; submit the bio */
8308c2ecf20Sopenharmony_ci			del_bio_entry(be);
8318c2ecf20Sopenharmony_ci			__submit_bio(sbi, *bio, DATA);
8328c2ecf20Sopenharmony_ci			break;
8338c2ecf20Sopenharmony_ci		}
8348c2ecf20Sopenharmony_ci		up_write(&io->bio_list_lock);
8358c2ecf20Sopenharmony_ci	}
8368c2ecf20Sopenharmony_ci
8378c2ecf20Sopenharmony_ci	if (ret) {
8388c2ecf20Sopenharmony_ci		bio_put(*bio);
8398c2ecf20Sopenharmony_ci		*bio = NULL;
8408c2ecf20Sopenharmony_ci	}
8418c2ecf20Sopenharmony_ci
8428c2ecf20Sopenharmony_ci	return ret;
8438c2ecf20Sopenharmony_ci}
8448c2ecf20Sopenharmony_ci
8458c2ecf20Sopenharmony_civoid f2fs_submit_merged_ipu_write(struct f2fs_sb_info *sbi,
8468c2ecf20Sopenharmony_ci					struct bio **bio, struct page *page)
8478c2ecf20Sopenharmony_ci{
8488c2ecf20Sopenharmony_ci	enum temp_type temp;
8498c2ecf20Sopenharmony_ci	bool found = false;
8508c2ecf20Sopenharmony_ci	struct bio *target = bio ? *bio : NULL;
8518c2ecf20Sopenharmony_ci
8528c2ecf20Sopenharmony_ci	f2fs_bug_on(sbi, !target && !page);
8538c2ecf20Sopenharmony_ci
8548c2ecf20Sopenharmony_ci	for (temp = HOT; temp < NR_TEMP_TYPE && !found; temp++) {
8558c2ecf20Sopenharmony_ci		struct f2fs_bio_info *io = sbi->write_io[DATA] + temp;
8568c2ecf20Sopenharmony_ci		struct list_head *head = &io->bio_list;
8578c2ecf20Sopenharmony_ci		struct bio_entry *be;
8588c2ecf20Sopenharmony_ci
8598c2ecf20Sopenharmony_ci		if (list_empty(head))
8608c2ecf20Sopenharmony_ci			continue;
8618c2ecf20Sopenharmony_ci
8628c2ecf20Sopenharmony_ci		down_read(&io->bio_list_lock);
8638c2ecf20Sopenharmony_ci		list_for_each_entry(be, head, list) {
8648c2ecf20Sopenharmony_ci			if (target)
8658c2ecf20Sopenharmony_ci				found = (target == be->bio);
8668c2ecf20Sopenharmony_ci			else
8678c2ecf20Sopenharmony_ci				found = __has_merged_page(be->bio, NULL,
8688c2ecf20Sopenharmony_ci								page, 0);
8698c2ecf20Sopenharmony_ci			if (found)
8708c2ecf20Sopenharmony_ci				break;
8718c2ecf20Sopenharmony_ci		}
8728c2ecf20Sopenharmony_ci		up_read(&io->bio_list_lock);
8738c2ecf20Sopenharmony_ci
8748c2ecf20Sopenharmony_ci		if (!found)
8758c2ecf20Sopenharmony_ci			continue;
8768c2ecf20Sopenharmony_ci
8778c2ecf20Sopenharmony_ci		found = false;
8788c2ecf20Sopenharmony_ci
8798c2ecf20Sopenharmony_ci		down_write(&io->bio_list_lock);
8808c2ecf20Sopenharmony_ci		list_for_each_entry(be, head, list) {
8818c2ecf20Sopenharmony_ci			if (target)
8828c2ecf20Sopenharmony_ci				found = (target == be->bio);
8838c2ecf20Sopenharmony_ci			else
8848c2ecf20Sopenharmony_ci				found = __has_merged_page(be->bio, NULL,
8858c2ecf20Sopenharmony_ci								page, 0);
8868c2ecf20Sopenharmony_ci			if (found) {
8878c2ecf20Sopenharmony_ci				target = be->bio;
8888c2ecf20Sopenharmony_ci				del_bio_entry(be);
8898c2ecf20Sopenharmony_ci				break;
8908c2ecf20Sopenharmony_ci			}
8918c2ecf20Sopenharmony_ci		}
8928c2ecf20Sopenharmony_ci		up_write(&io->bio_list_lock);
8938c2ecf20Sopenharmony_ci	}
8948c2ecf20Sopenharmony_ci
8958c2ecf20Sopenharmony_ci	if (found)
8968c2ecf20Sopenharmony_ci		__submit_bio(sbi, target, DATA);
8978c2ecf20Sopenharmony_ci	if (bio && *bio) {
8988c2ecf20Sopenharmony_ci		bio_put(*bio);
8998c2ecf20Sopenharmony_ci		*bio = NULL;
9008c2ecf20Sopenharmony_ci	}
9018c2ecf20Sopenharmony_ci}
9028c2ecf20Sopenharmony_ci
9038c2ecf20Sopenharmony_ciint f2fs_merge_page_bio(struct f2fs_io_info *fio)
9048c2ecf20Sopenharmony_ci{
9058c2ecf20Sopenharmony_ci	struct bio *bio = *fio->bio;
9068c2ecf20Sopenharmony_ci	struct page *page = fio->encrypted_page ?
9078c2ecf20Sopenharmony_ci			fio->encrypted_page : fio->page;
9088c2ecf20Sopenharmony_ci
9098c2ecf20Sopenharmony_ci	if (!f2fs_is_valid_blkaddr(fio->sbi, fio->new_blkaddr,
9108c2ecf20Sopenharmony_ci			__is_meta_io(fio) ? META_GENERIC : DATA_GENERIC))
9118c2ecf20Sopenharmony_ci		return -EFSCORRUPTED;
9128c2ecf20Sopenharmony_ci
9138c2ecf20Sopenharmony_ci	trace_f2fs_submit_page_bio(page, fio);
9148c2ecf20Sopenharmony_ci	f2fs_trace_ios(fio, 0);
9158c2ecf20Sopenharmony_ci
9168c2ecf20Sopenharmony_ci	if (bio && !page_is_mergeable(fio->sbi, bio, *fio->last_block,
9178c2ecf20Sopenharmony_ci						fio->new_blkaddr))
9188c2ecf20Sopenharmony_ci		f2fs_submit_merged_ipu_write(fio->sbi, &bio, NULL);
9198c2ecf20Sopenharmony_cialloc_new:
9208c2ecf20Sopenharmony_ci	if (!bio) {
9218c2ecf20Sopenharmony_ci		bio = __bio_alloc(fio, BIO_MAX_PAGES);
9228c2ecf20Sopenharmony_ci		__attach_io_flag(fio);
9238c2ecf20Sopenharmony_ci		f2fs_set_bio_crypt_ctx(bio, fio->page->mapping->host,
9248c2ecf20Sopenharmony_ci				       fio->page->index, fio, GFP_NOIO);
9258c2ecf20Sopenharmony_ci		bio_set_op_attrs(bio, fio->op, fio->op_flags);
9268c2ecf20Sopenharmony_ci
9278c2ecf20Sopenharmony_ci		add_bio_entry(fio->sbi, bio, page, fio->temp);
9288c2ecf20Sopenharmony_ci	} else {
9298c2ecf20Sopenharmony_ci		if (add_ipu_page(fio, &bio, page))
9308c2ecf20Sopenharmony_ci			goto alloc_new;
9318c2ecf20Sopenharmony_ci	}
9328c2ecf20Sopenharmony_ci
9338c2ecf20Sopenharmony_ci	if (fio->io_wbc)
9348c2ecf20Sopenharmony_ci		wbc_account_cgroup_owner(fio->io_wbc, fio->page, PAGE_SIZE);
9358c2ecf20Sopenharmony_ci
9368c2ecf20Sopenharmony_ci	inc_page_count(fio->sbi, WB_DATA_TYPE(page));
9378c2ecf20Sopenharmony_ci
9388c2ecf20Sopenharmony_ci	*fio->last_block = fio->new_blkaddr;
9398c2ecf20Sopenharmony_ci	*fio->bio = bio;
9408c2ecf20Sopenharmony_ci
9418c2ecf20Sopenharmony_ci	return 0;
9428c2ecf20Sopenharmony_ci}
9438c2ecf20Sopenharmony_ci
9448c2ecf20Sopenharmony_civoid f2fs_submit_page_write(struct f2fs_io_info *fio)
9458c2ecf20Sopenharmony_ci{
9468c2ecf20Sopenharmony_ci	struct f2fs_sb_info *sbi = fio->sbi;
9478c2ecf20Sopenharmony_ci	enum page_type btype = PAGE_TYPE_OF_BIO(fio->type);
9488c2ecf20Sopenharmony_ci	struct f2fs_bio_info *io = sbi->write_io[btype] + fio->temp;
9498c2ecf20Sopenharmony_ci	struct page *bio_page;
9508c2ecf20Sopenharmony_ci
9518c2ecf20Sopenharmony_ci	f2fs_bug_on(sbi, is_read_io(fio->op));
9528c2ecf20Sopenharmony_ci
9538c2ecf20Sopenharmony_ci	down_write(&io->io_rwsem);
9548c2ecf20Sopenharmony_cinext:
9558c2ecf20Sopenharmony_ci	if (fio->in_list) {
9568c2ecf20Sopenharmony_ci		spin_lock(&io->io_lock);
9578c2ecf20Sopenharmony_ci		if (list_empty(&io->io_list)) {
9588c2ecf20Sopenharmony_ci			spin_unlock(&io->io_lock);
9598c2ecf20Sopenharmony_ci			goto out;
9608c2ecf20Sopenharmony_ci		}
9618c2ecf20Sopenharmony_ci		fio = list_first_entry(&io->io_list,
9628c2ecf20Sopenharmony_ci						struct f2fs_io_info, list);
9638c2ecf20Sopenharmony_ci		list_del(&fio->list);
9648c2ecf20Sopenharmony_ci		spin_unlock(&io->io_lock);
9658c2ecf20Sopenharmony_ci	}
9668c2ecf20Sopenharmony_ci
9678c2ecf20Sopenharmony_ci	verify_fio_blkaddr(fio);
9688c2ecf20Sopenharmony_ci
9698c2ecf20Sopenharmony_ci	if (fio->encrypted_page)
9708c2ecf20Sopenharmony_ci		bio_page = fio->encrypted_page;
9718c2ecf20Sopenharmony_ci	else if (fio->compressed_page)
9728c2ecf20Sopenharmony_ci		bio_page = fio->compressed_page;
9738c2ecf20Sopenharmony_ci	else
9748c2ecf20Sopenharmony_ci		bio_page = fio->page;
9758c2ecf20Sopenharmony_ci
9768c2ecf20Sopenharmony_ci	/* set submitted = true as a return value */
9778c2ecf20Sopenharmony_ci	fio->submitted = true;
9788c2ecf20Sopenharmony_ci
9798c2ecf20Sopenharmony_ci	inc_page_count(sbi, WB_DATA_TYPE(bio_page));
9808c2ecf20Sopenharmony_ci
9818c2ecf20Sopenharmony_ci	if (io->bio &&
9828c2ecf20Sopenharmony_ci	    (!io_is_mergeable(sbi, io->bio, io, fio, io->last_block_in_bio,
9838c2ecf20Sopenharmony_ci			      fio->new_blkaddr) ||
9848c2ecf20Sopenharmony_ci	     !f2fs_crypt_mergeable_bio(io->bio, fio->page->mapping->host,
9858c2ecf20Sopenharmony_ci				       bio_page->index, fio)))
9868c2ecf20Sopenharmony_ci		__submit_merged_bio(io);
9878c2ecf20Sopenharmony_cialloc_new:
9888c2ecf20Sopenharmony_ci	if (io->bio == NULL) {
9898c2ecf20Sopenharmony_ci		if (F2FS_IO_ALIGNED(sbi) &&
9908c2ecf20Sopenharmony_ci				(fio->type == DATA || fio->type == NODE) &&
9918c2ecf20Sopenharmony_ci				fio->new_blkaddr & F2FS_IO_SIZE_MASK(sbi)) {
9928c2ecf20Sopenharmony_ci			dec_page_count(sbi, WB_DATA_TYPE(bio_page));
9938c2ecf20Sopenharmony_ci			fio->retry = true;
9948c2ecf20Sopenharmony_ci			goto skip;
9958c2ecf20Sopenharmony_ci		}
9968c2ecf20Sopenharmony_ci		io->bio = __bio_alloc(fio, BIO_MAX_PAGES);
9978c2ecf20Sopenharmony_ci		f2fs_set_bio_crypt_ctx(io->bio, fio->page->mapping->host,
9988c2ecf20Sopenharmony_ci				       bio_page->index, fio, GFP_NOIO);
9998c2ecf20Sopenharmony_ci		io->fio = *fio;
10008c2ecf20Sopenharmony_ci	}
10018c2ecf20Sopenharmony_ci
10028c2ecf20Sopenharmony_ci	if (bio_add_page(io->bio, bio_page, PAGE_SIZE, 0) < PAGE_SIZE) {
10038c2ecf20Sopenharmony_ci		__submit_merged_bio(io);
10048c2ecf20Sopenharmony_ci		goto alloc_new;
10058c2ecf20Sopenharmony_ci	}
10068c2ecf20Sopenharmony_ci
10078c2ecf20Sopenharmony_ci	if (fio->io_wbc)
10088c2ecf20Sopenharmony_ci		wbc_account_cgroup_owner(fio->io_wbc, fio->page, PAGE_SIZE);
10098c2ecf20Sopenharmony_ci
10108c2ecf20Sopenharmony_ci	io->last_block_in_bio = fio->new_blkaddr;
10118c2ecf20Sopenharmony_ci	f2fs_trace_ios(fio, 0);
10128c2ecf20Sopenharmony_ci
10138c2ecf20Sopenharmony_ci	trace_f2fs_submit_page_write(fio->page, fio);
10148c2ecf20Sopenharmony_ciskip:
10158c2ecf20Sopenharmony_ci	if (fio->in_list)
10168c2ecf20Sopenharmony_ci		goto next;
10178c2ecf20Sopenharmony_ciout:
10188c2ecf20Sopenharmony_ci	if (is_sbi_flag_set(sbi, SBI_IS_SHUTDOWN) ||
10198c2ecf20Sopenharmony_ci				!f2fs_is_checkpoint_ready(sbi))
10208c2ecf20Sopenharmony_ci		__submit_merged_bio(io);
10218c2ecf20Sopenharmony_ci	up_write(&io->io_rwsem);
10228c2ecf20Sopenharmony_ci}
10238c2ecf20Sopenharmony_ci
10248c2ecf20Sopenharmony_cistatic inline bool f2fs_need_verity(const struct inode *inode, pgoff_t idx)
10258c2ecf20Sopenharmony_ci{
10268c2ecf20Sopenharmony_ci	return fsverity_active(inode) && (idx <
10278c2ecf20Sopenharmony_ci		DIV_ROUND_UP(fsverity_get_verified_data_size(inode), PAGE_SIZE));
10288c2ecf20Sopenharmony_ci}
10298c2ecf20Sopenharmony_ci
10308c2ecf20Sopenharmony_cistatic struct bio *f2fs_grab_read_bio(struct inode *inode, block_t blkaddr,
10318c2ecf20Sopenharmony_ci				      unsigned nr_pages, unsigned op_flag,
10328c2ecf20Sopenharmony_ci				      pgoff_t first_idx, bool for_write,
10338c2ecf20Sopenharmony_ci				      bool for_verity)
10348c2ecf20Sopenharmony_ci{
10358c2ecf20Sopenharmony_ci	struct f2fs_sb_info *sbi = F2FS_I_SB(inode);
10368c2ecf20Sopenharmony_ci	struct bio *bio;
10378c2ecf20Sopenharmony_ci	struct bio_post_read_ctx *ctx;
10388c2ecf20Sopenharmony_ci	unsigned int post_read_steps = 0;
10398c2ecf20Sopenharmony_ci
10408c2ecf20Sopenharmony_ci	bio = f2fs_bio_alloc(sbi, min_t(int, nr_pages, BIO_MAX_PAGES),
10418c2ecf20Sopenharmony_ci								for_write);
10428c2ecf20Sopenharmony_ci	if (!bio)
10438c2ecf20Sopenharmony_ci		return ERR_PTR(-ENOMEM);
10448c2ecf20Sopenharmony_ci
10458c2ecf20Sopenharmony_ci	f2fs_set_bio_crypt_ctx(bio, inode, first_idx, NULL, GFP_NOFS);
10468c2ecf20Sopenharmony_ci
10478c2ecf20Sopenharmony_ci	f2fs_target_device(sbi, blkaddr, bio);
10488c2ecf20Sopenharmony_ci	bio->bi_end_io = f2fs_read_end_io;
10498c2ecf20Sopenharmony_ci	bio_set_op_attrs(bio, REQ_OP_READ, op_flag);
10508c2ecf20Sopenharmony_ci
10518c2ecf20Sopenharmony_ci	if (fscrypt_inode_uses_fs_layer_crypto(inode))
10528c2ecf20Sopenharmony_ci		post_read_steps |= 1 << STEP_DECRYPT;
10538c2ecf20Sopenharmony_ci	if (f2fs_compressed_file(inode))
10548c2ecf20Sopenharmony_ci		post_read_steps |= 1 << STEP_DECOMPRESS_NOWQ;
10558c2ecf20Sopenharmony_ci	if (for_verity && f2fs_need_verity(inode, first_idx))
10568c2ecf20Sopenharmony_ci		post_read_steps |= 1 << STEP_VERITY;
10578c2ecf20Sopenharmony_ci
10588c2ecf20Sopenharmony_ci	if (post_read_steps) {
10598c2ecf20Sopenharmony_ci		/* Due to the mempool, this never fails. */
10608c2ecf20Sopenharmony_ci		ctx = mempool_alloc(bio_post_read_ctx_pool, GFP_NOFS);
10618c2ecf20Sopenharmony_ci		ctx->bio = bio;
10628c2ecf20Sopenharmony_ci		ctx->sbi = sbi;
10638c2ecf20Sopenharmony_ci		ctx->enabled_steps = post_read_steps;
10648c2ecf20Sopenharmony_ci		bio->bi_private = ctx;
10658c2ecf20Sopenharmony_ci	}
10668c2ecf20Sopenharmony_ci
10678c2ecf20Sopenharmony_ci	return bio;
10688c2ecf20Sopenharmony_ci}
10698c2ecf20Sopenharmony_ci
10708c2ecf20Sopenharmony_cistatic void f2fs_release_read_bio(struct bio *bio)
10718c2ecf20Sopenharmony_ci{
10728c2ecf20Sopenharmony_ci	if (bio->bi_private)
10738c2ecf20Sopenharmony_ci		mempool_free(bio->bi_private, bio_post_read_ctx_pool);
10748c2ecf20Sopenharmony_ci	bio_put(bio);
10758c2ecf20Sopenharmony_ci}
10768c2ecf20Sopenharmony_ci
10778c2ecf20Sopenharmony_ci/* This can handle encryption stuffs */
10788c2ecf20Sopenharmony_cistatic int f2fs_submit_page_read(struct inode *inode, struct page *page,
10798c2ecf20Sopenharmony_ci				 block_t blkaddr, int op_flags, bool for_write)
10808c2ecf20Sopenharmony_ci{
10818c2ecf20Sopenharmony_ci	struct f2fs_sb_info *sbi = F2FS_I_SB(inode);
10828c2ecf20Sopenharmony_ci	struct bio *bio;
10838c2ecf20Sopenharmony_ci
10848c2ecf20Sopenharmony_ci	bio = f2fs_grab_read_bio(inode, blkaddr, 1, op_flags,
10858c2ecf20Sopenharmony_ci					page->index, for_write, true);
10868c2ecf20Sopenharmony_ci	if (IS_ERR(bio))
10878c2ecf20Sopenharmony_ci		return PTR_ERR(bio);
10888c2ecf20Sopenharmony_ci
10898c2ecf20Sopenharmony_ci	/* wait for GCed page writeback via META_MAPPING */
10908c2ecf20Sopenharmony_ci	f2fs_wait_on_block_writeback(inode, blkaddr);
10918c2ecf20Sopenharmony_ci
10928c2ecf20Sopenharmony_ci	if (bio_add_page(bio, page, PAGE_SIZE, 0) < PAGE_SIZE) {
10938c2ecf20Sopenharmony_ci		bio_put(bio);
10948c2ecf20Sopenharmony_ci		return -EFAULT;
10958c2ecf20Sopenharmony_ci	}
10968c2ecf20Sopenharmony_ci	ClearPageError(page);
10978c2ecf20Sopenharmony_ci	inc_page_count(sbi, F2FS_RD_DATA);
10988c2ecf20Sopenharmony_ci	f2fs_update_iostat(sbi, FS_DATA_READ_IO, F2FS_BLKSIZE);
10998c2ecf20Sopenharmony_ci	__submit_bio(sbi, bio, DATA);
11008c2ecf20Sopenharmony_ci	return 0;
11018c2ecf20Sopenharmony_ci}
11028c2ecf20Sopenharmony_ci
11038c2ecf20Sopenharmony_cistatic void __set_data_blkaddr(struct dnode_of_data *dn)
11048c2ecf20Sopenharmony_ci{
11058c2ecf20Sopenharmony_ci	struct f2fs_node *rn = F2FS_NODE(dn->node_page);
11068c2ecf20Sopenharmony_ci	__le32 *addr_array;
11078c2ecf20Sopenharmony_ci	int base = 0;
11088c2ecf20Sopenharmony_ci
11098c2ecf20Sopenharmony_ci	if (IS_INODE(dn->node_page) && f2fs_has_extra_attr(dn->inode))
11108c2ecf20Sopenharmony_ci		base = get_extra_isize(dn->inode);
11118c2ecf20Sopenharmony_ci
11128c2ecf20Sopenharmony_ci	/* Get physical address of data block */
11138c2ecf20Sopenharmony_ci	addr_array = blkaddr_in_node(rn);
11148c2ecf20Sopenharmony_ci	addr_array[base + dn->ofs_in_node] = cpu_to_le32(dn->data_blkaddr);
11158c2ecf20Sopenharmony_ci}
11168c2ecf20Sopenharmony_ci
11178c2ecf20Sopenharmony_ci/*
11188c2ecf20Sopenharmony_ci * Lock ordering for the change of data block address:
11198c2ecf20Sopenharmony_ci * ->data_page
11208c2ecf20Sopenharmony_ci *  ->node_page
11218c2ecf20Sopenharmony_ci *    update block addresses in the node page
11228c2ecf20Sopenharmony_ci */
11238c2ecf20Sopenharmony_civoid f2fs_set_data_blkaddr(struct dnode_of_data *dn)
11248c2ecf20Sopenharmony_ci{
11258c2ecf20Sopenharmony_ci	f2fs_wait_on_page_writeback(dn->node_page, NODE, true, true);
11268c2ecf20Sopenharmony_ci	__set_data_blkaddr(dn);
11278c2ecf20Sopenharmony_ci	if (set_page_dirty(dn->node_page))
11288c2ecf20Sopenharmony_ci		dn->node_changed = true;
11298c2ecf20Sopenharmony_ci}
11308c2ecf20Sopenharmony_ci
11318c2ecf20Sopenharmony_civoid f2fs_update_data_blkaddr(struct dnode_of_data *dn, block_t blkaddr)
11328c2ecf20Sopenharmony_ci{
11338c2ecf20Sopenharmony_ci	dn->data_blkaddr = blkaddr;
11348c2ecf20Sopenharmony_ci	f2fs_set_data_blkaddr(dn);
11358c2ecf20Sopenharmony_ci	f2fs_update_extent_cache(dn);
11368c2ecf20Sopenharmony_ci}
11378c2ecf20Sopenharmony_ci
11388c2ecf20Sopenharmony_ci/* dn->ofs_in_node will be returned with up-to-date last block pointer */
11398c2ecf20Sopenharmony_ciint f2fs_reserve_new_blocks(struct dnode_of_data *dn, blkcnt_t count)
11408c2ecf20Sopenharmony_ci{
11418c2ecf20Sopenharmony_ci	struct f2fs_sb_info *sbi = F2FS_I_SB(dn->inode);
11428c2ecf20Sopenharmony_ci	int err;
11438c2ecf20Sopenharmony_ci
11448c2ecf20Sopenharmony_ci	if (!count)
11458c2ecf20Sopenharmony_ci		return 0;
11468c2ecf20Sopenharmony_ci
11478c2ecf20Sopenharmony_ci	if (unlikely(is_inode_flag_set(dn->inode, FI_NO_ALLOC)))
11488c2ecf20Sopenharmony_ci		return -EPERM;
11498c2ecf20Sopenharmony_ci	if (unlikely((err = inc_valid_block_count(sbi, dn->inode, &count))))
11508c2ecf20Sopenharmony_ci		return err;
11518c2ecf20Sopenharmony_ci
11528c2ecf20Sopenharmony_ci	trace_f2fs_reserve_new_blocks(dn->inode, dn->nid,
11538c2ecf20Sopenharmony_ci						dn->ofs_in_node, count);
11548c2ecf20Sopenharmony_ci
11558c2ecf20Sopenharmony_ci	f2fs_wait_on_page_writeback(dn->node_page, NODE, true, true);
11568c2ecf20Sopenharmony_ci
11578c2ecf20Sopenharmony_ci	for (; count > 0; dn->ofs_in_node++) {
11588c2ecf20Sopenharmony_ci		block_t blkaddr = f2fs_data_blkaddr(dn);
11598c2ecf20Sopenharmony_ci		if (blkaddr == NULL_ADDR) {
11608c2ecf20Sopenharmony_ci			dn->data_blkaddr = NEW_ADDR;
11618c2ecf20Sopenharmony_ci			__set_data_blkaddr(dn);
11628c2ecf20Sopenharmony_ci			count--;
11638c2ecf20Sopenharmony_ci		}
11648c2ecf20Sopenharmony_ci	}
11658c2ecf20Sopenharmony_ci
11668c2ecf20Sopenharmony_ci	if (set_page_dirty(dn->node_page))
11678c2ecf20Sopenharmony_ci		dn->node_changed = true;
11688c2ecf20Sopenharmony_ci	return 0;
11698c2ecf20Sopenharmony_ci}
11708c2ecf20Sopenharmony_ci
11718c2ecf20Sopenharmony_ci/* Should keep dn->ofs_in_node unchanged */
11728c2ecf20Sopenharmony_ciint f2fs_reserve_new_block(struct dnode_of_data *dn)
11738c2ecf20Sopenharmony_ci{
11748c2ecf20Sopenharmony_ci	unsigned int ofs_in_node = dn->ofs_in_node;
11758c2ecf20Sopenharmony_ci	int ret;
11768c2ecf20Sopenharmony_ci
11778c2ecf20Sopenharmony_ci	ret = f2fs_reserve_new_blocks(dn, 1);
11788c2ecf20Sopenharmony_ci	dn->ofs_in_node = ofs_in_node;
11798c2ecf20Sopenharmony_ci	return ret;
11808c2ecf20Sopenharmony_ci}
11818c2ecf20Sopenharmony_ci
11828c2ecf20Sopenharmony_ciint f2fs_reserve_block(struct dnode_of_data *dn, pgoff_t index)
11838c2ecf20Sopenharmony_ci{
11848c2ecf20Sopenharmony_ci	bool need_put = dn->inode_page ? false : true;
11858c2ecf20Sopenharmony_ci	int err;
11868c2ecf20Sopenharmony_ci
11878c2ecf20Sopenharmony_ci	err = f2fs_get_dnode_of_data(dn, index, ALLOC_NODE);
11888c2ecf20Sopenharmony_ci	if (err)
11898c2ecf20Sopenharmony_ci		return err;
11908c2ecf20Sopenharmony_ci
11918c2ecf20Sopenharmony_ci	if (dn->data_blkaddr == NULL_ADDR)
11928c2ecf20Sopenharmony_ci		err = f2fs_reserve_new_block(dn);
11938c2ecf20Sopenharmony_ci	if (err || need_put)
11948c2ecf20Sopenharmony_ci		f2fs_put_dnode(dn);
11958c2ecf20Sopenharmony_ci	return err;
11968c2ecf20Sopenharmony_ci}
11978c2ecf20Sopenharmony_ci
11988c2ecf20Sopenharmony_ciint f2fs_get_block(struct dnode_of_data *dn, pgoff_t index)
11998c2ecf20Sopenharmony_ci{
12008c2ecf20Sopenharmony_ci	struct extent_info ei = {0, 0, 0};
12018c2ecf20Sopenharmony_ci	struct inode *inode = dn->inode;
12028c2ecf20Sopenharmony_ci
12038c2ecf20Sopenharmony_ci	if (f2fs_lookup_extent_cache(inode, index, &ei)) {
12048c2ecf20Sopenharmony_ci		dn->data_blkaddr = ei.blk + index - ei.fofs;
12058c2ecf20Sopenharmony_ci		return 0;
12068c2ecf20Sopenharmony_ci	}
12078c2ecf20Sopenharmony_ci
12088c2ecf20Sopenharmony_ci	return f2fs_reserve_block(dn, index);
12098c2ecf20Sopenharmony_ci}
12108c2ecf20Sopenharmony_ci
12118c2ecf20Sopenharmony_cistruct page *f2fs_get_read_data_page(struct inode *inode, pgoff_t index,
12128c2ecf20Sopenharmony_ci						int op_flags, bool for_write)
12138c2ecf20Sopenharmony_ci{
12148c2ecf20Sopenharmony_ci	struct address_space *mapping = inode->i_mapping;
12158c2ecf20Sopenharmony_ci	struct dnode_of_data dn;
12168c2ecf20Sopenharmony_ci	struct page *page;
12178c2ecf20Sopenharmony_ci	struct extent_info ei = {0,0,0};
12188c2ecf20Sopenharmony_ci	int err;
12198c2ecf20Sopenharmony_ci
12208c2ecf20Sopenharmony_ci	page = f2fs_grab_cache_page(mapping, index, for_write);
12218c2ecf20Sopenharmony_ci	if (!page)
12228c2ecf20Sopenharmony_ci		return ERR_PTR(-ENOMEM);
12238c2ecf20Sopenharmony_ci
12248c2ecf20Sopenharmony_ci	if (f2fs_lookup_extent_cache(inode, index, &ei)) {
12258c2ecf20Sopenharmony_ci		dn.data_blkaddr = ei.blk + index - ei.fofs;
12268c2ecf20Sopenharmony_ci		if (!f2fs_is_valid_blkaddr(F2FS_I_SB(inode), dn.data_blkaddr,
12278c2ecf20Sopenharmony_ci						DATA_GENERIC_ENHANCE_READ)) {
12288c2ecf20Sopenharmony_ci			err = -EFSCORRUPTED;
12298c2ecf20Sopenharmony_ci			goto put_err;
12308c2ecf20Sopenharmony_ci		}
12318c2ecf20Sopenharmony_ci		goto got_it;
12328c2ecf20Sopenharmony_ci	}
12338c2ecf20Sopenharmony_ci
12348c2ecf20Sopenharmony_ci	set_new_dnode(&dn, inode, NULL, NULL, 0);
12358c2ecf20Sopenharmony_ci	err = f2fs_get_dnode_of_data(&dn, index, LOOKUP_NODE);
12368c2ecf20Sopenharmony_ci	if (err)
12378c2ecf20Sopenharmony_ci		goto put_err;
12388c2ecf20Sopenharmony_ci	f2fs_put_dnode(&dn);
12398c2ecf20Sopenharmony_ci
12408c2ecf20Sopenharmony_ci	if (unlikely(dn.data_blkaddr == NULL_ADDR)) {
12418c2ecf20Sopenharmony_ci		err = -ENOENT;
12428c2ecf20Sopenharmony_ci		goto put_err;
12438c2ecf20Sopenharmony_ci	}
12448c2ecf20Sopenharmony_ci	if (dn.data_blkaddr != NEW_ADDR &&
12458c2ecf20Sopenharmony_ci			!f2fs_is_valid_blkaddr(F2FS_I_SB(inode),
12468c2ecf20Sopenharmony_ci						dn.data_blkaddr,
12478c2ecf20Sopenharmony_ci						DATA_GENERIC_ENHANCE)) {
12488c2ecf20Sopenharmony_ci		err = -EFSCORRUPTED;
12498c2ecf20Sopenharmony_ci		goto put_err;
12508c2ecf20Sopenharmony_ci	}
12518c2ecf20Sopenharmony_cigot_it:
12528c2ecf20Sopenharmony_ci	if (PageUptodate(page)) {
12538c2ecf20Sopenharmony_ci		unlock_page(page);
12548c2ecf20Sopenharmony_ci		return page;
12558c2ecf20Sopenharmony_ci	}
12568c2ecf20Sopenharmony_ci
12578c2ecf20Sopenharmony_ci	/*
12588c2ecf20Sopenharmony_ci	 * A new dentry page is allocated but not able to be written, since its
12598c2ecf20Sopenharmony_ci	 * new inode page couldn't be allocated due to -ENOSPC.
12608c2ecf20Sopenharmony_ci	 * In such the case, its blkaddr can be remained as NEW_ADDR.
12618c2ecf20Sopenharmony_ci	 * see, f2fs_add_link -> f2fs_get_new_data_page ->
12628c2ecf20Sopenharmony_ci	 * f2fs_init_inode_metadata.
12638c2ecf20Sopenharmony_ci	 */
12648c2ecf20Sopenharmony_ci	if (dn.data_blkaddr == NEW_ADDR) {
12658c2ecf20Sopenharmony_ci		zero_user_segment(page, 0, PAGE_SIZE);
12668c2ecf20Sopenharmony_ci		if (!PageUptodate(page))
12678c2ecf20Sopenharmony_ci			SetPageUptodate(page);
12688c2ecf20Sopenharmony_ci		unlock_page(page);
12698c2ecf20Sopenharmony_ci		return page;
12708c2ecf20Sopenharmony_ci	}
12718c2ecf20Sopenharmony_ci
12728c2ecf20Sopenharmony_ci	err = f2fs_submit_page_read(inode, page, dn.data_blkaddr,
12738c2ecf20Sopenharmony_ci						op_flags, for_write);
12748c2ecf20Sopenharmony_ci	if (err)
12758c2ecf20Sopenharmony_ci		goto put_err;
12768c2ecf20Sopenharmony_ci	return page;
12778c2ecf20Sopenharmony_ci
12788c2ecf20Sopenharmony_ciput_err:
12798c2ecf20Sopenharmony_ci	f2fs_put_page(page, 1);
12808c2ecf20Sopenharmony_ci	return ERR_PTR(err);
12818c2ecf20Sopenharmony_ci}
12828c2ecf20Sopenharmony_ci
12838c2ecf20Sopenharmony_cistruct page *f2fs_find_data_page(struct inode *inode, pgoff_t index)
12848c2ecf20Sopenharmony_ci{
12858c2ecf20Sopenharmony_ci	struct address_space *mapping = inode->i_mapping;
12868c2ecf20Sopenharmony_ci	struct page *page;
12878c2ecf20Sopenharmony_ci
12888c2ecf20Sopenharmony_ci	page = find_get_page(mapping, index);
12898c2ecf20Sopenharmony_ci	if (page && PageUptodate(page))
12908c2ecf20Sopenharmony_ci		return page;
12918c2ecf20Sopenharmony_ci	f2fs_put_page(page, 0);
12928c2ecf20Sopenharmony_ci
12938c2ecf20Sopenharmony_ci	page = f2fs_get_read_data_page(inode, index, 0, false);
12948c2ecf20Sopenharmony_ci	if (IS_ERR(page))
12958c2ecf20Sopenharmony_ci		return page;
12968c2ecf20Sopenharmony_ci
12978c2ecf20Sopenharmony_ci	if (PageUptodate(page))
12988c2ecf20Sopenharmony_ci		return page;
12998c2ecf20Sopenharmony_ci
13008c2ecf20Sopenharmony_ci	wait_on_page_locked(page);
13018c2ecf20Sopenharmony_ci	if (unlikely(!PageUptodate(page))) {
13028c2ecf20Sopenharmony_ci		f2fs_put_page(page, 0);
13038c2ecf20Sopenharmony_ci		return ERR_PTR(-EIO);
13048c2ecf20Sopenharmony_ci	}
13058c2ecf20Sopenharmony_ci	return page;
13068c2ecf20Sopenharmony_ci}
13078c2ecf20Sopenharmony_ci
13088c2ecf20Sopenharmony_ci/*
13098c2ecf20Sopenharmony_ci * If it tries to access a hole, return an error.
13108c2ecf20Sopenharmony_ci * Because, the callers, functions in dir.c and GC, should be able to know
13118c2ecf20Sopenharmony_ci * whether this page exists or not.
13128c2ecf20Sopenharmony_ci */
13138c2ecf20Sopenharmony_cistruct page *f2fs_get_lock_data_page(struct inode *inode, pgoff_t index,
13148c2ecf20Sopenharmony_ci							bool for_write)
13158c2ecf20Sopenharmony_ci{
13168c2ecf20Sopenharmony_ci	struct address_space *mapping = inode->i_mapping;
13178c2ecf20Sopenharmony_ci	struct page *page;
13188c2ecf20Sopenharmony_cirepeat:
13198c2ecf20Sopenharmony_ci	page = f2fs_get_read_data_page(inode, index, 0, for_write);
13208c2ecf20Sopenharmony_ci	if (IS_ERR(page))
13218c2ecf20Sopenharmony_ci		return page;
13228c2ecf20Sopenharmony_ci
13238c2ecf20Sopenharmony_ci	/* wait for read completion */
13248c2ecf20Sopenharmony_ci	lock_page(page);
13258c2ecf20Sopenharmony_ci	if (unlikely(page->mapping != mapping)) {
13268c2ecf20Sopenharmony_ci		f2fs_put_page(page, 1);
13278c2ecf20Sopenharmony_ci		goto repeat;
13288c2ecf20Sopenharmony_ci	}
13298c2ecf20Sopenharmony_ci	if (unlikely(!PageUptodate(page))) {
13308c2ecf20Sopenharmony_ci		f2fs_put_page(page, 1);
13318c2ecf20Sopenharmony_ci		return ERR_PTR(-EIO);
13328c2ecf20Sopenharmony_ci	}
13338c2ecf20Sopenharmony_ci	return page;
13348c2ecf20Sopenharmony_ci}
13358c2ecf20Sopenharmony_ci
13368c2ecf20Sopenharmony_ci/*
13378c2ecf20Sopenharmony_ci * Caller ensures that this data page is never allocated.
13388c2ecf20Sopenharmony_ci * A new zero-filled data page is allocated in the page cache.
13398c2ecf20Sopenharmony_ci *
13408c2ecf20Sopenharmony_ci * Also, caller should grab and release a rwsem by calling f2fs_lock_op() and
13418c2ecf20Sopenharmony_ci * f2fs_unlock_op().
13428c2ecf20Sopenharmony_ci * Note that, ipage is set only by make_empty_dir, and if any error occur,
13438c2ecf20Sopenharmony_ci * ipage should be released by this function.
13448c2ecf20Sopenharmony_ci */
13458c2ecf20Sopenharmony_cistruct page *f2fs_get_new_data_page(struct inode *inode,
13468c2ecf20Sopenharmony_ci		struct page *ipage, pgoff_t index, bool new_i_size)
13478c2ecf20Sopenharmony_ci{
13488c2ecf20Sopenharmony_ci	struct address_space *mapping = inode->i_mapping;
13498c2ecf20Sopenharmony_ci	struct page *page;
13508c2ecf20Sopenharmony_ci	struct dnode_of_data dn;
13518c2ecf20Sopenharmony_ci	int err;
13528c2ecf20Sopenharmony_ci
13538c2ecf20Sopenharmony_ci	page = f2fs_grab_cache_page(mapping, index, true);
13548c2ecf20Sopenharmony_ci	if (!page) {
13558c2ecf20Sopenharmony_ci		/*
13568c2ecf20Sopenharmony_ci		 * before exiting, we should make sure ipage will be released
13578c2ecf20Sopenharmony_ci		 * if any error occur.
13588c2ecf20Sopenharmony_ci		 */
13598c2ecf20Sopenharmony_ci		f2fs_put_page(ipage, 1);
13608c2ecf20Sopenharmony_ci		return ERR_PTR(-ENOMEM);
13618c2ecf20Sopenharmony_ci	}
13628c2ecf20Sopenharmony_ci
13638c2ecf20Sopenharmony_ci	set_new_dnode(&dn, inode, ipage, NULL, 0);
13648c2ecf20Sopenharmony_ci	err = f2fs_reserve_block(&dn, index);
13658c2ecf20Sopenharmony_ci	if (err) {
13668c2ecf20Sopenharmony_ci		f2fs_put_page(page, 1);
13678c2ecf20Sopenharmony_ci		return ERR_PTR(err);
13688c2ecf20Sopenharmony_ci	}
13698c2ecf20Sopenharmony_ci	if (!ipage)
13708c2ecf20Sopenharmony_ci		f2fs_put_dnode(&dn);
13718c2ecf20Sopenharmony_ci
13728c2ecf20Sopenharmony_ci	if (PageUptodate(page))
13738c2ecf20Sopenharmony_ci		goto got_it;
13748c2ecf20Sopenharmony_ci
13758c2ecf20Sopenharmony_ci	if (dn.data_blkaddr == NEW_ADDR) {
13768c2ecf20Sopenharmony_ci		zero_user_segment(page, 0, PAGE_SIZE);
13778c2ecf20Sopenharmony_ci		if (!PageUptodate(page))
13788c2ecf20Sopenharmony_ci			SetPageUptodate(page);
13798c2ecf20Sopenharmony_ci	} else {
13808c2ecf20Sopenharmony_ci		f2fs_put_page(page, 1);
13818c2ecf20Sopenharmony_ci
13828c2ecf20Sopenharmony_ci		/* if ipage exists, blkaddr should be NEW_ADDR */
13838c2ecf20Sopenharmony_ci		f2fs_bug_on(F2FS_I_SB(inode), ipage);
13848c2ecf20Sopenharmony_ci		page = f2fs_get_lock_data_page(inode, index, true);
13858c2ecf20Sopenharmony_ci		if (IS_ERR(page))
13868c2ecf20Sopenharmony_ci			return page;
13878c2ecf20Sopenharmony_ci	}
13888c2ecf20Sopenharmony_cigot_it:
13898c2ecf20Sopenharmony_ci	if (new_i_size && i_size_read(inode) <
13908c2ecf20Sopenharmony_ci				((loff_t)(index + 1) << PAGE_SHIFT))
13918c2ecf20Sopenharmony_ci		f2fs_i_size_write(inode, ((loff_t)(index + 1) << PAGE_SHIFT));
13928c2ecf20Sopenharmony_ci	return page;
13938c2ecf20Sopenharmony_ci}
13948c2ecf20Sopenharmony_ci
13958c2ecf20Sopenharmony_cistatic int __allocate_data_block(struct dnode_of_data *dn, int seg_type, int contig_level)
13968c2ecf20Sopenharmony_ci{
13978c2ecf20Sopenharmony_ci	struct f2fs_sb_info *sbi = F2FS_I_SB(dn->inode);
13988c2ecf20Sopenharmony_ci	struct f2fs_summary sum;
13998c2ecf20Sopenharmony_ci	struct node_info ni;
14008c2ecf20Sopenharmony_ci	block_t old_blkaddr;
14018c2ecf20Sopenharmony_ci	blkcnt_t count = 1;
14028c2ecf20Sopenharmony_ci	int err;
14038c2ecf20Sopenharmony_ci
14048c2ecf20Sopenharmony_ci	if (unlikely(is_inode_flag_set(dn->inode, FI_NO_ALLOC)))
14058c2ecf20Sopenharmony_ci		return -EPERM;
14068c2ecf20Sopenharmony_ci
14078c2ecf20Sopenharmony_ci	err = f2fs_get_node_info(sbi, dn->nid, &ni);
14088c2ecf20Sopenharmony_ci	if (err)
14098c2ecf20Sopenharmony_ci		return err;
14108c2ecf20Sopenharmony_ci
14118c2ecf20Sopenharmony_ci	dn->data_blkaddr = f2fs_data_blkaddr(dn);
14128c2ecf20Sopenharmony_ci	if (dn->data_blkaddr != NULL_ADDR)
14138c2ecf20Sopenharmony_ci		goto alloc;
14148c2ecf20Sopenharmony_ci
14158c2ecf20Sopenharmony_ci	if (unlikely((err = inc_valid_block_count(sbi, dn->inode, &count))))
14168c2ecf20Sopenharmony_ci		return err;
14178c2ecf20Sopenharmony_ci
14188c2ecf20Sopenharmony_cialloc:
14198c2ecf20Sopenharmony_ci	set_summary(&sum, dn->nid, dn->ofs_in_node, ni.version);
14208c2ecf20Sopenharmony_ci	old_blkaddr = dn->data_blkaddr;
14218c2ecf20Sopenharmony_ci	f2fs_allocate_data_block(sbi, NULL, old_blkaddr, &dn->data_blkaddr,
14228c2ecf20Sopenharmony_ci				&sum, seg_type, NULL, contig_level);
14238c2ecf20Sopenharmony_ci	if (GET_SEGNO(sbi, old_blkaddr) != NULL_SEGNO)
14248c2ecf20Sopenharmony_ci		invalidate_mapping_pages(META_MAPPING(sbi),
14258c2ecf20Sopenharmony_ci					old_blkaddr, old_blkaddr);
14268c2ecf20Sopenharmony_ci	f2fs_update_data_blkaddr(dn, dn->data_blkaddr);
14278c2ecf20Sopenharmony_ci
14288c2ecf20Sopenharmony_ci	/*
14298c2ecf20Sopenharmony_ci	 * i_size will be updated by direct_IO. Otherwise, we'll get stale
14308c2ecf20Sopenharmony_ci	 * data from unwritten block via dio_read.
14318c2ecf20Sopenharmony_ci	 */
14328c2ecf20Sopenharmony_ci	return 0;
14338c2ecf20Sopenharmony_ci}
14348c2ecf20Sopenharmony_ci
14358c2ecf20Sopenharmony_ciint f2fs_preallocate_blocks(struct kiocb *iocb, struct iov_iter *from)
14368c2ecf20Sopenharmony_ci{
14378c2ecf20Sopenharmony_ci	struct inode *inode = file_inode(iocb->ki_filp);
14388c2ecf20Sopenharmony_ci	struct f2fs_map_blocks map;
14398c2ecf20Sopenharmony_ci	int flag;
14408c2ecf20Sopenharmony_ci	int err = 0;
14418c2ecf20Sopenharmony_ci	bool direct_io = iocb->ki_flags & IOCB_DIRECT;
14428c2ecf20Sopenharmony_ci
14438c2ecf20Sopenharmony_ci	map.m_lblk = F2FS_BLK_ALIGN(iocb->ki_pos);
14448c2ecf20Sopenharmony_ci	map.m_len = F2FS_BYTES_TO_BLK(iocb->ki_pos + iov_iter_count(from));
14458c2ecf20Sopenharmony_ci	if (map.m_len > map.m_lblk)
14468c2ecf20Sopenharmony_ci		map.m_len -= map.m_lblk;
14478c2ecf20Sopenharmony_ci	else
14488c2ecf20Sopenharmony_ci		map.m_len = 0;
14498c2ecf20Sopenharmony_ci
14508c2ecf20Sopenharmony_ci	map.m_next_pgofs = NULL;
14518c2ecf20Sopenharmony_ci	map.m_next_extent = NULL;
14528c2ecf20Sopenharmony_ci	map.m_seg_type = NO_CHECK_TYPE;
14538c2ecf20Sopenharmony_ci	map.m_may_create = true;
14548c2ecf20Sopenharmony_ci
14558c2ecf20Sopenharmony_ci	if (direct_io) {
14568c2ecf20Sopenharmony_ci		map.m_seg_type = f2fs_rw_hint_to_seg_type(iocb->ki_hint);
14578c2ecf20Sopenharmony_ci		flag = f2fs_force_buffered_io(inode, iocb, from) ?
14588c2ecf20Sopenharmony_ci					F2FS_GET_BLOCK_PRE_AIO :
14598c2ecf20Sopenharmony_ci					F2FS_GET_BLOCK_PRE_DIO;
14608c2ecf20Sopenharmony_ci		goto map_blocks;
14618c2ecf20Sopenharmony_ci	}
14628c2ecf20Sopenharmony_ci	if (iocb->ki_pos + iov_iter_count(from) > MAX_INLINE_DATA(inode)) {
14638c2ecf20Sopenharmony_ci		err = f2fs_convert_inline_inode(inode);
14648c2ecf20Sopenharmony_ci		if (err)
14658c2ecf20Sopenharmony_ci			return err;
14668c2ecf20Sopenharmony_ci	}
14678c2ecf20Sopenharmony_ci	if (f2fs_has_inline_data(inode))
14688c2ecf20Sopenharmony_ci		return err;
14698c2ecf20Sopenharmony_ci
14708c2ecf20Sopenharmony_ci	flag = F2FS_GET_BLOCK_PRE_AIO;
14718c2ecf20Sopenharmony_ci
14728c2ecf20Sopenharmony_cimap_blocks:
14738c2ecf20Sopenharmony_ci	err = f2fs_map_blocks(inode, &map, 1, flag);
14748c2ecf20Sopenharmony_ci	if (map.m_len > 0 && err == -ENOSPC) {
14758c2ecf20Sopenharmony_ci		if (!direct_io)
14768c2ecf20Sopenharmony_ci			set_inode_flag(inode, FI_NO_PREALLOC);
14778c2ecf20Sopenharmony_ci		err = 0;
14788c2ecf20Sopenharmony_ci	}
14798c2ecf20Sopenharmony_ci	return err;
14808c2ecf20Sopenharmony_ci}
14818c2ecf20Sopenharmony_ci
14828c2ecf20Sopenharmony_civoid f2fs_do_map_lock(struct f2fs_sb_info *sbi, int flag, bool lock)
14838c2ecf20Sopenharmony_ci{
14848c2ecf20Sopenharmony_ci	if (flag == F2FS_GET_BLOCK_PRE_AIO) {
14858c2ecf20Sopenharmony_ci		if (lock)
14868c2ecf20Sopenharmony_ci			down_read(&sbi->node_change);
14878c2ecf20Sopenharmony_ci		else
14888c2ecf20Sopenharmony_ci			up_read(&sbi->node_change);
14898c2ecf20Sopenharmony_ci	} else {
14908c2ecf20Sopenharmony_ci		if (lock)
14918c2ecf20Sopenharmony_ci			f2fs_lock_op(sbi);
14928c2ecf20Sopenharmony_ci		else
14938c2ecf20Sopenharmony_ci			f2fs_unlock_op(sbi);
14948c2ecf20Sopenharmony_ci	}
14958c2ecf20Sopenharmony_ci}
14968c2ecf20Sopenharmony_ci
14978c2ecf20Sopenharmony_ci/*
14988c2ecf20Sopenharmony_ci * f2fs_map_blocks() tries to find or build mapping relationship which
14998c2ecf20Sopenharmony_ci * maps continuous logical blocks to physical blocks, and return such
15008c2ecf20Sopenharmony_ci * info via f2fs_map_blocks structure.
15018c2ecf20Sopenharmony_ci */
15028c2ecf20Sopenharmony_ciint f2fs_map_blocks(struct inode *inode, struct f2fs_map_blocks *map,
15038c2ecf20Sopenharmony_ci						int create, int flag)
15048c2ecf20Sopenharmony_ci{
15058c2ecf20Sopenharmony_ci	unsigned int maxblocks = map->m_len;
15068c2ecf20Sopenharmony_ci	struct dnode_of_data dn;
15078c2ecf20Sopenharmony_ci	struct f2fs_sb_info *sbi = F2FS_I_SB(inode);
15088c2ecf20Sopenharmony_ci	int mode = map->m_may_create ? ALLOC_NODE : LOOKUP_NODE;
15098c2ecf20Sopenharmony_ci	pgoff_t pgofs, end_offset, end;
15108c2ecf20Sopenharmony_ci	int err = 0, ofs = 1;
15118c2ecf20Sopenharmony_ci	unsigned int ofs_in_node, last_ofs_in_node;
15128c2ecf20Sopenharmony_ci	blkcnt_t prealloc;
15138c2ecf20Sopenharmony_ci	struct extent_info ei = {0,0,0};
15148c2ecf20Sopenharmony_ci	block_t blkaddr;
15158c2ecf20Sopenharmony_ci	unsigned int start_pgofs;
15168c2ecf20Sopenharmony_ci	int contig_level = SEQ_NONE;
15178c2ecf20Sopenharmony_ci#ifdef CONFIG_F2FS_GRADING_SSR
15188c2ecf20Sopenharmony_ci	contig_level = check_io_seq(maxblocks);
15198c2ecf20Sopenharmony_ci#endif
15208c2ecf20Sopenharmony_ci
15218c2ecf20Sopenharmony_ci	if (!maxblocks)
15228c2ecf20Sopenharmony_ci		return 0;
15238c2ecf20Sopenharmony_ci
15248c2ecf20Sopenharmony_ci	map->m_len = 0;
15258c2ecf20Sopenharmony_ci	map->m_flags = 0;
15268c2ecf20Sopenharmony_ci
15278c2ecf20Sopenharmony_ci	/* it only supports block size == page size */
15288c2ecf20Sopenharmony_ci	pgofs =	(pgoff_t)map->m_lblk;
15298c2ecf20Sopenharmony_ci	end = pgofs + maxblocks;
15308c2ecf20Sopenharmony_ci
15318c2ecf20Sopenharmony_ci	if (!create && f2fs_lookup_extent_cache(inode, pgofs, &ei)) {
15328c2ecf20Sopenharmony_ci		if (f2fs_lfs_mode(sbi) && flag == F2FS_GET_BLOCK_DIO &&
15338c2ecf20Sopenharmony_ci							map->m_may_create)
15348c2ecf20Sopenharmony_ci			goto next_dnode;
15358c2ecf20Sopenharmony_ci
15368c2ecf20Sopenharmony_ci		map->m_pblk = ei.blk + pgofs - ei.fofs;
15378c2ecf20Sopenharmony_ci		map->m_len = min((pgoff_t)maxblocks, ei.fofs + ei.len - pgofs);
15388c2ecf20Sopenharmony_ci		map->m_flags = F2FS_MAP_MAPPED;
15398c2ecf20Sopenharmony_ci		if (map->m_next_extent)
15408c2ecf20Sopenharmony_ci			*map->m_next_extent = pgofs + map->m_len;
15418c2ecf20Sopenharmony_ci
15428c2ecf20Sopenharmony_ci		/* for hardware encryption, but to avoid potential issue in future */
15438c2ecf20Sopenharmony_ci		if (flag == F2FS_GET_BLOCK_DIO)
15448c2ecf20Sopenharmony_ci			f2fs_wait_on_block_writeback_range(inode,
15458c2ecf20Sopenharmony_ci						map->m_pblk, map->m_len);
15468c2ecf20Sopenharmony_ci		goto out;
15478c2ecf20Sopenharmony_ci	}
15488c2ecf20Sopenharmony_ci
15498c2ecf20Sopenharmony_cinext_dnode:
15508c2ecf20Sopenharmony_ci	if (map->m_may_create)
15518c2ecf20Sopenharmony_ci		f2fs_do_map_lock(sbi, flag, true);
15528c2ecf20Sopenharmony_ci
15538c2ecf20Sopenharmony_ci	/* When reading holes, we need its node page */
15548c2ecf20Sopenharmony_ci	set_new_dnode(&dn, inode, NULL, NULL, 0);
15558c2ecf20Sopenharmony_ci	err = f2fs_get_dnode_of_data(&dn, pgofs, mode);
15568c2ecf20Sopenharmony_ci	if (err) {
15578c2ecf20Sopenharmony_ci		if (flag == F2FS_GET_BLOCK_BMAP)
15588c2ecf20Sopenharmony_ci			map->m_pblk = 0;
15598c2ecf20Sopenharmony_ci
15608c2ecf20Sopenharmony_ci		if (err == -ENOENT) {
15618c2ecf20Sopenharmony_ci			/*
15628c2ecf20Sopenharmony_ci			 * There is one exceptional case that read_node_page()
15638c2ecf20Sopenharmony_ci			 * may return -ENOENT due to filesystem has been
15648c2ecf20Sopenharmony_ci			 * shutdown or cp_error, so force to convert error
15658c2ecf20Sopenharmony_ci			 * number to EIO for such case.
15668c2ecf20Sopenharmony_ci			 */
15678c2ecf20Sopenharmony_ci			if (map->m_may_create &&
15688c2ecf20Sopenharmony_ci				(is_sbi_flag_set(sbi, SBI_IS_SHUTDOWN) ||
15698c2ecf20Sopenharmony_ci				f2fs_cp_error(sbi))) {
15708c2ecf20Sopenharmony_ci				err = -EIO;
15718c2ecf20Sopenharmony_ci				goto unlock_out;
15728c2ecf20Sopenharmony_ci			}
15738c2ecf20Sopenharmony_ci
15748c2ecf20Sopenharmony_ci			err = 0;
15758c2ecf20Sopenharmony_ci			if (map->m_next_pgofs)
15768c2ecf20Sopenharmony_ci				*map->m_next_pgofs =
15778c2ecf20Sopenharmony_ci					f2fs_get_next_page_offset(&dn, pgofs);
15788c2ecf20Sopenharmony_ci			if (map->m_next_extent)
15798c2ecf20Sopenharmony_ci				*map->m_next_extent =
15808c2ecf20Sopenharmony_ci					f2fs_get_next_page_offset(&dn, pgofs);
15818c2ecf20Sopenharmony_ci		}
15828c2ecf20Sopenharmony_ci		goto unlock_out;
15838c2ecf20Sopenharmony_ci	}
15848c2ecf20Sopenharmony_ci
15858c2ecf20Sopenharmony_ci	start_pgofs = pgofs;
15868c2ecf20Sopenharmony_ci	prealloc = 0;
15878c2ecf20Sopenharmony_ci	last_ofs_in_node = ofs_in_node = dn.ofs_in_node;
15888c2ecf20Sopenharmony_ci	end_offset = ADDRS_PER_PAGE(dn.node_page, inode);
15898c2ecf20Sopenharmony_ci
15908c2ecf20Sopenharmony_cinext_block:
15918c2ecf20Sopenharmony_ci	blkaddr = f2fs_data_blkaddr(&dn);
15928c2ecf20Sopenharmony_ci
15938c2ecf20Sopenharmony_ci	if (__is_valid_data_blkaddr(blkaddr) &&
15948c2ecf20Sopenharmony_ci		!f2fs_is_valid_blkaddr(sbi, blkaddr, DATA_GENERIC_ENHANCE)) {
15958c2ecf20Sopenharmony_ci		err = -EFSCORRUPTED;
15968c2ecf20Sopenharmony_ci		goto sync_out;
15978c2ecf20Sopenharmony_ci	}
15988c2ecf20Sopenharmony_ci
15998c2ecf20Sopenharmony_ci	if (__is_valid_data_blkaddr(blkaddr)) {
16008c2ecf20Sopenharmony_ci		/* use out-place-update for driect IO under LFS mode */
16018c2ecf20Sopenharmony_ci		if (f2fs_lfs_mode(sbi) && flag == F2FS_GET_BLOCK_DIO &&
16028c2ecf20Sopenharmony_ci							map->m_may_create) {
16038c2ecf20Sopenharmony_ci			err = __allocate_data_block(&dn, map->m_seg_type, contig_level);
16048c2ecf20Sopenharmony_ci			if (err)
16058c2ecf20Sopenharmony_ci				goto sync_out;
16068c2ecf20Sopenharmony_ci			blkaddr = dn.data_blkaddr;
16078c2ecf20Sopenharmony_ci			set_inode_flag(inode, FI_APPEND_WRITE);
16088c2ecf20Sopenharmony_ci		}
16098c2ecf20Sopenharmony_ci	} else {
16108c2ecf20Sopenharmony_ci		if (create) {
16118c2ecf20Sopenharmony_ci			if (unlikely(f2fs_cp_error(sbi))) {
16128c2ecf20Sopenharmony_ci				err = -EIO;
16138c2ecf20Sopenharmony_ci				goto sync_out;
16148c2ecf20Sopenharmony_ci			}
16158c2ecf20Sopenharmony_ci			if (flag == F2FS_GET_BLOCK_PRE_AIO) {
16168c2ecf20Sopenharmony_ci				if (blkaddr == NULL_ADDR) {
16178c2ecf20Sopenharmony_ci					prealloc++;
16188c2ecf20Sopenharmony_ci					last_ofs_in_node = dn.ofs_in_node;
16198c2ecf20Sopenharmony_ci				}
16208c2ecf20Sopenharmony_ci			} else {
16218c2ecf20Sopenharmony_ci				WARN_ON(flag != F2FS_GET_BLOCK_PRE_DIO &&
16228c2ecf20Sopenharmony_ci					flag != F2FS_GET_BLOCK_DIO);
16238c2ecf20Sopenharmony_ci				err = __allocate_data_block(&dn,
16248c2ecf20Sopenharmony_ci					map->m_seg_type, contig_level);
16258c2ecf20Sopenharmony_ci				if (!err)
16268c2ecf20Sopenharmony_ci					set_inode_flag(inode, FI_APPEND_WRITE);
16278c2ecf20Sopenharmony_ci			}
16288c2ecf20Sopenharmony_ci			if (err)
16298c2ecf20Sopenharmony_ci				goto sync_out;
16308c2ecf20Sopenharmony_ci			map->m_flags |= F2FS_MAP_NEW;
16318c2ecf20Sopenharmony_ci			blkaddr = dn.data_blkaddr;
16328c2ecf20Sopenharmony_ci		} else {
16338c2ecf20Sopenharmony_ci			if (flag == F2FS_GET_BLOCK_BMAP) {
16348c2ecf20Sopenharmony_ci				map->m_pblk = 0;
16358c2ecf20Sopenharmony_ci				goto sync_out;
16368c2ecf20Sopenharmony_ci			}
16378c2ecf20Sopenharmony_ci			if (flag == F2FS_GET_BLOCK_PRECACHE)
16388c2ecf20Sopenharmony_ci				goto sync_out;
16398c2ecf20Sopenharmony_ci			if (flag == F2FS_GET_BLOCK_FIEMAP &&
16408c2ecf20Sopenharmony_ci						blkaddr == NULL_ADDR) {
16418c2ecf20Sopenharmony_ci				if (map->m_next_pgofs)
16428c2ecf20Sopenharmony_ci					*map->m_next_pgofs = pgofs + 1;
16438c2ecf20Sopenharmony_ci				goto sync_out;
16448c2ecf20Sopenharmony_ci			}
16458c2ecf20Sopenharmony_ci			if (flag != F2FS_GET_BLOCK_FIEMAP) {
16468c2ecf20Sopenharmony_ci				/* for defragment case */
16478c2ecf20Sopenharmony_ci				if (map->m_next_pgofs)
16488c2ecf20Sopenharmony_ci					*map->m_next_pgofs = pgofs + 1;
16498c2ecf20Sopenharmony_ci				goto sync_out;
16508c2ecf20Sopenharmony_ci			}
16518c2ecf20Sopenharmony_ci		}
16528c2ecf20Sopenharmony_ci	}
16538c2ecf20Sopenharmony_ci
16548c2ecf20Sopenharmony_ci	if (flag == F2FS_GET_BLOCK_PRE_AIO)
16558c2ecf20Sopenharmony_ci		goto skip;
16568c2ecf20Sopenharmony_ci
16578c2ecf20Sopenharmony_ci	if (map->m_len == 0) {
16588c2ecf20Sopenharmony_ci		/* preallocated unwritten block should be mapped for fiemap. */
16598c2ecf20Sopenharmony_ci		if (blkaddr == NEW_ADDR)
16608c2ecf20Sopenharmony_ci			map->m_flags |= F2FS_MAP_UNWRITTEN;
16618c2ecf20Sopenharmony_ci		map->m_flags |= F2FS_MAP_MAPPED;
16628c2ecf20Sopenharmony_ci
16638c2ecf20Sopenharmony_ci		map->m_pblk = blkaddr;
16648c2ecf20Sopenharmony_ci		map->m_len = 1;
16658c2ecf20Sopenharmony_ci	} else if ((map->m_pblk != NEW_ADDR &&
16668c2ecf20Sopenharmony_ci			blkaddr == (map->m_pblk + ofs)) ||
16678c2ecf20Sopenharmony_ci			(map->m_pblk == NEW_ADDR && blkaddr == NEW_ADDR) ||
16688c2ecf20Sopenharmony_ci			flag == F2FS_GET_BLOCK_PRE_DIO) {
16698c2ecf20Sopenharmony_ci		ofs++;
16708c2ecf20Sopenharmony_ci		map->m_len++;
16718c2ecf20Sopenharmony_ci	} else {
16728c2ecf20Sopenharmony_ci		goto sync_out;
16738c2ecf20Sopenharmony_ci	}
16748c2ecf20Sopenharmony_ci
16758c2ecf20Sopenharmony_ciskip:
16768c2ecf20Sopenharmony_ci	dn.ofs_in_node++;
16778c2ecf20Sopenharmony_ci	pgofs++;
16788c2ecf20Sopenharmony_ci
16798c2ecf20Sopenharmony_ci	/* preallocate blocks in batch for one dnode page */
16808c2ecf20Sopenharmony_ci	if (flag == F2FS_GET_BLOCK_PRE_AIO &&
16818c2ecf20Sopenharmony_ci			(pgofs == end || dn.ofs_in_node == end_offset)) {
16828c2ecf20Sopenharmony_ci
16838c2ecf20Sopenharmony_ci		dn.ofs_in_node = ofs_in_node;
16848c2ecf20Sopenharmony_ci		err = f2fs_reserve_new_blocks(&dn, prealloc);
16858c2ecf20Sopenharmony_ci		if (err)
16868c2ecf20Sopenharmony_ci			goto sync_out;
16878c2ecf20Sopenharmony_ci
16888c2ecf20Sopenharmony_ci		map->m_len += dn.ofs_in_node - ofs_in_node;
16898c2ecf20Sopenharmony_ci		if (prealloc && dn.ofs_in_node != last_ofs_in_node + 1) {
16908c2ecf20Sopenharmony_ci			err = -ENOSPC;
16918c2ecf20Sopenharmony_ci			goto sync_out;
16928c2ecf20Sopenharmony_ci		}
16938c2ecf20Sopenharmony_ci		dn.ofs_in_node = end_offset;
16948c2ecf20Sopenharmony_ci	}
16958c2ecf20Sopenharmony_ci
16968c2ecf20Sopenharmony_ci	if (pgofs >= end)
16978c2ecf20Sopenharmony_ci		goto sync_out;
16988c2ecf20Sopenharmony_ci	else if (dn.ofs_in_node < end_offset)
16998c2ecf20Sopenharmony_ci		goto next_block;
17008c2ecf20Sopenharmony_ci
17018c2ecf20Sopenharmony_ci	if (flag == F2FS_GET_BLOCK_PRECACHE) {
17028c2ecf20Sopenharmony_ci		if (map->m_flags & F2FS_MAP_MAPPED) {
17038c2ecf20Sopenharmony_ci			unsigned int ofs = start_pgofs - map->m_lblk;
17048c2ecf20Sopenharmony_ci
17058c2ecf20Sopenharmony_ci			f2fs_update_extent_cache_range(&dn,
17068c2ecf20Sopenharmony_ci				start_pgofs, map->m_pblk + ofs,
17078c2ecf20Sopenharmony_ci				map->m_len - ofs);
17088c2ecf20Sopenharmony_ci		}
17098c2ecf20Sopenharmony_ci	}
17108c2ecf20Sopenharmony_ci
17118c2ecf20Sopenharmony_ci	f2fs_put_dnode(&dn);
17128c2ecf20Sopenharmony_ci
17138c2ecf20Sopenharmony_ci	if (map->m_may_create) {
17148c2ecf20Sopenharmony_ci		f2fs_do_map_lock(sbi, flag, false);
17158c2ecf20Sopenharmony_ci		f2fs_balance_fs(sbi, dn.node_changed);
17168c2ecf20Sopenharmony_ci	}
17178c2ecf20Sopenharmony_ci	goto next_dnode;
17188c2ecf20Sopenharmony_ci
17198c2ecf20Sopenharmony_cisync_out:
17208c2ecf20Sopenharmony_ci
17218c2ecf20Sopenharmony_ci	/* for hardware encryption, but to avoid potential issue in future */
17228c2ecf20Sopenharmony_ci	if (flag == F2FS_GET_BLOCK_DIO && map->m_flags & F2FS_MAP_MAPPED)
17238c2ecf20Sopenharmony_ci		f2fs_wait_on_block_writeback_range(inode,
17248c2ecf20Sopenharmony_ci						map->m_pblk, map->m_len);
17258c2ecf20Sopenharmony_ci
17268c2ecf20Sopenharmony_ci	if (flag == F2FS_GET_BLOCK_PRECACHE) {
17278c2ecf20Sopenharmony_ci		if (map->m_flags & F2FS_MAP_MAPPED) {
17288c2ecf20Sopenharmony_ci			unsigned int ofs = start_pgofs - map->m_lblk;
17298c2ecf20Sopenharmony_ci
17308c2ecf20Sopenharmony_ci			f2fs_update_extent_cache_range(&dn,
17318c2ecf20Sopenharmony_ci				start_pgofs, map->m_pblk + ofs,
17328c2ecf20Sopenharmony_ci				map->m_len - ofs);
17338c2ecf20Sopenharmony_ci		}
17348c2ecf20Sopenharmony_ci		if (map->m_next_extent)
17358c2ecf20Sopenharmony_ci			*map->m_next_extent = pgofs + 1;
17368c2ecf20Sopenharmony_ci	}
17378c2ecf20Sopenharmony_ci	f2fs_put_dnode(&dn);
17388c2ecf20Sopenharmony_ciunlock_out:
17398c2ecf20Sopenharmony_ci	if (map->m_may_create) {
17408c2ecf20Sopenharmony_ci		f2fs_do_map_lock(sbi, flag, false);
17418c2ecf20Sopenharmony_ci		f2fs_balance_fs(sbi, dn.node_changed);
17428c2ecf20Sopenharmony_ci	}
17438c2ecf20Sopenharmony_ciout:
17448c2ecf20Sopenharmony_ci	trace_f2fs_map_blocks(inode, map, err);
17458c2ecf20Sopenharmony_ci	return err;
17468c2ecf20Sopenharmony_ci}
17478c2ecf20Sopenharmony_ci
17488c2ecf20Sopenharmony_cibool f2fs_overwrite_io(struct inode *inode, loff_t pos, size_t len)
17498c2ecf20Sopenharmony_ci{
17508c2ecf20Sopenharmony_ci	struct f2fs_map_blocks map;
17518c2ecf20Sopenharmony_ci	block_t last_lblk;
17528c2ecf20Sopenharmony_ci	int err;
17538c2ecf20Sopenharmony_ci
17548c2ecf20Sopenharmony_ci	if (pos + len > i_size_read(inode))
17558c2ecf20Sopenharmony_ci		return false;
17568c2ecf20Sopenharmony_ci
17578c2ecf20Sopenharmony_ci	map.m_lblk = F2FS_BYTES_TO_BLK(pos);
17588c2ecf20Sopenharmony_ci	map.m_next_pgofs = NULL;
17598c2ecf20Sopenharmony_ci	map.m_next_extent = NULL;
17608c2ecf20Sopenharmony_ci	map.m_seg_type = NO_CHECK_TYPE;
17618c2ecf20Sopenharmony_ci	map.m_may_create = false;
17628c2ecf20Sopenharmony_ci	last_lblk = F2FS_BLK_ALIGN(pos + len);
17638c2ecf20Sopenharmony_ci
17648c2ecf20Sopenharmony_ci	while (map.m_lblk < last_lblk) {
17658c2ecf20Sopenharmony_ci		map.m_len = last_lblk - map.m_lblk;
17668c2ecf20Sopenharmony_ci		err = f2fs_map_blocks(inode, &map, 0, F2FS_GET_BLOCK_DEFAULT);
17678c2ecf20Sopenharmony_ci		if (err || map.m_len == 0)
17688c2ecf20Sopenharmony_ci			return false;
17698c2ecf20Sopenharmony_ci		map.m_lblk += map.m_len;
17708c2ecf20Sopenharmony_ci	}
17718c2ecf20Sopenharmony_ci	return true;
17728c2ecf20Sopenharmony_ci}
17738c2ecf20Sopenharmony_ci
17748c2ecf20Sopenharmony_cistatic int __get_data_block(struct inode *inode, sector_t iblock,
17758c2ecf20Sopenharmony_ci			struct buffer_head *bh, int create, int flag,
17768c2ecf20Sopenharmony_ci			pgoff_t *next_pgofs, int seg_type, bool may_write)
17778c2ecf20Sopenharmony_ci{
17788c2ecf20Sopenharmony_ci	struct f2fs_map_blocks map;
17798c2ecf20Sopenharmony_ci	int err;
17808c2ecf20Sopenharmony_ci
17818c2ecf20Sopenharmony_ci	map.m_lblk = iblock;
17828c2ecf20Sopenharmony_ci	map.m_len = bh->b_size >> inode->i_blkbits;
17838c2ecf20Sopenharmony_ci	map.m_next_pgofs = next_pgofs;
17848c2ecf20Sopenharmony_ci	map.m_next_extent = NULL;
17858c2ecf20Sopenharmony_ci	map.m_seg_type = seg_type;
17868c2ecf20Sopenharmony_ci	map.m_may_create = may_write;
17878c2ecf20Sopenharmony_ci
17888c2ecf20Sopenharmony_ci	err = f2fs_map_blocks(inode, &map, create, flag);
17898c2ecf20Sopenharmony_ci	if (!err) {
17908c2ecf20Sopenharmony_ci		map_bh(bh, inode->i_sb, map.m_pblk);
17918c2ecf20Sopenharmony_ci		bh->b_state = (bh->b_state & ~F2FS_MAP_FLAGS) | map.m_flags;
17928c2ecf20Sopenharmony_ci		bh->b_size = (u64)map.m_len << inode->i_blkbits;
17938c2ecf20Sopenharmony_ci	}
17948c2ecf20Sopenharmony_ci	return err;
17958c2ecf20Sopenharmony_ci}
17968c2ecf20Sopenharmony_ci
17978c2ecf20Sopenharmony_cistatic int get_data_block(struct inode *inode, sector_t iblock,
17988c2ecf20Sopenharmony_ci			struct buffer_head *bh_result, int create, int flag,
17998c2ecf20Sopenharmony_ci			pgoff_t *next_pgofs)
18008c2ecf20Sopenharmony_ci{
18018c2ecf20Sopenharmony_ci	return __get_data_block(inode, iblock, bh_result, create,
18028c2ecf20Sopenharmony_ci							flag, next_pgofs,
18038c2ecf20Sopenharmony_ci							NO_CHECK_TYPE, create);
18048c2ecf20Sopenharmony_ci}
18058c2ecf20Sopenharmony_ci
18068c2ecf20Sopenharmony_cistatic int get_data_block_dio_write(struct inode *inode, sector_t iblock,
18078c2ecf20Sopenharmony_ci			struct buffer_head *bh_result, int create)
18088c2ecf20Sopenharmony_ci{
18098c2ecf20Sopenharmony_ci	return __get_data_block(inode, iblock, bh_result, create,
18108c2ecf20Sopenharmony_ci				F2FS_GET_BLOCK_DIO, NULL,
18118c2ecf20Sopenharmony_ci				f2fs_rw_hint_to_seg_type(inode->i_write_hint),
18128c2ecf20Sopenharmony_ci				IS_SWAPFILE(inode) ? false : true);
18138c2ecf20Sopenharmony_ci}
18148c2ecf20Sopenharmony_ci
18158c2ecf20Sopenharmony_cistatic int get_data_block_dio(struct inode *inode, sector_t iblock,
18168c2ecf20Sopenharmony_ci			struct buffer_head *bh_result, int create)
18178c2ecf20Sopenharmony_ci{
18188c2ecf20Sopenharmony_ci	return __get_data_block(inode, iblock, bh_result, create,
18198c2ecf20Sopenharmony_ci				F2FS_GET_BLOCK_DIO, NULL,
18208c2ecf20Sopenharmony_ci				f2fs_rw_hint_to_seg_type(inode->i_write_hint),
18218c2ecf20Sopenharmony_ci				false);
18228c2ecf20Sopenharmony_ci}
18238c2ecf20Sopenharmony_ci
18248c2ecf20Sopenharmony_cistatic int get_data_block_bmap(struct inode *inode, sector_t iblock,
18258c2ecf20Sopenharmony_ci			struct buffer_head *bh_result, int create)
18268c2ecf20Sopenharmony_ci{
18278c2ecf20Sopenharmony_ci	return __get_data_block(inode, iblock, bh_result, create,
18288c2ecf20Sopenharmony_ci						F2FS_GET_BLOCK_BMAP, NULL,
18298c2ecf20Sopenharmony_ci						NO_CHECK_TYPE, create);
18308c2ecf20Sopenharmony_ci}
18318c2ecf20Sopenharmony_ci
18328c2ecf20Sopenharmony_cistatic inline sector_t logical_to_blk(struct inode *inode, loff_t offset)
18338c2ecf20Sopenharmony_ci{
18348c2ecf20Sopenharmony_ci	return (offset >> inode->i_blkbits);
18358c2ecf20Sopenharmony_ci}
18368c2ecf20Sopenharmony_ci
18378c2ecf20Sopenharmony_cistatic inline loff_t blk_to_logical(struct inode *inode, sector_t blk)
18388c2ecf20Sopenharmony_ci{
18398c2ecf20Sopenharmony_ci	return (blk << inode->i_blkbits);
18408c2ecf20Sopenharmony_ci}
18418c2ecf20Sopenharmony_ci
18428c2ecf20Sopenharmony_cistatic int f2fs_xattr_fiemap(struct inode *inode,
18438c2ecf20Sopenharmony_ci				struct fiemap_extent_info *fieinfo)
18448c2ecf20Sopenharmony_ci{
18458c2ecf20Sopenharmony_ci	struct f2fs_sb_info *sbi = F2FS_I_SB(inode);
18468c2ecf20Sopenharmony_ci	struct page *page;
18478c2ecf20Sopenharmony_ci	struct node_info ni;
18488c2ecf20Sopenharmony_ci	__u64 phys = 0, len;
18498c2ecf20Sopenharmony_ci	__u32 flags;
18508c2ecf20Sopenharmony_ci	nid_t xnid = F2FS_I(inode)->i_xattr_nid;
18518c2ecf20Sopenharmony_ci	int err = 0;
18528c2ecf20Sopenharmony_ci
18538c2ecf20Sopenharmony_ci	if (f2fs_has_inline_xattr(inode)) {
18548c2ecf20Sopenharmony_ci		int offset;
18558c2ecf20Sopenharmony_ci
18568c2ecf20Sopenharmony_ci		page = f2fs_grab_cache_page(NODE_MAPPING(sbi),
18578c2ecf20Sopenharmony_ci						inode->i_ino, false);
18588c2ecf20Sopenharmony_ci		if (!page)
18598c2ecf20Sopenharmony_ci			return -ENOMEM;
18608c2ecf20Sopenharmony_ci
18618c2ecf20Sopenharmony_ci		err = f2fs_get_node_info(sbi, inode->i_ino, &ni);
18628c2ecf20Sopenharmony_ci		if (err) {
18638c2ecf20Sopenharmony_ci			f2fs_put_page(page, 1);
18648c2ecf20Sopenharmony_ci			return err;
18658c2ecf20Sopenharmony_ci		}
18668c2ecf20Sopenharmony_ci
18678c2ecf20Sopenharmony_ci		phys = (__u64)blk_to_logical(inode, ni.blk_addr);
18688c2ecf20Sopenharmony_ci		offset = offsetof(struct f2fs_inode, i_addr) +
18698c2ecf20Sopenharmony_ci					sizeof(__le32) * (DEF_ADDRS_PER_INODE -
18708c2ecf20Sopenharmony_ci					get_inline_xattr_addrs(inode));
18718c2ecf20Sopenharmony_ci
18728c2ecf20Sopenharmony_ci		phys += offset;
18738c2ecf20Sopenharmony_ci		len = inline_xattr_size(inode);
18748c2ecf20Sopenharmony_ci
18758c2ecf20Sopenharmony_ci		f2fs_put_page(page, 1);
18768c2ecf20Sopenharmony_ci
18778c2ecf20Sopenharmony_ci		flags = FIEMAP_EXTENT_DATA_INLINE | FIEMAP_EXTENT_NOT_ALIGNED;
18788c2ecf20Sopenharmony_ci
18798c2ecf20Sopenharmony_ci		if (!xnid)
18808c2ecf20Sopenharmony_ci			flags |= FIEMAP_EXTENT_LAST;
18818c2ecf20Sopenharmony_ci
18828c2ecf20Sopenharmony_ci		err = fiemap_fill_next_extent(fieinfo, 0, phys, len, flags);
18838c2ecf20Sopenharmony_ci		trace_f2fs_fiemap(inode, 0, phys, len, flags, err);
18848c2ecf20Sopenharmony_ci		if (err || err == 1)
18858c2ecf20Sopenharmony_ci			return err;
18868c2ecf20Sopenharmony_ci	}
18878c2ecf20Sopenharmony_ci
18888c2ecf20Sopenharmony_ci	if (xnid) {
18898c2ecf20Sopenharmony_ci		page = f2fs_grab_cache_page(NODE_MAPPING(sbi), xnid, false);
18908c2ecf20Sopenharmony_ci		if (!page)
18918c2ecf20Sopenharmony_ci			return -ENOMEM;
18928c2ecf20Sopenharmony_ci
18938c2ecf20Sopenharmony_ci		err = f2fs_get_node_info(sbi, xnid, &ni);
18948c2ecf20Sopenharmony_ci		if (err) {
18958c2ecf20Sopenharmony_ci			f2fs_put_page(page, 1);
18968c2ecf20Sopenharmony_ci			return err;
18978c2ecf20Sopenharmony_ci		}
18988c2ecf20Sopenharmony_ci
18998c2ecf20Sopenharmony_ci		phys = (__u64)blk_to_logical(inode, ni.blk_addr);
19008c2ecf20Sopenharmony_ci		len = inode->i_sb->s_blocksize;
19018c2ecf20Sopenharmony_ci
19028c2ecf20Sopenharmony_ci		f2fs_put_page(page, 1);
19038c2ecf20Sopenharmony_ci
19048c2ecf20Sopenharmony_ci		flags = FIEMAP_EXTENT_LAST;
19058c2ecf20Sopenharmony_ci	}
19068c2ecf20Sopenharmony_ci
19078c2ecf20Sopenharmony_ci	if (phys) {
19088c2ecf20Sopenharmony_ci		err = fiemap_fill_next_extent(fieinfo, 0, phys, len, flags);
19098c2ecf20Sopenharmony_ci		trace_f2fs_fiemap(inode, 0, phys, len, flags, err);
19108c2ecf20Sopenharmony_ci	}
19118c2ecf20Sopenharmony_ci
19128c2ecf20Sopenharmony_ci	return (err < 0 ? err : 0);
19138c2ecf20Sopenharmony_ci}
19148c2ecf20Sopenharmony_ci
19158c2ecf20Sopenharmony_cistatic loff_t max_inode_blocks(struct inode *inode)
19168c2ecf20Sopenharmony_ci{
19178c2ecf20Sopenharmony_ci	loff_t result = ADDRS_PER_INODE(inode);
19188c2ecf20Sopenharmony_ci	loff_t leaf_count = ADDRS_PER_BLOCK(inode);
19198c2ecf20Sopenharmony_ci
19208c2ecf20Sopenharmony_ci	/* two direct node blocks */
19218c2ecf20Sopenharmony_ci	result += (leaf_count * 2);
19228c2ecf20Sopenharmony_ci
19238c2ecf20Sopenharmony_ci	/* two indirect node blocks */
19248c2ecf20Sopenharmony_ci	leaf_count *= NIDS_PER_BLOCK;
19258c2ecf20Sopenharmony_ci	result += (leaf_count * 2);
19268c2ecf20Sopenharmony_ci
19278c2ecf20Sopenharmony_ci	/* one double indirect node block */
19288c2ecf20Sopenharmony_ci	leaf_count *= NIDS_PER_BLOCK;
19298c2ecf20Sopenharmony_ci	result += leaf_count;
19308c2ecf20Sopenharmony_ci
19318c2ecf20Sopenharmony_ci	return result;
19328c2ecf20Sopenharmony_ci}
19338c2ecf20Sopenharmony_ci
19348c2ecf20Sopenharmony_ciint f2fs_fiemap(struct inode *inode, struct fiemap_extent_info *fieinfo,
19358c2ecf20Sopenharmony_ci		u64 start, u64 len)
19368c2ecf20Sopenharmony_ci{
19378c2ecf20Sopenharmony_ci	struct buffer_head map_bh;
19388c2ecf20Sopenharmony_ci	sector_t start_blk, last_blk;
19398c2ecf20Sopenharmony_ci	pgoff_t next_pgofs;
19408c2ecf20Sopenharmony_ci	u64 logical = 0, phys = 0, size = 0;
19418c2ecf20Sopenharmony_ci	u32 flags = 0;
19428c2ecf20Sopenharmony_ci	int ret = 0;
19438c2ecf20Sopenharmony_ci	bool compr_cluster = false;
19448c2ecf20Sopenharmony_ci	unsigned int cluster_size = F2FS_I(inode)->i_cluster_size;
19458c2ecf20Sopenharmony_ci
19468c2ecf20Sopenharmony_ci	if (fieinfo->fi_flags & FIEMAP_FLAG_CACHE) {
19478c2ecf20Sopenharmony_ci		ret = f2fs_precache_extents(inode);
19488c2ecf20Sopenharmony_ci		if (ret)
19498c2ecf20Sopenharmony_ci			return ret;
19508c2ecf20Sopenharmony_ci	}
19518c2ecf20Sopenharmony_ci
19528c2ecf20Sopenharmony_ci	ret = fiemap_prep(inode, fieinfo, start, &len, FIEMAP_FLAG_XATTR);
19538c2ecf20Sopenharmony_ci	if (ret)
19548c2ecf20Sopenharmony_ci		return ret;
19558c2ecf20Sopenharmony_ci
19568c2ecf20Sopenharmony_ci	inode_lock(inode);
19578c2ecf20Sopenharmony_ci
19588c2ecf20Sopenharmony_ci	if (fieinfo->fi_flags & FIEMAP_FLAG_XATTR) {
19598c2ecf20Sopenharmony_ci		ret = f2fs_xattr_fiemap(inode, fieinfo);
19608c2ecf20Sopenharmony_ci		goto out;
19618c2ecf20Sopenharmony_ci	}
19628c2ecf20Sopenharmony_ci
19638c2ecf20Sopenharmony_ci	if (f2fs_has_inline_data(inode) || f2fs_has_inline_dentry(inode)) {
19648c2ecf20Sopenharmony_ci		ret = f2fs_inline_data_fiemap(inode, fieinfo, start, len);
19658c2ecf20Sopenharmony_ci		if (ret != -EAGAIN)
19668c2ecf20Sopenharmony_ci			goto out;
19678c2ecf20Sopenharmony_ci	}
19688c2ecf20Sopenharmony_ci
19698c2ecf20Sopenharmony_ci	if (logical_to_blk(inode, len) == 0)
19708c2ecf20Sopenharmony_ci		len = blk_to_logical(inode, 1);
19718c2ecf20Sopenharmony_ci
19728c2ecf20Sopenharmony_ci	start_blk = logical_to_blk(inode, start);
19738c2ecf20Sopenharmony_ci	last_blk = logical_to_blk(inode, start + len - 1);
19748c2ecf20Sopenharmony_ci
19758c2ecf20Sopenharmony_cinext:
19768c2ecf20Sopenharmony_ci	memset(&map_bh, 0, sizeof(struct buffer_head));
19778c2ecf20Sopenharmony_ci	map_bh.b_size = len;
19788c2ecf20Sopenharmony_ci
19798c2ecf20Sopenharmony_ci	if (compr_cluster)
19808c2ecf20Sopenharmony_ci		map_bh.b_size = blk_to_logical(inode, cluster_size - 1);
19818c2ecf20Sopenharmony_ci
19828c2ecf20Sopenharmony_ci	ret = get_data_block(inode, start_blk, &map_bh, 0,
19838c2ecf20Sopenharmony_ci					F2FS_GET_BLOCK_FIEMAP, &next_pgofs);
19848c2ecf20Sopenharmony_ci	if (ret)
19858c2ecf20Sopenharmony_ci		goto out;
19868c2ecf20Sopenharmony_ci
19878c2ecf20Sopenharmony_ci	/* HOLE */
19888c2ecf20Sopenharmony_ci	if (!buffer_mapped(&map_bh)) {
19898c2ecf20Sopenharmony_ci		start_blk = next_pgofs;
19908c2ecf20Sopenharmony_ci
19918c2ecf20Sopenharmony_ci		if (blk_to_logical(inode, start_blk) < blk_to_logical(inode,
19928c2ecf20Sopenharmony_ci						max_inode_blocks(inode)))
19938c2ecf20Sopenharmony_ci			goto prep_next;
19948c2ecf20Sopenharmony_ci
19958c2ecf20Sopenharmony_ci		flags |= FIEMAP_EXTENT_LAST;
19968c2ecf20Sopenharmony_ci	}
19978c2ecf20Sopenharmony_ci
19988c2ecf20Sopenharmony_ci	if (size) {
19998c2ecf20Sopenharmony_ci		if (IS_ENCRYPTED(inode))
20008c2ecf20Sopenharmony_ci			flags |= FIEMAP_EXTENT_DATA_ENCRYPTED;
20018c2ecf20Sopenharmony_ci
20028c2ecf20Sopenharmony_ci		ret = fiemap_fill_next_extent(fieinfo, logical,
20038c2ecf20Sopenharmony_ci				phys, size, flags);
20048c2ecf20Sopenharmony_ci		trace_f2fs_fiemap(inode, logical, phys, size, flags, ret);
20058c2ecf20Sopenharmony_ci		if (ret)
20068c2ecf20Sopenharmony_ci			goto out;
20078c2ecf20Sopenharmony_ci		size = 0;
20088c2ecf20Sopenharmony_ci	}
20098c2ecf20Sopenharmony_ci
20108c2ecf20Sopenharmony_ci	if (start_blk > last_blk)
20118c2ecf20Sopenharmony_ci		goto out;
20128c2ecf20Sopenharmony_ci
20138c2ecf20Sopenharmony_ci	if (compr_cluster) {
20148c2ecf20Sopenharmony_ci		compr_cluster = false;
20158c2ecf20Sopenharmony_ci
20168c2ecf20Sopenharmony_ci
20178c2ecf20Sopenharmony_ci		logical = blk_to_logical(inode, start_blk - 1);
20188c2ecf20Sopenharmony_ci		phys = blk_to_logical(inode, map_bh.b_blocknr);
20198c2ecf20Sopenharmony_ci		size = blk_to_logical(inode, cluster_size);
20208c2ecf20Sopenharmony_ci
20218c2ecf20Sopenharmony_ci		flags |= FIEMAP_EXTENT_ENCODED;
20228c2ecf20Sopenharmony_ci
20238c2ecf20Sopenharmony_ci		start_blk += cluster_size - 1;
20248c2ecf20Sopenharmony_ci
20258c2ecf20Sopenharmony_ci		if (start_blk > last_blk)
20268c2ecf20Sopenharmony_ci			goto out;
20278c2ecf20Sopenharmony_ci
20288c2ecf20Sopenharmony_ci		goto prep_next;
20298c2ecf20Sopenharmony_ci	}
20308c2ecf20Sopenharmony_ci
20318c2ecf20Sopenharmony_ci	if (map_bh.b_blocknr == COMPRESS_ADDR) {
20328c2ecf20Sopenharmony_ci		compr_cluster = true;
20338c2ecf20Sopenharmony_ci		start_blk++;
20348c2ecf20Sopenharmony_ci		goto prep_next;
20358c2ecf20Sopenharmony_ci	}
20368c2ecf20Sopenharmony_ci
20378c2ecf20Sopenharmony_ci	logical = blk_to_logical(inode, start_blk);
20388c2ecf20Sopenharmony_ci	phys = blk_to_logical(inode, map_bh.b_blocknr);
20398c2ecf20Sopenharmony_ci	size = map_bh.b_size;
20408c2ecf20Sopenharmony_ci	flags = 0;
20418c2ecf20Sopenharmony_ci	if (buffer_unwritten(&map_bh))
20428c2ecf20Sopenharmony_ci		flags = FIEMAP_EXTENT_UNWRITTEN;
20438c2ecf20Sopenharmony_ci
20448c2ecf20Sopenharmony_ci	start_blk += logical_to_blk(inode, size);
20458c2ecf20Sopenharmony_ci
20468c2ecf20Sopenharmony_ciprep_next:
20478c2ecf20Sopenharmony_ci	cond_resched();
20488c2ecf20Sopenharmony_ci	if (fatal_signal_pending(current))
20498c2ecf20Sopenharmony_ci		ret = -EINTR;
20508c2ecf20Sopenharmony_ci	else
20518c2ecf20Sopenharmony_ci		goto next;
20528c2ecf20Sopenharmony_ciout:
20538c2ecf20Sopenharmony_ci	if (ret == 1)
20548c2ecf20Sopenharmony_ci		ret = 0;
20558c2ecf20Sopenharmony_ci
20568c2ecf20Sopenharmony_ci	inode_unlock(inode);
20578c2ecf20Sopenharmony_ci	return ret;
20588c2ecf20Sopenharmony_ci}
20598c2ecf20Sopenharmony_ci
20608c2ecf20Sopenharmony_cistatic inline loff_t f2fs_readpage_limit(struct inode *inode)
20618c2ecf20Sopenharmony_ci{
20628c2ecf20Sopenharmony_ci	if (IS_ENABLED(CONFIG_FS_VERITY) &&
20638c2ecf20Sopenharmony_ci	    (IS_VERITY(inode) || f2fs_verity_in_progress(inode)))
20648c2ecf20Sopenharmony_ci		return inode->i_sb->s_maxbytes;
20658c2ecf20Sopenharmony_ci
20668c2ecf20Sopenharmony_ci	return i_size_read(inode);
20678c2ecf20Sopenharmony_ci}
20688c2ecf20Sopenharmony_ci
20698c2ecf20Sopenharmony_cistatic int f2fs_read_single_page(struct inode *inode, struct page *page,
20708c2ecf20Sopenharmony_ci					unsigned nr_pages,
20718c2ecf20Sopenharmony_ci					struct f2fs_map_blocks *map,
20728c2ecf20Sopenharmony_ci					struct bio **bio_ret,
20738c2ecf20Sopenharmony_ci					sector_t *last_block_in_bio,
20748c2ecf20Sopenharmony_ci					bool is_readahead)
20758c2ecf20Sopenharmony_ci{
20768c2ecf20Sopenharmony_ci	struct bio *bio = *bio_ret;
20778c2ecf20Sopenharmony_ci	const unsigned blkbits = inode->i_blkbits;
20788c2ecf20Sopenharmony_ci	const unsigned blocksize = 1 << blkbits;
20798c2ecf20Sopenharmony_ci	sector_t block_in_file;
20808c2ecf20Sopenharmony_ci	sector_t last_block;
20818c2ecf20Sopenharmony_ci	sector_t last_block_in_file;
20828c2ecf20Sopenharmony_ci	sector_t block_nr;
20838c2ecf20Sopenharmony_ci	int ret = 0;
20848c2ecf20Sopenharmony_ci
20858c2ecf20Sopenharmony_ci	block_in_file = (sector_t)page_index(page);
20868c2ecf20Sopenharmony_ci	last_block = block_in_file + nr_pages;
20878c2ecf20Sopenharmony_ci	last_block_in_file = (f2fs_readpage_limit(inode) + blocksize - 1) >>
20888c2ecf20Sopenharmony_ci							blkbits;
20898c2ecf20Sopenharmony_ci	if (last_block > last_block_in_file)
20908c2ecf20Sopenharmony_ci		last_block = last_block_in_file;
20918c2ecf20Sopenharmony_ci
20928c2ecf20Sopenharmony_ci	/* just zeroing out page which is beyond EOF */
20938c2ecf20Sopenharmony_ci	if (block_in_file >= last_block)
20948c2ecf20Sopenharmony_ci		goto zero_out;
20958c2ecf20Sopenharmony_ci	/*
20968c2ecf20Sopenharmony_ci	 * Map blocks using the previous result first.
20978c2ecf20Sopenharmony_ci	 */
20988c2ecf20Sopenharmony_ci	if ((map->m_flags & F2FS_MAP_MAPPED) &&
20998c2ecf20Sopenharmony_ci			block_in_file > map->m_lblk &&
21008c2ecf20Sopenharmony_ci			block_in_file < (map->m_lblk + map->m_len))
21018c2ecf20Sopenharmony_ci		goto got_it;
21028c2ecf20Sopenharmony_ci
21038c2ecf20Sopenharmony_ci	/*
21048c2ecf20Sopenharmony_ci	 * Then do more f2fs_map_blocks() calls until we are
21058c2ecf20Sopenharmony_ci	 * done with this page.
21068c2ecf20Sopenharmony_ci	 */
21078c2ecf20Sopenharmony_ci	map->m_lblk = block_in_file;
21088c2ecf20Sopenharmony_ci	map->m_len = last_block - block_in_file;
21098c2ecf20Sopenharmony_ci
21108c2ecf20Sopenharmony_ci	ret = f2fs_map_blocks(inode, map, 0, F2FS_GET_BLOCK_DEFAULT);
21118c2ecf20Sopenharmony_ci	if (ret)
21128c2ecf20Sopenharmony_ci		goto out;
21138c2ecf20Sopenharmony_cigot_it:
21148c2ecf20Sopenharmony_ci	if ((map->m_flags & F2FS_MAP_MAPPED)) {
21158c2ecf20Sopenharmony_ci		block_nr = map->m_pblk + block_in_file - map->m_lblk;
21168c2ecf20Sopenharmony_ci		SetPageMappedToDisk(page);
21178c2ecf20Sopenharmony_ci
21188c2ecf20Sopenharmony_ci		if (!PageUptodate(page) && (!PageSwapCache(page) &&
21198c2ecf20Sopenharmony_ci					!cleancache_get_page(page))) {
21208c2ecf20Sopenharmony_ci			SetPageUptodate(page);
21218c2ecf20Sopenharmony_ci			goto confused;
21228c2ecf20Sopenharmony_ci		}
21238c2ecf20Sopenharmony_ci
21248c2ecf20Sopenharmony_ci		if (!f2fs_is_valid_blkaddr(F2FS_I_SB(inode), block_nr,
21258c2ecf20Sopenharmony_ci						DATA_GENERIC_ENHANCE_READ)) {
21268c2ecf20Sopenharmony_ci			ret = -EFSCORRUPTED;
21278c2ecf20Sopenharmony_ci			goto out;
21288c2ecf20Sopenharmony_ci		}
21298c2ecf20Sopenharmony_ci	} else {
21308c2ecf20Sopenharmony_cizero_out:
21318c2ecf20Sopenharmony_ci		zero_user_segment(page, 0, PAGE_SIZE);
21328c2ecf20Sopenharmony_ci		if (f2fs_need_verity(inode, page->index) &&
21338c2ecf20Sopenharmony_ci		    !fsverity_verify_page(page)) {
21348c2ecf20Sopenharmony_ci			ret = -EIO;
21358c2ecf20Sopenharmony_ci			goto out;
21368c2ecf20Sopenharmony_ci		}
21378c2ecf20Sopenharmony_ci		if (!PageUptodate(page))
21388c2ecf20Sopenharmony_ci			SetPageUptodate(page);
21398c2ecf20Sopenharmony_ci		unlock_page(page);
21408c2ecf20Sopenharmony_ci		goto out;
21418c2ecf20Sopenharmony_ci	}
21428c2ecf20Sopenharmony_ci
21438c2ecf20Sopenharmony_ci	/*
21448c2ecf20Sopenharmony_ci	 * This page will go to BIO.  Do we need to send this
21458c2ecf20Sopenharmony_ci	 * BIO off first?
21468c2ecf20Sopenharmony_ci	 */
21478c2ecf20Sopenharmony_ci	if (bio && (!page_is_mergeable(F2FS_I_SB(inode), bio,
21488c2ecf20Sopenharmony_ci				       *last_block_in_bio, block_nr) ||
21498c2ecf20Sopenharmony_ci		    !f2fs_crypt_mergeable_bio(bio, inode, page->index, NULL))) {
21508c2ecf20Sopenharmony_cisubmit_and_realloc:
21518c2ecf20Sopenharmony_ci		__submit_bio(F2FS_I_SB(inode), bio, DATA);
21528c2ecf20Sopenharmony_ci		bio = NULL;
21538c2ecf20Sopenharmony_ci	}
21548c2ecf20Sopenharmony_ci	if (bio == NULL) {
21558c2ecf20Sopenharmony_ci		bio = f2fs_grab_read_bio(inode, block_nr, nr_pages,
21568c2ecf20Sopenharmony_ci				is_readahead ? REQ_RAHEAD : 0, page->index,
21578c2ecf20Sopenharmony_ci				false, true);
21588c2ecf20Sopenharmony_ci		if (IS_ERR(bio)) {
21598c2ecf20Sopenharmony_ci			ret = PTR_ERR(bio);
21608c2ecf20Sopenharmony_ci			bio = NULL;
21618c2ecf20Sopenharmony_ci			goto out;
21628c2ecf20Sopenharmony_ci		}
21638c2ecf20Sopenharmony_ci	}
21648c2ecf20Sopenharmony_ci
21658c2ecf20Sopenharmony_ci	/*
21668c2ecf20Sopenharmony_ci	 * If the page is under writeback, we need to wait for
21678c2ecf20Sopenharmony_ci	 * its completion to see the correct decrypted data.
21688c2ecf20Sopenharmony_ci	 */
21698c2ecf20Sopenharmony_ci	f2fs_wait_on_block_writeback(inode, block_nr);
21708c2ecf20Sopenharmony_ci
21718c2ecf20Sopenharmony_ci	if (bio_add_page(bio, page, blocksize, 0) < blocksize)
21728c2ecf20Sopenharmony_ci		goto submit_and_realloc;
21738c2ecf20Sopenharmony_ci
21748c2ecf20Sopenharmony_ci	inc_page_count(F2FS_I_SB(inode), F2FS_RD_DATA);
21758c2ecf20Sopenharmony_ci	f2fs_update_iostat(F2FS_I_SB(inode), FS_DATA_READ_IO, F2FS_BLKSIZE);
21768c2ecf20Sopenharmony_ci	ClearPageError(page);
21778c2ecf20Sopenharmony_ci	*last_block_in_bio = block_nr;
21788c2ecf20Sopenharmony_ci	goto out;
21798c2ecf20Sopenharmony_ciconfused:
21808c2ecf20Sopenharmony_ci	if (bio) {
21818c2ecf20Sopenharmony_ci		__submit_bio(F2FS_I_SB(inode), bio, DATA);
21828c2ecf20Sopenharmony_ci		bio = NULL;
21838c2ecf20Sopenharmony_ci	}
21848c2ecf20Sopenharmony_ci	unlock_page(page);
21858c2ecf20Sopenharmony_ciout:
21868c2ecf20Sopenharmony_ci	*bio_ret = bio;
21878c2ecf20Sopenharmony_ci	return ret;
21888c2ecf20Sopenharmony_ci}
21898c2ecf20Sopenharmony_ci
21908c2ecf20Sopenharmony_ci#ifdef CONFIG_F2FS_FS_COMPRESSION
21918c2ecf20Sopenharmony_ciint f2fs_read_multi_pages(struct compress_ctx *cc, struct bio **bio_ret,
21928c2ecf20Sopenharmony_ci				unsigned nr_pages, sector_t *last_block_in_bio,
21938c2ecf20Sopenharmony_ci				bool is_readahead, bool for_write)
21948c2ecf20Sopenharmony_ci{
21958c2ecf20Sopenharmony_ci	struct dnode_of_data dn;
21968c2ecf20Sopenharmony_ci	struct inode *inode = cc->inode;
21978c2ecf20Sopenharmony_ci	struct f2fs_sb_info *sbi = F2FS_I_SB(inode);
21988c2ecf20Sopenharmony_ci	struct bio *bio = *bio_ret;
21998c2ecf20Sopenharmony_ci	unsigned int start_idx = cc->cluster_idx << cc->log_cluster_size;
22008c2ecf20Sopenharmony_ci	sector_t last_block_in_file;
22018c2ecf20Sopenharmony_ci	const unsigned blkbits = inode->i_blkbits;
22028c2ecf20Sopenharmony_ci	const unsigned blocksize = 1 << blkbits;
22038c2ecf20Sopenharmony_ci	struct decompress_io_ctx *dic = NULL;
22048c2ecf20Sopenharmony_ci	struct bio_post_read_ctx *ctx;
22058c2ecf20Sopenharmony_ci	bool for_verity = false;
22068c2ecf20Sopenharmony_ci	int i;
22078c2ecf20Sopenharmony_ci	int ret = 0;
22088c2ecf20Sopenharmony_ci
22098c2ecf20Sopenharmony_ci	f2fs_bug_on(sbi, f2fs_cluster_is_empty(cc));
22108c2ecf20Sopenharmony_ci
22118c2ecf20Sopenharmony_ci	last_block_in_file = (f2fs_readpage_limit(inode) +
22128c2ecf20Sopenharmony_ci					blocksize - 1) >> blkbits;
22138c2ecf20Sopenharmony_ci
22148c2ecf20Sopenharmony_ci	/* get rid of pages beyond EOF */
22158c2ecf20Sopenharmony_ci	for (i = 0; i < cc->cluster_size; i++) {
22168c2ecf20Sopenharmony_ci		struct page *page = cc->rpages[i];
22178c2ecf20Sopenharmony_ci
22188c2ecf20Sopenharmony_ci		if (!page)
22198c2ecf20Sopenharmony_ci			continue;
22208c2ecf20Sopenharmony_ci		if ((sector_t)page->index >= last_block_in_file) {
22218c2ecf20Sopenharmony_ci			zero_user_segment(page, 0, PAGE_SIZE);
22228c2ecf20Sopenharmony_ci			if (!PageUptodate(page))
22238c2ecf20Sopenharmony_ci				SetPageUptodate(page);
22248c2ecf20Sopenharmony_ci		} else if (!PageUptodate(page)) {
22258c2ecf20Sopenharmony_ci			continue;
22268c2ecf20Sopenharmony_ci		}
22278c2ecf20Sopenharmony_ci		unlock_page(page);
22288c2ecf20Sopenharmony_ci		if (for_write)
22298c2ecf20Sopenharmony_ci			put_page(page);
22308c2ecf20Sopenharmony_ci		cc->rpages[i] = NULL;
22318c2ecf20Sopenharmony_ci		cc->nr_rpages--;
22328c2ecf20Sopenharmony_ci	}
22338c2ecf20Sopenharmony_ci
22348c2ecf20Sopenharmony_ci	/* we are done since all pages are beyond EOF */
22358c2ecf20Sopenharmony_ci	if (f2fs_cluster_is_empty(cc))
22368c2ecf20Sopenharmony_ci		goto out;
22378c2ecf20Sopenharmony_ci
22388c2ecf20Sopenharmony_ci	set_new_dnode(&dn, inode, NULL, NULL, 0);
22398c2ecf20Sopenharmony_ci	ret = f2fs_get_dnode_of_data(&dn, start_idx, LOOKUP_NODE);
22408c2ecf20Sopenharmony_ci	if (ret)
22418c2ecf20Sopenharmony_ci		goto out;
22428c2ecf20Sopenharmony_ci
22438c2ecf20Sopenharmony_ci	f2fs_bug_on(sbi, dn.data_blkaddr != COMPRESS_ADDR);
22448c2ecf20Sopenharmony_ci
22458c2ecf20Sopenharmony_ci	for (i = 1; i < cc->cluster_size; i++) {
22468c2ecf20Sopenharmony_ci		block_t blkaddr;
22478c2ecf20Sopenharmony_ci
22488c2ecf20Sopenharmony_ci		blkaddr = data_blkaddr(dn.inode, dn.node_page,
22498c2ecf20Sopenharmony_ci						dn.ofs_in_node + i);
22508c2ecf20Sopenharmony_ci
22518c2ecf20Sopenharmony_ci		if (!__is_valid_data_blkaddr(blkaddr))
22528c2ecf20Sopenharmony_ci			break;
22538c2ecf20Sopenharmony_ci
22548c2ecf20Sopenharmony_ci		if (!f2fs_is_valid_blkaddr(sbi, blkaddr, DATA_GENERIC)) {
22558c2ecf20Sopenharmony_ci			ret = -EFAULT;
22568c2ecf20Sopenharmony_ci			goto out_put_dnode;
22578c2ecf20Sopenharmony_ci		}
22588c2ecf20Sopenharmony_ci		cc->nr_cpages++;
22598c2ecf20Sopenharmony_ci	}
22608c2ecf20Sopenharmony_ci
22618c2ecf20Sopenharmony_ci	/* nothing to decompress */
22628c2ecf20Sopenharmony_ci	if (cc->nr_cpages == 0) {
22638c2ecf20Sopenharmony_ci		ret = 0;
22648c2ecf20Sopenharmony_ci		goto out_put_dnode;
22658c2ecf20Sopenharmony_ci	}
22668c2ecf20Sopenharmony_ci
22678c2ecf20Sopenharmony_ci	dic = f2fs_alloc_dic(cc);
22688c2ecf20Sopenharmony_ci	if (IS_ERR(dic)) {
22698c2ecf20Sopenharmony_ci		ret = PTR_ERR(dic);
22708c2ecf20Sopenharmony_ci		goto out_put_dnode;
22718c2ecf20Sopenharmony_ci	}
22728c2ecf20Sopenharmony_ci
22738c2ecf20Sopenharmony_ci	/*
22748c2ecf20Sopenharmony_ci	 * It's possible to enable fsverity on the fly when handling a cluster,
22758c2ecf20Sopenharmony_ci	 * which requires complicated error handling. Instead of adding more
22768c2ecf20Sopenharmony_ci	 * complexity, let's give a rule where end_io post-processes fsverity
22778c2ecf20Sopenharmony_ci	 * per cluster. In order to do that, we need to submit bio, if previous
22788c2ecf20Sopenharmony_ci	 * bio sets a different post-process policy.
22798c2ecf20Sopenharmony_ci	 */
22808c2ecf20Sopenharmony_ci	if (fsverity_active(cc->inode)) {
22818c2ecf20Sopenharmony_ci		atomic_set(&dic->verity_pages, cc->nr_cpages);
22828c2ecf20Sopenharmony_ci		for_verity = true;
22838c2ecf20Sopenharmony_ci
22848c2ecf20Sopenharmony_ci		if (bio) {
22858c2ecf20Sopenharmony_ci			ctx = bio->bi_private;
22868c2ecf20Sopenharmony_ci			if (!(ctx->enabled_steps & (1 << STEP_VERITY))) {
22878c2ecf20Sopenharmony_ci				__submit_bio(sbi, bio, DATA);
22888c2ecf20Sopenharmony_ci				bio = NULL;
22898c2ecf20Sopenharmony_ci			}
22908c2ecf20Sopenharmony_ci		}
22918c2ecf20Sopenharmony_ci	}
22928c2ecf20Sopenharmony_ci
22938c2ecf20Sopenharmony_ci	for (i = 0; i < dic->nr_cpages; i++) {
22948c2ecf20Sopenharmony_ci		struct page *page = dic->cpages[i];
22958c2ecf20Sopenharmony_ci		block_t blkaddr;
22968c2ecf20Sopenharmony_ci
22978c2ecf20Sopenharmony_ci		blkaddr = data_blkaddr(dn.inode, dn.node_page,
22988c2ecf20Sopenharmony_ci						dn.ofs_in_node + i + 1);
22998c2ecf20Sopenharmony_ci
23008c2ecf20Sopenharmony_ci		if (bio && (!page_is_mergeable(sbi, bio,
23018c2ecf20Sopenharmony_ci					*last_block_in_bio, blkaddr) ||
23028c2ecf20Sopenharmony_ci		    !f2fs_crypt_mergeable_bio(bio, inode, page->index, NULL))) {
23038c2ecf20Sopenharmony_cisubmit_and_realloc:
23048c2ecf20Sopenharmony_ci			__submit_bio(sbi, bio, DATA);
23058c2ecf20Sopenharmony_ci			bio = NULL;
23068c2ecf20Sopenharmony_ci		}
23078c2ecf20Sopenharmony_ci
23088c2ecf20Sopenharmony_ci		if (!bio) {
23098c2ecf20Sopenharmony_ci			bio = f2fs_grab_read_bio(inode, blkaddr, nr_pages,
23108c2ecf20Sopenharmony_ci					is_readahead ? REQ_RAHEAD : 0,
23118c2ecf20Sopenharmony_ci					page->index, for_write, for_verity);
23128c2ecf20Sopenharmony_ci			if (IS_ERR(bio)) {
23138c2ecf20Sopenharmony_ci				unsigned int remained = dic->nr_cpages - i;
23148c2ecf20Sopenharmony_ci				bool release = false;
23158c2ecf20Sopenharmony_ci
23168c2ecf20Sopenharmony_ci				ret = PTR_ERR(bio);
23178c2ecf20Sopenharmony_ci				dic->failed = true;
23188c2ecf20Sopenharmony_ci
23198c2ecf20Sopenharmony_ci				if (for_verity) {
23208c2ecf20Sopenharmony_ci					if (!atomic_sub_return(remained,
23218c2ecf20Sopenharmony_ci						&dic->verity_pages))
23228c2ecf20Sopenharmony_ci						release = true;
23238c2ecf20Sopenharmony_ci				} else {
23248c2ecf20Sopenharmony_ci					if (!atomic_sub_return(remained,
23258c2ecf20Sopenharmony_ci						&dic->pending_pages))
23268c2ecf20Sopenharmony_ci						release = true;
23278c2ecf20Sopenharmony_ci				}
23288c2ecf20Sopenharmony_ci
23298c2ecf20Sopenharmony_ci				if (release) {
23308c2ecf20Sopenharmony_ci					f2fs_decompress_end_io(dic->rpages,
23318c2ecf20Sopenharmony_ci						cc->cluster_size, true,
23328c2ecf20Sopenharmony_ci						false);
23338c2ecf20Sopenharmony_ci					f2fs_free_dic(dic);
23348c2ecf20Sopenharmony_ci				}
23358c2ecf20Sopenharmony_ci
23368c2ecf20Sopenharmony_ci				f2fs_put_dnode(&dn);
23378c2ecf20Sopenharmony_ci				*bio_ret = NULL;
23388c2ecf20Sopenharmony_ci				return ret;
23398c2ecf20Sopenharmony_ci			}
23408c2ecf20Sopenharmony_ci		}
23418c2ecf20Sopenharmony_ci
23428c2ecf20Sopenharmony_ci		f2fs_wait_on_block_writeback(inode, blkaddr);
23438c2ecf20Sopenharmony_ci
23448c2ecf20Sopenharmony_ci		if (bio_add_page(bio, page, blocksize, 0) < blocksize)
23458c2ecf20Sopenharmony_ci			goto submit_and_realloc;
23468c2ecf20Sopenharmony_ci
23478c2ecf20Sopenharmony_ci		/* tag STEP_DECOMPRESS to handle IO in wq */
23488c2ecf20Sopenharmony_ci		ctx = bio->bi_private;
23498c2ecf20Sopenharmony_ci		if (!(ctx->enabled_steps & (1 << STEP_DECOMPRESS)))
23508c2ecf20Sopenharmony_ci			ctx->enabled_steps |= 1 << STEP_DECOMPRESS;
23518c2ecf20Sopenharmony_ci
23528c2ecf20Sopenharmony_ci		inc_page_count(sbi, F2FS_RD_DATA);
23538c2ecf20Sopenharmony_ci		f2fs_update_iostat(sbi, FS_DATA_READ_IO, F2FS_BLKSIZE);
23548c2ecf20Sopenharmony_ci		f2fs_update_iostat(sbi, FS_CDATA_READ_IO, F2FS_BLKSIZE);
23558c2ecf20Sopenharmony_ci		ClearPageError(page);
23568c2ecf20Sopenharmony_ci		*last_block_in_bio = blkaddr;
23578c2ecf20Sopenharmony_ci	}
23588c2ecf20Sopenharmony_ci
23598c2ecf20Sopenharmony_ci	f2fs_put_dnode(&dn);
23608c2ecf20Sopenharmony_ci
23618c2ecf20Sopenharmony_ci	*bio_ret = bio;
23628c2ecf20Sopenharmony_ci	return 0;
23638c2ecf20Sopenharmony_ci
23648c2ecf20Sopenharmony_ciout_put_dnode:
23658c2ecf20Sopenharmony_ci	f2fs_put_dnode(&dn);
23668c2ecf20Sopenharmony_ciout:
23678c2ecf20Sopenharmony_ci	f2fs_decompress_end_io(cc->rpages, cc->cluster_size, true, false);
23688c2ecf20Sopenharmony_ci	*bio_ret = bio;
23698c2ecf20Sopenharmony_ci	return ret;
23708c2ecf20Sopenharmony_ci}
23718c2ecf20Sopenharmony_ci#endif
23728c2ecf20Sopenharmony_ci
23738c2ecf20Sopenharmony_ci/*
23748c2ecf20Sopenharmony_ci * This function was originally taken from fs/mpage.c, and customized for f2fs.
23758c2ecf20Sopenharmony_ci * Major change was from block_size == page_size in f2fs by default.
23768c2ecf20Sopenharmony_ci *
23778c2ecf20Sopenharmony_ci * Note that the aops->readpages() function is ONLY used for read-ahead. If
23788c2ecf20Sopenharmony_ci * this function ever deviates from doing just read-ahead, it should either
23798c2ecf20Sopenharmony_ci * use ->readpage() or do the necessary surgery to decouple ->readpages()
23808c2ecf20Sopenharmony_ci * from read-ahead.
23818c2ecf20Sopenharmony_ci */
23828c2ecf20Sopenharmony_cistatic int f2fs_mpage_readpages(struct inode *inode,
23838c2ecf20Sopenharmony_ci		struct readahead_control *rac, struct page *page)
23848c2ecf20Sopenharmony_ci{
23858c2ecf20Sopenharmony_ci	struct bio *bio = NULL;
23868c2ecf20Sopenharmony_ci	sector_t last_block_in_bio = 0;
23878c2ecf20Sopenharmony_ci	struct f2fs_map_blocks map;
23888c2ecf20Sopenharmony_ci#ifdef CONFIG_F2FS_FS_COMPRESSION
23898c2ecf20Sopenharmony_ci	struct compress_ctx cc = {
23908c2ecf20Sopenharmony_ci		.inode = inode,
23918c2ecf20Sopenharmony_ci		.log_cluster_size = F2FS_I(inode)->i_log_cluster_size,
23928c2ecf20Sopenharmony_ci		.cluster_size = F2FS_I(inode)->i_cluster_size,
23938c2ecf20Sopenharmony_ci		.cluster_idx = NULL_CLUSTER,
23948c2ecf20Sopenharmony_ci		.rpages = NULL,
23958c2ecf20Sopenharmony_ci		.cpages = NULL,
23968c2ecf20Sopenharmony_ci		.nr_rpages = 0,
23978c2ecf20Sopenharmony_ci		.nr_cpages = 0,
23988c2ecf20Sopenharmony_ci	};
23998c2ecf20Sopenharmony_ci#endif
24008c2ecf20Sopenharmony_ci	unsigned nr_pages = rac ? readahead_count(rac) : 1;
24018c2ecf20Sopenharmony_ci	unsigned max_nr_pages = nr_pages;
24028c2ecf20Sopenharmony_ci	int ret = 0;
24038c2ecf20Sopenharmony_ci	bool drop_ra = false;
24048c2ecf20Sopenharmony_ci
24058c2ecf20Sopenharmony_ci	map.m_pblk = 0;
24068c2ecf20Sopenharmony_ci	map.m_lblk = 0;
24078c2ecf20Sopenharmony_ci	map.m_len = 0;
24088c2ecf20Sopenharmony_ci	map.m_flags = 0;
24098c2ecf20Sopenharmony_ci	map.m_next_pgofs = NULL;
24108c2ecf20Sopenharmony_ci	map.m_next_extent = NULL;
24118c2ecf20Sopenharmony_ci	map.m_seg_type = NO_CHECK_TYPE;
24128c2ecf20Sopenharmony_ci	map.m_may_create = false;
24138c2ecf20Sopenharmony_ci
24148c2ecf20Sopenharmony_ci	/*
24158c2ecf20Sopenharmony_ci	 * Two readahead threads for same address range can cause race condition
24168c2ecf20Sopenharmony_ci	 * which fragments sequential read IOs. So let's avoid each other.
24178c2ecf20Sopenharmony_ci	 */
24188c2ecf20Sopenharmony_ci	if (rac && readahead_count(rac)) {
24198c2ecf20Sopenharmony_ci		if (READ_ONCE(F2FS_I(inode)->ra_offset) == readahead_index(rac))
24208c2ecf20Sopenharmony_ci			drop_ra = true;
24218c2ecf20Sopenharmony_ci		else
24228c2ecf20Sopenharmony_ci			WRITE_ONCE(F2FS_I(inode)->ra_offset,
24238c2ecf20Sopenharmony_ci						readahead_index(rac));
24248c2ecf20Sopenharmony_ci	}
24258c2ecf20Sopenharmony_ci
24268c2ecf20Sopenharmony_ci	for (; nr_pages; nr_pages--) {
24278c2ecf20Sopenharmony_ci		if (rac) {
24288c2ecf20Sopenharmony_ci			page = readahead_page(rac);
24298c2ecf20Sopenharmony_ci			prefetchw(&page->flags);
24308c2ecf20Sopenharmony_ci			if (drop_ra) {
24318c2ecf20Sopenharmony_ci				f2fs_put_page(page, 1);
24328c2ecf20Sopenharmony_ci				continue;
24338c2ecf20Sopenharmony_ci			}
24348c2ecf20Sopenharmony_ci		}
24358c2ecf20Sopenharmony_ci
24368c2ecf20Sopenharmony_ci#ifdef CONFIG_F2FS_FS_COMPRESSION
24378c2ecf20Sopenharmony_ci		if (f2fs_compressed_file(inode)) {
24388c2ecf20Sopenharmony_ci			/* there are remained comressed pages, submit them */
24398c2ecf20Sopenharmony_ci			if (!f2fs_cluster_can_merge_page(&cc, page->index)) {
24408c2ecf20Sopenharmony_ci				ret = f2fs_read_multi_pages(&cc, &bio,
24418c2ecf20Sopenharmony_ci							max_nr_pages,
24428c2ecf20Sopenharmony_ci							&last_block_in_bio,
24438c2ecf20Sopenharmony_ci							rac != NULL, false);
24448c2ecf20Sopenharmony_ci				f2fs_destroy_compress_ctx(&cc, false);
24458c2ecf20Sopenharmony_ci				if (ret)
24468c2ecf20Sopenharmony_ci					goto set_error_page;
24478c2ecf20Sopenharmony_ci			}
24488c2ecf20Sopenharmony_ci			ret = f2fs_is_compressed_cluster(inode, page->index);
24498c2ecf20Sopenharmony_ci			if (ret < 0)
24508c2ecf20Sopenharmony_ci				goto set_error_page;
24518c2ecf20Sopenharmony_ci			else if (!ret)
24528c2ecf20Sopenharmony_ci				goto read_single_page;
24538c2ecf20Sopenharmony_ci
24548c2ecf20Sopenharmony_ci			ret = f2fs_init_compress_ctx(&cc);
24558c2ecf20Sopenharmony_ci			if (ret)
24568c2ecf20Sopenharmony_ci				goto set_error_page;
24578c2ecf20Sopenharmony_ci
24588c2ecf20Sopenharmony_ci			f2fs_compress_ctx_add_page(&cc, page);
24598c2ecf20Sopenharmony_ci
24608c2ecf20Sopenharmony_ci			goto next_page;
24618c2ecf20Sopenharmony_ci		}
24628c2ecf20Sopenharmony_ciread_single_page:
24638c2ecf20Sopenharmony_ci#endif
24648c2ecf20Sopenharmony_ci
24658c2ecf20Sopenharmony_ci		ret = f2fs_read_single_page(inode, page, max_nr_pages, &map,
24668c2ecf20Sopenharmony_ci					&bio, &last_block_in_bio, rac);
24678c2ecf20Sopenharmony_ci		if (ret) {
24688c2ecf20Sopenharmony_ci#ifdef CONFIG_F2FS_FS_COMPRESSION
24698c2ecf20Sopenharmony_ciset_error_page:
24708c2ecf20Sopenharmony_ci#endif
24718c2ecf20Sopenharmony_ci			SetPageError(page);
24728c2ecf20Sopenharmony_ci			zero_user_segment(page, 0, PAGE_SIZE);
24738c2ecf20Sopenharmony_ci			unlock_page(page);
24748c2ecf20Sopenharmony_ci		}
24758c2ecf20Sopenharmony_ci#ifdef CONFIG_F2FS_FS_COMPRESSION
24768c2ecf20Sopenharmony_cinext_page:
24778c2ecf20Sopenharmony_ci#endif
24788c2ecf20Sopenharmony_ci		if (rac)
24798c2ecf20Sopenharmony_ci			put_page(page);
24808c2ecf20Sopenharmony_ci
24818c2ecf20Sopenharmony_ci#ifdef CONFIG_F2FS_FS_COMPRESSION
24828c2ecf20Sopenharmony_ci		if (f2fs_compressed_file(inode)) {
24838c2ecf20Sopenharmony_ci			/* last page */
24848c2ecf20Sopenharmony_ci			if (nr_pages == 1 && !f2fs_cluster_is_empty(&cc)) {
24858c2ecf20Sopenharmony_ci				ret = f2fs_read_multi_pages(&cc, &bio,
24868c2ecf20Sopenharmony_ci							max_nr_pages,
24878c2ecf20Sopenharmony_ci							&last_block_in_bio,
24888c2ecf20Sopenharmony_ci							rac != NULL, false);
24898c2ecf20Sopenharmony_ci				f2fs_destroy_compress_ctx(&cc, false);
24908c2ecf20Sopenharmony_ci			}
24918c2ecf20Sopenharmony_ci		}
24928c2ecf20Sopenharmony_ci#endif
24938c2ecf20Sopenharmony_ci	}
24948c2ecf20Sopenharmony_ci	if (bio)
24958c2ecf20Sopenharmony_ci		__submit_bio(F2FS_I_SB(inode), bio, DATA);
24968c2ecf20Sopenharmony_ci
24978c2ecf20Sopenharmony_ci	if (rac && readahead_count(rac) && !drop_ra)
24988c2ecf20Sopenharmony_ci		WRITE_ONCE(F2FS_I(inode)->ra_offset, -1);
24998c2ecf20Sopenharmony_ci	return ret;
25008c2ecf20Sopenharmony_ci}
25018c2ecf20Sopenharmony_ci
25028c2ecf20Sopenharmony_cistatic int f2fs_read_data_page(struct file *file, struct page *page)
25038c2ecf20Sopenharmony_ci{
25048c2ecf20Sopenharmony_ci	struct inode *inode = page_file_mapping(page)->host;
25058c2ecf20Sopenharmony_ci	int ret = -EAGAIN;
25068c2ecf20Sopenharmony_ci
25078c2ecf20Sopenharmony_ci	trace_f2fs_readpage(page, DATA);
25088c2ecf20Sopenharmony_ci
25098c2ecf20Sopenharmony_ci	if (!f2fs_is_compress_backend_ready(inode)) {
25108c2ecf20Sopenharmony_ci		unlock_page(page);
25118c2ecf20Sopenharmony_ci		return -EOPNOTSUPP;
25128c2ecf20Sopenharmony_ci	}
25138c2ecf20Sopenharmony_ci
25148c2ecf20Sopenharmony_ci	/* If the file has inline data, try to read it directly */
25158c2ecf20Sopenharmony_ci	if (f2fs_has_inline_data(inode))
25168c2ecf20Sopenharmony_ci		ret = f2fs_read_inline_data(inode, page);
25178c2ecf20Sopenharmony_ci	if (ret == -EAGAIN)
25188c2ecf20Sopenharmony_ci		ret = f2fs_mpage_readpages(inode, NULL, page);
25198c2ecf20Sopenharmony_ci	return ret;
25208c2ecf20Sopenharmony_ci}
25218c2ecf20Sopenharmony_ci
25228c2ecf20Sopenharmony_cistatic void f2fs_readahead(struct readahead_control *rac)
25238c2ecf20Sopenharmony_ci{
25248c2ecf20Sopenharmony_ci	struct inode *inode = rac->mapping->host;
25258c2ecf20Sopenharmony_ci
25268c2ecf20Sopenharmony_ci	trace_f2fs_readpages(inode, readahead_index(rac), readahead_count(rac));
25278c2ecf20Sopenharmony_ci
25288c2ecf20Sopenharmony_ci	if (!f2fs_is_compress_backend_ready(inode))
25298c2ecf20Sopenharmony_ci		return;
25308c2ecf20Sopenharmony_ci
25318c2ecf20Sopenharmony_ci	/* If the file has inline data, skip readpages */
25328c2ecf20Sopenharmony_ci	if (f2fs_has_inline_data(inode))
25338c2ecf20Sopenharmony_ci		return;
25348c2ecf20Sopenharmony_ci
25358c2ecf20Sopenharmony_ci	f2fs_mpage_readpages(inode, rac, NULL);
25368c2ecf20Sopenharmony_ci}
25378c2ecf20Sopenharmony_ci
25388c2ecf20Sopenharmony_ciint f2fs_encrypt_one_page(struct f2fs_io_info *fio)
25398c2ecf20Sopenharmony_ci{
25408c2ecf20Sopenharmony_ci	struct inode *inode = fio->page->mapping->host;
25418c2ecf20Sopenharmony_ci	struct page *mpage, *page;
25428c2ecf20Sopenharmony_ci	gfp_t gfp_flags = GFP_NOFS;
25438c2ecf20Sopenharmony_ci
25448c2ecf20Sopenharmony_ci	if (!f2fs_encrypted_file(inode))
25458c2ecf20Sopenharmony_ci		return 0;
25468c2ecf20Sopenharmony_ci
25478c2ecf20Sopenharmony_ci	page = fio->compressed_page ? fio->compressed_page : fio->page;
25488c2ecf20Sopenharmony_ci
25498c2ecf20Sopenharmony_ci	/* wait for GCed page writeback via META_MAPPING */
25508c2ecf20Sopenharmony_ci	f2fs_wait_on_block_writeback(inode, fio->old_blkaddr);
25518c2ecf20Sopenharmony_ci
25528c2ecf20Sopenharmony_ci	if (fscrypt_inode_uses_inline_crypto(inode))
25538c2ecf20Sopenharmony_ci		return 0;
25548c2ecf20Sopenharmony_ci
25558c2ecf20Sopenharmony_ciretry_encrypt:
25568c2ecf20Sopenharmony_ci	fio->encrypted_page = fscrypt_encrypt_pagecache_blocks(page,
25578c2ecf20Sopenharmony_ci					PAGE_SIZE, 0, gfp_flags);
25588c2ecf20Sopenharmony_ci	if (IS_ERR(fio->encrypted_page)) {
25598c2ecf20Sopenharmony_ci		/* flush pending IOs and wait for a while in the ENOMEM case */
25608c2ecf20Sopenharmony_ci		if (PTR_ERR(fio->encrypted_page) == -ENOMEM) {
25618c2ecf20Sopenharmony_ci			f2fs_flush_merged_writes(fio->sbi);
25628c2ecf20Sopenharmony_ci			congestion_wait(BLK_RW_ASYNC, DEFAULT_IO_TIMEOUT);
25638c2ecf20Sopenharmony_ci			gfp_flags |= __GFP_NOFAIL;
25648c2ecf20Sopenharmony_ci			goto retry_encrypt;
25658c2ecf20Sopenharmony_ci		}
25668c2ecf20Sopenharmony_ci		return PTR_ERR(fio->encrypted_page);
25678c2ecf20Sopenharmony_ci	}
25688c2ecf20Sopenharmony_ci
25698c2ecf20Sopenharmony_ci	mpage = find_lock_page(META_MAPPING(fio->sbi), fio->old_blkaddr);
25708c2ecf20Sopenharmony_ci	if (mpage) {
25718c2ecf20Sopenharmony_ci		if (PageUptodate(mpage))
25728c2ecf20Sopenharmony_ci			memcpy(page_address(mpage),
25738c2ecf20Sopenharmony_ci				page_address(fio->encrypted_page), PAGE_SIZE);
25748c2ecf20Sopenharmony_ci		f2fs_put_page(mpage, 1);
25758c2ecf20Sopenharmony_ci	}
25768c2ecf20Sopenharmony_ci	return 0;
25778c2ecf20Sopenharmony_ci}
25788c2ecf20Sopenharmony_ci
25798c2ecf20Sopenharmony_cistatic inline bool check_inplace_update_policy(struct inode *inode,
25808c2ecf20Sopenharmony_ci				struct f2fs_io_info *fio)
25818c2ecf20Sopenharmony_ci{
25828c2ecf20Sopenharmony_ci	struct f2fs_sb_info *sbi = F2FS_I_SB(inode);
25838c2ecf20Sopenharmony_ci	unsigned int policy = SM_I(sbi)->ipu_policy;
25848c2ecf20Sopenharmony_ci
25858c2ecf20Sopenharmony_ci	if (policy & (0x1 << F2FS_IPU_FORCE))
25868c2ecf20Sopenharmony_ci		return true;
25878c2ecf20Sopenharmony_ci	if (policy & (0x1 << F2FS_IPU_SSR) && f2fs_need_SSR(sbi))
25888c2ecf20Sopenharmony_ci		return true;
25898c2ecf20Sopenharmony_ci	if (policy & (0x1 << F2FS_IPU_UTIL) &&
25908c2ecf20Sopenharmony_ci			utilization(sbi) > SM_I(sbi)->min_ipu_util)
25918c2ecf20Sopenharmony_ci		return true;
25928c2ecf20Sopenharmony_ci	if (policy & (0x1 << F2FS_IPU_SSR_UTIL) && f2fs_need_SSR(sbi) &&
25938c2ecf20Sopenharmony_ci			utilization(sbi) > SM_I(sbi)->min_ipu_util)
25948c2ecf20Sopenharmony_ci		return true;
25958c2ecf20Sopenharmony_ci
25968c2ecf20Sopenharmony_ci	/*
25978c2ecf20Sopenharmony_ci	 * IPU for rewrite async pages
25988c2ecf20Sopenharmony_ci	 */
25998c2ecf20Sopenharmony_ci	if (policy & (0x1 << F2FS_IPU_ASYNC) &&
26008c2ecf20Sopenharmony_ci			fio && fio->op == REQ_OP_WRITE &&
26018c2ecf20Sopenharmony_ci			!(fio->op_flags & REQ_SYNC) &&
26028c2ecf20Sopenharmony_ci			!IS_ENCRYPTED(inode))
26038c2ecf20Sopenharmony_ci		return true;
26048c2ecf20Sopenharmony_ci
26058c2ecf20Sopenharmony_ci	/* this is only set during fdatasync */
26068c2ecf20Sopenharmony_ci	if (policy & (0x1 << F2FS_IPU_FSYNC) &&
26078c2ecf20Sopenharmony_ci			is_inode_flag_set(inode, FI_NEED_IPU))
26088c2ecf20Sopenharmony_ci		return true;
26098c2ecf20Sopenharmony_ci
26108c2ecf20Sopenharmony_ci	if (unlikely(fio && is_sbi_flag_set(sbi, SBI_CP_DISABLED) &&
26118c2ecf20Sopenharmony_ci			!f2fs_is_checkpointed_data(sbi, fio->old_blkaddr)))
26128c2ecf20Sopenharmony_ci		return true;
26138c2ecf20Sopenharmony_ci
26148c2ecf20Sopenharmony_ci	return false;
26158c2ecf20Sopenharmony_ci}
26168c2ecf20Sopenharmony_ci
26178c2ecf20Sopenharmony_cibool f2fs_should_update_inplace(struct inode *inode, struct f2fs_io_info *fio)
26188c2ecf20Sopenharmony_ci{
26198c2ecf20Sopenharmony_ci	if (f2fs_is_pinned_file(inode))
26208c2ecf20Sopenharmony_ci		return true;
26218c2ecf20Sopenharmony_ci
26228c2ecf20Sopenharmony_ci	/* if this is cold file, we should overwrite to avoid fragmentation */
26238c2ecf20Sopenharmony_ci	if (file_is_cold(inode))
26248c2ecf20Sopenharmony_ci		return true;
26258c2ecf20Sopenharmony_ci
26268c2ecf20Sopenharmony_ci	return check_inplace_update_policy(inode, fio);
26278c2ecf20Sopenharmony_ci}
26288c2ecf20Sopenharmony_ci
26298c2ecf20Sopenharmony_cibool f2fs_should_update_outplace(struct inode *inode, struct f2fs_io_info *fio)
26308c2ecf20Sopenharmony_ci{
26318c2ecf20Sopenharmony_ci	struct f2fs_sb_info *sbi = F2FS_I_SB(inode);
26328c2ecf20Sopenharmony_ci
26338c2ecf20Sopenharmony_ci	if (f2fs_lfs_mode(sbi))
26348c2ecf20Sopenharmony_ci		return true;
26358c2ecf20Sopenharmony_ci	if (S_ISDIR(inode->i_mode))
26368c2ecf20Sopenharmony_ci		return true;
26378c2ecf20Sopenharmony_ci	if (IS_NOQUOTA(inode))
26388c2ecf20Sopenharmony_ci		return true;
26398c2ecf20Sopenharmony_ci	if (f2fs_is_atomic_file(inode))
26408c2ecf20Sopenharmony_ci		return true;
26418c2ecf20Sopenharmony_ci	if (fio) {
26428c2ecf20Sopenharmony_ci		if (is_cold_data(fio->page))
26438c2ecf20Sopenharmony_ci			return true;
26448c2ecf20Sopenharmony_ci		if (IS_ATOMIC_WRITTEN_PAGE(fio->page))
26458c2ecf20Sopenharmony_ci			return true;
26468c2ecf20Sopenharmony_ci		if (unlikely(is_sbi_flag_set(sbi, SBI_CP_DISABLED) &&
26478c2ecf20Sopenharmony_ci			f2fs_is_checkpointed_data(sbi, fio->old_blkaddr)))
26488c2ecf20Sopenharmony_ci			return true;
26498c2ecf20Sopenharmony_ci	}
26508c2ecf20Sopenharmony_ci	return false;
26518c2ecf20Sopenharmony_ci}
26528c2ecf20Sopenharmony_ci
26538c2ecf20Sopenharmony_cistatic inline bool need_inplace_update(struct f2fs_io_info *fio)
26548c2ecf20Sopenharmony_ci{
26558c2ecf20Sopenharmony_ci	struct inode *inode = fio->page->mapping->host;
26568c2ecf20Sopenharmony_ci
26578c2ecf20Sopenharmony_ci	if (f2fs_should_update_outplace(inode, fio))
26588c2ecf20Sopenharmony_ci		return false;
26598c2ecf20Sopenharmony_ci
26608c2ecf20Sopenharmony_ci	return f2fs_should_update_inplace(inode, fio);
26618c2ecf20Sopenharmony_ci}
26628c2ecf20Sopenharmony_ci
26638c2ecf20Sopenharmony_ciint f2fs_do_write_data_page(struct f2fs_io_info *fio)
26648c2ecf20Sopenharmony_ci{
26658c2ecf20Sopenharmony_ci	struct page *page = fio->page;
26668c2ecf20Sopenharmony_ci	struct inode *inode = page->mapping->host;
26678c2ecf20Sopenharmony_ci	struct dnode_of_data dn;
26688c2ecf20Sopenharmony_ci	struct extent_info ei = {0,0,0};
26698c2ecf20Sopenharmony_ci	struct node_info ni;
26708c2ecf20Sopenharmony_ci	bool ipu_force = false;
26718c2ecf20Sopenharmony_ci	int err = 0;
26728c2ecf20Sopenharmony_ci
26738c2ecf20Sopenharmony_ci	set_new_dnode(&dn, inode, NULL, NULL, 0);
26748c2ecf20Sopenharmony_ci	if (need_inplace_update(fio) &&
26758c2ecf20Sopenharmony_ci			f2fs_lookup_extent_cache(inode, page->index, &ei)) {
26768c2ecf20Sopenharmony_ci		fio->old_blkaddr = ei.blk + page->index - ei.fofs;
26778c2ecf20Sopenharmony_ci
26788c2ecf20Sopenharmony_ci		if (!f2fs_is_valid_blkaddr(fio->sbi, fio->old_blkaddr,
26798c2ecf20Sopenharmony_ci						DATA_GENERIC_ENHANCE))
26808c2ecf20Sopenharmony_ci			return -EFSCORRUPTED;
26818c2ecf20Sopenharmony_ci
26828c2ecf20Sopenharmony_ci		ipu_force = true;
26838c2ecf20Sopenharmony_ci		fio->need_lock = LOCK_DONE;
26848c2ecf20Sopenharmony_ci		goto got_it;
26858c2ecf20Sopenharmony_ci	}
26868c2ecf20Sopenharmony_ci
26878c2ecf20Sopenharmony_ci	/* Deadlock due to between page->lock and f2fs_lock_op */
26888c2ecf20Sopenharmony_ci	if (fio->need_lock == LOCK_REQ && !f2fs_trylock_op(fio->sbi))
26898c2ecf20Sopenharmony_ci		return -EAGAIN;
26908c2ecf20Sopenharmony_ci
26918c2ecf20Sopenharmony_ci	err = f2fs_get_dnode_of_data(&dn, page->index, LOOKUP_NODE);
26928c2ecf20Sopenharmony_ci	if (err)
26938c2ecf20Sopenharmony_ci		goto out;
26948c2ecf20Sopenharmony_ci
26958c2ecf20Sopenharmony_ci	fio->old_blkaddr = dn.data_blkaddr;
26968c2ecf20Sopenharmony_ci
26978c2ecf20Sopenharmony_ci	/* This page is already truncated */
26988c2ecf20Sopenharmony_ci	if (fio->old_blkaddr == NULL_ADDR) {
26998c2ecf20Sopenharmony_ci		ClearPageUptodate(page);
27008c2ecf20Sopenharmony_ci		clear_cold_data(page);
27018c2ecf20Sopenharmony_ci		goto out_writepage;
27028c2ecf20Sopenharmony_ci	}
27038c2ecf20Sopenharmony_cigot_it:
27048c2ecf20Sopenharmony_ci	if (__is_valid_data_blkaddr(fio->old_blkaddr) &&
27058c2ecf20Sopenharmony_ci		!f2fs_is_valid_blkaddr(fio->sbi, fio->old_blkaddr,
27068c2ecf20Sopenharmony_ci						DATA_GENERIC_ENHANCE)) {
27078c2ecf20Sopenharmony_ci		err = -EFSCORRUPTED;
27088c2ecf20Sopenharmony_ci		goto out_writepage;
27098c2ecf20Sopenharmony_ci	}
27108c2ecf20Sopenharmony_ci	/*
27118c2ecf20Sopenharmony_ci	 * If current allocation needs SSR,
27128c2ecf20Sopenharmony_ci	 * it had better in-place writes for updated data.
27138c2ecf20Sopenharmony_ci	 */
27148c2ecf20Sopenharmony_ci	if (ipu_force ||
27158c2ecf20Sopenharmony_ci		(__is_valid_data_blkaddr(fio->old_blkaddr) &&
27168c2ecf20Sopenharmony_ci					need_inplace_update(fio))) {
27178c2ecf20Sopenharmony_ci		err = f2fs_encrypt_one_page(fio);
27188c2ecf20Sopenharmony_ci		if (err)
27198c2ecf20Sopenharmony_ci			goto out_writepage;
27208c2ecf20Sopenharmony_ci
27218c2ecf20Sopenharmony_ci		set_page_writeback(page);
27228c2ecf20Sopenharmony_ci		ClearPageError(page);
27238c2ecf20Sopenharmony_ci		f2fs_put_dnode(&dn);
27248c2ecf20Sopenharmony_ci		if (fio->need_lock == LOCK_REQ)
27258c2ecf20Sopenharmony_ci			f2fs_unlock_op(fio->sbi);
27268c2ecf20Sopenharmony_ci		err = f2fs_inplace_write_data(fio);
27278c2ecf20Sopenharmony_ci		if (err) {
27288c2ecf20Sopenharmony_ci			if (fscrypt_inode_uses_fs_layer_crypto(inode))
27298c2ecf20Sopenharmony_ci				fscrypt_finalize_bounce_page(&fio->encrypted_page);
27308c2ecf20Sopenharmony_ci			if (PageWriteback(page))
27318c2ecf20Sopenharmony_ci				end_page_writeback(page);
27328c2ecf20Sopenharmony_ci		} else {
27338c2ecf20Sopenharmony_ci			set_inode_flag(inode, FI_UPDATE_WRITE);
27348c2ecf20Sopenharmony_ci		}
27358c2ecf20Sopenharmony_ci		trace_f2fs_do_write_data_page(fio->page, IPU);
27368c2ecf20Sopenharmony_ci		return err;
27378c2ecf20Sopenharmony_ci	}
27388c2ecf20Sopenharmony_ci
27398c2ecf20Sopenharmony_ci	if (fio->need_lock == LOCK_RETRY) {
27408c2ecf20Sopenharmony_ci		if (!f2fs_trylock_op(fio->sbi)) {
27418c2ecf20Sopenharmony_ci			err = -EAGAIN;
27428c2ecf20Sopenharmony_ci			goto out_writepage;
27438c2ecf20Sopenharmony_ci		}
27448c2ecf20Sopenharmony_ci		fio->need_lock = LOCK_REQ;
27458c2ecf20Sopenharmony_ci	}
27468c2ecf20Sopenharmony_ci
27478c2ecf20Sopenharmony_ci	err = f2fs_get_node_info(fio->sbi, dn.nid, &ni);
27488c2ecf20Sopenharmony_ci	if (err)
27498c2ecf20Sopenharmony_ci		goto out_writepage;
27508c2ecf20Sopenharmony_ci
27518c2ecf20Sopenharmony_ci	fio->version = ni.version;
27528c2ecf20Sopenharmony_ci
27538c2ecf20Sopenharmony_ci	err = f2fs_encrypt_one_page(fio);
27548c2ecf20Sopenharmony_ci	if (err)
27558c2ecf20Sopenharmony_ci		goto out_writepage;
27568c2ecf20Sopenharmony_ci
27578c2ecf20Sopenharmony_ci	set_page_writeback(page);
27588c2ecf20Sopenharmony_ci	ClearPageError(page);
27598c2ecf20Sopenharmony_ci
27608c2ecf20Sopenharmony_ci	if (fio->compr_blocks && fio->old_blkaddr == COMPRESS_ADDR)
27618c2ecf20Sopenharmony_ci		f2fs_i_compr_blocks_update(inode, fio->compr_blocks - 1, false);
27628c2ecf20Sopenharmony_ci
27638c2ecf20Sopenharmony_ci	/* LFS mode write path */
27648c2ecf20Sopenharmony_ci	f2fs_outplace_write_data(&dn, fio);
27658c2ecf20Sopenharmony_ci	trace_f2fs_do_write_data_page(page, OPU);
27668c2ecf20Sopenharmony_ci	set_inode_flag(inode, FI_APPEND_WRITE);
27678c2ecf20Sopenharmony_ci	if (page->index == 0)
27688c2ecf20Sopenharmony_ci		set_inode_flag(inode, FI_FIRST_BLOCK_WRITTEN);
27698c2ecf20Sopenharmony_ciout_writepage:
27708c2ecf20Sopenharmony_ci	f2fs_put_dnode(&dn);
27718c2ecf20Sopenharmony_ciout:
27728c2ecf20Sopenharmony_ci	if (fio->need_lock == LOCK_REQ)
27738c2ecf20Sopenharmony_ci		f2fs_unlock_op(fio->sbi);
27748c2ecf20Sopenharmony_ci	return err;
27758c2ecf20Sopenharmony_ci}
27768c2ecf20Sopenharmony_ci
27778c2ecf20Sopenharmony_ciint f2fs_write_single_data_page(struct page *page, int *submitted,
27788c2ecf20Sopenharmony_ci				struct bio **bio,
27798c2ecf20Sopenharmony_ci				sector_t *last_block,
27808c2ecf20Sopenharmony_ci				struct writeback_control *wbc,
27818c2ecf20Sopenharmony_ci				enum iostat_type io_type,
27828c2ecf20Sopenharmony_ci				int compr_blocks,
27838c2ecf20Sopenharmony_ci				bool allow_balance)
27848c2ecf20Sopenharmony_ci{
27858c2ecf20Sopenharmony_ci	struct inode *inode = page->mapping->host;
27868c2ecf20Sopenharmony_ci	struct f2fs_sb_info *sbi = F2FS_I_SB(inode);
27878c2ecf20Sopenharmony_ci	loff_t i_size = i_size_read(inode);
27888c2ecf20Sopenharmony_ci	const pgoff_t end_index = ((unsigned long long)i_size)
27898c2ecf20Sopenharmony_ci							>> PAGE_SHIFT;
27908c2ecf20Sopenharmony_ci	loff_t psize = (loff_t)(page->index + 1) << PAGE_SHIFT;
27918c2ecf20Sopenharmony_ci	unsigned offset = 0;
27928c2ecf20Sopenharmony_ci	bool need_balance_fs = false;
27938c2ecf20Sopenharmony_ci	int err = 0;
27948c2ecf20Sopenharmony_ci	struct f2fs_io_info fio = {
27958c2ecf20Sopenharmony_ci		.sbi = sbi,
27968c2ecf20Sopenharmony_ci		.ino = inode->i_ino,
27978c2ecf20Sopenharmony_ci		.type = DATA,
27988c2ecf20Sopenharmony_ci		.op = REQ_OP_WRITE,
27998c2ecf20Sopenharmony_ci		.op_flags = wbc_to_write_flags(wbc),
28008c2ecf20Sopenharmony_ci		.old_blkaddr = NULL_ADDR,
28018c2ecf20Sopenharmony_ci		.page = page,
28028c2ecf20Sopenharmony_ci		.encrypted_page = NULL,
28038c2ecf20Sopenharmony_ci		.submitted = false,
28048c2ecf20Sopenharmony_ci		.compr_blocks = compr_blocks,
28058c2ecf20Sopenharmony_ci		.need_lock = LOCK_RETRY,
28068c2ecf20Sopenharmony_ci		.io_type = io_type,
28078c2ecf20Sopenharmony_ci		.io_wbc = wbc,
28088c2ecf20Sopenharmony_ci		.bio = bio,
28098c2ecf20Sopenharmony_ci		.last_block = last_block,
28108c2ecf20Sopenharmony_ci	};
28118c2ecf20Sopenharmony_ci
28128c2ecf20Sopenharmony_ci	trace_f2fs_writepage(page, DATA);
28138c2ecf20Sopenharmony_ci
28148c2ecf20Sopenharmony_ci	/* we should bypass data pages to proceed the kworkder jobs */
28158c2ecf20Sopenharmony_ci	if (unlikely(f2fs_cp_error(sbi))) {
28168c2ecf20Sopenharmony_ci		mapping_set_error(page->mapping, -EIO);
28178c2ecf20Sopenharmony_ci		/*
28188c2ecf20Sopenharmony_ci		 * don't drop any dirty dentry pages for keeping lastest
28198c2ecf20Sopenharmony_ci		 * directory structure.
28208c2ecf20Sopenharmony_ci		 */
28218c2ecf20Sopenharmony_ci		if (S_ISDIR(inode->i_mode) &&
28228c2ecf20Sopenharmony_ci				!is_sbi_flag_set(sbi, SBI_IS_CLOSE))
28238c2ecf20Sopenharmony_ci			goto redirty_out;
28248c2ecf20Sopenharmony_ci		goto out;
28258c2ecf20Sopenharmony_ci	}
28268c2ecf20Sopenharmony_ci
28278c2ecf20Sopenharmony_ci	if (unlikely(is_sbi_flag_set(sbi, SBI_POR_DOING)))
28288c2ecf20Sopenharmony_ci		goto redirty_out;
28298c2ecf20Sopenharmony_ci
28308c2ecf20Sopenharmony_ci	if (page->index < end_index ||
28318c2ecf20Sopenharmony_ci			f2fs_verity_in_progress(inode) ||
28328c2ecf20Sopenharmony_ci			compr_blocks)
28338c2ecf20Sopenharmony_ci		goto write;
28348c2ecf20Sopenharmony_ci
28358c2ecf20Sopenharmony_ci	/*
28368c2ecf20Sopenharmony_ci	 * If the offset is out-of-range of file size,
28378c2ecf20Sopenharmony_ci	 * this page does not have to be written to disk.
28388c2ecf20Sopenharmony_ci	 */
28398c2ecf20Sopenharmony_ci	offset = i_size & (PAGE_SIZE - 1);
28408c2ecf20Sopenharmony_ci	if ((page->index >= end_index + 1) || !offset)
28418c2ecf20Sopenharmony_ci		goto out;
28428c2ecf20Sopenharmony_ci
28438c2ecf20Sopenharmony_ci	zero_user_segment(page, offset, PAGE_SIZE);
28448c2ecf20Sopenharmony_ciwrite:
28458c2ecf20Sopenharmony_ci	if (f2fs_is_drop_cache(inode))
28468c2ecf20Sopenharmony_ci		goto out;
28478c2ecf20Sopenharmony_ci	/* we should not write 0'th page having journal header */
28488c2ecf20Sopenharmony_ci	if (f2fs_is_volatile_file(inode) && (!page->index ||
28498c2ecf20Sopenharmony_ci			(!wbc->for_reclaim &&
28508c2ecf20Sopenharmony_ci			f2fs_available_free_memory(sbi, BASE_CHECK))))
28518c2ecf20Sopenharmony_ci		goto redirty_out;
28528c2ecf20Sopenharmony_ci
28538c2ecf20Sopenharmony_ci	/* Dentry/quota blocks are controlled by checkpoint */
28548c2ecf20Sopenharmony_ci	if (S_ISDIR(inode->i_mode) || IS_NOQUOTA(inode)) {
28558c2ecf20Sopenharmony_ci		/*
28568c2ecf20Sopenharmony_ci		 * We need to wait for node_write to avoid block allocation during
28578c2ecf20Sopenharmony_ci		 * checkpoint. This can only happen to quota writes which can cause
28588c2ecf20Sopenharmony_ci		 * the below discard race condition.
28598c2ecf20Sopenharmony_ci		 */
28608c2ecf20Sopenharmony_ci		if (IS_NOQUOTA(inode))
28618c2ecf20Sopenharmony_ci			down_read(&sbi->node_write);
28628c2ecf20Sopenharmony_ci
28638c2ecf20Sopenharmony_ci		fio.need_lock = LOCK_DONE;
28648c2ecf20Sopenharmony_ci		err = f2fs_do_write_data_page(&fio);
28658c2ecf20Sopenharmony_ci
28668c2ecf20Sopenharmony_ci		if (IS_NOQUOTA(inode))
28678c2ecf20Sopenharmony_ci			up_read(&sbi->node_write);
28688c2ecf20Sopenharmony_ci
28698c2ecf20Sopenharmony_ci		goto done;
28708c2ecf20Sopenharmony_ci	}
28718c2ecf20Sopenharmony_ci
28728c2ecf20Sopenharmony_ci	if (!wbc->for_reclaim)
28738c2ecf20Sopenharmony_ci		need_balance_fs = true;
28748c2ecf20Sopenharmony_ci	else if (has_not_enough_free_secs(sbi, 0, 0))
28758c2ecf20Sopenharmony_ci		goto redirty_out;
28768c2ecf20Sopenharmony_ci	else
28778c2ecf20Sopenharmony_ci		set_inode_flag(inode, FI_HOT_DATA);
28788c2ecf20Sopenharmony_ci
28798c2ecf20Sopenharmony_ci	err = -EAGAIN;
28808c2ecf20Sopenharmony_ci	if (f2fs_has_inline_data(inode)) {
28818c2ecf20Sopenharmony_ci		err = f2fs_write_inline_data(inode, page);
28828c2ecf20Sopenharmony_ci		if (!err)
28838c2ecf20Sopenharmony_ci			goto out;
28848c2ecf20Sopenharmony_ci	}
28858c2ecf20Sopenharmony_ci
28868c2ecf20Sopenharmony_ci	if (err == -EAGAIN) {
28878c2ecf20Sopenharmony_ci		err = f2fs_do_write_data_page(&fio);
28888c2ecf20Sopenharmony_ci		if (err == -EAGAIN) {
28898c2ecf20Sopenharmony_ci			fio.need_lock = LOCK_REQ;
28908c2ecf20Sopenharmony_ci			err = f2fs_do_write_data_page(&fio);
28918c2ecf20Sopenharmony_ci		}
28928c2ecf20Sopenharmony_ci	}
28938c2ecf20Sopenharmony_ci
28948c2ecf20Sopenharmony_ci	if (err) {
28958c2ecf20Sopenharmony_ci		file_set_keep_isize(inode);
28968c2ecf20Sopenharmony_ci	} else {
28978c2ecf20Sopenharmony_ci		spin_lock(&F2FS_I(inode)->i_size_lock);
28988c2ecf20Sopenharmony_ci		if (F2FS_I(inode)->last_disk_size < psize)
28998c2ecf20Sopenharmony_ci			F2FS_I(inode)->last_disk_size = psize;
29008c2ecf20Sopenharmony_ci		spin_unlock(&F2FS_I(inode)->i_size_lock);
29018c2ecf20Sopenharmony_ci	}
29028c2ecf20Sopenharmony_ci
29038c2ecf20Sopenharmony_cidone:
29048c2ecf20Sopenharmony_ci	if (err && err != -ENOENT)
29058c2ecf20Sopenharmony_ci		goto redirty_out;
29068c2ecf20Sopenharmony_ci
29078c2ecf20Sopenharmony_ciout:
29088c2ecf20Sopenharmony_ci	inode_dec_dirty_pages(inode);
29098c2ecf20Sopenharmony_ci	if (err) {
29108c2ecf20Sopenharmony_ci		ClearPageUptodate(page);
29118c2ecf20Sopenharmony_ci		clear_cold_data(page);
29128c2ecf20Sopenharmony_ci	}
29138c2ecf20Sopenharmony_ci
29148c2ecf20Sopenharmony_ci	if (wbc->for_reclaim) {
29158c2ecf20Sopenharmony_ci		f2fs_submit_merged_write_cond(sbi, NULL, page, 0, DATA);
29168c2ecf20Sopenharmony_ci		clear_inode_flag(inode, FI_HOT_DATA);
29178c2ecf20Sopenharmony_ci		f2fs_remove_dirty_inode(inode);
29188c2ecf20Sopenharmony_ci		submitted = NULL;
29198c2ecf20Sopenharmony_ci	}
29208c2ecf20Sopenharmony_ci	unlock_page(page);
29218c2ecf20Sopenharmony_ci	if (!S_ISDIR(inode->i_mode) && !IS_NOQUOTA(inode) &&
29228c2ecf20Sopenharmony_ci			!F2FS_I(inode)->wb_task && allow_balance)
29238c2ecf20Sopenharmony_ci		f2fs_balance_fs(sbi, need_balance_fs);
29248c2ecf20Sopenharmony_ci
29258c2ecf20Sopenharmony_ci	if (unlikely(f2fs_cp_error(sbi))) {
29268c2ecf20Sopenharmony_ci		f2fs_submit_merged_write(sbi, DATA);
29278c2ecf20Sopenharmony_ci		if (bio && *bio)
29288c2ecf20Sopenharmony_ci			f2fs_submit_merged_ipu_write(sbi, bio, NULL);
29298c2ecf20Sopenharmony_ci		submitted = NULL;
29308c2ecf20Sopenharmony_ci	}
29318c2ecf20Sopenharmony_ci
29328c2ecf20Sopenharmony_ci	if (submitted)
29338c2ecf20Sopenharmony_ci		*submitted = fio.submitted ? 1 : 0;
29348c2ecf20Sopenharmony_ci
29358c2ecf20Sopenharmony_ci	return 0;
29368c2ecf20Sopenharmony_ci
29378c2ecf20Sopenharmony_ciredirty_out:
29388c2ecf20Sopenharmony_ci	redirty_page_for_writepage(wbc, page);
29398c2ecf20Sopenharmony_ci	/*
29408c2ecf20Sopenharmony_ci	 * pageout() in MM traslates EAGAIN, so calls handle_write_error()
29418c2ecf20Sopenharmony_ci	 * -> mapping_set_error() -> set_bit(AS_EIO, ...).
29428c2ecf20Sopenharmony_ci	 * file_write_and_wait_range() will see EIO error, which is critical
29438c2ecf20Sopenharmony_ci	 * to return value of fsync() followed by atomic_write failure to user.
29448c2ecf20Sopenharmony_ci	 */
29458c2ecf20Sopenharmony_ci	if (!err || wbc->for_reclaim)
29468c2ecf20Sopenharmony_ci		return AOP_WRITEPAGE_ACTIVATE;
29478c2ecf20Sopenharmony_ci	unlock_page(page);
29488c2ecf20Sopenharmony_ci	return err;
29498c2ecf20Sopenharmony_ci}
29508c2ecf20Sopenharmony_ci
29518c2ecf20Sopenharmony_cistatic int f2fs_write_data_page(struct page *page,
29528c2ecf20Sopenharmony_ci					struct writeback_control *wbc)
29538c2ecf20Sopenharmony_ci{
29548c2ecf20Sopenharmony_ci#ifdef CONFIG_F2FS_FS_COMPRESSION
29558c2ecf20Sopenharmony_ci	struct inode *inode = page->mapping->host;
29568c2ecf20Sopenharmony_ci
29578c2ecf20Sopenharmony_ci	if (unlikely(f2fs_cp_error(F2FS_I_SB(inode))))
29588c2ecf20Sopenharmony_ci		goto out;
29598c2ecf20Sopenharmony_ci
29608c2ecf20Sopenharmony_ci	if (f2fs_compressed_file(inode)) {
29618c2ecf20Sopenharmony_ci		if (f2fs_is_compressed_cluster(inode, page->index)) {
29628c2ecf20Sopenharmony_ci			redirty_page_for_writepage(wbc, page);
29638c2ecf20Sopenharmony_ci			return AOP_WRITEPAGE_ACTIVATE;
29648c2ecf20Sopenharmony_ci		}
29658c2ecf20Sopenharmony_ci	}
29668c2ecf20Sopenharmony_ciout:
29678c2ecf20Sopenharmony_ci#endif
29688c2ecf20Sopenharmony_ci
29698c2ecf20Sopenharmony_ci	return f2fs_write_single_data_page(page, NULL, NULL, NULL,
29708c2ecf20Sopenharmony_ci						wbc, FS_DATA_IO, 0, true);
29718c2ecf20Sopenharmony_ci}
29728c2ecf20Sopenharmony_ci
29738c2ecf20Sopenharmony_ci/*
29748c2ecf20Sopenharmony_ci * This function was copied from write_cche_pages from mm/page-writeback.c.
29758c2ecf20Sopenharmony_ci * The major change is making write step of cold data page separately from
29768c2ecf20Sopenharmony_ci * warm/hot data page.
29778c2ecf20Sopenharmony_ci */
29788c2ecf20Sopenharmony_cistatic int f2fs_write_cache_pages(struct address_space *mapping,
29798c2ecf20Sopenharmony_ci					struct writeback_control *wbc,
29808c2ecf20Sopenharmony_ci					enum iostat_type io_type)
29818c2ecf20Sopenharmony_ci{
29828c2ecf20Sopenharmony_ci	int ret = 0;
29838c2ecf20Sopenharmony_ci	int done = 0, retry = 0;
29848c2ecf20Sopenharmony_ci	struct pagevec pvec;
29858c2ecf20Sopenharmony_ci	struct f2fs_sb_info *sbi = F2FS_M_SB(mapping);
29868c2ecf20Sopenharmony_ci	struct bio *bio = NULL;
29878c2ecf20Sopenharmony_ci	sector_t last_block;
29888c2ecf20Sopenharmony_ci#ifdef CONFIG_F2FS_FS_COMPRESSION
29898c2ecf20Sopenharmony_ci	struct inode *inode = mapping->host;
29908c2ecf20Sopenharmony_ci	struct compress_ctx cc = {
29918c2ecf20Sopenharmony_ci		.inode = inode,
29928c2ecf20Sopenharmony_ci		.log_cluster_size = F2FS_I(inode)->i_log_cluster_size,
29938c2ecf20Sopenharmony_ci		.cluster_size = F2FS_I(inode)->i_cluster_size,
29948c2ecf20Sopenharmony_ci		.cluster_idx = NULL_CLUSTER,
29958c2ecf20Sopenharmony_ci		.rpages = NULL,
29968c2ecf20Sopenharmony_ci		.nr_rpages = 0,
29978c2ecf20Sopenharmony_ci		.cpages = NULL,
29988c2ecf20Sopenharmony_ci		.rbuf = NULL,
29998c2ecf20Sopenharmony_ci		.cbuf = NULL,
30008c2ecf20Sopenharmony_ci		.rlen = PAGE_SIZE * F2FS_I(inode)->i_cluster_size,
30018c2ecf20Sopenharmony_ci		.private = NULL,
30028c2ecf20Sopenharmony_ci	};
30038c2ecf20Sopenharmony_ci#endif
30048c2ecf20Sopenharmony_ci	int nr_pages;
30058c2ecf20Sopenharmony_ci	pgoff_t index;
30068c2ecf20Sopenharmony_ci	pgoff_t end;		/* Inclusive */
30078c2ecf20Sopenharmony_ci	pgoff_t done_index;
30088c2ecf20Sopenharmony_ci	int range_whole = 0;
30098c2ecf20Sopenharmony_ci	xa_mark_t tag;
30108c2ecf20Sopenharmony_ci	int nwritten = 0;
30118c2ecf20Sopenharmony_ci	int submitted = 0;
30128c2ecf20Sopenharmony_ci	int i;
30138c2ecf20Sopenharmony_ci
30148c2ecf20Sopenharmony_ci	pagevec_init(&pvec);
30158c2ecf20Sopenharmony_ci
30168c2ecf20Sopenharmony_ci	if (get_dirty_pages(mapping->host) <=
30178c2ecf20Sopenharmony_ci				SM_I(F2FS_M_SB(mapping))->min_hot_blocks)
30188c2ecf20Sopenharmony_ci		set_inode_flag(mapping->host, FI_HOT_DATA);
30198c2ecf20Sopenharmony_ci	else
30208c2ecf20Sopenharmony_ci		clear_inode_flag(mapping->host, FI_HOT_DATA);
30218c2ecf20Sopenharmony_ci
30228c2ecf20Sopenharmony_ci	if (wbc->range_cyclic) {
30238c2ecf20Sopenharmony_ci		index = mapping->writeback_index; /* prev offset */
30248c2ecf20Sopenharmony_ci		end = -1;
30258c2ecf20Sopenharmony_ci	} else {
30268c2ecf20Sopenharmony_ci		index = wbc->range_start >> PAGE_SHIFT;
30278c2ecf20Sopenharmony_ci		end = wbc->range_end >> PAGE_SHIFT;
30288c2ecf20Sopenharmony_ci		if (wbc->range_start == 0 && wbc->range_end == LLONG_MAX)
30298c2ecf20Sopenharmony_ci			range_whole = 1;
30308c2ecf20Sopenharmony_ci	}
30318c2ecf20Sopenharmony_ci	if (wbc->sync_mode == WB_SYNC_ALL || wbc->tagged_writepages)
30328c2ecf20Sopenharmony_ci		tag = PAGECACHE_TAG_TOWRITE;
30338c2ecf20Sopenharmony_ci	else
30348c2ecf20Sopenharmony_ci		tag = PAGECACHE_TAG_DIRTY;
30358c2ecf20Sopenharmony_ciretry:
30368c2ecf20Sopenharmony_ci	retry = 0;
30378c2ecf20Sopenharmony_ci	if (wbc->sync_mode == WB_SYNC_ALL || wbc->tagged_writepages)
30388c2ecf20Sopenharmony_ci		tag_pages_for_writeback(mapping, index, end);
30398c2ecf20Sopenharmony_ci	done_index = index;
30408c2ecf20Sopenharmony_ci	while (!done && !retry && (index <= end)) {
30418c2ecf20Sopenharmony_ci		nr_pages = pagevec_lookup_range_tag(&pvec, mapping, &index, end,
30428c2ecf20Sopenharmony_ci				tag);
30438c2ecf20Sopenharmony_ci		if (nr_pages == 0)
30448c2ecf20Sopenharmony_ci			break;
30458c2ecf20Sopenharmony_ci
30468c2ecf20Sopenharmony_ci		for (i = 0; i < nr_pages; i++) {
30478c2ecf20Sopenharmony_ci			struct page *page = pvec.pages[i];
30488c2ecf20Sopenharmony_ci			bool need_readd;
30498c2ecf20Sopenharmony_cireadd:
30508c2ecf20Sopenharmony_ci			need_readd = false;
30518c2ecf20Sopenharmony_ci#ifdef CONFIG_F2FS_FS_COMPRESSION
30528c2ecf20Sopenharmony_ci			if (f2fs_compressed_file(inode)) {
30538c2ecf20Sopenharmony_ci				ret = f2fs_init_compress_ctx(&cc);
30548c2ecf20Sopenharmony_ci				if (ret) {
30558c2ecf20Sopenharmony_ci					done = 1;
30568c2ecf20Sopenharmony_ci					break;
30578c2ecf20Sopenharmony_ci				}
30588c2ecf20Sopenharmony_ci
30598c2ecf20Sopenharmony_ci				if (!f2fs_cluster_can_merge_page(&cc,
30608c2ecf20Sopenharmony_ci								page->index)) {
30618c2ecf20Sopenharmony_ci					ret = f2fs_write_multi_pages(&cc,
30628c2ecf20Sopenharmony_ci						&submitted, wbc, io_type);
30638c2ecf20Sopenharmony_ci					if (!ret)
30648c2ecf20Sopenharmony_ci						need_readd = true;
30658c2ecf20Sopenharmony_ci					goto result;
30668c2ecf20Sopenharmony_ci				}
30678c2ecf20Sopenharmony_ci
30688c2ecf20Sopenharmony_ci				if (unlikely(f2fs_cp_error(sbi)))
30698c2ecf20Sopenharmony_ci					goto lock_page;
30708c2ecf20Sopenharmony_ci
30718c2ecf20Sopenharmony_ci				if (f2fs_cluster_is_empty(&cc)) {
30728c2ecf20Sopenharmony_ci					void *fsdata = NULL;
30738c2ecf20Sopenharmony_ci					struct page *pagep;
30748c2ecf20Sopenharmony_ci					int ret2;
30758c2ecf20Sopenharmony_ci
30768c2ecf20Sopenharmony_ci					ret2 = f2fs_prepare_compress_overwrite(
30778c2ecf20Sopenharmony_ci							inode, &pagep,
30788c2ecf20Sopenharmony_ci							page->index, &fsdata);
30798c2ecf20Sopenharmony_ci					if (ret2 < 0) {
30808c2ecf20Sopenharmony_ci						ret = ret2;
30818c2ecf20Sopenharmony_ci						done = 1;
30828c2ecf20Sopenharmony_ci						break;
30838c2ecf20Sopenharmony_ci					} else if (ret2 &&
30848c2ecf20Sopenharmony_ci						!f2fs_compress_write_end(inode,
30858c2ecf20Sopenharmony_ci								fsdata, page->index,
30868c2ecf20Sopenharmony_ci								1)) {
30878c2ecf20Sopenharmony_ci						retry = 1;
30888c2ecf20Sopenharmony_ci						break;
30898c2ecf20Sopenharmony_ci					}
30908c2ecf20Sopenharmony_ci				} else {
30918c2ecf20Sopenharmony_ci					goto lock_page;
30928c2ecf20Sopenharmony_ci				}
30938c2ecf20Sopenharmony_ci			}
30948c2ecf20Sopenharmony_ci#endif
30958c2ecf20Sopenharmony_ci			/* give a priority to WB_SYNC threads */
30968c2ecf20Sopenharmony_ci			if (atomic_read(&sbi->wb_sync_req[DATA]) &&
30978c2ecf20Sopenharmony_ci					wbc->sync_mode == WB_SYNC_NONE) {
30988c2ecf20Sopenharmony_ci				done = 1;
30998c2ecf20Sopenharmony_ci				break;
31008c2ecf20Sopenharmony_ci			}
31018c2ecf20Sopenharmony_ci#ifdef CONFIG_F2FS_FS_COMPRESSION
31028c2ecf20Sopenharmony_cilock_page:
31038c2ecf20Sopenharmony_ci#endif
31048c2ecf20Sopenharmony_ci			done_index = page->index;
31058c2ecf20Sopenharmony_ciretry_write:
31068c2ecf20Sopenharmony_ci			lock_page(page);
31078c2ecf20Sopenharmony_ci
31088c2ecf20Sopenharmony_ci			if (unlikely(page->mapping != mapping)) {
31098c2ecf20Sopenharmony_cicontinue_unlock:
31108c2ecf20Sopenharmony_ci				unlock_page(page);
31118c2ecf20Sopenharmony_ci				continue;
31128c2ecf20Sopenharmony_ci			}
31138c2ecf20Sopenharmony_ci
31148c2ecf20Sopenharmony_ci			if (!PageDirty(page)) {
31158c2ecf20Sopenharmony_ci				/* someone wrote it for us */
31168c2ecf20Sopenharmony_ci				goto continue_unlock;
31178c2ecf20Sopenharmony_ci			}
31188c2ecf20Sopenharmony_ci
31198c2ecf20Sopenharmony_ci			if (PageWriteback(page)) {
31208c2ecf20Sopenharmony_ci				if (wbc->sync_mode != WB_SYNC_NONE)
31218c2ecf20Sopenharmony_ci					f2fs_wait_on_page_writeback(page,
31228c2ecf20Sopenharmony_ci							DATA, true, true);
31238c2ecf20Sopenharmony_ci				else
31248c2ecf20Sopenharmony_ci					goto continue_unlock;
31258c2ecf20Sopenharmony_ci			}
31268c2ecf20Sopenharmony_ci
31278c2ecf20Sopenharmony_ci			if (!clear_page_dirty_for_io(page))
31288c2ecf20Sopenharmony_ci				goto continue_unlock;
31298c2ecf20Sopenharmony_ci
31308c2ecf20Sopenharmony_ci#ifdef CONFIG_F2FS_FS_COMPRESSION
31318c2ecf20Sopenharmony_ci			if (f2fs_compressed_file(inode)) {
31328c2ecf20Sopenharmony_ci				get_page(page);
31338c2ecf20Sopenharmony_ci				f2fs_compress_ctx_add_page(&cc, page);
31348c2ecf20Sopenharmony_ci				continue;
31358c2ecf20Sopenharmony_ci			}
31368c2ecf20Sopenharmony_ci#endif
31378c2ecf20Sopenharmony_ci			ret = f2fs_write_single_data_page(page, &submitted,
31388c2ecf20Sopenharmony_ci					&bio, &last_block, wbc, io_type,
31398c2ecf20Sopenharmony_ci					0, true);
31408c2ecf20Sopenharmony_ci			if (ret == AOP_WRITEPAGE_ACTIVATE)
31418c2ecf20Sopenharmony_ci				unlock_page(page);
31428c2ecf20Sopenharmony_ci#ifdef CONFIG_F2FS_FS_COMPRESSION
31438c2ecf20Sopenharmony_ciresult:
31448c2ecf20Sopenharmony_ci#endif
31458c2ecf20Sopenharmony_ci			nwritten += submitted;
31468c2ecf20Sopenharmony_ci			wbc->nr_to_write -= submitted;
31478c2ecf20Sopenharmony_ci
31488c2ecf20Sopenharmony_ci			if (unlikely(ret)) {
31498c2ecf20Sopenharmony_ci				/*
31508c2ecf20Sopenharmony_ci				 * keep nr_to_write, since vfs uses this to
31518c2ecf20Sopenharmony_ci				 * get # of written pages.
31528c2ecf20Sopenharmony_ci				 */
31538c2ecf20Sopenharmony_ci				if (ret == AOP_WRITEPAGE_ACTIVATE) {
31548c2ecf20Sopenharmony_ci					ret = 0;
31558c2ecf20Sopenharmony_ci					goto next;
31568c2ecf20Sopenharmony_ci				} else if (ret == -EAGAIN) {
31578c2ecf20Sopenharmony_ci					ret = 0;
31588c2ecf20Sopenharmony_ci					if (wbc->sync_mode == WB_SYNC_ALL) {
31598c2ecf20Sopenharmony_ci						cond_resched();
31608c2ecf20Sopenharmony_ci						congestion_wait(BLK_RW_ASYNC,
31618c2ecf20Sopenharmony_ci							DEFAULT_IO_TIMEOUT);
31628c2ecf20Sopenharmony_ci						goto retry_write;
31638c2ecf20Sopenharmony_ci					}
31648c2ecf20Sopenharmony_ci					goto next;
31658c2ecf20Sopenharmony_ci				}
31668c2ecf20Sopenharmony_ci				done_index = page->index + 1;
31678c2ecf20Sopenharmony_ci				done = 1;
31688c2ecf20Sopenharmony_ci				break;
31698c2ecf20Sopenharmony_ci			}
31708c2ecf20Sopenharmony_ci
31718c2ecf20Sopenharmony_ci			if (wbc->nr_to_write <= 0 &&
31728c2ecf20Sopenharmony_ci					wbc->sync_mode == WB_SYNC_NONE) {
31738c2ecf20Sopenharmony_ci				done = 1;
31748c2ecf20Sopenharmony_ci				break;
31758c2ecf20Sopenharmony_ci			}
31768c2ecf20Sopenharmony_cinext:
31778c2ecf20Sopenharmony_ci			if (need_readd)
31788c2ecf20Sopenharmony_ci				goto readd;
31798c2ecf20Sopenharmony_ci		}
31808c2ecf20Sopenharmony_ci		pagevec_release(&pvec);
31818c2ecf20Sopenharmony_ci		cond_resched();
31828c2ecf20Sopenharmony_ci	}
31838c2ecf20Sopenharmony_ci#ifdef CONFIG_F2FS_FS_COMPRESSION
31848c2ecf20Sopenharmony_ci	/* flush remained pages in compress cluster */
31858c2ecf20Sopenharmony_ci	if (f2fs_compressed_file(inode) && !f2fs_cluster_is_empty(&cc)) {
31868c2ecf20Sopenharmony_ci		ret = f2fs_write_multi_pages(&cc, &submitted, wbc, io_type);
31878c2ecf20Sopenharmony_ci		nwritten += submitted;
31888c2ecf20Sopenharmony_ci		wbc->nr_to_write -= submitted;
31898c2ecf20Sopenharmony_ci		if (ret) {
31908c2ecf20Sopenharmony_ci			done = 1;
31918c2ecf20Sopenharmony_ci			retry = 0;
31928c2ecf20Sopenharmony_ci		}
31938c2ecf20Sopenharmony_ci	}
31948c2ecf20Sopenharmony_ci	if (f2fs_compressed_file(inode))
31958c2ecf20Sopenharmony_ci		f2fs_destroy_compress_ctx(&cc, false);
31968c2ecf20Sopenharmony_ci#endif
31978c2ecf20Sopenharmony_ci	if (retry) {
31988c2ecf20Sopenharmony_ci		index = 0;
31998c2ecf20Sopenharmony_ci		end = -1;
32008c2ecf20Sopenharmony_ci		goto retry;
32018c2ecf20Sopenharmony_ci	}
32028c2ecf20Sopenharmony_ci	if (wbc->range_cyclic && !done)
32038c2ecf20Sopenharmony_ci		done_index = 0;
32048c2ecf20Sopenharmony_ci	if (wbc->range_cyclic || (range_whole && wbc->nr_to_write > 0))
32058c2ecf20Sopenharmony_ci		mapping->writeback_index = done_index;
32068c2ecf20Sopenharmony_ci
32078c2ecf20Sopenharmony_ci	if (nwritten)
32088c2ecf20Sopenharmony_ci		f2fs_submit_merged_write_cond(F2FS_M_SB(mapping), mapping->host,
32098c2ecf20Sopenharmony_ci								NULL, 0, DATA);
32108c2ecf20Sopenharmony_ci	/* submit cached bio of IPU write */
32118c2ecf20Sopenharmony_ci	if (bio)
32128c2ecf20Sopenharmony_ci		f2fs_submit_merged_ipu_write(sbi, &bio, NULL);
32138c2ecf20Sopenharmony_ci
32148c2ecf20Sopenharmony_ci	return ret;
32158c2ecf20Sopenharmony_ci}
32168c2ecf20Sopenharmony_ci
32178c2ecf20Sopenharmony_cistatic inline bool __should_serialize_io(struct inode *inode,
32188c2ecf20Sopenharmony_ci					struct writeback_control *wbc)
32198c2ecf20Sopenharmony_ci{
32208c2ecf20Sopenharmony_ci	/* to avoid deadlock in path of data flush */
32218c2ecf20Sopenharmony_ci	if (F2FS_I(inode)->wb_task)
32228c2ecf20Sopenharmony_ci		return false;
32238c2ecf20Sopenharmony_ci
32248c2ecf20Sopenharmony_ci	if (!S_ISREG(inode->i_mode))
32258c2ecf20Sopenharmony_ci		return false;
32268c2ecf20Sopenharmony_ci	if (IS_NOQUOTA(inode))
32278c2ecf20Sopenharmony_ci		return false;
32288c2ecf20Sopenharmony_ci
32298c2ecf20Sopenharmony_ci	if (f2fs_compressed_file(inode))
32308c2ecf20Sopenharmony_ci		return true;
32318c2ecf20Sopenharmony_ci	if (wbc->sync_mode != WB_SYNC_ALL)
32328c2ecf20Sopenharmony_ci		return true;
32338c2ecf20Sopenharmony_ci	if (get_dirty_pages(inode) >= SM_I(F2FS_I_SB(inode))->min_seq_blocks)
32348c2ecf20Sopenharmony_ci		return true;
32358c2ecf20Sopenharmony_ci	return false;
32368c2ecf20Sopenharmony_ci}
32378c2ecf20Sopenharmony_ci
32388c2ecf20Sopenharmony_cistatic int __f2fs_write_data_pages(struct address_space *mapping,
32398c2ecf20Sopenharmony_ci						struct writeback_control *wbc,
32408c2ecf20Sopenharmony_ci						enum iostat_type io_type)
32418c2ecf20Sopenharmony_ci{
32428c2ecf20Sopenharmony_ci	struct inode *inode = mapping->host;
32438c2ecf20Sopenharmony_ci	struct f2fs_sb_info *sbi = F2FS_I_SB(inode);
32448c2ecf20Sopenharmony_ci	struct blk_plug plug;
32458c2ecf20Sopenharmony_ci	int ret;
32468c2ecf20Sopenharmony_ci	bool locked = false;
32478c2ecf20Sopenharmony_ci
32488c2ecf20Sopenharmony_ci	/* deal with chardevs and other special file */
32498c2ecf20Sopenharmony_ci	if (!mapping->a_ops->writepage)
32508c2ecf20Sopenharmony_ci		return 0;
32518c2ecf20Sopenharmony_ci
32528c2ecf20Sopenharmony_ci	/* skip writing if there is no dirty page in this inode */
32538c2ecf20Sopenharmony_ci	if (!get_dirty_pages(inode) && wbc->sync_mode == WB_SYNC_NONE)
32548c2ecf20Sopenharmony_ci		return 0;
32558c2ecf20Sopenharmony_ci
32568c2ecf20Sopenharmony_ci	/* during POR, we don't need to trigger writepage at all. */
32578c2ecf20Sopenharmony_ci	if (unlikely(is_sbi_flag_set(sbi, SBI_POR_DOING)))
32588c2ecf20Sopenharmony_ci		goto skip_write;
32598c2ecf20Sopenharmony_ci
32608c2ecf20Sopenharmony_ci	if ((S_ISDIR(inode->i_mode) || IS_NOQUOTA(inode)) &&
32618c2ecf20Sopenharmony_ci			wbc->sync_mode == WB_SYNC_NONE &&
32628c2ecf20Sopenharmony_ci			get_dirty_pages(inode) < nr_pages_to_skip(sbi, DATA) &&
32638c2ecf20Sopenharmony_ci			f2fs_available_free_memory(sbi, DIRTY_DENTS))
32648c2ecf20Sopenharmony_ci		goto skip_write;
32658c2ecf20Sopenharmony_ci
32668c2ecf20Sopenharmony_ci	/* skip writing during file defragment */
32678c2ecf20Sopenharmony_ci	if (is_inode_flag_set(inode, FI_DO_DEFRAG))
32688c2ecf20Sopenharmony_ci		goto skip_write;
32698c2ecf20Sopenharmony_ci
32708c2ecf20Sopenharmony_ci	trace_f2fs_writepages(mapping->host, wbc, DATA);
32718c2ecf20Sopenharmony_ci
32728c2ecf20Sopenharmony_ci	/* to avoid spliting IOs due to mixed WB_SYNC_ALL and WB_SYNC_NONE */
32738c2ecf20Sopenharmony_ci	if (wbc->sync_mode == WB_SYNC_ALL)
32748c2ecf20Sopenharmony_ci		atomic_inc(&sbi->wb_sync_req[DATA]);
32758c2ecf20Sopenharmony_ci	else if (atomic_read(&sbi->wb_sync_req[DATA])) {
32768c2ecf20Sopenharmony_ci		/* to avoid potential deadlock */
32778c2ecf20Sopenharmony_ci		if (current->plug)
32788c2ecf20Sopenharmony_ci			blk_finish_plug(current->plug);
32798c2ecf20Sopenharmony_ci		goto skip_write;
32808c2ecf20Sopenharmony_ci	}
32818c2ecf20Sopenharmony_ci
32828c2ecf20Sopenharmony_ci	if (__should_serialize_io(inode, wbc)) {
32838c2ecf20Sopenharmony_ci		mutex_lock(&sbi->writepages);
32848c2ecf20Sopenharmony_ci		locked = true;
32858c2ecf20Sopenharmony_ci	}
32868c2ecf20Sopenharmony_ci
32878c2ecf20Sopenharmony_ci	blk_start_plug(&plug);
32888c2ecf20Sopenharmony_ci	ret = f2fs_write_cache_pages(mapping, wbc, io_type);
32898c2ecf20Sopenharmony_ci	blk_finish_plug(&plug);
32908c2ecf20Sopenharmony_ci
32918c2ecf20Sopenharmony_ci	if (locked)
32928c2ecf20Sopenharmony_ci		mutex_unlock(&sbi->writepages);
32938c2ecf20Sopenharmony_ci
32948c2ecf20Sopenharmony_ci	if (wbc->sync_mode == WB_SYNC_ALL)
32958c2ecf20Sopenharmony_ci		atomic_dec(&sbi->wb_sync_req[DATA]);
32968c2ecf20Sopenharmony_ci	/*
32978c2ecf20Sopenharmony_ci	 * if some pages were truncated, we cannot guarantee its mapping->host
32988c2ecf20Sopenharmony_ci	 * to detect pending bios.
32998c2ecf20Sopenharmony_ci	 */
33008c2ecf20Sopenharmony_ci
33018c2ecf20Sopenharmony_ci	f2fs_remove_dirty_inode(inode);
33028c2ecf20Sopenharmony_ci	return ret;
33038c2ecf20Sopenharmony_ci
33048c2ecf20Sopenharmony_ciskip_write:
33058c2ecf20Sopenharmony_ci	wbc->pages_skipped += get_dirty_pages(inode);
33068c2ecf20Sopenharmony_ci	trace_f2fs_writepages(mapping->host, wbc, DATA);
33078c2ecf20Sopenharmony_ci	return 0;
33088c2ecf20Sopenharmony_ci}
33098c2ecf20Sopenharmony_ci
33108c2ecf20Sopenharmony_cistatic int f2fs_write_data_pages(struct address_space *mapping,
33118c2ecf20Sopenharmony_ci			    struct writeback_control *wbc)
33128c2ecf20Sopenharmony_ci{
33138c2ecf20Sopenharmony_ci	struct inode *inode = mapping->host;
33148c2ecf20Sopenharmony_ci
33158c2ecf20Sopenharmony_ci	return __f2fs_write_data_pages(mapping, wbc,
33168c2ecf20Sopenharmony_ci			F2FS_I(inode)->cp_task == current ?
33178c2ecf20Sopenharmony_ci			FS_CP_DATA_IO : FS_DATA_IO);
33188c2ecf20Sopenharmony_ci}
33198c2ecf20Sopenharmony_ci
33208c2ecf20Sopenharmony_cistatic void f2fs_write_failed(struct address_space *mapping, loff_t to)
33218c2ecf20Sopenharmony_ci{
33228c2ecf20Sopenharmony_ci	struct inode *inode = mapping->host;
33238c2ecf20Sopenharmony_ci	loff_t i_size = i_size_read(inode);
33248c2ecf20Sopenharmony_ci
33258c2ecf20Sopenharmony_ci	if (IS_NOQUOTA(inode))
33268c2ecf20Sopenharmony_ci		return;
33278c2ecf20Sopenharmony_ci
33288c2ecf20Sopenharmony_ci	/* In the fs-verity case, f2fs_end_enable_verity() does the truncate */
33298c2ecf20Sopenharmony_ci	if (to > i_size && !f2fs_verity_in_progress(inode)) {
33308c2ecf20Sopenharmony_ci		down_write(&F2FS_I(inode)->i_gc_rwsem[WRITE]);
33318c2ecf20Sopenharmony_ci		down_write(&F2FS_I(inode)->i_mmap_sem);
33328c2ecf20Sopenharmony_ci
33338c2ecf20Sopenharmony_ci		truncate_pagecache(inode, i_size);
33348c2ecf20Sopenharmony_ci		f2fs_truncate_blocks(inode, i_size, true);
33358c2ecf20Sopenharmony_ci
33368c2ecf20Sopenharmony_ci		up_write(&F2FS_I(inode)->i_mmap_sem);
33378c2ecf20Sopenharmony_ci		up_write(&F2FS_I(inode)->i_gc_rwsem[WRITE]);
33388c2ecf20Sopenharmony_ci	}
33398c2ecf20Sopenharmony_ci}
33408c2ecf20Sopenharmony_ci
33418c2ecf20Sopenharmony_cistatic int prepare_write_begin(struct f2fs_sb_info *sbi,
33428c2ecf20Sopenharmony_ci			struct page *page, loff_t pos, unsigned len,
33438c2ecf20Sopenharmony_ci			block_t *blk_addr, bool *node_changed)
33448c2ecf20Sopenharmony_ci{
33458c2ecf20Sopenharmony_ci	struct inode *inode = page->mapping->host;
33468c2ecf20Sopenharmony_ci	pgoff_t index = page->index;
33478c2ecf20Sopenharmony_ci	struct dnode_of_data dn;
33488c2ecf20Sopenharmony_ci	struct page *ipage;
33498c2ecf20Sopenharmony_ci	bool locked = false;
33508c2ecf20Sopenharmony_ci	struct extent_info ei = {0,0,0};
33518c2ecf20Sopenharmony_ci	int err = 0;
33528c2ecf20Sopenharmony_ci	int flag;
33538c2ecf20Sopenharmony_ci
33548c2ecf20Sopenharmony_ci	/*
33558c2ecf20Sopenharmony_ci	 * we already allocated all the blocks, so we don't need to get
33568c2ecf20Sopenharmony_ci	 * the block addresses when there is no need to fill the page.
33578c2ecf20Sopenharmony_ci	 */
33588c2ecf20Sopenharmony_ci	if (!f2fs_has_inline_data(inode) && len == PAGE_SIZE &&
33598c2ecf20Sopenharmony_ci	    !is_inode_flag_set(inode, FI_NO_PREALLOC) &&
33608c2ecf20Sopenharmony_ci	    !f2fs_verity_in_progress(inode))
33618c2ecf20Sopenharmony_ci		return 0;
33628c2ecf20Sopenharmony_ci
33638c2ecf20Sopenharmony_ci	/* f2fs_lock_op avoids race between write CP and convert_inline_page */
33648c2ecf20Sopenharmony_ci	if (f2fs_has_inline_data(inode) && pos + len > MAX_INLINE_DATA(inode))
33658c2ecf20Sopenharmony_ci		flag = F2FS_GET_BLOCK_DEFAULT;
33668c2ecf20Sopenharmony_ci	else
33678c2ecf20Sopenharmony_ci		flag = F2FS_GET_BLOCK_PRE_AIO;
33688c2ecf20Sopenharmony_ci
33698c2ecf20Sopenharmony_ci	if (f2fs_has_inline_data(inode) ||
33708c2ecf20Sopenharmony_ci			(pos & PAGE_MASK) >= i_size_read(inode)) {
33718c2ecf20Sopenharmony_ci		f2fs_do_map_lock(sbi, flag, true);
33728c2ecf20Sopenharmony_ci		locked = true;
33738c2ecf20Sopenharmony_ci	}
33748c2ecf20Sopenharmony_ci
33758c2ecf20Sopenharmony_cirestart:
33768c2ecf20Sopenharmony_ci	/* check inline_data */
33778c2ecf20Sopenharmony_ci	ipage = f2fs_get_node_page(sbi, inode->i_ino);
33788c2ecf20Sopenharmony_ci	if (IS_ERR(ipage)) {
33798c2ecf20Sopenharmony_ci		err = PTR_ERR(ipage);
33808c2ecf20Sopenharmony_ci		goto unlock_out;
33818c2ecf20Sopenharmony_ci	}
33828c2ecf20Sopenharmony_ci
33838c2ecf20Sopenharmony_ci	set_new_dnode(&dn, inode, ipage, ipage, 0);
33848c2ecf20Sopenharmony_ci
33858c2ecf20Sopenharmony_ci	if (f2fs_has_inline_data(inode)) {
33868c2ecf20Sopenharmony_ci		if (pos + len <= MAX_INLINE_DATA(inode)) {
33878c2ecf20Sopenharmony_ci			f2fs_do_read_inline_data(page, ipage);
33888c2ecf20Sopenharmony_ci			set_inode_flag(inode, FI_DATA_EXIST);
33898c2ecf20Sopenharmony_ci			if (inode->i_nlink)
33908c2ecf20Sopenharmony_ci				set_inline_node(ipage);
33918c2ecf20Sopenharmony_ci		} else {
33928c2ecf20Sopenharmony_ci			err = f2fs_convert_inline_page(&dn, page);
33938c2ecf20Sopenharmony_ci			if (err)
33948c2ecf20Sopenharmony_ci				goto out;
33958c2ecf20Sopenharmony_ci			if (dn.data_blkaddr == NULL_ADDR)
33968c2ecf20Sopenharmony_ci				err = f2fs_get_block(&dn, index);
33978c2ecf20Sopenharmony_ci		}
33988c2ecf20Sopenharmony_ci	} else if (locked) {
33998c2ecf20Sopenharmony_ci		err = f2fs_get_block(&dn, index);
34008c2ecf20Sopenharmony_ci	} else {
34018c2ecf20Sopenharmony_ci		if (f2fs_lookup_extent_cache(inode, index, &ei)) {
34028c2ecf20Sopenharmony_ci			dn.data_blkaddr = ei.blk + index - ei.fofs;
34038c2ecf20Sopenharmony_ci		} else {
34048c2ecf20Sopenharmony_ci			/* hole case */
34058c2ecf20Sopenharmony_ci			err = f2fs_get_dnode_of_data(&dn, index, LOOKUP_NODE);
34068c2ecf20Sopenharmony_ci			if (err || dn.data_blkaddr == NULL_ADDR) {
34078c2ecf20Sopenharmony_ci				f2fs_put_dnode(&dn);
34088c2ecf20Sopenharmony_ci				f2fs_do_map_lock(sbi, F2FS_GET_BLOCK_PRE_AIO,
34098c2ecf20Sopenharmony_ci								true);
34108c2ecf20Sopenharmony_ci				WARN_ON(flag != F2FS_GET_BLOCK_PRE_AIO);
34118c2ecf20Sopenharmony_ci				locked = true;
34128c2ecf20Sopenharmony_ci				goto restart;
34138c2ecf20Sopenharmony_ci			}
34148c2ecf20Sopenharmony_ci		}
34158c2ecf20Sopenharmony_ci	}
34168c2ecf20Sopenharmony_ci
34178c2ecf20Sopenharmony_ci	/* convert_inline_page can make node_changed */
34188c2ecf20Sopenharmony_ci	*blk_addr = dn.data_blkaddr;
34198c2ecf20Sopenharmony_ci	*node_changed = dn.node_changed;
34208c2ecf20Sopenharmony_ciout:
34218c2ecf20Sopenharmony_ci	f2fs_put_dnode(&dn);
34228c2ecf20Sopenharmony_ciunlock_out:
34238c2ecf20Sopenharmony_ci	if (locked)
34248c2ecf20Sopenharmony_ci		f2fs_do_map_lock(sbi, flag, false);
34258c2ecf20Sopenharmony_ci	return err;
34268c2ecf20Sopenharmony_ci}
34278c2ecf20Sopenharmony_ci
34288c2ecf20Sopenharmony_cistatic int f2fs_write_begin(struct file *file, struct address_space *mapping,
34298c2ecf20Sopenharmony_ci		loff_t pos, unsigned len, unsigned flags,
34308c2ecf20Sopenharmony_ci		struct page **pagep, void **fsdata)
34318c2ecf20Sopenharmony_ci{
34328c2ecf20Sopenharmony_ci	struct inode *inode = mapping->host;
34338c2ecf20Sopenharmony_ci	struct f2fs_sb_info *sbi = F2FS_I_SB(inode);
34348c2ecf20Sopenharmony_ci	struct page *page = NULL;
34358c2ecf20Sopenharmony_ci	pgoff_t index = ((unsigned long long) pos) >> PAGE_SHIFT;
34368c2ecf20Sopenharmony_ci	bool need_balance = false, drop_atomic = false;
34378c2ecf20Sopenharmony_ci	block_t blkaddr = NULL_ADDR;
34388c2ecf20Sopenharmony_ci	int err = 0;
34398c2ecf20Sopenharmony_ci
34408c2ecf20Sopenharmony_ci	trace_f2fs_write_begin(inode, pos, len, flags);
34418c2ecf20Sopenharmony_ci
34428c2ecf20Sopenharmony_ci	if (!f2fs_is_checkpoint_ready(sbi)) {
34438c2ecf20Sopenharmony_ci		err = -ENOSPC;
34448c2ecf20Sopenharmony_ci		goto fail;
34458c2ecf20Sopenharmony_ci	}
34468c2ecf20Sopenharmony_ci
34478c2ecf20Sopenharmony_ci	if ((f2fs_is_atomic_file(inode) &&
34488c2ecf20Sopenharmony_ci			!f2fs_available_free_memory(sbi, INMEM_PAGES)) ||
34498c2ecf20Sopenharmony_ci			is_inode_flag_set(inode, FI_ATOMIC_REVOKE_REQUEST)) {
34508c2ecf20Sopenharmony_ci		err = -ENOMEM;
34518c2ecf20Sopenharmony_ci		drop_atomic = true;
34528c2ecf20Sopenharmony_ci		goto fail;
34538c2ecf20Sopenharmony_ci	}
34548c2ecf20Sopenharmony_ci
34558c2ecf20Sopenharmony_ci	/*
34568c2ecf20Sopenharmony_ci	 * We should check this at this moment to avoid deadlock on inode page
34578c2ecf20Sopenharmony_ci	 * and #0 page. The locking rule for inline_data conversion should be:
34588c2ecf20Sopenharmony_ci	 * lock_page(page #0) -> lock_page(inode_page)
34598c2ecf20Sopenharmony_ci	 */
34608c2ecf20Sopenharmony_ci	if (index != 0) {
34618c2ecf20Sopenharmony_ci		err = f2fs_convert_inline_inode(inode);
34628c2ecf20Sopenharmony_ci		if (err)
34638c2ecf20Sopenharmony_ci			goto fail;
34648c2ecf20Sopenharmony_ci	}
34658c2ecf20Sopenharmony_ci
34668c2ecf20Sopenharmony_ci#ifdef CONFIG_F2FS_FS_COMPRESSION
34678c2ecf20Sopenharmony_ci	if (f2fs_compressed_file(inode)) {
34688c2ecf20Sopenharmony_ci		int ret;
34698c2ecf20Sopenharmony_ci
34708c2ecf20Sopenharmony_ci		*fsdata = NULL;
34718c2ecf20Sopenharmony_ci
34728c2ecf20Sopenharmony_ci		if (len == PAGE_SIZE && !(f2fs_is_atomic_file(inode)))
34738c2ecf20Sopenharmony_ci			goto repeat;
34748c2ecf20Sopenharmony_ci
34758c2ecf20Sopenharmony_ci		ret = f2fs_prepare_compress_overwrite(inode, pagep,
34768c2ecf20Sopenharmony_ci							index, fsdata);
34778c2ecf20Sopenharmony_ci		if (ret < 0) {
34788c2ecf20Sopenharmony_ci			err = ret;
34798c2ecf20Sopenharmony_ci			goto fail;
34808c2ecf20Sopenharmony_ci		} else if (ret) {
34818c2ecf20Sopenharmony_ci			return 0;
34828c2ecf20Sopenharmony_ci		}
34838c2ecf20Sopenharmony_ci	}
34848c2ecf20Sopenharmony_ci#endif
34858c2ecf20Sopenharmony_ci
34868c2ecf20Sopenharmony_cirepeat:
34878c2ecf20Sopenharmony_ci	/*
34888c2ecf20Sopenharmony_ci	 * Do not use grab_cache_page_write_begin() to avoid deadlock due to
34898c2ecf20Sopenharmony_ci	 * wait_for_stable_page. Will wait that below with our IO control.
34908c2ecf20Sopenharmony_ci	 */
34918c2ecf20Sopenharmony_ci	page = f2fs_pagecache_get_page(mapping, index,
34928c2ecf20Sopenharmony_ci				FGP_LOCK | FGP_WRITE | FGP_CREAT, GFP_NOFS);
34938c2ecf20Sopenharmony_ci	if (!page) {
34948c2ecf20Sopenharmony_ci		err = -ENOMEM;
34958c2ecf20Sopenharmony_ci		goto fail;
34968c2ecf20Sopenharmony_ci	}
34978c2ecf20Sopenharmony_ci
34988c2ecf20Sopenharmony_ci	/* TODO: cluster can be compressed due to race with .writepage */
34998c2ecf20Sopenharmony_ci
35008c2ecf20Sopenharmony_ci	*pagep = page;
35018c2ecf20Sopenharmony_ci
35028c2ecf20Sopenharmony_ci	err = prepare_write_begin(sbi, page, pos, len,
35038c2ecf20Sopenharmony_ci					&blkaddr, &need_balance);
35048c2ecf20Sopenharmony_ci	if (err)
35058c2ecf20Sopenharmony_ci		goto fail;
35068c2ecf20Sopenharmony_ci
35078c2ecf20Sopenharmony_ci	if (need_balance && !IS_NOQUOTA(inode) &&
35088c2ecf20Sopenharmony_ci			has_not_enough_free_secs(sbi, 0, 0)) {
35098c2ecf20Sopenharmony_ci		unlock_page(page);
35108c2ecf20Sopenharmony_ci		f2fs_balance_fs(sbi, true);
35118c2ecf20Sopenharmony_ci		lock_page(page);
35128c2ecf20Sopenharmony_ci		if (page->mapping != mapping) {
35138c2ecf20Sopenharmony_ci			/* The page got truncated from under us */
35148c2ecf20Sopenharmony_ci			f2fs_put_page(page, 1);
35158c2ecf20Sopenharmony_ci			goto repeat;
35168c2ecf20Sopenharmony_ci		}
35178c2ecf20Sopenharmony_ci	}
35188c2ecf20Sopenharmony_ci
35198c2ecf20Sopenharmony_ci	f2fs_wait_on_page_writeback(page, DATA, false, true);
35208c2ecf20Sopenharmony_ci
35218c2ecf20Sopenharmony_ci	if (len == PAGE_SIZE || PageUptodate(page))
35228c2ecf20Sopenharmony_ci		return 0;
35238c2ecf20Sopenharmony_ci
35248c2ecf20Sopenharmony_ci	if (!(pos & (PAGE_SIZE - 1)) && (pos + len) >= i_size_read(inode) &&
35258c2ecf20Sopenharmony_ci	    !f2fs_verity_in_progress(inode)) {
35268c2ecf20Sopenharmony_ci		zero_user_segment(page, len, PAGE_SIZE);
35278c2ecf20Sopenharmony_ci		return 0;
35288c2ecf20Sopenharmony_ci	}
35298c2ecf20Sopenharmony_ci
35308c2ecf20Sopenharmony_ci	if (blkaddr == NEW_ADDR) {
35318c2ecf20Sopenharmony_ci		zero_user_segment(page, 0, PAGE_SIZE);
35328c2ecf20Sopenharmony_ci		SetPageUptodate(page);
35338c2ecf20Sopenharmony_ci	} else {
35348c2ecf20Sopenharmony_ci		if (!f2fs_is_valid_blkaddr(sbi, blkaddr,
35358c2ecf20Sopenharmony_ci				DATA_GENERIC_ENHANCE_READ)) {
35368c2ecf20Sopenharmony_ci			err = -EFSCORRUPTED;
35378c2ecf20Sopenharmony_ci			goto fail;
35388c2ecf20Sopenharmony_ci		}
35398c2ecf20Sopenharmony_ci		err = f2fs_submit_page_read(inode, page, blkaddr, 0, true);
35408c2ecf20Sopenharmony_ci		if (err)
35418c2ecf20Sopenharmony_ci			goto fail;
35428c2ecf20Sopenharmony_ci
35438c2ecf20Sopenharmony_ci		lock_page(page);
35448c2ecf20Sopenharmony_ci		if (unlikely(page->mapping != mapping)) {
35458c2ecf20Sopenharmony_ci			f2fs_put_page(page, 1);
35468c2ecf20Sopenharmony_ci			goto repeat;
35478c2ecf20Sopenharmony_ci		}
35488c2ecf20Sopenharmony_ci		if (unlikely(!PageUptodate(page))) {
35498c2ecf20Sopenharmony_ci			err = -EIO;
35508c2ecf20Sopenharmony_ci			goto fail;
35518c2ecf20Sopenharmony_ci		}
35528c2ecf20Sopenharmony_ci	}
35538c2ecf20Sopenharmony_ci	return 0;
35548c2ecf20Sopenharmony_ci
35558c2ecf20Sopenharmony_cifail:
35568c2ecf20Sopenharmony_ci	f2fs_put_page(page, 1);
35578c2ecf20Sopenharmony_ci	f2fs_write_failed(mapping, pos + len);
35588c2ecf20Sopenharmony_ci	if (drop_atomic)
35598c2ecf20Sopenharmony_ci		f2fs_drop_inmem_pages_all(sbi, false);
35608c2ecf20Sopenharmony_ci	return err;
35618c2ecf20Sopenharmony_ci}
35628c2ecf20Sopenharmony_ci
35638c2ecf20Sopenharmony_cistatic int f2fs_write_end(struct file *file,
35648c2ecf20Sopenharmony_ci			struct address_space *mapping,
35658c2ecf20Sopenharmony_ci			loff_t pos, unsigned len, unsigned copied,
35668c2ecf20Sopenharmony_ci			struct page *page, void *fsdata)
35678c2ecf20Sopenharmony_ci{
35688c2ecf20Sopenharmony_ci	struct inode *inode = page->mapping->host;
35698c2ecf20Sopenharmony_ci
35708c2ecf20Sopenharmony_ci	trace_f2fs_write_end(inode, pos, len, copied);
35718c2ecf20Sopenharmony_ci
35728c2ecf20Sopenharmony_ci	/*
35738c2ecf20Sopenharmony_ci	 * This should be come from len == PAGE_SIZE, and we expect copied
35748c2ecf20Sopenharmony_ci	 * should be PAGE_SIZE. Otherwise, we treat it with zero copied and
35758c2ecf20Sopenharmony_ci	 * let generic_perform_write() try to copy data again through copied=0.
35768c2ecf20Sopenharmony_ci	 */
35778c2ecf20Sopenharmony_ci	if (!PageUptodate(page)) {
35788c2ecf20Sopenharmony_ci		if (unlikely(copied != len))
35798c2ecf20Sopenharmony_ci			copied = 0;
35808c2ecf20Sopenharmony_ci		else
35818c2ecf20Sopenharmony_ci			SetPageUptodate(page);
35828c2ecf20Sopenharmony_ci	}
35838c2ecf20Sopenharmony_ci
35848c2ecf20Sopenharmony_ci#ifdef CONFIG_F2FS_FS_COMPRESSION
35858c2ecf20Sopenharmony_ci	/* overwrite compressed file */
35868c2ecf20Sopenharmony_ci	if (f2fs_compressed_file(inode) && fsdata) {
35878c2ecf20Sopenharmony_ci		f2fs_compress_write_end(inode, fsdata, page->index, copied);
35888c2ecf20Sopenharmony_ci		f2fs_update_time(F2FS_I_SB(inode), REQ_TIME);
35898c2ecf20Sopenharmony_ci
35908c2ecf20Sopenharmony_ci		if (pos + copied > i_size_read(inode) &&
35918c2ecf20Sopenharmony_ci				!f2fs_verity_in_progress(inode))
35928c2ecf20Sopenharmony_ci			f2fs_i_size_write(inode, pos + copied);
35938c2ecf20Sopenharmony_ci		return copied;
35948c2ecf20Sopenharmony_ci	}
35958c2ecf20Sopenharmony_ci#endif
35968c2ecf20Sopenharmony_ci
35978c2ecf20Sopenharmony_ci	if (!copied)
35988c2ecf20Sopenharmony_ci		goto unlock_out;
35998c2ecf20Sopenharmony_ci
36008c2ecf20Sopenharmony_ci	set_page_dirty(page);
36018c2ecf20Sopenharmony_ci
36028c2ecf20Sopenharmony_ci	if (pos + copied > i_size_read(inode) &&
36038c2ecf20Sopenharmony_ci	    !f2fs_verity_in_progress(inode))
36048c2ecf20Sopenharmony_ci		f2fs_i_size_write(inode, pos + copied);
36058c2ecf20Sopenharmony_ciunlock_out:
36068c2ecf20Sopenharmony_ci	f2fs_put_page(page, 1);
36078c2ecf20Sopenharmony_ci	f2fs_update_time(F2FS_I_SB(inode), REQ_TIME);
36088c2ecf20Sopenharmony_ci	return copied;
36098c2ecf20Sopenharmony_ci}
36108c2ecf20Sopenharmony_ci
36118c2ecf20Sopenharmony_cistatic int check_direct_IO(struct inode *inode, struct iov_iter *iter,
36128c2ecf20Sopenharmony_ci			   loff_t offset)
36138c2ecf20Sopenharmony_ci{
36148c2ecf20Sopenharmony_ci	unsigned i_blkbits = READ_ONCE(inode->i_blkbits);
36158c2ecf20Sopenharmony_ci	unsigned blkbits = i_blkbits;
36168c2ecf20Sopenharmony_ci	unsigned blocksize_mask = (1 << blkbits) - 1;
36178c2ecf20Sopenharmony_ci	unsigned long align = offset | iov_iter_alignment(iter);
36188c2ecf20Sopenharmony_ci	struct block_device *bdev = inode->i_sb->s_bdev;
36198c2ecf20Sopenharmony_ci
36208c2ecf20Sopenharmony_ci	if (iov_iter_rw(iter) == READ && offset >= i_size_read(inode))
36218c2ecf20Sopenharmony_ci		return 1;
36228c2ecf20Sopenharmony_ci
36238c2ecf20Sopenharmony_ci	if (align & blocksize_mask) {
36248c2ecf20Sopenharmony_ci		if (bdev)
36258c2ecf20Sopenharmony_ci			blkbits = blksize_bits(bdev_logical_block_size(bdev));
36268c2ecf20Sopenharmony_ci		blocksize_mask = (1 << blkbits) - 1;
36278c2ecf20Sopenharmony_ci		if (align & blocksize_mask)
36288c2ecf20Sopenharmony_ci			return -EINVAL;
36298c2ecf20Sopenharmony_ci		return 1;
36308c2ecf20Sopenharmony_ci	}
36318c2ecf20Sopenharmony_ci	return 0;
36328c2ecf20Sopenharmony_ci}
36338c2ecf20Sopenharmony_ci
36348c2ecf20Sopenharmony_cistatic void f2fs_dio_end_io(struct bio *bio)
36358c2ecf20Sopenharmony_ci{
36368c2ecf20Sopenharmony_ci	struct f2fs_private_dio *dio = bio->bi_private;
36378c2ecf20Sopenharmony_ci
36388c2ecf20Sopenharmony_ci	dec_page_count(F2FS_I_SB(dio->inode),
36398c2ecf20Sopenharmony_ci			dio->write ? F2FS_DIO_WRITE : F2FS_DIO_READ);
36408c2ecf20Sopenharmony_ci
36418c2ecf20Sopenharmony_ci	bio->bi_private = dio->orig_private;
36428c2ecf20Sopenharmony_ci	bio->bi_end_io = dio->orig_end_io;
36438c2ecf20Sopenharmony_ci
36448c2ecf20Sopenharmony_ci	kfree(dio);
36458c2ecf20Sopenharmony_ci
36468c2ecf20Sopenharmony_ci	bio_endio(bio);
36478c2ecf20Sopenharmony_ci}
36488c2ecf20Sopenharmony_ci
36498c2ecf20Sopenharmony_cistatic void f2fs_dio_submit_bio(struct bio *bio, struct inode *inode,
36508c2ecf20Sopenharmony_ci							loff_t file_offset)
36518c2ecf20Sopenharmony_ci{
36528c2ecf20Sopenharmony_ci	struct f2fs_private_dio *dio;
36538c2ecf20Sopenharmony_ci	bool write = (bio_op(bio) == REQ_OP_WRITE);
36548c2ecf20Sopenharmony_ci
36558c2ecf20Sopenharmony_ci	dio = f2fs_kzalloc(F2FS_I_SB(inode),
36568c2ecf20Sopenharmony_ci			sizeof(struct f2fs_private_dio), GFP_NOFS);
36578c2ecf20Sopenharmony_ci	if (!dio)
36588c2ecf20Sopenharmony_ci		goto out;
36598c2ecf20Sopenharmony_ci
36608c2ecf20Sopenharmony_ci	dio->inode = inode;
36618c2ecf20Sopenharmony_ci	dio->orig_end_io = bio->bi_end_io;
36628c2ecf20Sopenharmony_ci	dio->orig_private = bio->bi_private;
36638c2ecf20Sopenharmony_ci	dio->write = write;
36648c2ecf20Sopenharmony_ci
36658c2ecf20Sopenharmony_ci	bio->bi_end_io = f2fs_dio_end_io;
36668c2ecf20Sopenharmony_ci	bio->bi_private = dio;
36678c2ecf20Sopenharmony_ci
36688c2ecf20Sopenharmony_ci	inc_page_count(F2FS_I_SB(inode),
36698c2ecf20Sopenharmony_ci			write ? F2FS_DIO_WRITE : F2FS_DIO_READ);
36708c2ecf20Sopenharmony_ci
36718c2ecf20Sopenharmony_ci	submit_bio(bio);
36728c2ecf20Sopenharmony_ci	return;
36738c2ecf20Sopenharmony_ciout:
36748c2ecf20Sopenharmony_ci	bio->bi_status = BLK_STS_IOERR;
36758c2ecf20Sopenharmony_ci	bio_endio(bio);
36768c2ecf20Sopenharmony_ci}
36778c2ecf20Sopenharmony_ci
36788c2ecf20Sopenharmony_cistatic ssize_t f2fs_direct_IO(struct kiocb *iocb, struct iov_iter *iter)
36798c2ecf20Sopenharmony_ci{
36808c2ecf20Sopenharmony_ci	struct address_space *mapping = iocb->ki_filp->f_mapping;
36818c2ecf20Sopenharmony_ci	struct inode *inode = mapping->host;
36828c2ecf20Sopenharmony_ci	struct f2fs_sb_info *sbi = F2FS_I_SB(inode);
36838c2ecf20Sopenharmony_ci	struct f2fs_inode_info *fi = F2FS_I(inode);
36848c2ecf20Sopenharmony_ci	size_t count = iov_iter_count(iter);
36858c2ecf20Sopenharmony_ci	loff_t offset = iocb->ki_pos;
36868c2ecf20Sopenharmony_ci	int rw = iov_iter_rw(iter);
36878c2ecf20Sopenharmony_ci	int err;
36888c2ecf20Sopenharmony_ci	enum rw_hint hint = iocb->ki_hint;
36898c2ecf20Sopenharmony_ci	int whint_mode = F2FS_OPTION(sbi).whint_mode;
36908c2ecf20Sopenharmony_ci	bool do_opu;
36918c2ecf20Sopenharmony_ci
36928c2ecf20Sopenharmony_ci	err = check_direct_IO(inode, iter, offset);
36938c2ecf20Sopenharmony_ci	if (err)
36948c2ecf20Sopenharmony_ci		return err < 0 ? err : 0;
36958c2ecf20Sopenharmony_ci
36968c2ecf20Sopenharmony_ci	if (f2fs_force_buffered_io(inode, iocb, iter))
36978c2ecf20Sopenharmony_ci		return 0;
36988c2ecf20Sopenharmony_ci
36998c2ecf20Sopenharmony_ci	do_opu = allow_outplace_dio(inode, iocb, iter);
37008c2ecf20Sopenharmony_ci
37018c2ecf20Sopenharmony_ci	trace_f2fs_direct_IO_enter(inode, offset, count, rw);
37028c2ecf20Sopenharmony_ci
37038c2ecf20Sopenharmony_ci	if (rw == WRITE && whint_mode == WHINT_MODE_OFF)
37048c2ecf20Sopenharmony_ci		iocb->ki_hint = WRITE_LIFE_NOT_SET;
37058c2ecf20Sopenharmony_ci
37068c2ecf20Sopenharmony_ci	if (iocb->ki_flags & IOCB_NOWAIT) {
37078c2ecf20Sopenharmony_ci		if (!down_read_trylock(&fi->i_gc_rwsem[rw])) {
37088c2ecf20Sopenharmony_ci			iocb->ki_hint = hint;
37098c2ecf20Sopenharmony_ci			err = -EAGAIN;
37108c2ecf20Sopenharmony_ci			goto out;
37118c2ecf20Sopenharmony_ci		}
37128c2ecf20Sopenharmony_ci		if (do_opu && !down_read_trylock(&fi->i_gc_rwsem[READ])) {
37138c2ecf20Sopenharmony_ci			up_read(&fi->i_gc_rwsem[rw]);
37148c2ecf20Sopenharmony_ci			iocb->ki_hint = hint;
37158c2ecf20Sopenharmony_ci			err = -EAGAIN;
37168c2ecf20Sopenharmony_ci			goto out;
37178c2ecf20Sopenharmony_ci		}
37188c2ecf20Sopenharmony_ci	} else {
37198c2ecf20Sopenharmony_ci		down_read(&fi->i_gc_rwsem[rw]);
37208c2ecf20Sopenharmony_ci		if (do_opu)
37218c2ecf20Sopenharmony_ci			down_read(&fi->i_gc_rwsem[READ]);
37228c2ecf20Sopenharmony_ci	}
37238c2ecf20Sopenharmony_ci
37248c2ecf20Sopenharmony_ci	err = __blockdev_direct_IO(iocb, inode, inode->i_sb->s_bdev,
37258c2ecf20Sopenharmony_ci			iter, rw == WRITE ? get_data_block_dio_write :
37268c2ecf20Sopenharmony_ci			get_data_block_dio, NULL, f2fs_dio_submit_bio,
37278c2ecf20Sopenharmony_ci			rw == WRITE ? DIO_LOCKING | DIO_SKIP_HOLES :
37288c2ecf20Sopenharmony_ci			DIO_SKIP_HOLES);
37298c2ecf20Sopenharmony_ci
37308c2ecf20Sopenharmony_ci	if (do_opu)
37318c2ecf20Sopenharmony_ci		up_read(&fi->i_gc_rwsem[READ]);
37328c2ecf20Sopenharmony_ci
37338c2ecf20Sopenharmony_ci	up_read(&fi->i_gc_rwsem[rw]);
37348c2ecf20Sopenharmony_ci
37358c2ecf20Sopenharmony_ci	if (rw == WRITE) {
37368c2ecf20Sopenharmony_ci		if (whint_mode == WHINT_MODE_OFF)
37378c2ecf20Sopenharmony_ci			iocb->ki_hint = hint;
37388c2ecf20Sopenharmony_ci		if (err > 0) {
37398c2ecf20Sopenharmony_ci			f2fs_update_iostat(F2FS_I_SB(inode), APP_DIRECT_IO,
37408c2ecf20Sopenharmony_ci									err);
37418c2ecf20Sopenharmony_ci			if (!do_opu)
37428c2ecf20Sopenharmony_ci				set_inode_flag(inode, FI_UPDATE_WRITE);
37438c2ecf20Sopenharmony_ci		} else if (err == -EIOCBQUEUED) {
37448c2ecf20Sopenharmony_ci			f2fs_update_iostat(F2FS_I_SB(inode), APP_DIRECT_IO,
37458c2ecf20Sopenharmony_ci						count - iov_iter_count(iter));
37468c2ecf20Sopenharmony_ci		} else if (err < 0) {
37478c2ecf20Sopenharmony_ci			f2fs_write_failed(mapping, offset + count);
37488c2ecf20Sopenharmony_ci		}
37498c2ecf20Sopenharmony_ci	} else {
37508c2ecf20Sopenharmony_ci		if (err > 0)
37518c2ecf20Sopenharmony_ci			f2fs_update_iostat(sbi, APP_DIRECT_READ_IO, err);
37528c2ecf20Sopenharmony_ci		else if (err == -EIOCBQUEUED)
37538c2ecf20Sopenharmony_ci			f2fs_update_iostat(F2FS_I_SB(inode), APP_DIRECT_READ_IO,
37548c2ecf20Sopenharmony_ci						count - iov_iter_count(iter));
37558c2ecf20Sopenharmony_ci	}
37568c2ecf20Sopenharmony_ci
37578c2ecf20Sopenharmony_ciout:
37588c2ecf20Sopenharmony_ci	trace_f2fs_direct_IO_exit(inode, offset, count, rw, err);
37598c2ecf20Sopenharmony_ci
37608c2ecf20Sopenharmony_ci	return err;
37618c2ecf20Sopenharmony_ci}
37628c2ecf20Sopenharmony_ci
37638c2ecf20Sopenharmony_civoid f2fs_invalidate_page(struct page *page, unsigned int offset,
37648c2ecf20Sopenharmony_ci							unsigned int length)
37658c2ecf20Sopenharmony_ci{
37668c2ecf20Sopenharmony_ci	struct inode *inode = page->mapping->host;
37678c2ecf20Sopenharmony_ci	struct f2fs_sb_info *sbi = F2FS_I_SB(inode);
37688c2ecf20Sopenharmony_ci
37698c2ecf20Sopenharmony_ci	if (inode->i_ino >= F2FS_ROOT_INO(sbi) &&
37708c2ecf20Sopenharmony_ci		(offset % PAGE_SIZE || length != PAGE_SIZE))
37718c2ecf20Sopenharmony_ci		return;
37728c2ecf20Sopenharmony_ci
37738c2ecf20Sopenharmony_ci	if (PageDirty(page)) {
37748c2ecf20Sopenharmony_ci		if (inode->i_ino == F2FS_META_INO(sbi)) {
37758c2ecf20Sopenharmony_ci			dec_page_count(sbi, F2FS_DIRTY_META);
37768c2ecf20Sopenharmony_ci		} else if (inode->i_ino == F2FS_NODE_INO(sbi)) {
37778c2ecf20Sopenharmony_ci			dec_page_count(sbi, F2FS_DIRTY_NODES);
37788c2ecf20Sopenharmony_ci		} else {
37798c2ecf20Sopenharmony_ci			inode_dec_dirty_pages(inode);
37808c2ecf20Sopenharmony_ci			f2fs_remove_dirty_inode(inode);
37818c2ecf20Sopenharmony_ci		}
37828c2ecf20Sopenharmony_ci	}
37838c2ecf20Sopenharmony_ci
37848c2ecf20Sopenharmony_ci	clear_cold_data(page);
37858c2ecf20Sopenharmony_ci
37868c2ecf20Sopenharmony_ci	if (IS_ATOMIC_WRITTEN_PAGE(page))
37878c2ecf20Sopenharmony_ci		return f2fs_drop_inmem_page(inode, page);
37888c2ecf20Sopenharmony_ci
37898c2ecf20Sopenharmony_ci	f2fs_clear_page_private(page);
37908c2ecf20Sopenharmony_ci}
37918c2ecf20Sopenharmony_ci
37928c2ecf20Sopenharmony_ciint f2fs_release_page(struct page *page, gfp_t wait)
37938c2ecf20Sopenharmony_ci{
37948c2ecf20Sopenharmony_ci	/* If this is dirty page, keep PagePrivate */
37958c2ecf20Sopenharmony_ci	if (PageDirty(page))
37968c2ecf20Sopenharmony_ci		return 0;
37978c2ecf20Sopenharmony_ci
37988c2ecf20Sopenharmony_ci	/* This is atomic written page, keep Private */
37998c2ecf20Sopenharmony_ci	if (IS_ATOMIC_WRITTEN_PAGE(page))
38008c2ecf20Sopenharmony_ci		return 0;
38018c2ecf20Sopenharmony_ci
38028c2ecf20Sopenharmony_ci	clear_cold_data(page);
38038c2ecf20Sopenharmony_ci	f2fs_clear_page_private(page);
38048c2ecf20Sopenharmony_ci	return 1;
38058c2ecf20Sopenharmony_ci}
38068c2ecf20Sopenharmony_ci
38078c2ecf20Sopenharmony_cistatic int f2fs_set_data_page_dirty(struct page *page)
38088c2ecf20Sopenharmony_ci{
38098c2ecf20Sopenharmony_ci	struct inode *inode = page_file_mapping(page)->host;
38108c2ecf20Sopenharmony_ci
38118c2ecf20Sopenharmony_ci	trace_f2fs_set_page_dirty(page, DATA);
38128c2ecf20Sopenharmony_ci
38138c2ecf20Sopenharmony_ci	if (!PageUptodate(page))
38148c2ecf20Sopenharmony_ci		SetPageUptodate(page);
38158c2ecf20Sopenharmony_ci	if (PageSwapCache(page))
38168c2ecf20Sopenharmony_ci		return __set_page_dirty_nobuffers(page);
38178c2ecf20Sopenharmony_ci
38188c2ecf20Sopenharmony_ci	if (f2fs_is_atomic_file(inode) && !f2fs_is_commit_atomic_write(inode)) {
38198c2ecf20Sopenharmony_ci		if (!IS_ATOMIC_WRITTEN_PAGE(page)) {
38208c2ecf20Sopenharmony_ci			f2fs_register_inmem_page(inode, page);
38218c2ecf20Sopenharmony_ci			return 1;
38228c2ecf20Sopenharmony_ci		}
38238c2ecf20Sopenharmony_ci		/*
38248c2ecf20Sopenharmony_ci		 * Previously, this page has been registered, we just
38258c2ecf20Sopenharmony_ci		 * return here.
38268c2ecf20Sopenharmony_ci		 */
38278c2ecf20Sopenharmony_ci		return 0;
38288c2ecf20Sopenharmony_ci	}
38298c2ecf20Sopenharmony_ci
38308c2ecf20Sopenharmony_ci	if (!PageDirty(page)) {
38318c2ecf20Sopenharmony_ci		__set_page_dirty_nobuffers(page);
38328c2ecf20Sopenharmony_ci		f2fs_update_dirty_page(inode, page);
38338c2ecf20Sopenharmony_ci		return 1;
38348c2ecf20Sopenharmony_ci	}
38358c2ecf20Sopenharmony_ci	return 0;
38368c2ecf20Sopenharmony_ci}
38378c2ecf20Sopenharmony_ci
38388c2ecf20Sopenharmony_ci
38398c2ecf20Sopenharmony_cistatic sector_t f2fs_bmap_compress(struct inode *inode, sector_t block)
38408c2ecf20Sopenharmony_ci{
38418c2ecf20Sopenharmony_ci#ifdef CONFIG_F2FS_FS_COMPRESSION
38428c2ecf20Sopenharmony_ci	struct dnode_of_data dn;
38438c2ecf20Sopenharmony_ci	sector_t start_idx, blknr = 0;
38448c2ecf20Sopenharmony_ci	int ret;
38458c2ecf20Sopenharmony_ci
38468c2ecf20Sopenharmony_ci	start_idx = round_down(block, F2FS_I(inode)->i_cluster_size);
38478c2ecf20Sopenharmony_ci
38488c2ecf20Sopenharmony_ci	set_new_dnode(&dn, inode, NULL, NULL, 0);
38498c2ecf20Sopenharmony_ci	ret = f2fs_get_dnode_of_data(&dn, start_idx, LOOKUP_NODE);
38508c2ecf20Sopenharmony_ci	if (ret)
38518c2ecf20Sopenharmony_ci		return 0;
38528c2ecf20Sopenharmony_ci
38538c2ecf20Sopenharmony_ci	if (dn.data_blkaddr != COMPRESS_ADDR) {
38548c2ecf20Sopenharmony_ci		dn.ofs_in_node += block - start_idx;
38558c2ecf20Sopenharmony_ci		blknr = f2fs_data_blkaddr(&dn);
38568c2ecf20Sopenharmony_ci		if (!__is_valid_data_blkaddr(blknr))
38578c2ecf20Sopenharmony_ci			blknr = 0;
38588c2ecf20Sopenharmony_ci	}
38598c2ecf20Sopenharmony_ci
38608c2ecf20Sopenharmony_ci	f2fs_put_dnode(&dn);
38618c2ecf20Sopenharmony_ci	return blknr;
38628c2ecf20Sopenharmony_ci#else
38638c2ecf20Sopenharmony_ci	return 0;
38648c2ecf20Sopenharmony_ci#endif
38658c2ecf20Sopenharmony_ci}
38668c2ecf20Sopenharmony_ci
38678c2ecf20Sopenharmony_ci
38688c2ecf20Sopenharmony_cistatic sector_t f2fs_bmap(struct address_space *mapping, sector_t block)
38698c2ecf20Sopenharmony_ci{
38708c2ecf20Sopenharmony_ci	struct inode *inode = mapping->host;
38718c2ecf20Sopenharmony_ci	struct buffer_head tmp = {
38728c2ecf20Sopenharmony_ci		.b_size = i_blocksize(inode),
38738c2ecf20Sopenharmony_ci	};
38748c2ecf20Sopenharmony_ci	sector_t blknr = 0;
38758c2ecf20Sopenharmony_ci
38768c2ecf20Sopenharmony_ci	if (f2fs_has_inline_data(inode))
38778c2ecf20Sopenharmony_ci		goto out;
38788c2ecf20Sopenharmony_ci
38798c2ecf20Sopenharmony_ci	/* make sure allocating whole blocks */
38808c2ecf20Sopenharmony_ci	if (mapping_tagged(mapping, PAGECACHE_TAG_DIRTY))
38818c2ecf20Sopenharmony_ci		filemap_write_and_wait(mapping);
38828c2ecf20Sopenharmony_ci
38838c2ecf20Sopenharmony_ci	/* Block number less than F2FS MAX BLOCKS */
38848c2ecf20Sopenharmony_ci	if (unlikely(block >= F2FS_I_SB(inode)->max_file_blocks))
38858c2ecf20Sopenharmony_ci		goto out;
38868c2ecf20Sopenharmony_ci
38878c2ecf20Sopenharmony_ci	if (f2fs_compressed_file(inode)) {
38888c2ecf20Sopenharmony_ci		blknr = f2fs_bmap_compress(inode, block);
38898c2ecf20Sopenharmony_ci	} else {
38908c2ecf20Sopenharmony_ci		if (!get_data_block_bmap(inode, block, &tmp, 0))
38918c2ecf20Sopenharmony_ci			blknr = tmp.b_blocknr;
38928c2ecf20Sopenharmony_ci	}
38938c2ecf20Sopenharmony_ciout:
38948c2ecf20Sopenharmony_ci	trace_f2fs_bmap(inode, block, blknr);
38958c2ecf20Sopenharmony_ci	return blknr;
38968c2ecf20Sopenharmony_ci}
38978c2ecf20Sopenharmony_ci
38988c2ecf20Sopenharmony_ci#ifdef CONFIG_MIGRATION
38998c2ecf20Sopenharmony_ci#include <linux/migrate.h>
39008c2ecf20Sopenharmony_ci
39018c2ecf20Sopenharmony_ciint f2fs_migrate_page(struct address_space *mapping,
39028c2ecf20Sopenharmony_ci		struct page *newpage, struct page *page, enum migrate_mode mode)
39038c2ecf20Sopenharmony_ci{
39048c2ecf20Sopenharmony_ci	int rc, extra_count;
39058c2ecf20Sopenharmony_ci	struct f2fs_inode_info *fi = F2FS_I(mapping->host);
39068c2ecf20Sopenharmony_ci	bool atomic_written = IS_ATOMIC_WRITTEN_PAGE(page);
39078c2ecf20Sopenharmony_ci
39088c2ecf20Sopenharmony_ci	BUG_ON(PageWriteback(page));
39098c2ecf20Sopenharmony_ci
39108c2ecf20Sopenharmony_ci	/* migrating an atomic written page is safe with the inmem_lock hold */
39118c2ecf20Sopenharmony_ci	if (atomic_written) {
39128c2ecf20Sopenharmony_ci		if (mode != MIGRATE_SYNC)
39138c2ecf20Sopenharmony_ci			return -EBUSY;
39148c2ecf20Sopenharmony_ci		if (!mutex_trylock(&fi->inmem_lock))
39158c2ecf20Sopenharmony_ci			return -EAGAIN;
39168c2ecf20Sopenharmony_ci	}
39178c2ecf20Sopenharmony_ci
39188c2ecf20Sopenharmony_ci	/* one extra reference was held for atomic_write page */
39198c2ecf20Sopenharmony_ci	extra_count = atomic_written ? 1 : 0;
39208c2ecf20Sopenharmony_ci	rc = migrate_page_move_mapping(mapping, newpage,
39218c2ecf20Sopenharmony_ci				page, extra_count);
39228c2ecf20Sopenharmony_ci	if (rc != MIGRATEPAGE_SUCCESS) {
39238c2ecf20Sopenharmony_ci		if (atomic_written)
39248c2ecf20Sopenharmony_ci			mutex_unlock(&fi->inmem_lock);
39258c2ecf20Sopenharmony_ci		return rc;
39268c2ecf20Sopenharmony_ci	}
39278c2ecf20Sopenharmony_ci
39288c2ecf20Sopenharmony_ci	if (atomic_written) {
39298c2ecf20Sopenharmony_ci		struct inmem_pages *cur;
39308c2ecf20Sopenharmony_ci		list_for_each_entry(cur, &fi->inmem_pages, list)
39318c2ecf20Sopenharmony_ci			if (cur->page == page) {
39328c2ecf20Sopenharmony_ci				cur->page = newpage;
39338c2ecf20Sopenharmony_ci				break;
39348c2ecf20Sopenharmony_ci			}
39358c2ecf20Sopenharmony_ci		mutex_unlock(&fi->inmem_lock);
39368c2ecf20Sopenharmony_ci		put_page(page);
39378c2ecf20Sopenharmony_ci		get_page(newpage);
39388c2ecf20Sopenharmony_ci	}
39398c2ecf20Sopenharmony_ci
39408c2ecf20Sopenharmony_ci	if (PagePrivate(page)) {
39418c2ecf20Sopenharmony_ci		f2fs_set_page_private(newpage, page_private(page));
39428c2ecf20Sopenharmony_ci		f2fs_clear_page_private(page);
39438c2ecf20Sopenharmony_ci	}
39448c2ecf20Sopenharmony_ci
39458c2ecf20Sopenharmony_ci	if (mode != MIGRATE_SYNC_NO_COPY)
39468c2ecf20Sopenharmony_ci		migrate_page_copy(newpage, page);
39478c2ecf20Sopenharmony_ci	else
39488c2ecf20Sopenharmony_ci		migrate_page_states(newpage, page);
39498c2ecf20Sopenharmony_ci
39508c2ecf20Sopenharmony_ci	return MIGRATEPAGE_SUCCESS;
39518c2ecf20Sopenharmony_ci}
39528c2ecf20Sopenharmony_ci#endif
39538c2ecf20Sopenharmony_ci
39548c2ecf20Sopenharmony_ci#ifdef CONFIG_SWAP
39558c2ecf20Sopenharmony_cistatic int check_swap_activate_fast(struct swap_info_struct *sis,
39568c2ecf20Sopenharmony_ci				struct file *swap_file, sector_t *span)
39578c2ecf20Sopenharmony_ci{
39588c2ecf20Sopenharmony_ci	struct address_space *mapping = swap_file->f_mapping;
39598c2ecf20Sopenharmony_ci	struct inode *inode = mapping->host;
39608c2ecf20Sopenharmony_ci	sector_t cur_lblock;
39618c2ecf20Sopenharmony_ci	sector_t last_lblock;
39628c2ecf20Sopenharmony_ci	sector_t pblock;
39638c2ecf20Sopenharmony_ci	sector_t lowest_pblock = -1;
39648c2ecf20Sopenharmony_ci	sector_t highest_pblock = 0;
39658c2ecf20Sopenharmony_ci	int nr_extents = 0;
39668c2ecf20Sopenharmony_ci	unsigned long nr_pblocks;
39678c2ecf20Sopenharmony_ci	unsigned long len;
39688c2ecf20Sopenharmony_ci	int ret;
39698c2ecf20Sopenharmony_ci
39708c2ecf20Sopenharmony_ci	/*
39718c2ecf20Sopenharmony_ci	 * Map all the blocks into the extent list.  This code doesn't try
39728c2ecf20Sopenharmony_ci	 * to be very smart.
39738c2ecf20Sopenharmony_ci	 */
39748c2ecf20Sopenharmony_ci	cur_lblock = 0;
39758c2ecf20Sopenharmony_ci	last_lblock = logical_to_blk(inode, i_size_read(inode));
39768c2ecf20Sopenharmony_ci	len = i_size_read(inode);
39778c2ecf20Sopenharmony_ci
39788c2ecf20Sopenharmony_ci	while (cur_lblock <= last_lblock && cur_lblock < sis->max) {
39798c2ecf20Sopenharmony_ci		struct buffer_head map_bh;
39808c2ecf20Sopenharmony_ci		pgoff_t next_pgofs;
39818c2ecf20Sopenharmony_ci
39828c2ecf20Sopenharmony_ci		cond_resched();
39838c2ecf20Sopenharmony_ci
39848c2ecf20Sopenharmony_ci		memset(&map_bh, 0, sizeof(struct buffer_head));
39858c2ecf20Sopenharmony_ci		map_bh.b_size = len - cur_lblock;
39868c2ecf20Sopenharmony_ci
39878c2ecf20Sopenharmony_ci		ret = get_data_block(inode, cur_lblock, &map_bh, 0,
39888c2ecf20Sopenharmony_ci					F2FS_GET_BLOCK_FIEMAP, &next_pgofs);
39898c2ecf20Sopenharmony_ci		if (ret)
39908c2ecf20Sopenharmony_ci			goto err_out;
39918c2ecf20Sopenharmony_ci
39928c2ecf20Sopenharmony_ci		/* hole */
39938c2ecf20Sopenharmony_ci		if (!buffer_mapped(&map_bh))
39948c2ecf20Sopenharmony_ci			goto err_out;
39958c2ecf20Sopenharmony_ci
39968c2ecf20Sopenharmony_ci		pblock = map_bh.b_blocknr;
39978c2ecf20Sopenharmony_ci		nr_pblocks = logical_to_blk(inode, map_bh.b_size);
39988c2ecf20Sopenharmony_ci
39998c2ecf20Sopenharmony_ci		if (cur_lblock + nr_pblocks >= sis->max)
40008c2ecf20Sopenharmony_ci			nr_pblocks = sis->max - cur_lblock;
40018c2ecf20Sopenharmony_ci
40028c2ecf20Sopenharmony_ci		if (cur_lblock) {	/* exclude the header page */
40038c2ecf20Sopenharmony_ci			if (pblock < lowest_pblock)
40048c2ecf20Sopenharmony_ci				lowest_pblock = pblock;
40058c2ecf20Sopenharmony_ci			if (pblock + nr_pblocks - 1 > highest_pblock)
40068c2ecf20Sopenharmony_ci				highest_pblock = pblock + nr_pblocks - 1;
40078c2ecf20Sopenharmony_ci		}
40088c2ecf20Sopenharmony_ci
40098c2ecf20Sopenharmony_ci		/*
40108c2ecf20Sopenharmony_ci		 * We found a PAGE_SIZE-length, PAGE_SIZE-aligned run of blocks
40118c2ecf20Sopenharmony_ci		 */
40128c2ecf20Sopenharmony_ci		ret = add_swap_extent(sis, cur_lblock, nr_pblocks, pblock);
40138c2ecf20Sopenharmony_ci		if (ret < 0)
40148c2ecf20Sopenharmony_ci			goto out;
40158c2ecf20Sopenharmony_ci		nr_extents += ret;
40168c2ecf20Sopenharmony_ci		cur_lblock += nr_pblocks;
40178c2ecf20Sopenharmony_ci	}
40188c2ecf20Sopenharmony_ci	ret = nr_extents;
40198c2ecf20Sopenharmony_ci	*span = 1 + highest_pblock - lowest_pblock;
40208c2ecf20Sopenharmony_ci	if (cur_lblock == 0)
40218c2ecf20Sopenharmony_ci		cur_lblock = 1;	/* force Empty message */
40228c2ecf20Sopenharmony_ci	sis->max = cur_lblock;
40238c2ecf20Sopenharmony_ci	sis->pages = cur_lblock - 1;
40248c2ecf20Sopenharmony_ci	sis->highest_bit = cur_lblock - 1;
40258c2ecf20Sopenharmony_ciout:
40268c2ecf20Sopenharmony_ci	return ret;
40278c2ecf20Sopenharmony_cierr_out:
40288c2ecf20Sopenharmony_ci	pr_err("swapon: swapfile has holes\n");
40298c2ecf20Sopenharmony_ci	return -EINVAL;
40308c2ecf20Sopenharmony_ci}
40318c2ecf20Sopenharmony_ci
40328c2ecf20Sopenharmony_ci/* Copied from generic_swapfile_activate() to check any holes */
40338c2ecf20Sopenharmony_cistatic int check_swap_activate(struct swap_info_struct *sis,
40348c2ecf20Sopenharmony_ci				struct file *swap_file, sector_t *span)
40358c2ecf20Sopenharmony_ci{
40368c2ecf20Sopenharmony_ci	struct address_space *mapping = swap_file->f_mapping;
40378c2ecf20Sopenharmony_ci	struct inode *inode = mapping->host;
40388c2ecf20Sopenharmony_ci	unsigned blocks_per_page;
40398c2ecf20Sopenharmony_ci	unsigned long page_no;
40408c2ecf20Sopenharmony_ci	unsigned blkbits;
40418c2ecf20Sopenharmony_ci	sector_t probe_block;
40428c2ecf20Sopenharmony_ci	sector_t last_block;
40438c2ecf20Sopenharmony_ci	sector_t lowest_block = -1;
40448c2ecf20Sopenharmony_ci	sector_t highest_block = 0;
40458c2ecf20Sopenharmony_ci	int nr_extents = 0;
40468c2ecf20Sopenharmony_ci	int ret;
40478c2ecf20Sopenharmony_ci
40488c2ecf20Sopenharmony_ci	if (PAGE_SIZE == F2FS_BLKSIZE)
40498c2ecf20Sopenharmony_ci		return check_swap_activate_fast(sis, swap_file, span);
40508c2ecf20Sopenharmony_ci
40518c2ecf20Sopenharmony_ci	blkbits = inode->i_blkbits;
40528c2ecf20Sopenharmony_ci	blocks_per_page = PAGE_SIZE >> blkbits;
40538c2ecf20Sopenharmony_ci
40548c2ecf20Sopenharmony_ci	/*
40558c2ecf20Sopenharmony_ci	 * Map all the blocks into the extent list.  This code doesn't try
40568c2ecf20Sopenharmony_ci	 * to be very smart.
40578c2ecf20Sopenharmony_ci	 */
40588c2ecf20Sopenharmony_ci	probe_block = 0;
40598c2ecf20Sopenharmony_ci	page_no = 0;
40608c2ecf20Sopenharmony_ci	last_block = i_size_read(inode) >> blkbits;
40618c2ecf20Sopenharmony_ci	while ((probe_block + blocks_per_page) <= last_block &&
40628c2ecf20Sopenharmony_ci			page_no < sis->max) {
40638c2ecf20Sopenharmony_ci		unsigned block_in_page;
40648c2ecf20Sopenharmony_ci		sector_t first_block;
40658c2ecf20Sopenharmony_ci		sector_t block = 0;
40668c2ecf20Sopenharmony_ci		int	 err = 0;
40678c2ecf20Sopenharmony_ci
40688c2ecf20Sopenharmony_ci		cond_resched();
40698c2ecf20Sopenharmony_ci
40708c2ecf20Sopenharmony_ci		block = probe_block;
40718c2ecf20Sopenharmony_ci		err = bmap(inode, &block);
40728c2ecf20Sopenharmony_ci		if (err || !block)
40738c2ecf20Sopenharmony_ci			goto bad_bmap;
40748c2ecf20Sopenharmony_ci		first_block = block;
40758c2ecf20Sopenharmony_ci
40768c2ecf20Sopenharmony_ci		/*
40778c2ecf20Sopenharmony_ci		 * It must be PAGE_SIZE aligned on-disk
40788c2ecf20Sopenharmony_ci		 */
40798c2ecf20Sopenharmony_ci		if (first_block & (blocks_per_page - 1)) {
40808c2ecf20Sopenharmony_ci			probe_block++;
40818c2ecf20Sopenharmony_ci			goto reprobe;
40828c2ecf20Sopenharmony_ci		}
40838c2ecf20Sopenharmony_ci
40848c2ecf20Sopenharmony_ci		for (block_in_page = 1; block_in_page < blocks_per_page;
40858c2ecf20Sopenharmony_ci					block_in_page++) {
40868c2ecf20Sopenharmony_ci
40878c2ecf20Sopenharmony_ci			block = probe_block + block_in_page;
40888c2ecf20Sopenharmony_ci			err = bmap(inode, &block);
40898c2ecf20Sopenharmony_ci
40908c2ecf20Sopenharmony_ci			if (err || !block)
40918c2ecf20Sopenharmony_ci				goto bad_bmap;
40928c2ecf20Sopenharmony_ci
40938c2ecf20Sopenharmony_ci			if (block != first_block + block_in_page) {
40948c2ecf20Sopenharmony_ci				/* Discontiguity */
40958c2ecf20Sopenharmony_ci				probe_block++;
40968c2ecf20Sopenharmony_ci				goto reprobe;
40978c2ecf20Sopenharmony_ci			}
40988c2ecf20Sopenharmony_ci		}
40998c2ecf20Sopenharmony_ci
41008c2ecf20Sopenharmony_ci		first_block >>= (PAGE_SHIFT - blkbits);
41018c2ecf20Sopenharmony_ci		if (page_no) {	/* exclude the header page */
41028c2ecf20Sopenharmony_ci			if (first_block < lowest_block)
41038c2ecf20Sopenharmony_ci				lowest_block = first_block;
41048c2ecf20Sopenharmony_ci			if (first_block > highest_block)
41058c2ecf20Sopenharmony_ci				highest_block = first_block;
41068c2ecf20Sopenharmony_ci		}
41078c2ecf20Sopenharmony_ci
41088c2ecf20Sopenharmony_ci		/*
41098c2ecf20Sopenharmony_ci		 * We found a PAGE_SIZE-length, PAGE_SIZE-aligned run of blocks
41108c2ecf20Sopenharmony_ci		 */
41118c2ecf20Sopenharmony_ci		ret = add_swap_extent(sis, page_no, 1, first_block);
41128c2ecf20Sopenharmony_ci		if (ret < 0)
41138c2ecf20Sopenharmony_ci			goto out;
41148c2ecf20Sopenharmony_ci		nr_extents += ret;
41158c2ecf20Sopenharmony_ci		page_no++;
41168c2ecf20Sopenharmony_ci		probe_block += blocks_per_page;
41178c2ecf20Sopenharmony_cireprobe:
41188c2ecf20Sopenharmony_ci		continue;
41198c2ecf20Sopenharmony_ci	}
41208c2ecf20Sopenharmony_ci	ret = nr_extents;
41218c2ecf20Sopenharmony_ci	*span = 1 + highest_block - lowest_block;
41228c2ecf20Sopenharmony_ci	if (page_no == 0)
41238c2ecf20Sopenharmony_ci		page_no = 1;	/* force Empty message */
41248c2ecf20Sopenharmony_ci	sis->max = page_no;
41258c2ecf20Sopenharmony_ci	sis->pages = page_no - 1;
41268c2ecf20Sopenharmony_ci	sis->highest_bit = page_no - 1;
41278c2ecf20Sopenharmony_ciout:
41288c2ecf20Sopenharmony_ci	return ret;
41298c2ecf20Sopenharmony_cibad_bmap:
41308c2ecf20Sopenharmony_ci	pr_err("swapon: swapfile has holes\n");
41318c2ecf20Sopenharmony_ci	return -EINVAL;
41328c2ecf20Sopenharmony_ci}
41338c2ecf20Sopenharmony_ci
41348c2ecf20Sopenharmony_cistatic int f2fs_swap_activate(struct swap_info_struct *sis, struct file *file,
41358c2ecf20Sopenharmony_ci				sector_t *span)
41368c2ecf20Sopenharmony_ci{
41378c2ecf20Sopenharmony_ci	struct inode *inode = file_inode(file);
41388c2ecf20Sopenharmony_ci	int ret;
41398c2ecf20Sopenharmony_ci
41408c2ecf20Sopenharmony_ci	if (!S_ISREG(inode->i_mode))
41418c2ecf20Sopenharmony_ci		return -EINVAL;
41428c2ecf20Sopenharmony_ci
41438c2ecf20Sopenharmony_ci	if (f2fs_readonly(F2FS_I_SB(inode)->sb))
41448c2ecf20Sopenharmony_ci		return -EROFS;
41458c2ecf20Sopenharmony_ci
41468c2ecf20Sopenharmony_ci	if (f2fs_lfs_mode(F2FS_I_SB(inode))) {
41478c2ecf20Sopenharmony_ci		f2fs_err(F2FS_I_SB(inode),
41488c2ecf20Sopenharmony_ci			"Swapfile not supported in LFS mode");
41498c2ecf20Sopenharmony_ci		return -EINVAL;
41508c2ecf20Sopenharmony_ci	}
41518c2ecf20Sopenharmony_ci
41528c2ecf20Sopenharmony_ci	ret = f2fs_convert_inline_inode(inode);
41538c2ecf20Sopenharmony_ci	if (ret)
41548c2ecf20Sopenharmony_ci		return ret;
41558c2ecf20Sopenharmony_ci
41568c2ecf20Sopenharmony_ci	if (!f2fs_disable_compressed_file(inode))
41578c2ecf20Sopenharmony_ci		return -EINVAL;
41588c2ecf20Sopenharmony_ci
41598c2ecf20Sopenharmony_ci	ret = check_swap_activate(sis, file, span);
41608c2ecf20Sopenharmony_ci	if (ret < 0)
41618c2ecf20Sopenharmony_ci		return ret;
41628c2ecf20Sopenharmony_ci
41638c2ecf20Sopenharmony_ci	set_inode_flag(inode, FI_PIN_FILE);
41648c2ecf20Sopenharmony_ci	f2fs_precache_extents(inode);
41658c2ecf20Sopenharmony_ci	f2fs_update_time(F2FS_I_SB(inode), REQ_TIME);
41668c2ecf20Sopenharmony_ci	return ret;
41678c2ecf20Sopenharmony_ci}
41688c2ecf20Sopenharmony_ci
41698c2ecf20Sopenharmony_cistatic void f2fs_swap_deactivate(struct file *file)
41708c2ecf20Sopenharmony_ci{
41718c2ecf20Sopenharmony_ci	struct inode *inode = file_inode(file);
41728c2ecf20Sopenharmony_ci
41738c2ecf20Sopenharmony_ci	clear_inode_flag(inode, FI_PIN_FILE);
41748c2ecf20Sopenharmony_ci}
41758c2ecf20Sopenharmony_ci#else
41768c2ecf20Sopenharmony_cistatic int f2fs_swap_activate(struct swap_info_struct *sis, struct file *file,
41778c2ecf20Sopenharmony_ci				sector_t *span)
41788c2ecf20Sopenharmony_ci{
41798c2ecf20Sopenharmony_ci	return -EOPNOTSUPP;
41808c2ecf20Sopenharmony_ci}
41818c2ecf20Sopenharmony_ci
41828c2ecf20Sopenharmony_cistatic void f2fs_swap_deactivate(struct file *file)
41838c2ecf20Sopenharmony_ci{
41848c2ecf20Sopenharmony_ci}
41858c2ecf20Sopenharmony_ci#endif
41868c2ecf20Sopenharmony_ci
41878c2ecf20Sopenharmony_ciconst struct address_space_operations f2fs_dblock_aops = {
41888c2ecf20Sopenharmony_ci	.readpage	= f2fs_read_data_page,
41898c2ecf20Sopenharmony_ci	.readahead	= f2fs_readahead,
41908c2ecf20Sopenharmony_ci	.writepage	= f2fs_write_data_page,
41918c2ecf20Sopenharmony_ci	.writepages	= f2fs_write_data_pages,
41928c2ecf20Sopenharmony_ci	.write_begin	= f2fs_write_begin,
41938c2ecf20Sopenharmony_ci	.write_end	= f2fs_write_end,
41948c2ecf20Sopenharmony_ci	.set_page_dirty	= f2fs_set_data_page_dirty,
41958c2ecf20Sopenharmony_ci	.invalidatepage	= f2fs_invalidate_page,
41968c2ecf20Sopenharmony_ci	.releasepage	= f2fs_release_page,
41978c2ecf20Sopenharmony_ci	.direct_IO	= f2fs_direct_IO,
41988c2ecf20Sopenharmony_ci	.bmap		= f2fs_bmap,
41998c2ecf20Sopenharmony_ci	.swap_activate  = f2fs_swap_activate,
42008c2ecf20Sopenharmony_ci	.swap_deactivate = f2fs_swap_deactivate,
42018c2ecf20Sopenharmony_ci#ifdef CONFIG_MIGRATION
42028c2ecf20Sopenharmony_ci	.migratepage    = f2fs_migrate_page,
42038c2ecf20Sopenharmony_ci#endif
42048c2ecf20Sopenharmony_ci};
42058c2ecf20Sopenharmony_ci
42068c2ecf20Sopenharmony_civoid f2fs_clear_page_cache_dirty_tag(struct page *page)
42078c2ecf20Sopenharmony_ci{
42088c2ecf20Sopenharmony_ci	struct address_space *mapping = page_mapping(page);
42098c2ecf20Sopenharmony_ci	unsigned long flags;
42108c2ecf20Sopenharmony_ci
42118c2ecf20Sopenharmony_ci	xa_lock_irqsave(&mapping->i_pages, flags);
42128c2ecf20Sopenharmony_ci	__xa_clear_mark(&mapping->i_pages, page_index(page),
42138c2ecf20Sopenharmony_ci						PAGECACHE_TAG_DIRTY);
42148c2ecf20Sopenharmony_ci	xa_unlock_irqrestore(&mapping->i_pages, flags);
42158c2ecf20Sopenharmony_ci}
42168c2ecf20Sopenharmony_ci
42178c2ecf20Sopenharmony_ciint __init f2fs_init_post_read_processing(void)
42188c2ecf20Sopenharmony_ci{
42198c2ecf20Sopenharmony_ci	bio_post_read_ctx_cache =
42208c2ecf20Sopenharmony_ci		kmem_cache_create("f2fs_bio_post_read_ctx",
42218c2ecf20Sopenharmony_ci				  sizeof(struct bio_post_read_ctx), 0, 0, NULL);
42228c2ecf20Sopenharmony_ci	if (!bio_post_read_ctx_cache)
42238c2ecf20Sopenharmony_ci		goto fail;
42248c2ecf20Sopenharmony_ci	bio_post_read_ctx_pool =
42258c2ecf20Sopenharmony_ci		mempool_create_slab_pool(NUM_PREALLOC_POST_READ_CTXS,
42268c2ecf20Sopenharmony_ci					 bio_post_read_ctx_cache);
42278c2ecf20Sopenharmony_ci	if (!bio_post_read_ctx_pool)
42288c2ecf20Sopenharmony_ci		goto fail_free_cache;
42298c2ecf20Sopenharmony_ci	return 0;
42308c2ecf20Sopenharmony_ci
42318c2ecf20Sopenharmony_cifail_free_cache:
42328c2ecf20Sopenharmony_ci	kmem_cache_destroy(bio_post_read_ctx_cache);
42338c2ecf20Sopenharmony_cifail:
42348c2ecf20Sopenharmony_ci	return -ENOMEM;
42358c2ecf20Sopenharmony_ci}
42368c2ecf20Sopenharmony_ci
42378c2ecf20Sopenharmony_civoid f2fs_destroy_post_read_processing(void)
42388c2ecf20Sopenharmony_ci{
42398c2ecf20Sopenharmony_ci	mempool_destroy(bio_post_read_ctx_pool);
42408c2ecf20Sopenharmony_ci	kmem_cache_destroy(bio_post_read_ctx_cache);
42418c2ecf20Sopenharmony_ci}
42428c2ecf20Sopenharmony_ci
42438c2ecf20Sopenharmony_ciint f2fs_init_post_read_wq(struct f2fs_sb_info *sbi)
42448c2ecf20Sopenharmony_ci{
42458c2ecf20Sopenharmony_ci	if (!f2fs_sb_has_encrypt(sbi) &&
42468c2ecf20Sopenharmony_ci		!f2fs_sb_has_verity(sbi) &&
42478c2ecf20Sopenharmony_ci		!f2fs_sb_has_compression(sbi))
42488c2ecf20Sopenharmony_ci		return 0;
42498c2ecf20Sopenharmony_ci
42508c2ecf20Sopenharmony_ci	sbi->post_read_wq = alloc_workqueue("f2fs_post_read_wq",
42518c2ecf20Sopenharmony_ci						 WQ_UNBOUND | WQ_HIGHPRI,
42528c2ecf20Sopenharmony_ci						 num_online_cpus());
42538c2ecf20Sopenharmony_ci	if (!sbi->post_read_wq)
42548c2ecf20Sopenharmony_ci		return -ENOMEM;
42558c2ecf20Sopenharmony_ci	return 0;
42568c2ecf20Sopenharmony_ci}
42578c2ecf20Sopenharmony_ci
42588c2ecf20Sopenharmony_civoid f2fs_destroy_post_read_wq(struct f2fs_sb_info *sbi)
42598c2ecf20Sopenharmony_ci{
42608c2ecf20Sopenharmony_ci	if (sbi->post_read_wq)
42618c2ecf20Sopenharmony_ci		destroy_workqueue(sbi->post_read_wq);
42628c2ecf20Sopenharmony_ci}
42638c2ecf20Sopenharmony_ci
42648c2ecf20Sopenharmony_ciint __init f2fs_init_bio_entry_cache(void)
42658c2ecf20Sopenharmony_ci{
42668c2ecf20Sopenharmony_ci	bio_entry_slab = f2fs_kmem_cache_create("f2fs_bio_entry_slab",
42678c2ecf20Sopenharmony_ci			sizeof(struct bio_entry));
42688c2ecf20Sopenharmony_ci	if (!bio_entry_slab)
42698c2ecf20Sopenharmony_ci		return -ENOMEM;
42708c2ecf20Sopenharmony_ci	return 0;
42718c2ecf20Sopenharmony_ci}
42728c2ecf20Sopenharmony_ci
42738c2ecf20Sopenharmony_civoid f2fs_destroy_bio_entry_cache(void)
42748c2ecf20Sopenharmony_ci{
42758c2ecf20Sopenharmony_ci	kmem_cache_destroy(bio_entry_slab);
42768c2ecf20Sopenharmony_ci}
4277