162306a36Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0 */
262306a36Sopenharmony_ci/*
362306a36Sopenharmony_ci * fs/f2fs/f2fs.h
462306a36Sopenharmony_ci *
562306a36Sopenharmony_ci * Copyright (c) 2012 Samsung Electronics Co., Ltd.
662306a36Sopenharmony_ci *             http://www.samsung.com/
762306a36Sopenharmony_ci */
862306a36Sopenharmony_ci#ifndef _LINUX_F2FS_H
962306a36Sopenharmony_ci#define _LINUX_F2FS_H
1062306a36Sopenharmony_ci
1162306a36Sopenharmony_ci#include <linux/uio.h>
1262306a36Sopenharmony_ci#include <linux/types.h>
1362306a36Sopenharmony_ci#include <linux/page-flags.h>
1462306a36Sopenharmony_ci#include <linux/buffer_head.h>
1562306a36Sopenharmony_ci#include <linux/slab.h>
1662306a36Sopenharmony_ci#include <linux/crc32.h>
1762306a36Sopenharmony_ci#include <linux/magic.h>
1862306a36Sopenharmony_ci#include <linux/kobject.h>
1962306a36Sopenharmony_ci#include <linux/sched.h>
2062306a36Sopenharmony_ci#include <linux/cred.h>
2162306a36Sopenharmony_ci#include <linux/sched/mm.h>
2262306a36Sopenharmony_ci#include <linux/vmalloc.h>
2362306a36Sopenharmony_ci#include <linux/bio.h>
2462306a36Sopenharmony_ci#include <linux/blkdev.h>
2562306a36Sopenharmony_ci#include <linux/quotaops.h>
2662306a36Sopenharmony_ci#include <linux/part_stat.h>
2762306a36Sopenharmony_ci#include <crypto/hash.h>
2862306a36Sopenharmony_ci
2962306a36Sopenharmony_ci#include <linux/fscrypt.h>
3062306a36Sopenharmony_ci#include <linux/fsverity.h>
3162306a36Sopenharmony_ci
3262306a36Sopenharmony_cistruct pagevec;
3362306a36Sopenharmony_ci
3462306a36Sopenharmony_ci#ifdef CONFIG_F2FS_CHECK_FS
3562306a36Sopenharmony_ci#define f2fs_bug_on(sbi, condition)	BUG_ON(condition)
3662306a36Sopenharmony_ci#else
3762306a36Sopenharmony_ci#define f2fs_bug_on(sbi, condition)					\
3862306a36Sopenharmony_ci	do {								\
3962306a36Sopenharmony_ci		if (WARN_ON(condition))					\
4062306a36Sopenharmony_ci			set_sbi_flag(sbi, SBI_NEED_FSCK);		\
4162306a36Sopenharmony_ci	} while (0)
4262306a36Sopenharmony_ci#endif
4362306a36Sopenharmony_ci
4462306a36Sopenharmony_cienum {
4562306a36Sopenharmony_ci	FAULT_KMALLOC,
4662306a36Sopenharmony_ci	FAULT_KVMALLOC,
4762306a36Sopenharmony_ci	FAULT_PAGE_ALLOC,
4862306a36Sopenharmony_ci	FAULT_PAGE_GET,
4962306a36Sopenharmony_ci	FAULT_ALLOC_BIO,	/* it's obsolete due to bio_alloc() will never fail */
5062306a36Sopenharmony_ci	FAULT_ALLOC_NID,
5162306a36Sopenharmony_ci	FAULT_ORPHAN,
5262306a36Sopenharmony_ci	FAULT_BLOCK,
5362306a36Sopenharmony_ci	FAULT_DIR_DEPTH,
5462306a36Sopenharmony_ci	FAULT_EVICT_INODE,
5562306a36Sopenharmony_ci	FAULT_TRUNCATE,
5662306a36Sopenharmony_ci	FAULT_READ_IO,
5762306a36Sopenharmony_ci	FAULT_CHECKPOINT,
5862306a36Sopenharmony_ci	FAULT_DISCARD,
5962306a36Sopenharmony_ci	FAULT_WRITE_IO,
6062306a36Sopenharmony_ci	FAULT_SLAB_ALLOC,
6162306a36Sopenharmony_ci	FAULT_DQUOT_INIT,
6262306a36Sopenharmony_ci	FAULT_LOCK_OP,
6362306a36Sopenharmony_ci	FAULT_BLKADDR,
6462306a36Sopenharmony_ci	FAULT_MAX,
6562306a36Sopenharmony_ci};
6662306a36Sopenharmony_ci
6762306a36Sopenharmony_ci#ifdef CONFIG_F2FS_FAULT_INJECTION
6862306a36Sopenharmony_ci#define F2FS_ALL_FAULT_TYPE		(GENMASK(FAULT_MAX - 1, 0))
6962306a36Sopenharmony_ci
7062306a36Sopenharmony_cistruct f2fs_fault_info {
7162306a36Sopenharmony_ci	atomic_t inject_ops;
7262306a36Sopenharmony_ci	unsigned int inject_rate;
7362306a36Sopenharmony_ci	unsigned int inject_type;
7462306a36Sopenharmony_ci};
7562306a36Sopenharmony_ci
7662306a36Sopenharmony_ciextern const char *f2fs_fault_name[FAULT_MAX];
7762306a36Sopenharmony_ci#define IS_FAULT_SET(fi, type) ((fi)->inject_type & BIT(type))
7862306a36Sopenharmony_ci
7962306a36Sopenharmony_ci/* maximum retry count for injected failure */
8062306a36Sopenharmony_ci#define DEFAULT_FAILURE_RETRY_COUNT		8
8162306a36Sopenharmony_ci#else
8262306a36Sopenharmony_ci#define DEFAULT_FAILURE_RETRY_COUNT		1
8362306a36Sopenharmony_ci#endif
8462306a36Sopenharmony_ci
8562306a36Sopenharmony_ci/*
8662306a36Sopenharmony_ci * For mount options
8762306a36Sopenharmony_ci */
8862306a36Sopenharmony_ci#define F2FS_MOUNT_DISABLE_ROLL_FORWARD	0x00000001
8962306a36Sopenharmony_ci#define F2FS_MOUNT_DISCARD		0x00000002
9062306a36Sopenharmony_ci#define F2FS_MOUNT_NOHEAP		0x00000004
9162306a36Sopenharmony_ci#define F2FS_MOUNT_XATTR_USER		0x00000008
9262306a36Sopenharmony_ci#define F2FS_MOUNT_POSIX_ACL		0x00000010
9362306a36Sopenharmony_ci#define F2FS_MOUNT_DISABLE_EXT_IDENTIFY	0x00000020
9462306a36Sopenharmony_ci#define F2FS_MOUNT_INLINE_XATTR		0x00000040
9562306a36Sopenharmony_ci#define F2FS_MOUNT_INLINE_DATA		0x00000080
9662306a36Sopenharmony_ci#define F2FS_MOUNT_INLINE_DENTRY	0x00000100
9762306a36Sopenharmony_ci#define F2FS_MOUNT_FLUSH_MERGE		0x00000200
9862306a36Sopenharmony_ci#define F2FS_MOUNT_NOBARRIER		0x00000400
9962306a36Sopenharmony_ci#define F2FS_MOUNT_FASTBOOT		0x00000800
10062306a36Sopenharmony_ci#define F2FS_MOUNT_READ_EXTENT_CACHE	0x00001000
10162306a36Sopenharmony_ci#define F2FS_MOUNT_DATA_FLUSH		0x00002000
10262306a36Sopenharmony_ci#define F2FS_MOUNT_FAULT_INJECTION	0x00004000
10362306a36Sopenharmony_ci#define F2FS_MOUNT_USRQUOTA		0x00008000
10462306a36Sopenharmony_ci#define F2FS_MOUNT_GRPQUOTA		0x00010000
10562306a36Sopenharmony_ci#define F2FS_MOUNT_PRJQUOTA		0x00020000
10662306a36Sopenharmony_ci#define F2FS_MOUNT_QUOTA		0x00040000
10762306a36Sopenharmony_ci#define F2FS_MOUNT_INLINE_XATTR_SIZE	0x00080000
10862306a36Sopenharmony_ci#define F2FS_MOUNT_RESERVE_ROOT		0x00100000
10962306a36Sopenharmony_ci#define F2FS_MOUNT_DISABLE_CHECKPOINT	0x00200000
11062306a36Sopenharmony_ci#define F2FS_MOUNT_NORECOVERY		0x00400000
11162306a36Sopenharmony_ci#define F2FS_MOUNT_ATGC			0x00800000
11262306a36Sopenharmony_ci#define F2FS_MOUNT_MERGE_CHECKPOINT	0x01000000
11362306a36Sopenharmony_ci#define	F2FS_MOUNT_GC_MERGE		0x02000000
11462306a36Sopenharmony_ci#define F2FS_MOUNT_COMPRESS_CACHE	0x04000000
11562306a36Sopenharmony_ci#define F2FS_MOUNT_AGE_EXTENT_CACHE	0x08000000
11662306a36Sopenharmony_ci
11762306a36Sopenharmony_ci#define F2FS_OPTION(sbi)	((sbi)->mount_opt)
11862306a36Sopenharmony_ci#define clear_opt(sbi, option)	(F2FS_OPTION(sbi).opt &= ~F2FS_MOUNT_##option)
11962306a36Sopenharmony_ci#define set_opt(sbi, option)	(F2FS_OPTION(sbi).opt |= F2FS_MOUNT_##option)
12062306a36Sopenharmony_ci#define test_opt(sbi, option)	(F2FS_OPTION(sbi).opt & F2FS_MOUNT_##option)
12162306a36Sopenharmony_ci
12262306a36Sopenharmony_ci#define ver_after(a, b)	(typecheck(unsigned long long, a) &&		\
12362306a36Sopenharmony_ci		typecheck(unsigned long long, b) &&			\
12462306a36Sopenharmony_ci		((long long)((a) - (b)) > 0))
12562306a36Sopenharmony_ci
12662306a36Sopenharmony_citypedef u32 block_t;	/*
12762306a36Sopenharmony_ci			 * should not change u32, since it is the on-disk block
12862306a36Sopenharmony_ci			 * address format, __le32.
12962306a36Sopenharmony_ci			 */
13062306a36Sopenharmony_citypedef u32 nid_t;
13162306a36Sopenharmony_ci
13262306a36Sopenharmony_ci#define COMPRESS_EXT_NUM		16
13362306a36Sopenharmony_ci
13462306a36Sopenharmony_ci/*
13562306a36Sopenharmony_ci * An implementation of an rwsem that is explicitly unfair to readers. This
13662306a36Sopenharmony_ci * prevents priority inversion when a low-priority reader acquires the read lock
13762306a36Sopenharmony_ci * while sleeping on the write lock but the write lock is needed by
13862306a36Sopenharmony_ci * higher-priority clients.
13962306a36Sopenharmony_ci */
14062306a36Sopenharmony_ci
14162306a36Sopenharmony_cistruct f2fs_rwsem {
14262306a36Sopenharmony_ci        struct rw_semaphore internal_rwsem;
14362306a36Sopenharmony_ci#ifdef CONFIG_F2FS_UNFAIR_RWSEM
14462306a36Sopenharmony_ci        wait_queue_head_t read_waiters;
14562306a36Sopenharmony_ci#endif
14662306a36Sopenharmony_ci};
14762306a36Sopenharmony_ci
14862306a36Sopenharmony_cistruct f2fs_mount_info {
14962306a36Sopenharmony_ci	unsigned int opt;
15062306a36Sopenharmony_ci	int write_io_size_bits;		/* Write IO size bits */
15162306a36Sopenharmony_ci	block_t root_reserved_blocks;	/* root reserved blocks */
15262306a36Sopenharmony_ci	kuid_t s_resuid;		/* reserved blocks for uid */
15362306a36Sopenharmony_ci	kgid_t s_resgid;		/* reserved blocks for gid */
15462306a36Sopenharmony_ci	int active_logs;		/* # of active logs */
15562306a36Sopenharmony_ci	int inline_xattr_size;		/* inline xattr size */
15662306a36Sopenharmony_ci#ifdef CONFIG_F2FS_FAULT_INJECTION
15762306a36Sopenharmony_ci	struct f2fs_fault_info fault_info;	/* For fault injection */
15862306a36Sopenharmony_ci#endif
15962306a36Sopenharmony_ci#ifdef CONFIG_QUOTA
16062306a36Sopenharmony_ci	/* Names of quota files with journalled quota */
16162306a36Sopenharmony_ci	char *s_qf_names[MAXQUOTAS];
16262306a36Sopenharmony_ci	int s_jquota_fmt;			/* Format of quota to use */
16362306a36Sopenharmony_ci#endif
16462306a36Sopenharmony_ci	/* For which write hints are passed down to block layer */
16562306a36Sopenharmony_ci	int alloc_mode;			/* segment allocation policy */
16662306a36Sopenharmony_ci	int fsync_mode;			/* fsync policy */
16762306a36Sopenharmony_ci	int fs_mode;			/* fs mode: LFS or ADAPTIVE */
16862306a36Sopenharmony_ci	int bggc_mode;			/* bggc mode: off, on or sync */
16962306a36Sopenharmony_ci	int memory_mode;		/* memory mode */
17062306a36Sopenharmony_ci	int errors;			/* errors parameter */
17162306a36Sopenharmony_ci	int discard_unit;		/*
17262306a36Sopenharmony_ci					 * discard command's offset/size should
17362306a36Sopenharmony_ci					 * be aligned to this unit: block,
17462306a36Sopenharmony_ci					 * segment or section
17562306a36Sopenharmony_ci					 */
17662306a36Sopenharmony_ci	struct fscrypt_dummy_policy dummy_enc_policy; /* test dummy encryption */
17762306a36Sopenharmony_ci	block_t unusable_cap_perc;	/* percentage for cap */
17862306a36Sopenharmony_ci	block_t unusable_cap;		/* Amount of space allowed to be
17962306a36Sopenharmony_ci					 * unusable when disabling checkpoint
18062306a36Sopenharmony_ci					 */
18162306a36Sopenharmony_ci
18262306a36Sopenharmony_ci	/* For compression */
18362306a36Sopenharmony_ci	unsigned char compress_algorithm;	/* algorithm type */
18462306a36Sopenharmony_ci	unsigned char compress_log_size;	/* cluster log size */
18562306a36Sopenharmony_ci	unsigned char compress_level;		/* compress level */
18662306a36Sopenharmony_ci	bool compress_chksum;			/* compressed data chksum */
18762306a36Sopenharmony_ci	unsigned char compress_ext_cnt;		/* extension count */
18862306a36Sopenharmony_ci	unsigned char nocompress_ext_cnt;		/* nocompress extension count */
18962306a36Sopenharmony_ci	int compress_mode;			/* compression mode */
19062306a36Sopenharmony_ci	unsigned char extensions[COMPRESS_EXT_NUM][F2FS_EXTENSION_LEN];	/* extensions */
19162306a36Sopenharmony_ci	unsigned char noextensions[COMPRESS_EXT_NUM][F2FS_EXTENSION_LEN]; /* extensions */
19262306a36Sopenharmony_ci};
19362306a36Sopenharmony_ci
19462306a36Sopenharmony_ci#define F2FS_FEATURE_ENCRYPT			0x00000001
19562306a36Sopenharmony_ci#define F2FS_FEATURE_BLKZONED			0x00000002
19662306a36Sopenharmony_ci#define F2FS_FEATURE_ATOMIC_WRITE		0x00000004
19762306a36Sopenharmony_ci#define F2FS_FEATURE_EXTRA_ATTR			0x00000008
19862306a36Sopenharmony_ci#define F2FS_FEATURE_PRJQUOTA			0x00000010
19962306a36Sopenharmony_ci#define F2FS_FEATURE_INODE_CHKSUM		0x00000020
20062306a36Sopenharmony_ci#define F2FS_FEATURE_FLEXIBLE_INLINE_XATTR	0x00000040
20162306a36Sopenharmony_ci#define F2FS_FEATURE_QUOTA_INO			0x00000080
20262306a36Sopenharmony_ci#define F2FS_FEATURE_INODE_CRTIME		0x00000100
20362306a36Sopenharmony_ci#define F2FS_FEATURE_LOST_FOUND			0x00000200
20462306a36Sopenharmony_ci#define F2FS_FEATURE_VERITY			0x00000400
20562306a36Sopenharmony_ci#define F2FS_FEATURE_SB_CHKSUM			0x00000800
20662306a36Sopenharmony_ci#define F2FS_FEATURE_CASEFOLD			0x00001000
20762306a36Sopenharmony_ci#define F2FS_FEATURE_COMPRESSION		0x00002000
20862306a36Sopenharmony_ci#define F2FS_FEATURE_RO				0x00004000
20962306a36Sopenharmony_ci
21062306a36Sopenharmony_ci#define __F2FS_HAS_FEATURE(raw_super, mask)				\
21162306a36Sopenharmony_ci	((raw_super->feature & cpu_to_le32(mask)) != 0)
21262306a36Sopenharmony_ci#define F2FS_HAS_FEATURE(sbi, mask)	__F2FS_HAS_FEATURE(sbi->raw_super, mask)
21362306a36Sopenharmony_ci
21462306a36Sopenharmony_ci/*
21562306a36Sopenharmony_ci * Default values for user and/or group using reserved blocks
21662306a36Sopenharmony_ci */
21762306a36Sopenharmony_ci#define	F2FS_DEF_RESUID		0
21862306a36Sopenharmony_ci#define	F2FS_DEF_RESGID		0
21962306a36Sopenharmony_ci
22062306a36Sopenharmony_ci/*
22162306a36Sopenharmony_ci * For checkpoint manager
22262306a36Sopenharmony_ci */
22362306a36Sopenharmony_cienum {
22462306a36Sopenharmony_ci	NAT_BITMAP,
22562306a36Sopenharmony_ci	SIT_BITMAP
22662306a36Sopenharmony_ci};
22762306a36Sopenharmony_ci
22862306a36Sopenharmony_ci#define	CP_UMOUNT	0x00000001
22962306a36Sopenharmony_ci#define	CP_FASTBOOT	0x00000002
23062306a36Sopenharmony_ci#define	CP_SYNC		0x00000004
23162306a36Sopenharmony_ci#define	CP_RECOVERY	0x00000008
23262306a36Sopenharmony_ci#define	CP_DISCARD	0x00000010
23362306a36Sopenharmony_ci#define CP_TRIMMED	0x00000020
23462306a36Sopenharmony_ci#define CP_PAUSE	0x00000040
23562306a36Sopenharmony_ci#define CP_RESIZE 	0x00000080
23662306a36Sopenharmony_ci
23762306a36Sopenharmony_ci#define DEF_MAX_DISCARD_REQUEST		8	/* issue 8 discards per round */
23862306a36Sopenharmony_ci#define DEF_MIN_DISCARD_ISSUE_TIME	50	/* 50 ms, if exists */
23962306a36Sopenharmony_ci#define DEF_MID_DISCARD_ISSUE_TIME	500	/* 500 ms, if device busy */
24062306a36Sopenharmony_ci#define DEF_MAX_DISCARD_ISSUE_TIME	60000	/* 60 s, if no candidates */
24162306a36Sopenharmony_ci#define DEF_DISCARD_URGENT_UTIL		80	/* do more discard over 80% */
24262306a36Sopenharmony_ci#define DEF_CP_INTERVAL			60	/* 60 secs */
24362306a36Sopenharmony_ci#define DEF_IDLE_INTERVAL		5	/* 5 secs */
24462306a36Sopenharmony_ci#define DEF_DISABLE_INTERVAL		5	/* 5 secs */
24562306a36Sopenharmony_ci#define DEF_DISABLE_QUICK_INTERVAL	1	/* 1 secs */
24662306a36Sopenharmony_ci#define DEF_UMOUNT_DISCARD_TIMEOUT	5	/* 5 secs */
24762306a36Sopenharmony_ci
24862306a36Sopenharmony_cistruct cp_control {
24962306a36Sopenharmony_ci	int reason;
25062306a36Sopenharmony_ci	__u64 trim_start;
25162306a36Sopenharmony_ci	__u64 trim_end;
25262306a36Sopenharmony_ci	__u64 trim_minlen;
25362306a36Sopenharmony_ci};
25462306a36Sopenharmony_ci
25562306a36Sopenharmony_ci/*
25662306a36Sopenharmony_ci * indicate meta/data type
25762306a36Sopenharmony_ci */
25862306a36Sopenharmony_cienum {
25962306a36Sopenharmony_ci	META_CP,
26062306a36Sopenharmony_ci	META_NAT,
26162306a36Sopenharmony_ci	META_SIT,
26262306a36Sopenharmony_ci	META_SSA,
26362306a36Sopenharmony_ci	META_MAX,
26462306a36Sopenharmony_ci	META_POR,
26562306a36Sopenharmony_ci	DATA_GENERIC,		/* check range only */
26662306a36Sopenharmony_ci	DATA_GENERIC_ENHANCE,	/* strong check on range and segment bitmap */
26762306a36Sopenharmony_ci	DATA_GENERIC_ENHANCE_READ,	/*
26862306a36Sopenharmony_ci					 * strong check on range and segment
26962306a36Sopenharmony_ci					 * bitmap but no warning due to race
27062306a36Sopenharmony_ci					 * condition of read on truncated area
27162306a36Sopenharmony_ci					 * by extent_cache
27262306a36Sopenharmony_ci					 */
27362306a36Sopenharmony_ci	DATA_GENERIC_ENHANCE_UPDATE,	/*
27462306a36Sopenharmony_ci					 * strong check on range and segment
27562306a36Sopenharmony_ci					 * bitmap for update case
27662306a36Sopenharmony_ci					 */
27762306a36Sopenharmony_ci	META_GENERIC,
27862306a36Sopenharmony_ci};
27962306a36Sopenharmony_ci
28062306a36Sopenharmony_ci/* for the list of ino */
28162306a36Sopenharmony_cienum {
28262306a36Sopenharmony_ci	ORPHAN_INO,		/* for orphan ino list */
28362306a36Sopenharmony_ci	APPEND_INO,		/* for append ino list */
28462306a36Sopenharmony_ci	UPDATE_INO,		/* for update ino list */
28562306a36Sopenharmony_ci	TRANS_DIR_INO,		/* for transactions dir ino list */
28662306a36Sopenharmony_ci	FLUSH_INO,		/* for multiple device flushing */
28762306a36Sopenharmony_ci	MAX_INO_ENTRY,		/* max. list */
28862306a36Sopenharmony_ci};
28962306a36Sopenharmony_ci
29062306a36Sopenharmony_cistruct ino_entry {
29162306a36Sopenharmony_ci	struct list_head list;		/* list head */
29262306a36Sopenharmony_ci	nid_t ino;			/* inode number */
29362306a36Sopenharmony_ci	unsigned int dirty_device;	/* dirty device bitmap */
29462306a36Sopenharmony_ci};
29562306a36Sopenharmony_ci
29662306a36Sopenharmony_ci/* for the list of inodes to be GCed */
29762306a36Sopenharmony_cistruct inode_entry {
29862306a36Sopenharmony_ci	struct list_head list;	/* list head */
29962306a36Sopenharmony_ci	struct inode *inode;	/* vfs inode pointer */
30062306a36Sopenharmony_ci};
30162306a36Sopenharmony_ci
30262306a36Sopenharmony_cistruct fsync_node_entry {
30362306a36Sopenharmony_ci	struct list_head list;	/* list head */
30462306a36Sopenharmony_ci	struct page *page;	/* warm node page pointer */
30562306a36Sopenharmony_ci	unsigned int seq_id;	/* sequence id */
30662306a36Sopenharmony_ci};
30762306a36Sopenharmony_ci
30862306a36Sopenharmony_cistruct ckpt_req {
30962306a36Sopenharmony_ci	struct completion wait;		/* completion for checkpoint done */
31062306a36Sopenharmony_ci	struct llist_node llnode;	/* llist_node to be linked in wait queue */
31162306a36Sopenharmony_ci	int ret;			/* return code of checkpoint */
31262306a36Sopenharmony_ci	ktime_t queue_time;		/* request queued time */
31362306a36Sopenharmony_ci};
31462306a36Sopenharmony_ci
31562306a36Sopenharmony_cistruct ckpt_req_control {
31662306a36Sopenharmony_ci	struct task_struct *f2fs_issue_ckpt;	/* checkpoint task */
31762306a36Sopenharmony_ci	int ckpt_thread_ioprio;			/* checkpoint merge thread ioprio */
31862306a36Sopenharmony_ci	wait_queue_head_t ckpt_wait_queue;	/* waiting queue for wake-up */
31962306a36Sopenharmony_ci	atomic_t issued_ckpt;		/* # of actually issued ckpts */
32062306a36Sopenharmony_ci	atomic_t total_ckpt;		/* # of total ckpts */
32162306a36Sopenharmony_ci	atomic_t queued_ckpt;		/* # of queued ckpts */
32262306a36Sopenharmony_ci	struct llist_head issue_list;	/* list for command issue */
32362306a36Sopenharmony_ci	spinlock_t stat_lock;		/* lock for below checkpoint time stats */
32462306a36Sopenharmony_ci	unsigned int cur_time;		/* cur wait time in msec for currently issued checkpoint */
32562306a36Sopenharmony_ci	unsigned int peak_time;		/* peak wait time in msec until now */
32662306a36Sopenharmony_ci};
32762306a36Sopenharmony_ci
32862306a36Sopenharmony_ci/* for the bitmap indicate blocks to be discarded */
32962306a36Sopenharmony_cistruct discard_entry {
33062306a36Sopenharmony_ci	struct list_head list;	/* list head */
33162306a36Sopenharmony_ci	block_t start_blkaddr;	/* start blockaddr of current segment */
33262306a36Sopenharmony_ci	unsigned char discard_map[SIT_VBLOCK_MAP_SIZE];	/* segment discard bitmap */
33362306a36Sopenharmony_ci};
33462306a36Sopenharmony_ci
33562306a36Sopenharmony_ci/* minimum discard granularity, unit: block count */
33662306a36Sopenharmony_ci#define MIN_DISCARD_GRANULARITY		1
33762306a36Sopenharmony_ci/* default discard granularity of inner discard thread, unit: block count */
33862306a36Sopenharmony_ci#define DEFAULT_DISCARD_GRANULARITY		16
33962306a36Sopenharmony_ci/* default maximum discard granularity of ordered discard, unit: block count */
34062306a36Sopenharmony_ci#define DEFAULT_MAX_ORDERED_DISCARD_GRANULARITY	16
34162306a36Sopenharmony_ci
34262306a36Sopenharmony_ci/* max discard pend list number */
34362306a36Sopenharmony_ci#define MAX_PLIST_NUM		512
34462306a36Sopenharmony_ci#define plist_idx(blk_num)	((blk_num) >= MAX_PLIST_NUM ?		\
34562306a36Sopenharmony_ci					(MAX_PLIST_NUM - 1) : ((blk_num) - 1))
34662306a36Sopenharmony_ci
34762306a36Sopenharmony_cienum {
34862306a36Sopenharmony_ci	D_PREP,			/* initial */
34962306a36Sopenharmony_ci	D_PARTIAL,		/* partially submitted */
35062306a36Sopenharmony_ci	D_SUBMIT,		/* all submitted */
35162306a36Sopenharmony_ci	D_DONE,			/* finished */
35262306a36Sopenharmony_ci};
35362306a36Sopenharmony_ci
35462306a36Sopenharmony_cistruct discard_info {
35562306a36Sopenharmony_ci	block_t lstart;			/* logical start address */
35662306a36Sopenharmony_ci	block_t len;			/* length */
35762306a36Sopenharmony_ci	block_t start;			/* actual start address in dev */
35862306a36Sopenharmony_ci};
35962306a36Sopenharmony_ci
36062306a36Sopenharmony_cistruct discard_cmd {
36162306a36Sopenharmony_ci	struct rb_node rb_node;		/* rb node located in rb-tree */
36262306a36Sopenharmony_ci	struct discard_info di;		/* discard info */
36362306a36Sopenharmony_ci	struct list_head list;		/* command list */
36462306a36Sopenharmony_ci	struct completion wait;		/* compleation */
36562306a36Sopenharmony_ci	struct block_device *bdev;	/* bdev */
36662306a36Sopenharmony_ci	unsigned short ref;		/* reference count */
36762306a36Sopenharmony_ci	unsigned char state;		/* state */
36862306a36Sopenharmony_ci	unsigned char queued;		/* queued discard */
36962306a36Sopenharmony_ci	int error;			/* bio error */
37062306a36Sopenharmony_ci	spinlock_t lock;		/* for state/bio_ref updating */
37162306a36Sopenharmony_ci	unsigned short bio_ref;		/* bio reference count */
37262306a36Sopenharmony_ci};
37362306a36Sopenharmony_ci
37462306a36Sopenharmony_cienum {
37562306a36Sopenharmony_ci	DPOLICY_BG,
37662306a36Sopenharmony_ci	DPOLICY_FORCE,
37762306a36Sopenharmony_ci	DPOLICY_FSTRIM,
37862306a36Sopenharmony_ci	DPOLICY_UMOUNT,
37962306a36Sopenharmony_ci	MAX_DPOLICY,
38062306a36Sopenharmony_ci};
38162306a36Sopenharmony_ci
38262306a36Sopenharmony_cistruct discard_policy {
38362306a36Sopenharmony_ci	int type;			/* type of discard */
38462306a36Sopenharmony_ci	unsigned int min_interval;	/* used for candidates exist */
38562306a36Sopenharmony_ci	unsigned int mid_interval;	/* used for device busy */
38662306a36Sopenharmony_ci	unsigned int max_interval;	/* used for candidates not exist */
38762306a36Sopenharmony_ci	unsigned int max_requests;	/* # of discards issued per round */
38862306a36Sopenharmony_ci	unsigned int io_aware_gran;	/* minimum granularity discard not be aware of I/O */
38962306a36Sopenharmony_ci	bool io_aware;			/* issue discard in idle time */
39062306a36Sopenharmony_ci	bool sync;			/* submit discard with REQ_SYNC flag */
39162306a36Sopenharmony_ci	bool ordered;			/* issue discard by lba order */
39262306a36Sopenharmony_ci	bool timeout;			/* discard timeout for put_super */
39362306a36Sopenharmony_ci	unsigned int granularity;	/* discard granularity */
39462306a36Sopenharmony_ci};
39562306a36Sopenharmony_ci
39662306a36Sopenharmony_cistruct discard_cmd_control {
39762306a36Sopenharmony_ci	struct task_struct *f2fs_issue_discard;	/* discard thread */
39862306a36Sopenharmony_ci	struct list_head entry_list;		/* 4KB discard entry list */
39962306a36Sopenharmony_ci	struct list_head pend_list[MAX_PLIST_NUM];/* store pending entries */
40062306a36Sopenharmony_ci	struct list_head wait_list;		/* store on-flushing entries */
40162306a36Sopenharmony_ci	struct list_head fstrim_list;		/* in-flight discard from fstrim */
40262306a36Sopenharmony_ci	wait_queue_head_t discard_wait_queue;	/* waiting queue for wake-up */
40362306a36Sopenharmony_ci	struct mutex cmd_lock;
40462306a36Sopenharmony_ci	unsigned int nr_discards;		/* # of discards in the list */
40562306a36Sopenharmony_ci	unsigned int max_discards;		/* max. discards to be issued */
40662306a36Sopenharmony_ci	unsigned int max_discard_request;	/* max. discard request per round */
40762306a36Sopenharmony_ci	unsigned int min_discard_issue_time;	/* min. interval between discard issue */
40862306a36Sopenharmony_ci	unsigned int mid_discard_issue_time;	/* mid. interval between discard issue */
40962306a36Sopenharmony_ci	unsigned int max_discard_issue_time;	/* max. interval between discard issue */
41062306a36Sopenharmony_ci	unsigned int discard_io_aware_gran; /* minimum discard granularity not be aware of I/O */
41162306a36Sopenharmony_ci	unsigned int discard_urgent_util;	/* utilization which issue discard proactively */
41262306a36Sopenharmony_ci	unsigned int discard_granularity;	/* discard granularity */
41362306a36Sopenharmony_ci	unsigned int max_ordered_discard;	/* maximum discard granularity issued by lba order */
41462306a36Sopenharmony_ci	unsigned int undiscard_blks;		/* # of undiscard blocks */
41562306a36Sopenharmony_ci	unsigned int next_pos;			/* next discard position */
41662306a36Sopenharmony_ci	atomic_t issued_discard;		/* # of issued discard */
41762306a36Sopenharmony_ci	atomic_t queued_discard;		/* # of queued discard */
41862306a36Sopenharmony_ci	atomic_t discard_cmd_cnt;		/* # of cached cmd count */
41962306a36Sopenharmony_ci	struct rb_root_cached root;		/* root of discard rb-tree */
42062306a36Sopenharmony_ci	bool rbtree_check;			/* config for consistence check */
42162306a36Sopenharmony_ci	bool discard_wake;			/* to wake up discard thread */
42262306a36Sopenharmony_ci};
42362306a36Sopenharmony_ci
42462306a36Sopenharmony_ci/* for the list of fsync inodes, used only during recovery */
42562306a36Sopenharmony_cistruct fsync_inode_entry {
42662306a36Sopenharmony_ci	struct list_head list;	/* list head */
42762306a36Sopenharmony_ci	struct inode *inode;	/* vfs inode pointer */
42862306a36Sopenharmony_ci	block_t blkaddr;	/* block address locating the last fsync */
42962306a36Sopenharmony_ci	block_t last_dentry;	/* block address locating the last dentry */
43062306a36Sopenharmony_ci};
43162306a36Sopenharmony_ci
43262306a36Sopenharmony_ci#define nats_in_cursum(jnl)		(le16_to_cpu((jnl)->n_nats))
43362306a36Sopenharmony_ci#define sits_in_cursum(jnl)		(le16_to_cpu((jnl)->n_sits))
43462306a36Sopenharmony_ci
43562306a36Sopenharmony_ci#define nat_in_journal(jnl, i)		((jnl)->nat_j.entries[i].ne)
43662306a36Sopenharmony_ci#define nid_in_journal(jnl, i)		((jnl)->nat_j.entries[i].nid)
43762306a36Sopenharmony_ci#define sit_in_journal(jnl, i)		((jnl)->sit_j.entries[i].se)
43862306a36Sopenharmony_ci#define segno_in_journal(jnl, i)	((jnl)->sit_j.entries[i].segno)
43962306a36Sopenharmony_ci
44062306a36Sopenharmony_ci#define MAX_NAT_JENTRIES(jnl)	(NAT_JOURNAL_ENTRIES - nats_in_cursum(jnl))
44162306a36Sopenharmony_ci#define MAX_SIT_JENTRIES(jnl)	(SIT_JOURNAL_ENTRIES - sits_in_cursum(jnl))
44262306a36Sopenharmony_ci
44362306a36Sopenharmony_cistatic inline int update_nats_in_cursum(struct f2fs_journal *journal, int i)
44462306a36Sopenharmony_ci{
44562306a36Sopenharmony_ci	int before = nats_in_cursum(journal);
44662306a36Sopenharmony_ci
44762306a36Sopenharmony_ci	journal->n_nats = cpu_to_le16(before + i);
44862306a36Sopenharmony_ci	return before;
44962306a36Sopenharmony_ci}
45062306a36Sopenharmony_ci
45162306a36Sopenharmony_cistatic inline int update_sits_in_cursum(struct f2fs_journal *journal, int i)
45262306a36Sopenharmony_ci{
45362306a36Sopenharmony_ci	int before = sits_in_cursum(journal);
45462306a36Sopenharmony_ci
45562306a36Sopenharmony_ci	journal->n_sits = cpu_to_le16(before + i);
45662306a36Sopenharmony_ci	return before;
45762306a36Sopenharmony_ci}
45862306a36Sopenharmony_ci
45962306a36Sopenharmony_cistatic inline bool __has_cursum_space(struct f2fs_journal *journal,
46062306a36Sopenharmony_ci							int size, int type)
46162306a36Sopenharmony_ci{
46262306a36Sopenharmony_ci	if (type == NAT_JOURNAL)
46362306a36Sopenharmony_ci		return size <= MAX_NAT_JENTRIES(journal);
46462306a36Sopenharmony_ci	return size <= MAX_SIT_JENTRIES(journal);
46562306a36Sopenharmony_ci}
46662306a36Sopenharmony_ci
46762306a36Sopenharmony_ci/* for inline stuff */
46862306a36Sopenharmony_ci#define DEF_INLINE_RESERVED_SIZE	1
46962306a36Sopenharmony_cistatic inline int get_extra_isize(struct inode *inode);
47062306a36Sopenharmony_cistatic inline int get_inline_xattr_addrs(struct inode *inode);
47162306a36Sopenharmony_ci#define MAX_INLINE_DATA(inode)	(sizeof(__le32) *			\
47262306a36Sopenharmony_ci				(CUR_ADDRS_PER_INODE(inode) -		\
47362306a36Sopenharmony_ci				get_inline_xattr_addrs(inode) -	\
47462306a36Sopenharmony_ci				DEF_INLINE_RESERVED_SIZE))
47562306a36Sopenharmony_ci
47662306a36Sopenharmony_ci/* for inline dir */
47762306a36Sopenharmony_ci#define NR_INLINE_DENTRY(inode)	(MAX_INLINE_DATA(inode) * BITS_PER_BYTE / \
47862306a36Sopenharmony_ci				((SIZE_OF_DIR_ENTRY + F2FS_SLOT_LEN) * \
47962306a36Sopenharmony_ci				BITS_PER_BYTE + 1))
48062306a36Sopenharmony_ci#define INLINE_DENTRY_BITMAP_SIZE(inode) \
48162306a36Sopenharmony_ci	DIV_ROUND_UP(NR_INLINE_DENTRY(inode), BITS_PER_BYTE)
48262306a36Sopenharmony_ci#define INLINE_RESERVED_SIZE(inode)	(MAX_INLINE_DATA(inode) - \
48362306a36Sopenharmony_ci				((SIZE_OF_DIR_ENTRY + F2FS_SLOT_LEN) * \
48462306a36Sopenharmony_ci				NR_INLINE_DENTRY(inode) + \
48562306a36Sopenharmony_ci				INLINE_DENTRY_BITMAP_SIZE(inode)))
48662306a36Sopenharmony_ci
48762306a36Sopenharmony_ci/*
48862306a36Sopenharmony_ci * For INODE and NODE manager
48962306a36Sopenharmony_ci */
49062306a36Sopenharmony_ci/* for directory operations */
49162306a36Sopenharmony_ci
49262306a36Sopenharmony_cistruct f2fs_filename {
49362306a36Sopenharmony_ci	/*
49462306a36Sopenharmony_ci	 * The filename the user specified.  This is NULL for some
49562306a36Sopenharmony_ci	 * filesystem-internal operations, e.g. converting an inline directory
49662306a36Sopenharmony_ci	 * to a non-inline one, or roll-forward recovering an encrypted dentry.
49762306a36Sopenharmony_ci	 */
49862306a36Sopenharmony_ci	const struct qstr *usr_fname;
49962306a36Sopenharmony_ci
50062306a36Sopenharmony_ci	/*
50162306a36Sopenharmony_ci	 * The on-disk filename.  For encrypted directories, this is encrypted.
50262306a36Sopenharmony_ci	 * This may be NULL for lookups in an encrypted dir without the key.
50362306a36Sopenharmony_ci	 */
50462306a36Sopenharmony_ci	struct fscrypt_str disk_name;
50562306a36Sopenharmony_ci
50662306a36Sopenharmony_ci	/* The dirhash of this filename */
50762306a36Sopenharmony_ci	f2fs_hash_t hash;
50862306a36Sopenharmony_ci
50962306a36Sopenharmony_ci#ifdef CONFIG_FS_ENCRYPTION
51062306a36Sopenharmony_ci	/*
51162306a36Sopenharmony_ci	 * For lookups in encrypted directories: either the buffer backing
51262306a36Sopenharmony_ci	 * disk_name, or a buffer that holds the decoded no-key name.
51362306a36Sopenharmony_ci	 */
51462306a36Sopenharmony_ci	struct fscrypt_str crypto_buf;
51562306a36Sopenharmony_ci#endif
51662306a36Sopenharmony_ci#if IS_ENABLED(CONFIG_UNICODE)
51762306a36Sopenharmony_ci	/*
51862306a36Sopenharmony_ci	 * For casefolded directories: the casefolded name, but it's left NULL
51962306a36Sopenharmony_ci	 * if the original name is not valid Unicode, if the original name is
52062306a36Sopenharmony_ci	 * "." or "..", if the directory is both casefolded and encrypted and
52162306a36Sopenharmony_ci	 * its encryption key is unavailable, or if the filesystem is doing an
52262306a36Sopenharmony_ci	 * internal operation where usr_fname is also NULL.  In all these cases
52362306a36Sopenharmony_ci	 * we fall back to treating the name as an opaque byte sequence.
52462306a36Sopenharmony_ci	 */
52562306a36Sopenharmony_ci	struct fscrypt_str cf_name;
52662306a36Sopenharmony_ci#endif
52762306a36Sopenharmony_ci};
52862306a36Sopenharmony_ci
52962306a36Sopenharmony_cistruct f2fs_dentry_ptr {
53062306a36Sopenharmony_ci	struct inode *inode;
53162306a36Sopenharmony_ci	void *bitmap;
53262306a36Sopenharmony_ci	struct f2fs_dir_entry *dentry;
53362306a36Sopenharmony_ci	__u8 (*filename)[F2FS_SLOT_LEN];
53462306a36Sopenharmony_ci	int max;
53562306a36Sopenharmony_ci	int nr_bitmap;
53662306a36Sopenharmony_ci};
53762306a36Sopenharmony_ci
53862306a36Sopenharmony_cistatic inline void make_dentry_ptr_block(struct inode *inode,
53962306a36Sopenharmony_ci		struct f2fs_dentry_ptr *d, struct f2fs_dentry_block *t)
54062306a36Sopenharmony_ci{
54162306a36Sopenharmony_ci	d->inode = inode;
54262306a36Sopenharmony_ci	d->max = NR_DENTRY_IN_BLOCK;
54362306a36Sopenharmony_ci	d->nr_bitmap = SIZE_OF_DENTRY_BITMAP;
54462306a36Sopenharmony_ci	d->bitmap = t->dentry_bitmap;
54562306a36Sopenharmony_ci	d->dentry = t->dentry;
54662306a36Sopenharmony_ci	d->filename = t->filename;
54762306a36Sopenharmony_ci}
54862306a36Sopenharmony_ci
54962306a36Sopenharmony_cistatic inline void make_dentry_ptr_inline(struct inode *inode,
55062306a36Sopenharmony_ci					struct f2fs_dentry_ptr *d, void *t)
55162306a36Sopenharmony_ci{
55262306a36Sopenharmony_ci	int entry_cnt = NR_INLINE_DENTRY(inode);
55362306a36Sopenharmony_ci	int bitmap_size = INLINE_DENTRY_BITMAP_SIZE(inode);
55462306a36Sopenharmony_ci	int reserved_size = INLINE_RESERVED_SIZE(inode);
55562306a36Sopenharmony_ci
55662306a36Sopenharmony_ci	d->inode = inode;
55762306a36Sopenharmony_ci	d->max = entry_cnt;
55862306a36Sopenharmony_ci	d->nr_bitmap = bitmap_size;
55962306a36Sopenharmony_ci	d->bitmap = t;
56062306a36Sopenharmony_ci	d->dentry = t + bitmap_size + reserved_size;
56162306a36Sopenharmony_ci	d->filename = t + bitmap_size + reserved_size +
56262306a36Sopenharmony_ci					SIZE_OF_DIR_ENTRY * entry_cnt;
56362306a36Sopenharmony_ci}
56462306a36Sopenharmony_ci
56562306a36Sopenharmony_ci/*
56662306a36Sopenharmony_ci * XATTR_NODE_OFFSET stores xattrs to one node block per file keeping -1
56762306a36Sopenharmony_ci * as its node offset to distinguish from index node blocks.
56862306a36Sopenharmony_ci * But some bits are used to mark the node block.
56962306a36Sopenharmony_ci */
57062306a36Sopenharmony_ci#define XATTR_NODE_OFFSET	((((unsigned int)-1) << OFFSET_BIT_SHIFT) \
57162306a36Sopenharmony_ci				>> OFFSET_BIT_SHIFT)
57262306a36Sopenharmony_cienum {
57362306a36Sopenharmony_ci	ALLOC_NODE,			/* allocate a new node page if needed */
57462306a36Sopenharmony_ci	LOOKUP_NODE,			/* look up a node without readahead */
57562306a36Sopenharmony_ci	LOOKUP_NODE_RA,			/*
57662306a36Sopenharmony_ci					 * look up a node with readahead called
57762306a36Sopenharmony_ci					 * by get_data_block.
57862306a36Sopenharmony_ci					 */
57962306a36Sopenharmony_ci};
58062306a36Sopenharmony_ci
58162306a36Sopenharmony_ci#define DEFAULT_RETRY_IO_COUNT	8	/* maximum retry read IO or flush count */
58262306a36Sopenharmony_ci
58362306a36Sopenharmony_ci/* congestion wait timeout value, default: 20ms */
58462306a36Sopenharmony_ci#define	DEFAULT_IO_TIMEOUT	(msecs_to_jiffies(20))
58562306a36Sopenharmony_ci
58662306a36Sopenharmony_ci/* maximum retry quota flush count */
58762306a36Sopenharmony_ci#define DEFAULT_RETRY_QUOTA_FLUSH_COUNT		8
58862306a36Sopenharmony_ci
58962306a36Sopenharmony_ci/* maximum retry of EIO'ed page */
59062306a36Sopenharmony_ci#define MAX_RETRY_PAGE_EIO			100
59162306a36Sopenharmony_ci
59262306a36Sopenharmony_ci#define F2FS_LINK_MAX	0xffffffff	/* maximum link count per file */
59362306a36Sopenharmony_ci
59462306a36Sopenharmony_ci#define MAX_DIR_RA_PAGES	4	/* maximum ra pages of dir */
59562306a36Sopenharmony_ci
59662306a36Sopenharmony_ci/* dirty segments threshold for triggering CP */
59762306a36Sopenharmony_ci#define DEFAULT_DIRTY_THRESHOLD		4
59862306a36Sopenharmony_ci
59962306a36Sopenharmony_ci#define RECOVERY_MAX_RA_BLOCKS		BIO_MAX_VECS
60062306a36Sopenharmony_ci#define RECOVERY_MIN_RA_BLOCKS		1
60162306a36Sopenharmony_ci
60262306a36Sopenharmony_ci#define F2FS_ONSTACK_PAGES	16	/* nr of onstack pages */
60362306a36Sopenharmony_ci
60462306a36Sopenharmony_ci/* for in-memory extent cache entry */
60562306a36Sopenharmony_ci#define F2FS_MIN_EXTENT_LEN	64	/* minimum extent length */
60662306a36Sopenharmony_ci
60762306a36Sopenharmony_ci/* number of extent info in extent cache we try to shrink */
60862306a36Sopenharmony_ci#define READ_EXTENT_CACHE_SHRINK_NUMBER	128
60962306a36Sopenharmony_ci
61062306a36Sopenharmony_ci/* number of age extent info in extent cache we try to shrink */
61162306a36Sopenharmony_ci#define AGE_EXTENT_CACHE_SHRINK_NUMBER	128
61262306a36Sopenharmony_ci#define LAST_AGE_WEIGHT			30
61362306a36Sopenharmony_ci#define SAME_AGE_REGION			1024
61462306a36Sopenharmony_ci
61562306a36Sopenharmony_ci/*
61662306a36Sopenharmony_ci * Define data block with age less than 1GB as hot data
61762306a36Sopenharmony_ci * define data block with age less than 10GB but more than 1GB as warm data
61862306a36Sopenharmony_ci */
61962306a36Sopenharmony_ci#define DEF_HOT_DATA_AGE_THRESHOLD	262144
62062306a36Sopenharmony_ci#define DEF_WARM_DATA_AGE_THRESHOLD	2621440
62162306a36Sopenharmony_ci
62262306a36Sopenharmony_ci/* extent cache type */
62362306a36Sopenharmony_cienum extent_type {
62462306a36Sopenharmony_ci	EX_READ,
62562306a36Sopenharmony_ci	EX_BLOCK_AGE,
62662306a36Sopenharmony_ci	NR_EXTENT_CACHES,
62762306a36Sopenharmony_ci};
62862306a36Sopenharmony_ci
62962306a36Sopenharmony_cistruct extent_info {
63062306a36Sopenharmony_ci	unsigned int fofs;		/* start offset in a file */
63162306a36Sopenharmony_ci	unsigned int len;		/* length of the extent */
63262306a36Sopenharmony_ci	union {
63362306a36Sopenharmony_ci		/* read extent_cache */
63462306a36Sopenharmony_ci		struct {
63562306a36Sopenharmony_ci			/* start block address of the extent */
63662306a36Sopenharmony_ci			block_t blk;
63762306a36Sopenharmony_ci#ifdef CONFIG_F2FS_FS_COMPRESSION
63862306a36Sopenharmony_ci			/* physical extent length of compressed blocks */
63962306a36Sopenharmony_ci			unsigned int c_len;
64062306a36Sopenharmony_ci#endif
64162306a36Sopenharmony_ci		};
64262306a36Sopenharmony_ci		/* block age extent_cache */
64362306a36Sopenharmony_ci		struct {
64462306a36Sopenharmony_ci			/* block age of the extent */
64562306a36Sopenharmony_ci			unsigned long long age;
64662306a36Sopenharmony_ci			/* last total blocks allocated */
64762306a36Sopenharmony_ci			unsigned long long last_blocks;
64862306a36Sopenharmony_ci		};
64962306a36Sopenharmony_ci	};
65062306a36Sopenharmony_ci};
65162306a36Sopenharmony_ci
65262306a36Sopenharmony_cistruct extent_node {
65362306a36Sopenharmony_ci	struct rb_node rb_node;		/* rb node located in rb-tree */
65462306a36Sopenharmony_ci	struct extent_info ei;		/* extent info */
65562306a36Sopenharmony_ci	struct list_head list;		/* node in global extent list of sbi */
65662306a36Sopenharmony_ci	struct extent_tree *et;		/* extent tree pointer */
65762306a36Sopenharmony_ci};
65862306a36Sopenharmony_ci
65962306a36Sopenharmony_cistruct extent_tree {
66062306a36Sopenharmony_ci	nid_t ino;			/* inode number */
66162306a36Sopenharmony_ci	enum extent_type type;		/* keep the extent tree type */
66262306a36Sopenharmony_ci	struct rb_root_cached root;	/* root of extent info rb-tree */
66362306a36Sopenharmony_ci	struct extent_node *cached_en;	/* recently accessed extent node */
66462306a36Sopenharmony_ci	struct list_head list;		/* to be used by sbi->zombie_list */
66562306a36Sopenharmony_ci	rwlock_t lock;			/* protect extent info rb-tree */
66662306a36Sopenharmony_ci	atomic_t node_cnt;		/* # of extent node in rb-tree*/
66762306a36Sopenharmony_ci	bool largest_updated;		/* largest extent updated */
66862306a36Sopenharmony_ci	struct extent_info largest;	/* largest cached extent for EX_READ */
66962306a36Sopenharmony_ci};
67062306a36Sopenharmony_ci
67162306a36Sopenharmony_cistruct extent_tree_info {
67262306a36Sopenharmony_ci	struct radix_tree_root extent_tree_root;/* cache extent cache entries */
67362306a36Sopenharmony_ci	struct mutex extent_tree_lock;	/* locking extent radix tree */
67462306a36Sopenharmony_ci	struct list_head extent_list;		/* lru list for shrinker */
67562306a36Sopenharmony_ci	spinlock_t extent_lock;			/* locking extent lru list */
67662306a36Sopenharmony_ci	atomic_t total_ext_tree;		/* extent tree count */
67762306a36Sopenharmony_ci	struct list_head zombie_list;		/* extent zombie tree list */
67862306a36Sopenharmony_ci	atomic_t total_zombie_tree;		/* extent zombie tree count */
67962306a36Sopenharmony_ci	atomic_t total_ext_node;		/* extent info count */
68062306a36Sopenharmony_ci};
68162306a36Sopenharmony_ci
68262306a36Sopenharmony_ci/*
68362306a36Sopenharmony_ci * State of block returned by f2fs_map_blocks.
68462306a36Sopenharmony_ci */
68562306a36Sopenharmony_ci#define F2FS_MAP_NEW		(1U << 0)
68662306a36Sopenharmony_ci#define F2FS_MAP_MAPPED		(1U << 1)
68762306a36Sopenharmony_ci#define F2FS_MAP_DELALLOC	(1U << 2)
68862306a36Sopenharmony_ci#define F2FS_MAP_FLAGS		(F2FS_MAP_NEW | F2FS_MAP_MAPPED |\
68962306a36Sopenharmony_ci				F2FS_MAP_DELALLOC)
69062306a36Sopenharmony_ci
69162306a36Sopenharmony_cistruct f2fs_map_blocks {
69262306a36Sopenharmony_ci	struct block_device *m_bdev;	/* for multi-device dio */
69362306a36Sopenharmony_ci	block_t m_pblk;
69462306a36Sopenharmony_ci	block_t m_lblk;
69562306a36Sopenharmony_ci	unsigned int m_len;
69662306a36Sopenharmony_ci	unsigned int m_flags;
69762306a36Sopenharmony_ci	pgoff_t *m_next_pgofs;		/* point next possible non-hole pgofs */
69862306a36Sopenharmony_ci	pgoff_t *m_next_extent;		/* point to next possible extent */
69962306a36Sopenharmony_ci	int m_seg_type;
70062306a36Sopenharmony_ci	bool m_may_create;		/* indicate it is from write path */
70162306a36Sopenharmony_ci	bool m_multidev_dio;		/* indicate it allows multi-device dio */
70262306a36Sopenharmony_ci};
70362306a36Sopenharmony_ci
70462306a36Sopenharmony_ci/* for flag in get_data_block */
70562306a36Sopenharmony_cienum {
70662306a36Sopenharmony_ci	F2FS_GET_BLOCK_DEFAULT,
70762306a36Sopenharmony_ci	F2FS_GET_BLOCK_FIEMAP,
70862306a36Sopenharmony_ci	F2FS_GET_BLOCK_BMAP,
70962306a36Sopenharmony_ci	F2FS_GET_BLOCK_DIO,
71062306a36Sopenharmony_ci	F2FS_GET_BLOCK_PRE_DIO,
71162306a36Sopenharmony_ci	F2FS_GET_BLOCK_PRE_AIO,
71262306a36Sopenharmony_ci	F2FS_GET_BLOCK_PRECACHE,
71362306a36Sopenharmony_ci};
71462306a36Sopenharmony_ci
71562306a36Sopenharmony_ci/*
71662306a36Sopenharmony_ci * i_advise uses FADVISE_XXX_BIT. We can add additional hints later.
71762306a36Sopenharmony_ci */
71862306a36Sopenharmony_ci#define FADVISE_COLD_BIT	0x01
71962306a36Sopenharmony_ci#define FADVISE_LOST_PINO_BIT	0x02
72062306a36Sopenharmony_ci#define FADVISE_ENCRYPT_BIT	0x04
72162306a36Sopenharmony_ci#define FADVISE_ENC_NAME_BIT	0x08
72262306a36Sopenharmony_ci#define FADVISE_KEEP_SIZE_BIT	0x10
72362306a36Sopenharmony_ci#define FADVISE_HOT_BIT		0x20
72462306a36Sopenharmony_ci#define FADVISE_VERITY_BIT	0x40
72562306a36Sopenharmony_ci#define FADVISE_TRUNC_BIT	0x80
72662306a36Sopenharmony_ci
72762306a36Sopenharmony_ci#define FADVISE_MODIFIABLE_BITS	(FADVISE_COLD_BIT | FADVISE_HOT_BIT)
72862306a36Sopenharmony_ci
72962306a36Sopenharmony_ci#define file_is_cold(inode)	is_file(inode, FADVISE_COLD_BIT)
73062306a36Sopenharmony_ci#define file_set_cold(inode)	set_file(inode, FADVISE_COLD_BIT)
73162306a36Sopenharmony_ci#define file_clear_cold(inode)	clear_file(inode, FADVISE_COLD_BIT)
73262306a36Sopenharmony_ci
73362306a36Sopenharmony_ci#define file_wrong_pino(inode)	is_file(inode, FADVISE_LOST_PINO_BIT)
73462306a36Sopenharmony_ci#define file_lost_pino(inode)	set_file(inode, FADVISE_LOST_PINO_BIT)
73562306a36Sopenharmony_ci#define file_got_pino(inode)	clear_file(inode, FADVISE_LOST_PINO_BIT)
73662306a36Sopenharmony_ci
73762306a36Sopenharmony_ci#define file_is_encrypt(inode)	is_file(inode, FADVISE_ENCRYPT_BIT)
73862306a36Sopenharmony_ci#define file_set_encrypt(inode)	set_file(inode, FADVISE_ENCRYPT_BIT)
73962306a36Sopenharmony_ci
74062306a36Sopenharmony_ci#define file_enc_name(inode)	is_file(inode, FADVISE_ENC_NAME_BIT)
74162306a36Sopenharmony_ci#define file_set_enc_name(inode) set_file(inode, FADVISE_ENC_NAME_BIT)
74262306a36Sopenharmony_ci
74362306a36Sopenharmony_ci#define file_keep_isize(inode)	is_file(inode, FADVISE_KEEP_SIZE_BIT)
74462306a36Sopenharmony_ci#define file_set_keep_isize(inode) set_file(inode, FADVISE_KEEP_SIZE_BIT)
74562306a36Sopenharmony_ci
74662306a36Sopenharmony_ci#define file_is_hot(inode)	is_file(inode, FADVISE_HOT_BIT)
74762306a36Sopenharmony_ci#define file_set_hot(inode)	set_file(inode, FADVISE_HOT_BIT)
74862306a36Sopenharmony_ci#define file_clear_hot(inode)	clear_file(inode, FADVISE_HOT_BIT)
74962306a36Sopenharmony_ci
75062306a36Sopenharmony_ci#define file_is_verity(inode)	is_file(inode, FADVISE_VERITY_BIT)
75162306a36Sopenharmony_ci#define file_set_verity(inode)	set_file(inode, FADVISE_VERITY_BIT)
75262306a36Sopenharmony_ci
75362306a36Sopenharmony_ci#define file_should_truncate(inode)	is_file(inode, FADVISE_TRUNC_BIT)
75462306a36Sopenharmony_ci#define file_need_truncate(inode)	set_file(inode, FADVISE_TRUNC_BIT)
75562306a36Sopenharmony_ci#define file_dont_truncate(inode)	clear_file(inode, FADVISE_TRUNC_BIT)
75662306a36Sopenharmony_ci
75762306a36Sopenharmony_ci#define DEF_DIR_LEVEL		0
75862306a36Sopenharmony_ci
75962306a36Sopenharmony_cienum {
76062306a36Sopenharmony_ci	GC_FAILURE_PIN,
76162306a36Sopenharmony_ci	MAX_GC_FAILURE
76262306a36Sopenharmony_ci};
76362306a36Sopenharmony_ci
76462306a36Sopenharmony_ci/* used for f2fs_inode_info->flags */
76562306a36Sopenharmony_cienum {
76662306a36Sopenharmony_ci	FI_NEW_INODE,		/* indicate newly allocated inode */
76762306a36Sopenharmony_ci	FI_DIRTY_INODE,		/* indicate inode is dirty or not */
76862306a36Sopenharmony_ci	FI_AUTO_RECOVER,	/* indicate inode is recoverable */
76962306a36Sopenharmony_ci	FI_DIRTY_DIR,		/* indicate directory has dirty pages */
77062306a36Sopenharmony_ci	FI_INC_LINK,		/* need to increment i_nlink */
77162306a36Sopenharmony_ci	FI_ACL_MODE,		/* indicate acl mode */
77262306a36Sopenharmony_ci	FI_NO_ALLOC,		/* should not allocate any blocks */
77362306a36Sopenharmony_ci	FI_FREE_NID,		/* free allocated nide */
77462306a36Sopenharmony_ci	FI_NO_EXTENT,		/* not to use the extent cache */
77562306a36Sopenharmony_ci	FI_INLINE_XATTR,	/* used for inline xattr */
77662306a36Sopenharmony_ci	FI_INLINE_DATA,		/* used for inline data*/
77762306a36Sopenharmony_ci	FI_INLINE_DENTRY,	/* used for inline dentry */
77862306a36Sopenharmony_ci	FI_APPEND_WRITE,	/* inode has appended data */
77962306a36Sopenharmony_ci	FI_UPDATE_WRITE,	/* inode has in-place-update data */
78062306a36Sopenharmony_ci	FI_NEED_IPU,		/* used for ipu per file */
78162306a36Sopenharmony_ci	FI_ATOMIC_FILE,		/* indicate atomic file */
78262306a36Sopenharmony_ci	FI_DATA_EXIST,		/* indicate data exists */
78362306a36Sopenharmony_ci	FI_INLINE_DOTS,		/* indicate inline dot dentries */
78462306a36Sopenharmony_ci	FI_SKIP_WRITES,		/* should skip data page writeback */
78562306a36Sopenharmony_ci	FI_OPU_WRITE,		/* used for opu per file */
78662306a36Sopenharmony_ci	FI_DIRTY_FILE,		/* indicate regular/symlink has dirty pages */
78762306a36Sopenharmony_ci	FI_PREALLOCATED_ALL,	/* all blocks for write were preallocated */
78862306a36Sopenharmony_ci	FI_HOT_DATA,		/* indicate file is hot */
78962306a36Sopenharmony_ci	FI_EXTRA_ATTR,		/* indicate file has extra attribute */
79062306a36Sopenharmony_ci	FI_PROJ_INHERIT,	/* indicate file inherits projectid */
79162306a36Sopenharmony_ci	FI_PIN_FILE,		/* indicate file should not be gced */
79262306a36Sopenharmony_ci	FI_VERITY_IN_PROGRESS,	/* building fs-verity Merkle tree */
79362306a36Sopenharmony_ci	FI_COMPRESSED_FILE,	/* indicate file's data can be compressed */
79462306a36Sopenharmony_ci	FI_COMPRESS_CORRUPT,	/* indicate compressed cluster is corrupted */
79562306a36Sopenharmony_ci	FI_MMAP_FILE,		/* indicate file was mmapped */
79662306a36Sopenharmony_ci	FI_ENABLE_COMPRESS,	/* enable compression in "user" compression mode */
79762306a36Sopenharmony_ci	FI_COMPRESS_RELEASED,	/* compressed blocks were released */
79862306a36Sopenharmony_ci	FI_ALIGNED_WRITE,	/* enable aligned write */
79962306a36Sopenharmony_ci	FI_COW_FILE,		/* indicate COW file */
80062306a36Sopenharmony_ci	FI_ATOMIC_COMMITTED,	/* indicate atomic commit completed except disk sync */
80162306a36Sopenharmony_ci	FI_ATOMIC_REPLACE,	/* indicate atomic replace */
80262306a36Sopenharmony_ci	FI_MAX,			/* max flag, never be used */
80362306a36Sopenharmony_ci};
80462306a36Sopenharmony_ci
80562306a36Sopenharmony_cistruct f2fs_inode_info {
80662306a36Sopenharmony_ci	struct inode vfs_inode;		/* serve a vfs inode */
80762306a36Sopenharmony_ci	unsigned long i_flags;		/* keep an inode flags for ioctl */
80862306a36Sopenharmony_ci	unsigned char i_advise;		/* use to give file attribute hints */
80962306a36Sopenharmony_ci	unsigned char i_dir_level;	/* use for dentry level for large dir */
81062306a36Sopenharmony_ci	unsigned int i_current_depth;	/* only for directory depth */
81162306a36Sopenharmony_ci	/* for gc failure statistic */
81262306a36Sopenharmony_ci	unsigned int i_gc_failures[MAX_GC_FAILURE];
81362306a36Sopenharmony_ci	unsigned int i_pino;		/* parent inode number */
81462306a36Sopenharmony_ci	umode_t i_acl_mode;		/* keep file acl mode temporarily */
81562306a36Sopenharmony_ci
81662306a36Sopenharmony_ci	/* Use below internally in f2fs*/
81762306a36Sopenharmony_ci	unsigned long flags[BITS_TO_LONGS(FI_MAX)];	/* use to pass per-file flags */
81862306a36Sopenharmony_ci	struct f2fs_rwsem i_sem;	/* protect fi info */
81962306a36Sopenharmony_ci	atomic_t dirty_pages;		/* # of dirty pages */
82062306a36Sopenharmony_ci	f2fs_hash_t chash;		/* hash value of given file name */
82162306a36Sopenharmony_ci	unsigned int clevel;		/* maximum level of given file name */
82262306a36Sopenharmony_ci	struct task_struct *task;	/* lookup and create consistency */
82362306a36Sopenharmony_ci	struct task_struct *cp_task;	/* separate cp/wb IO stats*/
82462306a36Sopenharmony_ci	struct task_struct *wb_task;	/* indicate inode is in context of writeback */
82562306a36Sopenharmony_ci	nid_t i_xattr_nid;		/* node id that contains xattrs */
82662306a36Sopenharmony_ci	loff_t	last_disk_size;		/* lastly written file size */
82762306a36Sopenharmony_ci	spinlock_t i_size_lock;		/* protect last_disk_size */
82862306a36Sopenharmony_ci
82962306a36Sopenharmony_ci#ifdef CONFIG_QUOTA
83062306a36Sopenharmony_ci	struct dquot __rcu *i_dquot[MAXQUOTAS];
83162306a36Sopenharmony_ci
83262306a36Sopenharmony_ci	/* quota space reservation, managed internally by quota code */
83362306a36Sopenharmony_ci	qsize_t i_reserved_quota;
83462306a36Sopenharmony_ci#endif
83562306a36Sopenharmony_ci	struct list_head dirty_list;	/* dirty list for dirs and files */
83662306a36Sopenharmony_ci	struct list_head gdirty_list;	/* linked in global dirty list */
83762306a36Sopenharmony_ci	struct task_struct *atomic_write_task;	/* store atomic write task */
83862306a36Sopenharmony_ci	struct extent_tree *extent_tree[NR_EXTENT_CACHES];
83962306a36Sopenharmony_ci					/* cached extent_tree entry */
84062306a36Sopenharmony_ci	struct inode *cow_inode;	/* copy-on-write inode for atomic write */
84162306a36Sopenharmony_ci
84262306a36Sopenharmony_ci	/* avoid racing between foreground op and gc */
84362306a36Sopenharmony_ci	struct f2fs_rwsem i_gc_rwsem[2];
84462306a36Sopenharmony_ci	struct f2fs_rwsem i_xattr_sem; /* avoid racing between reading and changing EAs */
84562306a36Sopenharmony_ci
84662306a36Sopenharmony_ci	int i_extra_isize;		/* size of extra space located in i_addr */
84762306a36Sopenharmony_ci	kprojid_t i_projid;		/* id for project quota */
84862306a36Sopenharmony_ci	int i_inline_xattr_size;	/* inline xattr size */
84962306a36Sopenharmony_ci	struct timespec64 i_crtime;	/* inode creation time */
85062306a36Sopenharmony_ci	struct timespec64 i_disk_time[3];/* inode disk times */
85162306a36Sopenharmony_ci
85262306a36Sopenharmony_ci	/* for file compress */
85362306a36Sopenharmony_ci	atomic_t i_compr_blocks;		/* # of compressed blocks */
85462306a36Sopenharmony_ci	unsigned char i_compress_algorithm;	/* algorithm type */
85562306a36Sopenharmony_ci	unsigned char i_log_cluster_size;	/* log of cluster size */
85662306a36Sopenharmony_ci	unsigned char i_compress_level;		/* compress level (lz4hc,zstd) */
85762306a36Sopenharmony_ci	unsigned char i_compress_flag;		/* compress flag */
85862306a36Sopenharmony_ci	unsigned int i_cluster_size;		/* cluster size */
85962306a36Sopenharmony_ci
86062306a36Sopenharmony_ci	unsigned int atomic_write_cnt;
86162306a36Sopenharmony_ci	loff_t original_i_size;		/* original i_size before atomic write */
86262306a36Sopenharmony_ci};
86362306a36Sopenharmony_ci
86462306a36Sopenharmony_cistatic inline void get_read_extent_info(struct extent_info *ext,
86562306a36Sopenharmony_ci					struct f2fs_extent *i_ext)
86662306a36Sopenharmony_ci{
86762306a36Sopenharmony_ci	ext->fofs = le32_to_cpu(i_ext->fofs);
86862306a36Sopenharmony_ci	ext->blk = le32_to_cpu(i_ext->blk);
86962306a36Sopenharmony_ci	ext->len = le32_to_cpu(i_ext->len);
87062306a36Sopenharmony_ci}
87162306a36Sopenharmony_ci
87262306a36Sopenharmony_cistatic inline void set_raw_read_extent(struct extent_info *ext,
87362306a36Sopenharmony_ci					struct f2fs_extent *i_ext)
87462306a36Sopenharmony_ci{
87562306a36Sopenharmony_ci	i_ext->fofs = cpu_to_le32(ext->fofs);
87662306a36Sopenharmony_ci	i_ext->blk = cpu_to_le32(ext->blk);
87762306a36Sopenharmony_ci	i_ext->len = cpu_to_le32(ext->len);
87862306a36Sopenharmony_ci}
87962306a36Sopenharmony_ci
88062306a36Sopenharmony_cistatic inline bool __is_discard_mergeable(struct discard_info *back,
88162306a36Sopenharmony_ci			struct discard_info *front, unsigned int max_len)
88262306a36Sopenharmony_ci{
88362306a36Sopenharmony_ci	return (back->lstart + back->len == front->lstart) &&
88462306a36Sopenharmony_ci		(back->len + front->len <= max_len);
88562306a36Sopenharmony_ci}
88662306a36Sopenharmony_ci
88762306a36Sopenharmony_cistatic inline bool __is_discard_back_mergeable(struct discard_info *cur,
88862306a36Sopenharmony_ci			struct discard_info *back, unsigned int max_len)
88962306a36Sopenharmony_ci{
89062306a36Sopenharmony_ci	return __is_discard_mergeable(back, cur, max_len);
89162306a36Sopenharmony_ci}
89262306a36Sopenharmony_ci
89362306a36Sopenharmony_cistatic inline bool __is_discard_front_mergeable(struct discard_info *cur,
89462306a36Sopenharmony_ci			struct discard_info *front, unsigned int max_len)
89562306a36Sopenharmony_ci{
89662306a36Sopenharmony_ci	return __is_discard_mergeable(cur, front, max_len);
89762306a36Sopenharmony_ci}
89862306a36Sopenharmony_ci
89962306a36Sopenharmony_ci/*
90062306a36Sopenharmony_ci * For free nid management
90162306a36Sopenharmony_ci */
90262306a36Sopenharmony_cienum nid_state {
90362306a36Sopenharmony_ci	FREE_NID,		/* newly added to free nid list */
90462306a36Sopenharmony_ci	PREALLOC_NID,		/* it is preallocated */
90562306a36Sopenharmony_ci	MAX_NID_STATE,
90662306a36Sopenharmony_ci};
90762306a36Sopenharmony_ci
90862306a36Sopenharmony_cienum nat_state {
90962306a36Sopenharmony_ci	TOTAL_NAT,
91062306a36Sopenharmony_ci	DIRTY_NAT,
91162306a36Sopenharmony_ci	RECLAIMABLE_NAT,
91262306a36Sopenharmony_ci	MAX_NAT_STATE,
91362306a36Sopenharmony_ci};
91462306a36Sopenharmony_ci
91562306a36Sopenharmony_cistruct f2fs_nm_info {
91662306a36Sopenharmony_ci	block_t nat_blkaddr;		/* base disk address of NAT */
91762306a36Sopenharmony_ci	nid_t max_nid;			/* maximum possible node ids */
91862306a36Sopenharmony_ci	nid_t available_nids;		/* # of available node ids */
91962306a36Sopenharmony_ci	nid_t next_scan_nid;		/* the next nid to be scanned */
92062306a36Sopenharmony_ci	nid_t max_rf_node_blocks;	/* max # of nodes for recovery */
92162306a36Sopenharmony_ci	unsigned int ram_thresh;	/* control the memory footprint */
92262306a36Sopenharmony_ci	unsigned int ra_nid_pages;	/* # of nid pages to be readaheaded */
92362306a36Sopenharmony_ci	unsigned int dirty_nats_ratio;	/* control dirty nats ratio threshold */
92462306a36Sopenharmony_ci
92562306a36Sopenharmony_ci	/* NAT cache management */
92662306a36Sopenharmony_ci	struct radix_tree_root nat_root;/* root of the nat entry cache */
92762306a36Sopenharmony_ci	struct radix_tree_root nat_set_root;/* root of the nat set cache */
92862306a36Sopenharmony_ci	struct f2fs_rwsem nat_tree_lock;	/* protect nat entry tree */
92962306a36Sopenharmony_ci	struct list_head nat_entries;	/* cached nat entry list (clean) */
93062306a36Sopenharmony_ci	spinlock_t nat_list_lock;	/* protect clean nat entry list */
93162306a36Sopenharmony_ci	unsigned int nat_cnt[MAX_NAT_STATE]; /* the # of cached nat entries */
93262306a36Sopenharmony_ci	unsigned int nat_blocks;	/* # of nat blocks */
93362306a36Sopenharmony_ci
93462306a36Sopenharmony_ci	/* free node ids management */
93562306a36Sopenharmony_ci	struct radix_tree_root free_nid_root;/* root of the free_nid cache */
93662306a36Sopenharmony_ci	struct list_head free_nid_list;		/* list for free nids excluding preallocated nids */
93762306a36Sopenharmony_ci	unsigned int nid_cnt[MAX_NID_STATE];	/* the number of free node id */
93862306a36Sopenharmony_ci	spinlock_t nid_list_lock;	/* protect nid lists ops */
93962306a36Sopenharmony_ci	struct mutex build_lock;	/* lock for build free nids */
94062306a36Sopenharmony_ci	unsigned char **free_nid_bitmap;
94162306a36Sopenharmony_ci	unsigned char *nat_block_bitmap;
94262306a36Sopenharmony_ci	unsigned short *free_nid_count;	/* free nid count of NAT block */
94362306a36Sopenharmony_ci
94462306a36Sopenharmony_ci	/* for checkpoint */
94562306a36Sopenharmony_ci	char *nat_bitmap;		/* NAT bitmap pointer */
94662306a36Sopenharmony_ci
94762306a36Sopenharmony_ci	unsigned int nat_bits_blocks;	/* # of nat bits blocks */
94862306a36Sopenharmony_ci	unsigned char *nat_bits;	/* NAT bits blocks */
94962306a36Sopenharmony_ci	unsigned char *full_nat_bits;	/* full NAT pages */
95062306a36Sopenharmony_ci	unsigned char *empty_nat_bits;	/* empty NAT pages */
95162306a36Sopenharmony_ci#ifdef CONFIG_F2FS_CHECK_FS
95262306a36Sopenharmony_ci	char *nat_bitmap_mir;		/* NAT bitmap mirror */
95362306a36Sopenharmony_ci#endif
95462306a36Sopenharmony_ci	int bitmap_size;		/* bitmap size */
95562306a36Sopenharmony_ci};
95662306a36Sopenharmony_ci
95762306a36Sopenharmony_ci/*
95862306a36Sopenharmony_ci * this structure is used as one of function parameters.
95962306a36Sopenharmony_ci * all the information are dedicated to a given direct node block determined
96062306a36Sopenharmony_ci * by the data offset in a file.
96162306a36Sopenharmony_ci */
96262306a36Sopenharmony_cistruct dnode_of_data {
96362306a36Sopenharmony_ci	struct inode *inode;		/* vfs inode pointer */
96462306a36Sopenharmony_ci	struct page *inode_page;	/* its inode page, NULL is possible */
96562306a36Sopenharmony_ci	struct page *node_page;		/* cached direct node page */
96662306a36Sopenharmony_ci	nid_t nid;			/* node id of the direct node block */
96762306a36Sopenharmony_ci	unsigned int ofs_in_node;	/* data offset in the node page */
96862306a36Sopenharmony_ci	bool inode_page_locked;		/* inode page is locked or not */
96962306a36Sopenharmony_ci	bool node_changed;		/* is node block changed */
97062306a36Sopenharmony_ci	char cur_level;			/* level of hole node page */
97162306a36Sopenharmony_ci	char max_level;			/* level of current page located */
97262306a36Sopenharmony_ci	block_t	data_blkaddr;		/* block address of the node block */
97362306a36Sopenharmony_ci};
97462306a36Sopenharmony_ci
97562306a36Sopenharmony_cistatic inline void set_new_dnode(struct dnode_of_data *dn, struct inode *inode,
97662306a36Sopenharmony_ci		struct page *ipage, struct page *npage, nid_t nid)
97762306a36Sopenharmony_ci{
97862306a36Sopenharmony_ci	memset(dn, 0, sizeof(*dn));
97962306a36Sopenharmony_ci	dn->inode = inode;
98062306a36Sopenharmony_ci	dn->inode_page = ipage;
98162306a36Sopenharmony_ci	dn->node_page = npage;
98262306a36Sopenharmony_ci	dn->nid = nid;
98362306a36Sopenharmony_ci}
98462306a36Sopenharmony_ci
98562306a36Sopenharmony_ci/*
98662306a36Sopenharmony_ci * For SIT manager
98762306a36Sopenharmony_ci *
98862306a36Sopenharmony_ci * By default, there are 6 active log areas across the whole main area.
98962306a36Sopenharmony_ci * When considering hot and cold data separation to reduce cleaning overhead,
99062306a36Sopenharmony_ci * we split 3 for data logs and 3 for node logs as hot, warm, and cold types,
99162306a36Sopenharmony_ci * respectively.
99262306a36Sopenharmony_ci * In the current design, you should not change the numbers intentionally.
99362306a36Sopenharmony_ci * Instead, as a mount option such as active_logs=x, you can use 2, 4, and 6
99462306a36Sopenharmony_ci * logs individually according to the underlying devices. (default: 6)
99562306a36Sopenharmony_ci * Just in case, on-disk layout covers maximum 16 logs that consist of 8 for
99662306a36Sopenharmony_ci * data and 8 for node logs.
99762306a36Sopenharmony_ci */
99862306a36Sopenharmony_ci#define	NR_CURSEG_DATA_TYPE	(3)
99962306a36Sopenharmony_ci#define NR_CURSEG_NODE_TYPE	(3)
100062306a36Sopenharmony_ci#define NR_CURSEG_INMEM_TYPE	(2)
100162306a36Sopenharmony_ci#define NR_CURSEG_RO_TYPE	(2)
100262306a36Sopenharmony_ci#define NR_CURSEG_PERSIST_TYPE	(NR_CURSEG_DATA_TYPE + NR_CURSEG_NODE_TYPE)
100362306a36Sopenharmony_ci#define NR_CURSEG_TYPE		(NR_CURSEG_INMEM_TYPE + NR_CURSEG_PERSIST_TYPE)
100462306a36Sopenharmony_ci
100562306a36Sopenharmony_cienum {
100662306a36Sopenharmony_ci	CURSEG_HOT_DATA	= 0,	/* directory entry blocks */
100762306a36Sopenharmony_ci	CURSEG_WARM_DATA,	/* data blocks */
100862306a36Sopenharmony_ci	CURSEG_COLD_DATA,	/* multimedia or GCed data blocks */
100962306a36Sopenharmony_ci	CURSEG_HOT_NODE,	/* direct node blocks of directory files */
101062306a36Sopenharmony_ci	CURSEG_WARM_NODE,	/* direct node blocks of normal files */
101162306a36Sopenharmony_ci	CURSEG_COLD_NODE,	/* indirect node blocks */
101262306a36Sopenharmony_ci	NR_PERSISTENT_LOG,	/* number of persistent log */
101362306a36Sopenharmony_ci	CURSEG_COLD_DATA_PINNED = NR_PERSISTENT_LOG,
101462306a36Sopenharmony_ci				/* pinned file that needs consecutive block address */
101562306a36Sopenharmony_ci	CURSEG_ALL_DATA_ATGC,	/* SSR alloctor in hot/warm/cold data area */
101662306a36Sopenharmony_ci	NO_CHECK_TYPE,		/* number of persistent & inmem log */
101762306a36Sopenharmony_ci};
101862306a36Sopenharmony_ci
101962306a36Sopenharmony_cistruct flush_cmd {
102062306a36Sopenharmony_ci	struct completion wait;
102162306a36Sopenharmony_ci	struct llist_node llnode;
102262306a36Sopenharmony_ci	nid_t ino;
102362306a36Sopenharmony_ci	int ret;
102462306a36Sopenharmony_ci};
102562306a36Sopenharmony_ci
102662306a36Sopenharmony_cistruct flush_cmd_control {
102762306a36Sopenharmony_ci	struct task_struct *f2fs_issue_flush;	/* flush thread */
102862306a36Sopenharmony_ci	wait_queue_head_t flush_wait_queue;	/* waiting queue for wake-up */
102962306a36Sopenharmony_ci	atomic_t issued_flush;			/* # of issued flushes */
103062306a36Sopenharmony_ci	atomic_t queued_flush;			/* # of queued flushes */
103162306a36Sopenharmony_ci	struct llist_head issue_list;		/* list for command issue */
103262306a36Sopenharmony_ci	struct llist_node *dispatch_list;	/* list for command dispatch */
103362306a36Sopenharmony_ci};
103462306a36Sopenharmony_ci
103562306a36Sopenharmony_cistruct f2fs_sm_info {
103662306a36Sopenharmony_ci	struct sit_info *sit_info;		/* whole segment information */
103762306a36Sopenharmony_ci	struct free_segmap_info *free_info;	/* free segment information */
103862306a36Sopenharmony_ci	struct dirty_seglist_info *dirty_info;	/* dirty segment information */
103962306a36Sopenharmony_ci	struct curseg_info *curseg_array;	/* active segment information */
104062306a36Sopenharmony_ci
104162306a36Sopenharmony_ci	struct f2fs_rwsem curseg_lock;	/* for preventing curseg change */
104262306a36Sopenharmony_ci
104362306a36Sopenharmony_ci	block_t seg0_blkaddr;		/* block address of 0'th segment */
104462306a36Sopenharmony_ci	block_t main_blkaddr;		/* start block address of main area */
104562306a36Sopenharmony_ci	block_t ssa_blkaddr;		/* start block address of SSA area */
104662306a36Sopenharmony_ci
104762306a36Sopenharmony_ci	unsigned int segment_count;	/* total # of segments */
104862306a36Sopenharmony_ci	unsigned int main_segments;	/* # of segments in main area */
104962306a36Sopenharmony_ci	unsigned int reserved_segments;	/* # of reserved segments */
105062306a36Sopenharmony_ci	unsigned int additional_reserved_segments;/* reserved segs for IO align feature */
105162306a36Sopenharmony_ci	unsigned int ovp_segments;	/* # of overprovision segments */
105262306a36Sopenharmony_ci
105362306a36Sopenharmony_ci	/* a threshold to reclaim prefree segments */
105462306a36Sopenharmony_ci	unsigned int rec_prefree_segments;
105562306a36Sopenharmony_ci
105662306a36Sopenharmony_ci	struct list_head sit_entry_set;	/* sit entry set list */
105762306a36Sopenharmony_ci
105862306a36Sopenharmony_ci	unsigned int ipu_policy;	/* in-place-update policy */
105962306a36Sopenharmony_ci	unsigned int min_ipu_util;	/* in-place-update threshold */
106062306a36Sopenharmony_ci	unsigned int min_fsync_blocks;	/* threshold for fsync */
106162306a36Sopenharmony_ci	unsigned int min_seq_blocks;	/* threshold for sequential blocks */
106262306a36Sopenharmony_ci	unsigned int min_hot_blocks;	/* threshold for hot block allocation */
106362306a36Sopenharmony_ci	unsigned int min_ssr_sections;	/* threshold to trigger SSR allocation */
106462306a36Sopenharmony_ci
106562306a36Sopenharmony_ci	/* for flush command control */
106662306a36Sopenharmony_ci	struct flush_cmd_control *fcc_info;
106762306a36Sopenharmony_ci
106862306a36Sopenharmony_ci	/* for discard command control */
106962306a36Sopenharmony_ci	struct discard_cmd_control *dcc_info;
107062306a36Sopenharmony_ci};
107162306a36Sopenharmony_ci
107262306a36Sopenharmony_ci/*
107362306a36Sopenharmony_ci * For superblock
107462306a36Sopenharmony_ci */
107562306a36Sopenharmony_ci/*
107662306a36Sopenharmony_ci * COUNT_TYPE for monitoring
107762306a36Sopenharmony_ci *
107862306a36Sopenharmony_ci * f2fs monitors the number of several block types such as on-writeback,
107962306a36Sopenharmony_ci * dirty dentry blocks, dirty node blocks, and dirty meta blocks.
108062306a36Sopenharmony_ci */
108162306a36Sopenharmony_ci#define WB_DATA_TYPE(p, f)			\
108262306a36Sopenharmony_ci	(f || f2fs_is_cp_guaranteed(p) ? F2FS_WB_CP_DATA : F2FS_WB_DATA)
108362306a36Sopenharmony_cienum count_type {
108462306a36Sopenharmony_ci	F2FS_DIRTY_DENTS,
108562306a36Sopenharmony_ci	F2FS_DIRTY_DATA,
108662306a36Sopenharmony_ci	F2FS_DIRTY_QDATA,
108762306a36Sopenharmony_ci	F2FS_DIRTY_NODES,
108862306a36Sopenharmony_ci	F2FS_DIRTY_META,
108962306a36Sopenharmony_ci	F2FS_DIRTY_IMETA,
109062306a36Sopenharmony_ci	F2FS_WB_CP_DATA,
109162306a36Sopenharmony_ci	F2FS_WB_DATA,
109262306a36Sopenharmony_ci	F2FS_RD_DATA,
109362306a36Sopenharmony_ci	F2FS_RD_NODE,
109462306a36Sopenharmony_ci	F2FS_RD_META,
109562306a36Sopenharmony_ci	F2FS_DIO_WRITE,
109662306a36Sopenharmony_ci	F2FS_DIO_READ,
109762306a36Sopenharmony_ci	NR_COUNT_TYPE,
109862306a36Sopenharmony_ci};
109962306a36Sopenharmony_ci
110062306a36Sopenharmony_ci/*
110162306a36Sopenharmony_ci * The below are the page types of bios used in submit_bio().
110262306a36Sopenharmony_ci * The available types are:
110362306a36Sopenharmony_ci * DATA			User data pages. It operates as async mode.
110462306a36Sopenharmony_ci * NODE			Node pages. It operates as async mode.
110562306a36Sopenharmony_ci * META			FS metadata pages such as SIT, NAT, CP.
110662306a36Sopenharmony_ci * NR_PAGE_TYPE		The number of page types.
110762306a36Sopenharmony_ci * META_FLUSH		Make sure the previous pages are written
110862306a36Sopenharmony_ci *			with waiting the bio's completion
110962306a36Sopenharmony_ci * ...			Only can be used with META.
111062306a36Sopenharmony_ci */
111162306a36Sopenharmony_ci#define PAGE_TYPE_OF_BIO(type)	((type) > META ? META : (type))
111262306a36Sopenharmony_cienum page_type {
111362306a36Sopenharmony_ci	DATA = 0,
111462306a36Sopenharmony_ci	NODE = 1,	/* should not change this */
111562306a36Sopenharmony_ci	META,
111662306a36Sopenharmony_ci	NR_PAGE_TYPE,
111762306a36Sopenharmony_ci	META_FLUSH,
111862306a36Sopenharmony_ci	IPU,		/* the below types are used by tracepoints only. */
111962306a36Sopenharmony_ci	OPU,
112062306a36Sopenharmony_ci};
112162306a36Sopenharmony_ci
112262306a36Sopenharmony_cienum temp_type {
112362306a36Sopenharmony_ci	HOT = 0,	/* must be zero for meta bio */
112462306a36Sopenharmony_ci	WARM,
112562306a36Sopenharmony_ci	COLD,
112662306a36Sopenharmony_ci	NR_TEMP_TYPE,
112762306a36Sopenharmony_ci};
112862306a36Sopenharmony_ci
112962306a36Sopenharmony_cienum need_lock_type {
113062306a36Sopenharmony_ci	LOCK_REQ = 0,
113162306a36Sopenharmony_ci	LOCK_DONE,
113262306a36Sopenharmony_ci	LOCK_RETRY,
113362306a36Sopenharmony_ci};
113462306a36Sopenharmony_ci
113562306a36Sopenharmony_cienum cp_reason_type {
113662306a36Sopenharmony_ci	CP_NO_NEEDED,
113762306a36Sopenharmony_ci	CP_NON_REGULAR,
113862306a36Sopenharmony_ci	CP_COMPRESSED,
113962306a36Sopenharmony_ci	CP_HARDLINK,
114062306a36Sopenharmony_ci	CP_SB_NEED_CP,
114162306a36Sopenharmony_ci	CP_WRONG_PINO,
114262306a36Sopenharmony_ci	CP_NO_SPC_ROLL,
114362306a36Sopenharmony_ci	CP_NODE_NEED_CP,
114462306a36Sopenharmony_ci	CP_FASTBOOT_MODE,
114562306a36Sopenharmony_ci	CP_SPEC_LOG_NUM,
114662306a36Sopenharmony_ci	CP_RECOVER_DIR,
114762306a36Sopenharmony_ci};
114862306a36Sopenharmony_ci
114962306a36Sopenharmony_cienum iostat_type {
115062306a36Sopenharmony_ci	/* WRITE IO */
115162306a36Sopenharmony_ci	APP_DIRECT_IO,			/* app direct write IOs */
115262306a36Sopenharmony_ci	APP_BUFFERED_IO,		/* app buffered write IOs */
115362306a36Sopenharmony_ci	APP_WRITE_IO,			/* app write IOs */
115462306a36Sopenharmony_ci	APP_MAPPED_IO,			/* app mapped IOs */
115562306a36Sopenharmony_ci	APP_BUFFERED_CDATA_IO,		/* app buffered write IOs on compressed file */
115662306a36Sopenharmony_ci	APP_MAPPED_CDATA_IO,		/* app mapped write IOs on compressed file */
115762306a36Sopenharmony_ci	FS_DATA_IO,			/* data IOs from kworker/fsync/reclaimer */
115862306a36Sopenharmony_ci	FS_CDATA_IO,			/* data IOs from kworker/fsync/reclaimer on compressed file */
115962306a36Sopenharmony_ci	FS_NODE_IO,			/* node IOs from kworker/fsync/reclaimer */
116062306a36Sopenharmony_ci	FS_META_IO,			/* meta IOs from kworker/reclaimer */
116162306a36Sopenharmony_ci	FS_GC_DATA_IO,			/* data IOs from forground gc */
116262306a36Sopenharmony_ci	FS_GC_NODE_IO,			/* node IOs from forground gc */
116362306a36Sopenharmony_ci	FS_CP_DATA_IO,			/* data IOs from checkpoint */
116462306a36Sopenharmony_ci	FS_CP_NODE_IO,			/* node IOs from checkpoint */
116562306a36Sopenharmony_ci	FS_CP_META_IO,			/* meta IOs from checkpoint */
116662306a36Sopenharmony_ci
116762306a36Sopenharmony_ci	/* READ IO */
116862306a36Sopenharmony_ci	APP_DIRECT_READ_IO,		/* app direct read IOs */
116962306a36Sopenharmony_ci	APP_BUFFERED_READ_IO,		/* app buffered read IOs */
117062306a36Sopenharmony_ci	APP_READ_IO,			/* app read IOs */
117162306a36Sopenharmony_ci	APP_MAPPED_READ_IO,		/* app mapped read IOs */
117262306a36Sopenharmony_ci	APP_BUFFERED_CDATA_READ_IO,	/* app buffered read IOs on compressed file  */
117362306a36Sopenharmony_ci	APP_MAPPED_CDATA_READ_IO,	/* app mapped read IOs on compressed file  */
117462306a36Sopenharmony_ci	FS_DATA_READ_IO,		/* data read IOs */
117562306a36Sopenharmony_ci	FS_GDATA_READ_IO,		/* data read IOs from background gc */
117662306a36Sopenharmony_ci	FS_CDATA_READ_IO,		/* compressed data read IOs */
117762306a36Sopenharmony_ci	FS_NODE_READ_IO,		/* node read IOs */
117862306a36Sopenharmony_ci	FS_META_READ_IO,		/* meta read IOs */
117962306a36Sopenharmony_ci
118062306a36Sopenharmony_ci	/* other */
118162306a36Sopenharmony_ci	FS_DISCARD_IO,			/* discard */
118262306a36Sopenharmony_ci	FS_FLUSH_IO,			/* flush */
118362306a36Sopenharmony_ci	FS_ZONE_RESET_IO,		/* zone reset */
118462306a36Sopenharmony_ci	NR_IO_TYPE,
118562306a36Sopenharmony_ci};
118662306a36Sopenharmony_ci
118762306a36Sopenharmony_cistruct f2fs_io_info {
118862306a36Sopenharmony_ci	struct f2fs_sb_info *sbi;	/* f2fs_sb_info pointer */
118962306a36Sopenharmony_ci	nid_t ino;		/* inode number */
119062306a36Sopenharmony_ci	enum page_type type;	/* contains DATA/NODE/META/META_FLUSH */
119162306a36Sopenharmony_ci	enum temp_type temp;	/* contains HOT/WARM/COLD */
119262306a36Sopenharmony_ci	enum req_op op;		/* contains REQ_OP_ */
119362306a36Sopenharmony_ci	blk_opf_t op_flags;	/* req_flag_bits */
119462306a36Sopenharmony_ci	block_t new_blkaddr;	/* new block address to be written */
119562306a36Sopenharmony_ci	block_t old_blkaddr;	/* old block address before Cow */
119662306a36Sopenharmony_ci	struct page *page;	/* page to be written */
119762306a36Sopenharmony_ci	struct page *encrypted_page;	/* encrypted page */
119862306a36Sopenharmony_ci	struct page *compressed_page;	/* compressed page */
119962306a36Sopenharmony_ci	struct list_head list;		/* serialize IOs */
120062306a36Sopenharmony_ci	unsigned int compr_blocks;	/* # of compressed block addresses */
120162306a36Sopenharmony_ci	unsigned int need_lock:8;	/* indicate we need to lock cp_rwsem */
120262306a36Sopenharmony_ci	unsigned int version:8;		/* version of the node */
120362306a36Sopenharmony_ci	unsigned int submitted:1;	/* indicate IO submission */
120462306a36Sopenharmony_ci	unsigned int in_list:1;		/* indicate fio is in io_list */
120562306a36Sopenharmony_ci	unsigned int is_por:1;		/* indicate IO is from recovery or not */
120662306a36Sopenharmony_ci	unsigned int retry:1;		/* need to reallocate block address */
120762306a36Sopenharmony_ci	unsigned int encrypted:1;	/* indicate file is encrypted */
120862306a36Sopenharmony_ci	unsigned int post_read:1;	/* require post read */
120962306a36Sopenharmony_ci	enum iostat_type io_type;	/* io type */
121062306a36Sopenharmony_ci	struct writeback_control *io_wbc; /* writeback control */
121162306a36Sopenharmony_ci	struct bio **bio;		/* bio for ipu */
121262306a36Sopenharmony_ci	sector_t *last_block;		/* last block number in bio */
121362306a36Sopenharmony_ci};
121462306a36Sopenharmony_ci
121562306a36Sopenharmony_cistruct bio_entry {
121662306a36Sopenharmony_ci	struct bio *bio;
121762306a36Sopenharmony_ci	struct list_head list;
121862306a36Sopenharmony_ci};
121962306a36Sopenharmony_ci
122062306a36Sopenharmony_ci#define is_read_io(rw) ((rw) == READ)
122162306a36Sopenharmony_cistruct f2fs_bio_info {
122262306a36Sopenharmony_ci	struct f2fs_sb_info *sbi;	/* f2fs superblock */
122362306a36Sopenharmony_ci	struct bio *bio;		/* bios to merge */
122462306a36Sopenharmony_ci	sector_t last_block_in_bio;	/* last block number */
122562306a36Sopenharmony_ci	struct f2fs_io_info fio;	/* store buffered io info. */
122662306a36Sopenharmony_ci#ifdef CONFIG_BLK_DEV_ZONED
122762306a36Sopenharmony_ci	struct completion zone_wait;	/* condition value for the previous open zone to close */
122862306a36Sopenharmony_ci	struct bio *zone_pending_bio;	/* pending bio for the previous zone */
122962306a36Sopenharmony_ci	void *bi_private;		/* previous bi_private for pending bio */
123062306a36Sopenharmony_ci#endif
123162306a36Sopenharmony_ci	struct f2fs_rwsem io_rwsem;	/* blocking op for bio */
123262306a36Sopenharmony_ci	spinlock_t io_lock;		/* serialize DATA/NODE IOs */
123362306a36Sopenharmony_ci	struct list_head io_list;	/* track fios */
123462306a36Sopenharmony_ci	struct list_head bio_list;	/* bio entry list head */
123562306a36Sopenharmony_ci	struct f2fs_rwsem bio_list_lock;	/* lock to protect bio entry list */
123662306a36Sopenharmony_ci};
123762306a36Sopenharmony_ci
123862306a36Sopenharmony_ci#define FDEV(i)				(sbi->devs[i])
123962306a36Sopenharmony_ci#define RDEV(i)				(raw_super->devs[i])
124062306a36Sopenharmony_cistruct f2fs_dev_info {
124162306a36Sopenharmony_ci	struct block_device *bdev;
124262306a36Sopenharmony_ci	char path[MAX_PATH_LEN];
124362306a36Sopenharmony_ci	unsigned int total_segments;
124462306a36Sopenharmony_ci	block_t start_blk;
124562306a36Sopenharmony_ci	block_t end_blk;
124662306a36Sopenharmony_ci#ifdef CONFIG_BLK_DEV_ZONED
124762306a36Sopenharmony_ci	unsigned int nr_blkz;		/* Total number of zones */
124862306a36Sopenharmony_ci	unsigned long *blkz_seq;	/* Bitmap indicating sequential zones */
124962306a36Sopenharmony_ci#endif
125062306a36Sopenharmony_ci};
125162306a36Sopenharmony_ci
125262306a36Sopenharmony_cienum inode_type {
125362306a36Sopenharmony_ci	DIR_INODE,			/* for dirty dir inode */
125462306a36Sopenharmony_ci	FILE_INODE,			/* for dirty regular/symlink inode */
125562306a36Sopenharmony_ci	DIRTY_META,			/* for all dirtied inode metadata */
125662306a36Sopenharmony_ci	NR_INODE_TYPE,
125762306a36Sopenharmony_ci};
125862306a36Sopenharmony_ci
125962306a36Sopenharmony_ci/* for inner inode cache management */
126062306a36Sopenharmony_cistruct inode_management {
126162306a36Sopenharmony_ci	struct radix_tree_root ino_root;	/* ino entry array */
126262306a36Sopenharmony_ci	spinlock_t ino_lock;			/* for ino entry lock */
126362306a36Sopenharmony_ci	struct list_head ino_list;		/* inode list head */
126462306a36Sopenharmony_ci	unsigned long ino_num;			/* number of entries */
126562306a36Sopenharmony_ci};
126662306a36Sopenharmony_ci
126762306a36Sopenharmony_ci/* for GC_AT */
126862306a36Sopenharmony_cistruct atgc_management {
126962306a36Sopenharmony_ci	bool atgc_enabled;			/* ATGC is enabled or not */
127062306a36Sopenharmony_ci	struct rb_root_cached root;		/* root of victim rb-tree */
127162306a36Sopenharmony_ci	struct list_head victim_list;		/* linked with all victim entries */
127262306a36Sopenharmony_ci	unsigned int victim_count;		/* victim count in rb-tree */
127362306a36Sopenharmony_ci	unsigned int candidate_ratio;		/* candidate ratio */
127462306a36Sopenharmony_ci	unsigned int max_candidate_count;	/* max candidate count */
127562306a36Sopenharmony_ci	unsigned int age_weight;		/* age weight, vblock_weight = 100 - age_weight */
127662306a36Sopenharmony_ci	unsigned long long age_threshold;	/* age threshold */
127762306a36Sopenharmony_ci};
127862306a36Sopenharmony_ci
127962306a36Sopenharmony_cistruct f2fs_gc_control {
128062306a36Sopenharmony_ci	unsigned int victim_segno;	/* target victim segment number */
128162306a36Sopenharmony_ci	int init_gc_type;		/* FG_GC or BG_GC */
128262306a36Sopenharmony_ci	bool no_bg_gc;			/* check the space and stop bg_gc */
128362306a36Sopenharmony_ci	bool should_migrate_blocks;	/* should migrate blocks */
128462306a36Sopenharmony_ci	bool err_gc_skipped;		/* return EAGAIN if GC skipped */
128562306a36Sopenharmony_ci	unsigned int nr_free_secs;	/* # of free sections to do GC */
128662306a36Sopenharmony_ci};
128762306a36Sopenharmony_ci
128862306a36Sopenharmony_ci/*
128962306a36Sopenharmony_ci * For s_flag in struct f2fs_sb_info
129062306a36Sopenharmony_ci * Modification on enum should be synchronized with s_flag array
129162306a36Sopenharmony_ci */
129262306a36Sopenharmony_cienum {
129362306a36Sopenharmony_ci	SBI_IS_DIRTY,				/* dirty flag for checkpoint */
129462306a36Sopenharmony_ci	SBI_IS_CLOSE,				/* specify unmounting */
129562306a36Sopenharmony_ci	SBI_NEED_FSCK,				/* need fsck.f2fs to fix */
129662306a36Sopenharmony_ci	SBI_POR_DOING,				/* recovery is doing or not */
129762306a36Sopenharmony_ci	SBI_NEED_SB_WRITE,			/* need to recover superblock */
129862306a36Sopenharmony_ci	SBI_NEED_CP,				/* need to checkpoint */
129962306a36Sopenharmony_ci	SBI_IS_SHUTDOWN,			/* shutdown by ioctl */
130062306a36Sopenharmony_ci	SBI_IS_RECOVERED,			/* recovered orphan/data */
130162306a36Sopenharmony_ci	SBI_CP_DISABLED,			/* CP was disabled last mount */
130262306a36Sopenharmony_ci	SBI_CP_DISABLED_QUICK,			/* CP was disabled quickly */
130362306a36Sopenharmony_ci	SBI_QUOTA_NEED_FLUSH,			/* need to flush quota info in CP */
130462306a36Sopenharmony_ci	SBI_QUOTA_SKIP_FLUSH,			/* skip flushing quota in current CP */
130562306a36Sopenharmony_ci	SBI_QUOTA_NEED_REPAIR,			/* quota file may be corrupted */
130662306a36Sopenharmony_ci	SBI_IS_RESIZEFS,			/* resizefs is in process */
130762306a36Sopenharmony_ci	SBI_IS_FREEZING,			/* freezefs is in process */
130862306a36Sopenharmony_ci	SBI_IS_WRITABLE,			/* remove ro mountoption transiently */
130962306a36Sopenharmony_ci	MAX_SBI_FLAG,
131062306a36Sopenharmony_ci};
131162306a36Sopenharmony_ci
131262306a36Sopenharmony_cienum {
131362306a36Sopenharmony_ci	CP_TIME,
131462306a36Sopenharmony_ci	REQ_TIME,
131562306a36Sopenharmony_ci	DISCARD_TIME,
131662306a36Sopenharmony_ci	GC_TIME,
131762306a36Sopenharmony_ci	DISABLE_TIME,
131862306a36Sopenharmony_ci	UMOUNT_DISCARD_TIMEOUT,
131962306a36Sopenharmony_ci	MAX_TIME,
132062306a36Sopenharmony_ci};
132162306a36Sopenharmony_ci
132262306a36Sopenharmony_ci/* Note that you need to keep synchronization with this gc_mode_names array */
132362306a36Sopenharmony_cienum {
132462306a36Sopenharmony_ci	GC_NORMAL,
132562306a36Sopenharmony_ci	GC_IDLE_CB,
132662306a36Sopenharmony_ci	GC_IDLE_GREEDY,
132762306a36Sopenharmony_ci	GC_IDLE_AT,
132862306a36Sopenharmony_ci	GC_URGENT_HIGH,
132962306a36Sopenharmony_ci	GC_URGENT_LOW,
133062306a36Sopenharmony_ci	GC_URGENT_MID,
133162306a36Sopenharmony_ci	MAX_GC_MODE,
133262306a36Sopenharmony_ci};
133362306a36Sopenharmony_ci
133462306a36Sopenharmony_cienum {
133562306a36Sopenharmony_ci	BGGC_MODE_ON,		/* background gc is on */
133662306a36Sopenharmony_ci	BGGC_MODE_OFF,		/* background gc is off */
133762306a36Sopenharmony_ci	BGGC_MODE_SYNC,		/*
133862306a36Sopenharmony_ci				 * background gc is on, migrating blocks
133962306a36Sopenharmony_ci				 * like foreground gc
134062306a36Sopenharmony_ci				 */
134162306a36Sopenharmony_ci};
134262306a36Sopenharmony_ci
134362306a36Sopenharmony_cienum {
134462306a36Sopenharmony_ci	FS_MODE_ADAPTIVE,		/* use both lfs/ssr allocation */
134562306a36Sopenharmony_ci	FS_MODE_LFS,			/* use lfs allocation only */
134662306a36Sopenharmony_ci	FS_MODE_FRAGMENT_SEG,		/* segment fragmentation mode */
134762306a36Sopenharmony_ci	FS_MODE_FRAGMENT_BLK,		/* block fragmentation mode */
134862306a36Sopenharmony_ci};
134962306a36Sopenharmony_ci
135062306a36Sopenharmony_cienum {
135162306a36Sopenharmony_ci	ALLOC_MODE_DEFAULT,	/* stay default */
135262306a36Sopenharmony_ci	ALLOC_MODE_REUSE,	/* reuse segments as much as possible */
135362306a36Sopenharmony_ci};
135462306a36Sopenharmony_ci
135562306a36Sopenharmony_cienum fsync_mode {
135662306a36Sopenharmony_ci	FSYNC_MODE_POSIX,	/* fsync follows posix semantics */
135762306a36Sopenharmony_ci	FSYNC_MODE_STRICT,	/* fsync behaves in line with ext4 */
135862306a36Sopenharmony_ci	FSYNC_MODE_NOBARRIER,	/* fsync behaves nobarrier based on posix */
135962306a36Sopenharmony_ci};
136062306a36Sopenharmony_ci
136162306a36Sopenharmony_cienum {
136262306a36Sopenharmony_ci	COMPR_MODE_FS,		/*
136362306a36Sopenharmony_ci				 * automatically compress compression
136462306a36Sopenharmony_ci				 * enabled files
136562306a36Sopenharmony_ci				 */
136662306a36Sopenharmony_ci	COMPR_MODE_USER,	/*
136762306a36Sopenharmony_ci				 * automatical compression is disabled.
136862306a36Sopenharmony_ci				 * user can control the file compression
136962306a36Sopenharmony_ci				 * using ioctls
137062306a36Sopenharmony_ci				 */
137162306a36Sopenharmony_ci};
137262306a36Sopenharmony_ci
137362306a36Sopenharmony_cienum {
137462306a36Sopenharmony_ci	DISCARD_UNIT_BLOCK,	/* basic discard unit is block */
137562306a36Sopenharmony_ci	DISCARD_UNIT_SEGMENT,	/* basic discard unit is segment */
137662306a36Sopenharmony_ci	DISCARD_UNIT_SECTION,	/* basic discard unit is section */
137762306a36Sopenharmony_ci};
137862306a36Sopenharmony_ci
137962306a36Sopenharmony_cienum {
138062306a36Sopenharmony_ci	MEMORY_MODE_NORMAL,	/* memory mode for normal devices */
138162306a36Sopenharmony_ci	MEMORY_MODE_LOW,	/* memory mode for low memry devices */
138262306a36Sopenharmony_ci};
138362306a36Sopenharmony_ci
138462306a36Sopenharmony_cienum errors_option {
138562306a36Sopenharmony_ci	MOUNT_ERRORS_READONLY,	/* remount fs ro on errors */
138662306a36Sopenharmony_ci	MOUNT_ERRORS_CONTINUE,	/* continue on errors */
138762306a36Sopenharmony_ci	MOUNT_ERRORS_PANIC,	/* panic on errors */
138862306a36Sopenharmony_ci};
138962306a36Sopenharmony_ci
139062306a36Sopenharmony_cienum {
139162306a36Sopenharmony_ci	BACKGROUND,
139262306a36Sopenharmony_ci	FOREGROUND,
139362306a36Sopenharmony_ci	MAX_CALL_TYPE,
139462306a36Sopenharmony_ci	TOTAL_CALL = FOREGROUND,
139562306a36Sopenharmony_ci};
139662306a36Sopenharmony_ci
139762306a36Sopenharmony_cistatic inline int f2fs_test_bit(unsigned int nr, char *addr);
139862306a36Sopenharmony_cistatic inline void f2fs_set_bit(unsigned int nr, char *addr);
139962306a36Sopenharmony_cistatic inline void f2fs_clear_bit(unsigned int nr, char *addr);
140062306a36Sopenharmony_ci
140162306a36Sopenharmony_ci/*
140262306a36Sopenharmony_ci * Layout of f2fs page.private:
140362306a36Sopenharmony_ci *
140462306a36Sopenharmony_ci * Layout A: lowest bit should be 1
140562306a36Sopenharmony_ci * | bit0 = 1 | bit1 | bit2 | ... | bit MAX | private data .... |
140662306a36Sopenharmony_ci * bit 0	PAGE_PRIVATE_NOT_POINTER
140762306a36Sopenharmony_ci * bit 1	PAGE_PRIVATE_DUMMY_WRITE
140862306a36Sopenharmony_ci * bit 2	PAGE_PRIVATE_ONGOING_MIGRATION
140962306a36Sopenharmony_ci * bit 3	PAGE_PRIVATE_INLINE_INODE
141062306a36Sopenharmony_ci * bit 4	PAGE_PRIVATE_REF_RESOURCE
141162306a36Sopenharmony_ci * bit 5-	f2fs private data
141262306a36Sopenharmony_ci *
141362306a36Sopenharmony_ci * Layout B: lowest bit should be 0
141462306a36Sopenharmony_ci * page.private is a wrapped pointer.
141562306a36Sopenharmony_ci */
141662306a36Sopenharmony_cienum {
141762306a36Sopenharmony_ci	PAGE_PRIVATE_NOT_POINTER,		/* private contains non-pointer data */
141862306a36Sopenharmony_ci	PAGE_PRIVATE_DUMMY_WRITE,		/* data page for padding aligned IO */
141962306a36Sopenharmony_ci	PAGE_PRIVATE_ONGOING_MIGRATION,		/* data page which is on-going migrating */
142062306a36Sopenharmony_ci	PAGE_PRIVATE_INLINE_INODE,		/* inode page contains inline data */
142162306a36Sopenharmony_ci	PAGE_PRIVATE_REF_RESOURCE,		/* dirty page has referenced resources */
142262306a36Sopenharmony_ci	PAGE_PRIVATE_MAX
142362306a36Sopenharmony_ci};
142462306a36Sopenharmony_ci
142562306a36Sopenharmony_ci/* For compression */
142662306a36Sopenharmony_cienum compress_algorithm_type {
142762306a36Sopenharmony_ci	COMPRESS_LZO,
142862306a36Sopenharmony_ci	COMPRESS_LZ4,
142962306a36Sopenharmony_ci	COMPRESS_ZSTD,
143062306a36Sopenharmony_ci	COMPRESS_LZORLE,
143162306a36Sopenharmony_ci	COMPRESS_MAX,
143262306a36Sopenharmony_ci};
143362306a36Sopenharmony_ci
143462306a36Sopenharmony_cienum compress_flag {
143562306a36Sopenharmony_ci	COMPRESS_CHKSUM,
143662306a36Sopenharmony_ci	COMPRESS_MAX_FLAG,
143762306a36Sopenharmony_ci};
143862306a36Sopenharmony_ci
143962306a36Sopenharmony_ci#define	COMPRESS_WATERMARK			20
144062306a36Sopenharmony_ci#define	COMPRESS_PERCENT			20
144162306a36Sopenharmony_ci
144262306a36Sopenharmony_ci#define COMPRESS_DATA_RESERVED_SIZE		4
144362306a36Sopenharmony_cistruct compress_data {
144462306a36Sopenharmony_ci	__le32 clen;			/* compressed data size */
144562306a36Sopenharmony_ci	__le32 chksum;			/* compressed data chksum */
144662306a36Sopenharmony_ci	__le32 reserved[COMPRESS_DATA_RESERVED_SIZE];	/* reserved */
144762306a36Sopenharmony_ci	u8 cdata[];			/* compressed data */
144862306a36Sopenharmony_ci};
144962306a36Sopenharmony_ci
145062306a36Sopenharmony_ci#define COMPRESS_HEADER_SIZE	(sizeof(struct compress_data))
145162306a36Sopenharmony_ci
145262306a36Sopenharmony_ci#define F2FS_COMPRESSED_PAGE_MAGIC	0xF5F2C000
145362306a36Sopenharmony_ci
145462306a36Sopenharmony_ci#define F2FS_ZSTD_DEFAULT_CLEVEL	1
145562306a36Sopenharmony_ci
145662306a36Sopenharmony_ci#define	COMPRESS_LEVEL_OFFSET	8
145762306a36Sopenharmony_ci
145862306a36Sopenharmony_ci/* compress context */
145962306a36Sopenharmony_cistruct compress_ctx {
146062306a36Sopenharmony_ci	struct inode *inode;		/* inode the context belong to */
146162306a36Sopenharmony_ci	pgoff_t cluster_idx;		/* cluster index number */
146262306a36Sopenharmony_ci	unsigned int cluster_size;	/* page count in cluster */
146362306a36Sopenharmony_ci	unsigned int log_cluster_size;	/* log of cluster size */
146462306a36Sopenharmony_ci	struct page **rpages;		/* pages store raw data in cluster */
146562306a36Sopenharmony_ci	unsigned int nr_rpages;		/* total page number in rpages */
146662306a36Sopenharmony_ci	struct page **cpages;		/* pages store compressed data in cluster */
146762306a36Sopenharmony_ci	unsigned int nr_cpages;		/* total page number in cpages */
146862306a36Sopenharmony_ci	unsigned int valid_nr_cpages;	/* valid page number in cpages */
146962306a36Sopenharmony_ci	void *rbuf;			/* virtual mapped address on rpages */
147062306a36Sopenharmony_ci	struct compress_data *cbuf;	/* virtual mapped address on cpages */
147162306a36Sopenharmony_ci	size_t rlen;			/* valid data length in rbuf */
147262306a36Sopenharmony_ci	size_t clen;			/* valid data length in cbuf */
147362306a36Sopenharmony_ci	void *private;			/* payload buffer for specified compression algorithm */
147462306a36Sopenharmony_ci	void *private2;			/* extra payload buffer */
147562306a36Sopenharmony_ci};
147662306a36Sopenharmony_ci
147762306a36Sopenharmony_ci/* compress context for write IO path */
147862306a36Sopenharmony_cistruct compress_io_ctx {
147962306a36Sopenharmony_ci	u32 magic;			/* magic number to indicate page is compressed */
148062306a36Sopenharmony_ci	struct inode *inode;		/* inode the context belong to */
148162306a36Sopenharmony_ci	struct page **rpages;		/* pages store raw data in cluster */
148262306a36Sopenharmony_ci	unsigned int nr_rpages;		/* total page number in rpages */
148362306a36Sopenharmony_ci	atomic_t pending_pages;		/* in-flight compressed page count */
148462306a36Sopenharmony_ci};
148562306a36Sopenharmony_ci
148662306a36Sopenharmony_ci/* Context for decompressing one cluster on the read IO path */
148762306a36Sopenharmony_cistruct decompress_io_ctx {
148862306a36Sopenharmony_ci	u32 magic;			/* magic number to indicate page is compressed */
148962306a36Sopenharmony_ci	struct inode *inode;		/* inode the context belong to */
149062306a36Sopenharmony_ci	pgoff_t cluster_idx;		/* cluster index number */
149162306a36Sopenharmony_ci	unsigned int cluster_size;	/* page count in cluster */
149262306a36Sopenharmony_ci	unsigned int log_cluster_size;	/* log of cluster size */
149362306a36Sopenharmony_ci	struct page **rpages;		/* pages store raw data in cluster */
149462306a36Sopenharmony_ci	unsigned int nr_rpages;		/* total page number in rpages */
149562306a36Sopenharmony_ci	struct page **cpages;		/* pages store compressed data in cluster */
149662306a36Sopenharmony_ci	unsigned int nr_cpages;		/* total page number in cpages */
149762306a36Sopenharmony_ci	struct page **tpages;		/* temp pages to pad holes in cluster */
149862306a36Sopenharmony_ci	void *rbuf;			/* virtual mapped address on rpages */
149962306a36Sopenharmony_ci	struct compress_data *cbuf;	/* virtual mapped address on cpages */
150062306a36Sopenharmony_ci	size_t rlen;			/* valid data length in rbuf */
150162306a36Sopenharmony_ci	size_t clen;			/* valid data length in cbuf */
150262306a36Sopenharmony_ci
150362306a36Sopenharmony_ci	/*
150462306a36Sopenharmony_ci	 * The number of compressed pages remaining to be read in this cluster.
150562306a36Sopenharmony_ci	 * This is initially nr_cpages.  It is decremented by 1 each time a page
150662306a36Sopenharmony_ci	 * has been read (or failed to be read).  When it reaches 0, the cluster
150762306a36Sopenharmony_ci	 * is decompressed (or an error is reported).
150862306a36Sopenharmony_ci	 *
150962306a36Sopenharmony_ci	 * If an error occurs before all the pages have been submitted for I/O,
151062306a36Sopenharmony_ci	 * then this will never reach 0.  In this case the I/O submitter is
151162306a36Sopenharmony_ci	 * responsible for calling f2fs_decompress_end_io() instead.
151262306a36Sopenharmony_ci	 */
151362306a36Sopenharmony_ci	atomic_t remaining_pages;
151462306a36Sopenharmony_ci
151562306a36Sopenharmony_ci	/*
151662306a36Sopenharmony_ci	 * Number of references to this decompress_io_ctx.
151762306a36Sopenharmony_ci	 *
151862306a36Sopenharmony_ci	 * One reference is held for I/O completion.  This reference is dropped
151962306a36Sopenharmony_ci	 * after the pagecache pages are updated and unlocked -- either after
152062306a36Sopenharmony_ci	 * decompression (and verity if enabled), or after an error.
152162306a36Sopenharmony_ci	 *
152262306a36Sopenharmony_ci	 * In addition, each compressed page holds a reference while it is in a
152362306a36Sopenharmony_ci	 * bio.  These references are necessary prevent compressed pages from
152462306a36Sopenharmony_ci	 * being freed while they are still in a bio.
152562306a36Sopenharmony_ci	 */
152662306a36Sopenharmony_ci	refcount_t refcnt;
152762306a36Sopenharmony_ci
152862306a36Sopenharmony_ci	bool failed;			/* IO error occurred before decompression? */
152962306a36Sopenharmony_ci	bool need_verity;		/* need fs-verity verification after decompression? */
153062306a36Sopenharmony_ci	void *private;			/* payload buffer for specified decompression algorithm */
153162306a36Sopenharmony_ci	void *private2;			/* extra payload buffer */
153262306a36Sopenharmony_ci	struct work_struct verity_work;	/* work to verify the decompressed pages */
153362306a36Sopenharmony_ci	struct work_struct free_work;	/* work for late free this structure itself */
153462306a36Sopenharmony_ci};
153562306a36Sopenharmony_ci
153662306a36Sopenharmony_ci#define NULL_CLUSTER			((unsigned int)(~0))
153762306a36Sopenharmony_ci#define MIN_COMPRESS_LOG_SIZE		2
153862306a36Sopenharmony_ci#define MAX_COMPRESS_LOG_SIZE		8
153962306a36Sopenharmony_ci#define MAX_COMPRESS_WINDOW_SIZE(log_size)	((PAGE_SIZE) << (log_size))
154062306a36Sopenharmony_ci
154162306a36Sopenharmony_cistruct f2fs_sb_info {
154262306a36Sopenharmony_ci	struct super_block *sb;			/* pointer to VFS super block */
154362306a36Sopenharmony_ci	struct proc_dir_entry *s_proc;		/* proc entry */
154462306a36Sopenharmony_ci	struct f2fs_super_block *raw_super;	/* raw super block pointer */
154562306a36Sopenharmony_ci	struct f2fs_rwsem sb_lock;		/* lock for raw super block */
154662306a36Sopenharmony_ci	int valid_super_block;			/* valid super block no */
154762306a36Sopenharmony_ci	unsigned long s_flag;				/* flags for sbi */
154862306a36Sopenharmony_ci	struct mutex writepages;		/* mutex for writepages() */
154962306a36Sopenharmony_ci
155062306a36Sopenharmony_ci#ifdef CONFIG_BLK_DEV_ZONED
155162306a36Sopenharmony_ci	unsigned int blocks_per_blkz;		/* F2FS blocks per zone */
155262306a36Sopenharmony_ci#endif
155362306a36Sopenharmony_ci
155462306a36Sopenharmony_ci	/* for node-related operations */
155562306a36Sopenharmony_ci	struct f2fs_nm_info *nm_info;		/* node manager */
155662306a36Sopenharmony_ci	struct inode *node_inode;		/* cache node blocks */
155762306a36Sopenharmony_ci
155862306a36Sopenharmony_ci	/* for segment-related operations */
155962306a36Sopenharmony_ci	struct f2fs_sm_info *sm_info;		/* segment manager */
156062306a36Sopenharmony_ci
156162306a36Sopenharmony_ci	/* for bio operations */
156262306a36Sopenharmony_ci	struct f2fs_bio_info *write_io[NR_PAGE_TYPE];	/* for write bios */
156362306a36Sopenharmony_ci	/* keep migration IO order for LFS mode */
156462306a36Sopenharmony_ci	struct f2fs_rwsem io_order_lock;
156562306a36Sopenharmony_ci	mempool_t *write_io_dummy;		/* Dummy pages */
156662306a36Sopenharmony_ci	pgoff_t page_eio_ofs[NR_PAGE_TYPE];	/* EIO page offset */
156762306a36Sopenharmony_ci	int page_eio_cnt[NR_PAGE_TYPE];		/* EIO count */
156862306a36Sopenharmony_ci
156962306a36Sopenharmony_ci	/* for checkpoint */
157062306a36Sopenharmony_ci	struct f2fs_checkpoint *ckpt;		/* raw checkpoint pointer */
157162306a36Sopenharmony_ci	int cur_cp_pack;			/* remain current cp pack */
157262306a36Sopenharmony_ci	spinlock_t cp_lock;			/* for flag in ckpt */
157362306a36Sopenharmony_ci	struct inode *meta_inode;		/* cache meta blocks */
157462306a36Sopenharmony_ci	struct f2fs_rwsem cp_global_sem;	/* checkpoint procedure lock */
157562306a36Sopenharmony_ci	struct f2fs_rwsem cp_rwsem;		/* blocking FS operations */
157662306a36Sopenharmony_ci	struct f2fs_rwsem node_write;		/* locking node writes */
157762306a36Sopenharmony_ci	struct f2fs_rwsem node_change;	/* locking node change */
157862306a36Sopenharmony_ci	wait_queue_head_t cp_wait;
157962306a36Sopenharmony_ci	unsigned long last_time[MAX_TIME];	/* to store time in jiffies */
158062306a36Sopenharmony_ci	long interval_time[MAX_TIME];		/* to store thresholds */
158162306a36Sopenharmony_ci	struct ckpt_req_control cprc_info;	/* for checkpoint request control */
158262306a36Sopenharmony_ci
158362306a36Sopenharmony_ci	struct inode_management im[MAX_INO_ENTRY];	/* manage inode cache */
158462306a36Sopenharmony_ci
158562306a36Sopenharmony_ci	spinlock_t fsync_node_lock;		/* for node entry lock */
158662306a36Sopenharmony_ci	struct list_head fsync_node_list;	/* node list head */
158762306a36Sopenharmony_ci	unsigned int fsync_seg_id;		/* sequence id */
158862306a36Sopenharmony_ci	unsigned int fsync_node_num;		/* number of node entries */
158962306a36Sopenharmony_ci
159062306a36Sopenharmony_ci	/* for orphan inode, use 0'th array */
159162306a36Sopenharmony_ci	unsigned int max_orphans;		/* max orphan inodes */
159262306a36Sopenharmony_ci
159362306a36Sopenharmony_ci	/* for inode management */
159462306a36Sopenharmony_ci	struct list_head inode_list[NR_INODE_TYPE];	/* dirty inode list */
159562306a36Sopenharmony_ci	spinlock_t inode_lock[NR_INODE_TYPE];	/* for dirty inode list lock */
159662306a36Sopenharmony_ci	struct mutex flush_lock;		/* for flush exclusion */
159762306a36Sopenharmony_ci
159862306a36Sopenharmony_ci	/* for extent tree cache */
159962306a36Sopenharmony_ci	struct extent_tree_info extent_tree[NR_EXTENT_CACHES];
160062306a36Sopenharmony_ci	atomic64_t allocated_data_blocks;	/* for block age extent_cache */
160162306a36Sopenharmony_ci
160262306a36Sopenharmony_ci	/* The threshold used for hot and warm data seperation*/
160362306a36Sopenharmony_ci	unsigned int hot_data_age_threshold;
160462306a36Sopenharmony_ci	unsigned int warm_data_age_threshold;
160562306a36Sopenharmony_ci	unsigned int last_age_weight;
160662306a36Sopenharmony_ci
160762306a36Sopenharmony_ci	/* basic filesystem units */
160862306a36Sopenharmony_ci	unsigned int log_sectors_per_block;	/* log2 sectors per block */
160962306a36Sopenharmony_ci	unsigned int log_blocksize;		/* log2 block size */
161062306a36Sopenharmony_ci	unsigned int blocksize;			/* block size */
161162306a36Sopenharmony_ci	unsigned int root_ino_num;		/* root inode number*/
161262306a36Sopenharmony_ci	unsigned int node_ino_num;		/* node inode number*/
161362306a36Sopenharmony_ci	unsigned int meta_ino_num;		/* meta inode number*/
161462306a36Sopenharmony_ci	unsigned int log_blocks_per_seg;	/* log2 blocks per segment */
161562306a36Sopenharmony_ci	unsigned int blocks_per_seg;		/* blocks per segment */
161662306a36Sopenharmony_ci	unsigned int unusable_blocks_per_sec;	/* unusable blocks per section */
161762306a36Sopenharmony_ci	unsigned int segs_per_sec;		/* segments per section */
161862306a36Sopenharmony_ci	unsigned int secs_per_zone;		/* sections per zone */
161962306a36Sopenharmony_ci	unsigned int total_sections;		/* total section count */
162062306a36Sopenharmony_ci	unsigned int total_node_count;		/* total node block count */
162162306a36Sopenharmony_ci	unsigned int total_valid_node_count;	/* valid node block count */
162262306a36Sopenharmony_ci	int dir_level;				/* directory level */
162362306a36Sopenharmony_ci	bool readdir_ra;			/* readahead inode in readdir */
162462306a36Sopenharmony_ci	u64 max_io_bytes;			/* max io bytes to merge IOs */
162562306a36Sopenharmony_ci
162662306a36Sopenharmony_ci	block_t user_block_count;		/* # of user blocks */
162762306a36Sopenharmony_ci	block_t total_valid_block_count;	/* # of valid blocks */
162862306a36Sopenharmony_ci	block_t discard_blks;			/* discard command candidats */
162962306a36Sopenharmony_ci	block_t last_valid_block_count;		/* for recovery */
163062306a36Sopenharmony_ci	block_t reserved_blocks;		/* configurable reserved blocks */
163162306a36Sopenharmony_ci	block_t current_reserved_blocks;	/* current reserved blocks */
163262306a36Sopenharmony_ci
163362306a36Sopenharmony_ci	/* Additional tracking for no checkpoint mode */
163462306a36Sopenharmony_ci	block_t unusable_block_count;		/* # of blocks saved by last cp */
163562306a36Sopenharmony_ci
163662306a36Sopenharmony_ci	unsigned int nquota_files;		/* # of quota sysfile */
163762306a36Sopenharmony_ci	struct f2fs_rwsem quota_sem;		/* blocking cp for flags */
163862306a36Sopenharmony_ci
163962306a36Sopenharmony_ci	/* # of pages, see count_type */
164062306a36Sopenharmony_ci	atomic_t nr_pages[NR_COUNT_TYPE];
164162306a36Sopenharmony_ci	/* # of allocated blocks */
164262306a36Sopenharmony_ci	struct percpu_counter alloc_valid_block_count;
164362306a36Sopenharmony_ci	/* # of node block writes as roll forward recovery */
164462306a36Sopenharmony_ci	struct percpu_counter rf_node_block_count;
164562306a36Sopenharmony_ci
164662306a36Sopenharmony_ci	/* writeback control */
164762306a36Sopenharmony_ci	atomic_t wb_sync_req[META];	/* count # of WB_SYNC threads */
164862306a36Sopenharmony_ci
164962306a36Sopenharmony_ci	/* valid inode count */
165062306a36Sopenharmony_ci	struct percpu_counter total_valid_inode_count;
165162306a36Sopenharmony_ci
165262306a36Sopenharmony_ci	struct f2fs_mount_info mount_opt;	/* mount options */
165362306a36Sopenharmony_ci
165462306a36Sopenharmony_ci	/* for cleaning operations */
165562306a36Sopenharmony_ci	struct f2fs_rwsem gc_lock;		/*
165662306a36Sopenharmony_ci						 * semaphore for GC, avoid
165762306a36Sopenharmony_ci						 * race between GC and GC or CP
165862306a36Sopenharmony_ci						 */
165962306a36Sopenharmony_ci	struct f2fs_gc_kthread	*gc_thread;	/* GC thread */
166062306a36Sopenharmony_ci	struct atgc_management am;		/* atgc management */
166162306a36Sopenharmony_ci	unsigned int cur_victim_sec;		/* current victim section num */
166262306a36Sopenharmony_ci	unsigned int gc_mode;			/* current GC state */
166362306a36Sopenharmony_ci	unsigned int next_victim_seg[2];	/* next segment in victim section */
166462306a36Sopenharmony_ci	spinlock_t gc_remaining_trials_lock;
166562306a36Sopenharmony_ci	/* remaining trial count for GC_URGENT_* and GC_IDLE_* */
166662306a36Sopenharmony_ci	unsigned int gc_remaining_trials;
166762306a36Sopenharmony_ci
166862306a36Sopenharmony_ci	/* for skip statistic */
166962306a36Sopenharmony_ci	unsigned long long skipped_gc_rwsem;		/* FG_GC only */
167062306a36Sopenharmony_ci
167162306a36Sopenharmony_ci	/* threshold for gc trials on pinned files */
167262306a36Sopenharmony_ci	u64 gc_pin_file_threshold;
167362306a36Sopenharmony_ci	struct f2fs_rwsem pin_sem;
167462306a36Sopenharmony_ci
167562306a36Sopenharmony_ci	/* maximum # of trials to find a victim segment for SSR and GC */
167662306a36Sopenharmony_ci	unsigned int max_victim_search;
167762306a36Sopenharmony_ci	/* migration granularity of garbage collection, unit: segment */
167862306a36Sopenharmony_ci	unsigned int migration_granularity;
167962306a36Sopenharmony_ci
168062306a36Sopenharmony_ci	/*
168162306a36Sopenharmony_ci	 * for stat information.
168262306a36Sopenharmony_ci	 * one is for the LFS mode, and the other is for the SSR mode.
168362306a36Sopenharmony_ci	 */
168462306a36Sopenharmony_ci#ifdef CONFIG_F2FS_STAT_FS
168562306a36Sopenharmony_ci	struct f2fs_stat_info *stat_info;	/* FS status information */
168662306a36Sopenharmony_ci	atomic_t meta_count[META_MAX];		/* # of meta blocks */
168762306a36Sopenharmony_ci	unsigned int segment_count[2];		/* # of allocated segments */
168862306a36Sopenharmony_ci	unsigned int block_count[2];		/* # of allocated blocks */
168962306a36Sopenharmony_ci	atomic_t inplace_count;		/* # of inplace update */
169062306a36Sopenharmony_ci	/* # of lookup extent cache */
169162306a36Sopenharmony_ci	atomic64_t total_hit_ext[NR_EXTENT_CACHES];
169262306a36Sopenharmony_ci	/* # of hit rbtree extent node */
169362306a36Sopenharmony_ci	atomic64_t read_hit_rbtree[NR_EXTENT_CACHES];
169462306a36Sopenharmony_ci	/* # of hit cached extent node */
169562306a36Sopenharmony_ci	atomic64_t read_hit_cached[NR_EXTENT_CACHES];
169662306a36Sopenharmony_ci	/* # of hit largest extent node in read extent cache */
169762306a36Sopenharmony_ci	atomic64_t read_hit_largest;
169862306a36Sopenharmony_ci	atomic_t inline_xattr;			/* # of inline_xattr inodes */
169962306a36Sopenharmony_ci	atomic_t inline_inode;			/* # of inline_data inodes */
170062306a36Sopenharmony_ci	atomic_t inline_dir;			/* # of inline_dentry inodes */
170162306a36Sopenharmony_ci	atomic_t compr_inode;			/* # of compressed inodes */
170262306a36Sopenharmony_ci	atomic64_t compr_blocks;		/* # of compressed blocks */
170362306a36Sopenharmony_ci	atomic_t swapfile_inode;		/* # of swapfile inodes */
170462306a36Sopenharmony_ci	atomic_t atomic_files;			/* # of opened atomic file */
170562306a36Sopenharmony_ci	atomic_t max_aw_cnt;			/* max # of atomic writes */
170662306a36Sopenharmony_ci	unsigned int io_skip_bggc;		/* skip background gc for in-flight IO */
170762306a36Sopenharmony_ci	unsigned int other_skip_bggc;		/* skip background gc for other reasons */
170862306a36Sopenharmony_ci	unsigned int ndirty_inode[NR_INODE_TYPE];	/* # of dirty inodes */
170962306a36Sopenharmony_ci	atomic_t cp_call_count[MAX_CALL_TYPE];	/* # of cp call */
171062306a36Sopenharmony_ci#endif
171162306a36Sopenharmony_ci	spinlock_t stat_lock;			/* lock for stat operations */
171262306a36Sopenharmony_ci
171362306a36Sopenharmony_ci	/* to attach REQ_META|REQ_FUA flags */
171462306a36Sopenharmony_ci	unsigned int data_io_flag;
171562306a36Sopenharmony_ci	unsigned int node_io_flag;
171662306a36Sopenharmony_ci
171762306a36Sopenharmony_ci	/* For sysfs support */
171862306a36Sopenharmony_ci	struct kobject s_kobj;			/* /sys/fs/f2fs/<devname> */
171962306a36Sopenharmony_ci	struct completion s_kobj_unregister;
172062306a36Sopenharmony_ci
172162306a36Sopenharmony_ci	struct kobject s_stat_kobj;		/* /sys/fs/f2fs/<devname>/stat */
172262306a36Sopenharmony_ci	struct completion s_stat_kobj_unregister;
172362306a36Sopenharmony_ci
172462306a36Sopenharmony_ci	struct kobject s_feature_list_kobj;		/* /sys/fs/f2fs/<devname>/feature_list */
172562306a36Sopenharmony_ci	struct completion s_feature_list_kobj_unregister;
172662306a36Sopenharmony_ci
172762306a36Sopenharmony_ci	/* For shrinker support */
172862306a36Sopenharmony_ci	struct list_head s_list;
172962306a36Sopenharmony_ci	struct mutex umount_mutex;
173062306a36Sopenharmony_ci	unsigned int shrinker_run_no;
173162306a36Sopenharmony_ci
173262306a36Sopenharmony_ci	/* For multi devices */
173362306a36Sopenharmony_ci	int s_ndevs;				/* number of devices */
173462306a36Sopenharmony_ci	struct f2fs_dev_info *devs;		/* for device list */
173562306a36Sopenharmony_ci	unsigned int dirty_device;		/* for checkpoint data flush */
173662306a36Sopenharmony_ci	spinlock_t dev_lock;			/* protect dirty_device */
173762306a36Sopenharmony_ci	bool aligned_blksize;			/* all devices has the same logical blksize */
173862306a36Sopenharmony_ci
173962306a36Sopenharmony_ci	/* For write statistics */
174062306a36Sopenharmony_ci	u64 sectors_written_start;
174162306a36Sopenharmony_ci	u64 kbytes_written;
174262306a36Sopenharmony_ci
174362306a36Sopenharmony_ci	/* Reference to checksum algorithm driver via cryptoapi */
174462306a36Sopenharmony_ci	struct crypto_shash *s_chksum_driver;
174562306a36Sopenharmony_ci
174662306a36Sopenharmony_ci	/* Precomputed FS UUID checksum for seeding other checksums */
174762306a36Sopenharmony_ci	__u32 s_chksum_seed;
174862306a36Sopenharmony_ci
174962306a36Sopenharmony_ci	struct workqueue_struct *post_read_wq;	/* post read workqueue */
175062306a36Sopenharmony_ci
175162306a36Sopenharmony_ci	/*
175262306a36Sopenharmony_ci	 * If we are in irq context, let's update error information into
175362306a36Sopenharmony_ci	 * on-disk superblock in the work.
175462306a36Sopenharmony_ci	 */
175562306a36Sopenharmony_ci	struct work_struct s_error_work;
175662306a36Sopenharmony_ci	unsigned char errors[MAX_F2FS_ERRORS];		/* error flags */
175762306a36Sopenharmony_ci	unsigned char stop_reason[MAX_STOP_REASON];	/* stop reason */
175862306a36Sopenharmony_ci	spinlock_t error_lock;			/* protect errors/stop_reason array */
175962306a36Sopenharmony_ci	bool error_dirty;			/* errors of sb is dirty */
176062306a36Sopenharmony_ci
176162306a36Sopenharmony_ci	struct kmem_cache *inline_xattr_slab;	/* inline xattr entry */
176262306a36Sopenharmony_ci	unsigned int inline_xattr_slab_size;	/* default inline xattr slab size */
176362306a36Sopenharmony_ci
176462306a36Sopenharmony_ci	/* For reclaimed segs statistics per each GC mode */
176562306a36Sopenharmony_ci	unsigned int gc_segment_mode;		/* GC state for reclaimed segments */
176662306a36Sopenharmony_ci	unsigned int gc_reclaimed_segs[MAX_GC_MODE];	/* Reclaimed segs for each mode */
176762306a36Sopenharmony_ci
176862306a36Sopenharmony_ci	unsigned long seq_file_ra_mul;		/* multiplier for ra_pages of seq. files in fadvise */
176962306a36Sopenharmony_ci
177062306a36Sopenharmony_ci	int max_fragment_chunk;			/* max chunk size for block fragmentation mode */
177162306a36Sopenharmony_ci	int max_fragment_hole;			/* max hole size for block fragmentation mode */
177262306a36Sopenharmony_ci
177362306a36Sopenharmony_ci	/* For atomic write statistics */
177462306a36Sopenharmony_ci	atomic64_t current_atomic_write;
177562306a36Sopenharmony_ci	s64 peak_atomic_write;
177662306a36Sopenharmony_ci	u64 committed_atomic_block;
177762306a36Sopenharmony_ci	u64 revoked_atomic_block;
177862306a36Sopenharmony_ci
177962306a36Sopenharmony_ci#ifdef CONFIG_F2FS_FS_COMPRESSION
178062306a36Sopenharmony_ci	struct kmem_cache *page_array_slab;	/* page array entry */
178162306a36Sopenharmony_ci	unsigned int page_array_slab_size;	/* default page array slab size */
178262306a36Sopenharmony_ci
178362306a36Sopenharmony_ci	/* For runtime compression statistics */
178462306a36Sopenharmony_ci	u64 compr_written_block;
178562306a36Sopenharmony_ci	u64 compr_saved_block;
178662306a36Sopenharmony_ci	u32 compr_new_inode;
178762306a36Sopenharmony_ci
178862306a36Sopenharmony_ci	/* For compressed block cache */
178962306a36Sopenharmony_ci	struct inode *compress_inode;		/* cache compressed blocks */
179062306a36Sopenharmony_ci	unsigned int compress_percent;		/* cache page percentage */
179162306a36Sopenharmony_ci	unsigned int compress_watermark;	/* cache page watermark */
179262306a36Sopenharmony_ci	atomic_t compress_page_hit;		/* cache hit count */
179362306a36Sopenharmony_ci#endif
179462306a36Sopenharmony_ci
179562306a36Sopenharmony_ci#ifdef CONFIG_F2FS_IOSTAT
179662306a36Sopenharmony_ci	/* For app/fs IO statistics */
179762306a36Sopenharmony_ci	spinlock_t iostat_lock;
179862306a36Sopenharmony_ci	unsigned long long iostat_count[NR_IO_TYPE];
179962306a36Sopenharmony_ci	unsigned long long iostat_bytes[NR_IO_TYPE];
180062306a36Sopenharmony_ci	unsigned long long prev_iostat_bytes[NR_IO_TYPE];
180162306a36Sopenharmony_ci	bool iostat_enable;
180262306a36Sopenharmony_ci	unsigned long iostat_next_period;
180362306a36Sopenharmony_ci	unsigned int iostat_period_ms;
180462306a36Sopenharmony_ci
180562306a36Sopenharmony_ci	/* For io latency related statistics info in one iostat period */
180662306a36Sopenharmony_ci	spinlock_t iostat_lat_lock;
180762306a36Sopenharmony_ci	struct iostat_lat_info *iostat_io_lat;
180862306a36Sopenharmony_ci#endif
180962306a36Sopenharmony_ci};
181062306a36Sopenharmony_ci
181162306a36Sopenharmony_ci#ifdef CONFIG_F2FS_FAULT_INJECTION
181262306a36Sopenharmony_ci#define time_to_inject(sbi, type) __time_to_inject(sbi, type, __func__,	\
181362306a36Sopenharmony_ci									__builtin_return_address(0))
181462306a36Sopenharmony_cistatic inline bool __time_to_inject(struct f2fs_sb_info *sbi, int type,
181562306a36Sopenharmony_ci				const char *func, const char *parent_func)
181662306a36Sopenharmony_ci{
181762306a36Sopenharmony_ci	struct f2fs_fault_info *ffi = &F2FS_OPTION(sbi).fault_info;
181862306a36Sopenharmony_ci
181962306a36Sopenharmony_ci	if (!ffi->inject_rate)
182062306a36Sopenharmony_ci		return false;
182162306a36Sopenharmony_ci
182262306a36Sopenharmony_ci	if (!IS_FAULT_SET(ffi, type))
182362306a36Sopenharmony_ci		return false;
182462306a36Sopenharmony_ci
182562306a36Sopenharmony_ci	atomic_inc(&ffi->inject_ops);
182662306a36Sopenharmony_ci	if (atomic_read(&ffi->inject_ops) >= ffi->inject_rate) {
182762306a36Sopenharmony_ci		atomic_set(&ffi->inject_ops, 0);
182862306a36Sopenharmony_ci		printk_ratelimited("%sF2FS-fs (%s) : inject %s in %s of %pS\n",
182962306a36Sopenharmony_ci			KERN_INFO, sbi->sb->s_id, f2fs_fault_name[type],
183062306a36Sopenharmony_ci			func, parent_func);
183162306a36Sopenharmony_ci		return true;
183262306a36Sopenharmony_ci	}
183362306a36Sopenharmony_ci	return false;
183462306a36Sopenharmony_ci}
183562306a36Sopenharmony_ci#else
183662306a36Sopenharmony_cistatic inline bool time_to_inject(struct f2fs_sb_info *sbi, int type)
183762306a36Sopenharmony_ci{
183862306a36Sopenharmony_ci	return false;
183962306a36Sopenharmony_ci}
184062306a36Sopenharmony_ci#endif
184162306a36Sopenharmony_ci
184262306a36Sopenharmony_ci/*
184362306a36Sopenharmony_ci * Test if the mounted volume is a multi-device volume.
184462306a36Sopenharmony_ci *   - For a single regular disk volume, sbi->s_ndevs is 0.
184562306a36Sopenharmony_ci *   - For a single zoned disk volume, sbi->s_ndevs is 1.
184662306a36Sopenharmony_ci *   - For a multi-device volume, sbi->s_ndevs is always 2 or more.
184762306a36Sopenharmony_ci */
184862306a36Sopenharmony_cistatic inline bool f2fs_is_multi_device(struct f2fs_sb_info *sbi)
184962306a36Sopenharmony_ci{
185062306a36Sopenharmony_ci	return sbi->s_ndevs > 1;
185162306a36Sopenharmony_ci}
185262306a36Sopenharmony_ci
185362306a36Sopenharmony_cistatic inline void f2fs_update_time(struct f2fs_sb_info *sbi, int type)
185462306a36Sopenharmony_ci{
185562306a36Sopenharmony_ci	unsigned long now = jiffies;
185662306a36Sopenharmony_ci
185762306a36Sopenharmony_ci	sbi->last_time[type] = now;
185862306a36Sopenharmony_ci
185962306a36Sopenharmony_ci	/* DISCARD_TIME and GC_TIME are based on REQ_TIME */
186062306a36Sopenharmony_ci	if (type == REQ_TIME) {
186162306a36Sopenharmony_ci		sbi->last_time[DISCARD_TIME] = now;
186262306a36Sopenharmony_ci		sbi->last_time[GC_TIME] = now;
186362306a36Sopenharmony_ci	}
186462306a36Sopenharmony_ci}
186562306a36Sopenharmony_ci
186662306a36Sopenharmony_cistatic inline bool f2fs_time_over(struct f2fs_sb_info *sbi, int type)
186762306a36Sopenharmony_ci{
186862306a36Sopenharmony_ci	unsigned long interval = sbi->interval_time[type] * HZ;
186962306a36Sopenharmony_ci
187062306a36Sopenharmony_ci	return time_after(jiffies, sbi->last_time[type] + interval);
187162306a36Sopenharmony_ci}
187262306a36Sopenharmony_ci
187362306a36Sopenharmony_cistatic inline unsigned int f2fs_time_to_wait(struct f2fs_sb_info *sbi,
187462306a36Sopenharmony_ci						int type)
187562306a36Sopenharmony_ci{
187662306a36Sopenharmony_ci	unsigned long interval = sbi->interval_time[type] * HZ;
187762306a36Sopenharmony_ci	unsigned int wait_ms = 0;
187862306a36Sopenharmony_ci	long delta;
187962306a36Sopenharmony_ci
188062306a36Sopenharmony_ci	delta = (sbi->last_time[type] + interval) - jiffies;
188162306a36Sopenharmony_ci	if (delta > 0)
188262306a36Sopenharmony_ci		wait_ms = jiffies_to_msecs(delta);
188362306a36Sopenharmony_ci
188462306a36Sopenharmony_ci	return wait_ms;
188562306a36Sopenharmony_ci}
188662306a36Sopenharmony_ci
188762306a36Sopenharmony_ci/*
188862306a36Sopenharmony_ci * Inline functions
188962306a36Sopenharmony_ci */
189062306a36Sopenharmony_cistatic inline u32 __f2fs_crc32(struct f2fs_sb_info *sbi, u32 crc,
189162306a36Sopenharmony_ci			      const void *address, unsigned int length)
189262306a36Sopenharmony_ci{
189362306a36Sopenharmony_ci	struct {
189462306a36Sopenharmony_ci		struct shash_desc shash;
189562306a36Sopenharmony_ci		char ctx[4];
189662306a36Sopenharmony_ci	} desc;
189762306a36Sopenharmony_ci	int err;
189862306a36Sopenharmony_ci
189962306a36Sopenharmony_ci	BUG_ON(crypto_shash_descsize(sbi->s_chksum_driver) != sizeof(desc.ctx));
190062306a36Sopenharmony_ci
190162306a36Sopenharmony_ci	desc.shash.tfm = sbi->s_chksum_driver;
190262306a36Sopenharmony_ci	*(u32 *)desc.ctx = crc;
190362306a36Sopenharmony_ci
190462306a36Sopenharmony_ci	err = crypto_shash_update(&desc.shash, address, length);
190562306a36Sopenharmony_ci	BUG_ON(err);
190662306a36Sopenharmony_ci
190762306a36Sopenharmony_ci	return *(u32 *)desc.ctx;
190862306a36Sopenharmony_ci}
190962306a36Sopenharmony_ci
191062306a36Sopenharmony_cistatic inline u32 f2fs_crc32(struct f2fs_sb_info *sbi, const void *address,
191162306a36Sopenharmony_ci			   unsigned int length)
191262306a36Sopenharmony_ci{
191362306a36Sopenharmony_ci	return __f2fs_crc32(sbi, F2FS_SUPER_MAGIC, address, length);
191462306a36Sopenharmony_ci}
191562306a36Sopenharmony_ci
191662306a36Sopenharmony_cistatic inline bool f2fs_crc_valid(struct f2fs_sb_info *sbi, __u32 blk_crc,
191762306a36Sopenharmony_ci				  void *buf, size_t buf_size)
191862306a36Sopenharmony_ci{
191962306a36Sopenharmony_ci	return f2fs_crc32(sbi, buf, buf_size) == blk_crc;
192062306a36Sopenharmony_ci}
192162306a36Sopenharmony_ci
192262306a36Sopenharmony_cistatic inline u32 f2fs_chksum(struct f2fs_sb_info *sbi, u32 crc,
192362306a36Sopenharmony_ci			      const void *address, unsigned int length)
192462306a36Sopenharmony_ci{
192562306a36Sopenharmony_ci	return __f2fs_crc32(sbi, crc, address, length);
192662306a36Sopenharmony_ci}
192762306a36Sopenharmony_ci
192862306a36Sopenharmony_cistatic inline struct f2fs_inode_info *F2FS_I(struct inode *inode)
192962306a36Sopenharmony_ci{
193062306a36Sopenharmony_ci	return container_of(inode, struct f2fs_inode_info, vfs_inode);
193162306a36Sopenharmony_ci}
193262306a36Sopenharmony_ci
193362306a36Sopenharmony_cistatic inline struct f2fs_sb_info *F2FS_SB(struct super_block *sb)
193462306a36Sopenharmony_ci{
193562306a36Sopenharmony_ci	return sb->s_fs_info;
193662306a36Sopenharmony_ci}
193762306a36Sopenharmony_ci
193862306a36Sopenharmony_cistatic inline struct f2fs_sb_info *F2FS_I_SB(struct inode *inode)
193962306a36Sopenharmony_ci{
194062306a36Sopenharmony_ci	return F2FS_SB(inode->i_sb);
194162306a36Sopenharmony_ci}
194262306a36Sopenharmony_ci
194362306a36Sopenharmony_cistatic inline struct f2fs_sb_info *F2FS_M_SB(struct address_space *mapping)
194462306a36Sopenharmony_ci{
194562306a36Sopenharmony_ci	return F2FS_I_SB(mapping->host);
194662306a36Sopenharmony_ci}
194762306a36Sopenharmony_ci
194862306a36Sopenharmony_cistatic inline struct f2fs_sb_info *F2FS_P_SB(struct page *page)
194962306a36Sopenharmony_ci{
195062306a36Sopenharmony_ci	return F2FS_M_SB(page_file_mapping(page));
195162306a36Sopenharmony_ci}
195262306a36Sopenharmony_ci
195362306a36Sopenharmony_cistatic inline struct f2fs_super_block *F2FS_RAW_SUPER(struct f2fs_sb_info *sbi)
195462306a36Sopenharmony_ci{
195562306a36Sopenharmony_ci	return (struct f2fs_super_block *)(sbi->raw_super);
195662306a36Sopenharmony_ci}
195762306a36Sopenharmony_ci
195862306a36Sopenharmony_cistatic inline struct f2fs_checkpoint *F2FS_CKPT(struct f2fs_sb_info *sbi)
195962306a36Sopenharmony_ci{
196062306a36Sopenharmony_ci	return (struct f2fs_checkpoint *)(sbi->ckpt);
196162306a36Sopenharmony_ci}
196262306a36Sopenharmony_ci
196362306a36Sopenharmony_cistatic inline struct f2fs_node *F2FS_NODE(struct page *page)
196462306a36Sopenharmony_ci{
196562306a36Sopenharmony_ci	return (struct f2fs_node *)page_address(page);
196662306a36Sopenharmony_ci}
196762306a36Sopenharmony_ci
196862306a36Sopenharmony_cistatic inline struct f2fs_inode *F2FS_INODE(struct page *page)
196962306a36Sopenharmony_ci{
197062306a36Sopenharmony_ci	return &((struct f2fs_node *)page_address(page))->i;
197162306a36Sopenharmony_ci}
197262306a36Sopenharmony_ci
197362306a36Sopenharmony_cistatic inline struct f2fs_nm_info *NM_I(struct f2fs_sb_info *sbi)
197462306a36Sopenharmony_ci{
197562306a36Sopenharmony_ci	return (struct f2fs_nm_info *)(sbi->nm_info);
197662306a36Sopenharmony_ci}
197762306a36Sopenharmony_ci
197862306a36Sopenharmony_cistatic inline struct f2fs_sm_info *SM_I(struct f2fs_sb_info *sbi)
197962306a36Sopenharmony_ci{
198062306a36Sopenharmony_ci	return (struct f2fs_sm_info *)(sbi->sm_info);
198162306a36Sopenharmony_ci}
198262306a36Sopenharmony_ci
198362306a36Sopenharmony_cistatic inline struct sit_info *SIT_I(struct f2fs_sb_info *sbi)
198462306a36Sopenharmony_ci{
198562306a36Sopenharmony_ci	return (struct sit_info *)(SM_I(sbi)->sit_info);
198662306a36Sopenharmony_ci}
198762306a36Sopenharmony_ci
198862306a36Sopenharmony_cistatic inline struct free_segmap_info *FREE_I(struct f2fs_sb_info *sbi)
198962306a36Sopenharmony_ci{
199062306a36Sopenharmony_ci	return (struct free_segmap_info *)(SM_I(sbi)->free_info);
199162306a36Sopenharmony_ci}
199262306a36Sopenharmony_ci
199362306a36Sopenharmony_cistatic inline struct dirty_seglist_info *DIRTY_I(struct f2fs_sb_info *sbi)
199462306a36Sopenharmony_ci{
199562306a36Sopenharmony_ci	return (struct dirty_seglist_info *)(SM_I(sbi)->dirty_info);
199662306a36Sopenharmony_ci}
199762306a36Sopenharmony_ci
199862306a36Sopenharmony_cistatic inline struct address_space *META_MAPPING(struct f2fs_sb_info *sbi)
199962306a36Sopenharmony_ci{
200062306a36Sopenharmony_ci	return sbi->meta_inode->i_mapping;
200162306a36Sopenharmony_ci}
200262306a36Sopenharmony_ci
200362306a36Sopenharmony_cistatic inline struct address_space *NODE_MAPPING(struct f2fs_sb_info *sbi)
200462306a36Sopenharmony_ci{
200562306a36Sopenharmony_ci	return sbi->node_inode->i_mapping;
200662306a36Sopenharmony_ci}
200762306a36Sopenharmony_ci
200862306a36Sopenharmony_cistatic inline bool is_sbi_flag_set(struct f2fs_sb_info *sbi, unsigned int type)
200962306a36Sopenharmony_ci{
201062306a36Sopenharmony_ci	return test_bit(type, &sbi->s_flag);
201162306a36Sopenharmony_ci}
201262306a36Sopenharmony_ci
201362306a36Sopenharmony_cistatic inline void set_sbi_flag(struct f2fs_sb_info *sbi, unsigned int type)
201462306a36Sopenharmony_ci{
201562306a36Sopenharmony_ci	set_bit(type, &sbi->s_flag);
201662306a36Sopenharmony_ci}
201762306a36Sopenharmony_ci
201862306a36Sopenharmony_cistatic inline void clear_sbi_flag(struct f2fs_sb_info *sbi, unsigned int type)
201962306a36Sopenharmony_ci{
202062306a36Sopenharmony_ci	clear_bit(type, &sbi->s_flag);
202162306a36Sopenharmony_ci}
202262306a36Sopenharmony_ci
202362306a36Sopenharmony_cistatic inline unsigned long long cur_cp_version(struct f2fs_checkpoint *cp)
202462306a36Sopenharmony_ci{
202562306a36Sopenharmony_ci	return le64_to_cpu(cp->checkpoint_ver);
202662306a36Sopenharmony_ci}
202762306a36Sopenharmony_ci
202862306a36Sopenharmony_cistatic inline unsigned long f2fs_qf_ino(struct super_block *sb, int type)
202962306a36Sopenharmony_ci{
203062306a36Sopenharmony_ci	if (type < F2FS_MAX_QUOTAS)
203162306a36Sopenharmony_ci		return le32_to_cpu(F2FS_SB(sb)->raw_super->qf_ino[type]);
203262306a36Sopenharmony_ci	return 0;
203362306a36Sopenharmony_ci}
203462306a36Sopenharmony_ci
203562306a36Sopenharmony_cistatic inline __u64 cur_cp_crc(struct f2fs_checkpoint *cp)
203662306a36Sopenharmony_ci{
203762306a36Sopenharmony_ci	size_t crc_offset = le32_to_cpu(cp->checksum_offset);
203862306a36Sopenharmony_ci	return le32_to_cpu(*((__le32 *)((unsigned char *)cp + crc_offset)));
203962306a36Sopenharmony_ci}
204062306a36Sopenharmony_ci
204162306a36Sopenharmony_cistatic inline bool __is_set_ckpt_flags(struct f2fs_checkpoint *cp, unsigned int f)
204262306a36Sopenharmony_ci{
204362306a36Sopenharmony_ci	unsigned int ckpt_flags = le32_to_cpu(cp->ckpt_flags);
204462306a36Sopenharmony_ci
204562306a36Sopenharmony_ci	return ckpt_flags & f;
204662306a36Sopenharmony_ci}
204762306a36Sopenharmony_ci
204862306a36Sopenharmony_cistatic inline bool is_set_ckpt_flags(struct f2fs_sb_info *sbi, unsigned int f)
204962306a36Sopenharmony_ci{
205062306a36Sopenharmony_ci	return __is_set_ckpt_flags(F2FS_CKPT(sbi), f);
205162306a36Sopenharmony_ci}
205262306a36Sopenharmony_ci
205362306a36Sopenharmony_cistatic inline void __set_ckpt_flags(struct f2fs_checkpoint *cp, unsigned int f)
205462306a36Sopenharmony_ci{
205562306a36Sopenharmony_ci	unsigned int ckpt_flags;
205662306a36Sopenharmony_ci
205762306a36Sopenharmony_ci	ckpt_flags = le32_to_cpu(cp->ckpt_flags);
205862306a36Sopenharmony_ci	ckpt_flags |= f;
205962306a36Sopenharmony_ci	cp->ckpt_flags = cpu_to_le32(ckpt_flags);
206062306a36Sopenharmony_ci}
206162306a36Sopenharmony_ci
206262306a36Sopenharmony_cistatic inline void set_ckpt_flags(struct f2fs_sb_info *sbi, unsigned int f)
206362306a36Sopenharmony_ci{
206462306a36Sopenharmony_ci	unsigned long flags;
206562306a36Sopenharmony_ci
206662306a36Sopenharmony_ci	spin_lock_irqsave(&sbi->cp_lock, flags);
206762306a36Sopenharmony_ci	__set_ckpt_flags(F2FS_CKPT(sbi), f);
206862306a36Sopenharmony_ci	spin_unlock_irqrestore(&sbi->cp_lock, flags);
206962306a36Sopenharmony_ci}
207062306a36Sopenharmony_ci
207162306a36Sopenharmony_cistatic inline void __clear_ckpt_flags(struct f2fs_checkpoint *cp, unsigned int f)
207262306a36Sopenharmony_ci{
207362306a36Sopenharmony_ci	unsigned int ckpt_flags;
207462306a36Sopenharmony_ci
207562306a36Sopenharmony_ci	ckpt_flags = le32_to_cpu(cp->ckpt_flags);
207662306a36Sopenharmony_ci	ckpt_flags &= (~f);
207762306a36Sopenharmony_ci	cp->ckpt_flags = cpu_to_le32(ckpt_flags);
207862306a36Sopenharmony_ci}
207962306a36Sopenharmony_ci
208062306a36Sopenharmony_cistatic inline void clear_ckpt_flags(struct f2fs_sb_info *sbi, unsigned int f)
208162306a36Sopenharmony_ci{
208262306a36Sopenharmony_ci	unsigned long flags;
208362306a36Sopenharmony_ci
208462306a36Sopenharmony_ci	spin_lock_irqsave(&sbi->cp_lock, flags);
208562306a36Sopenharmony_ci	__clear_ckpt_flags(F2FS_CKPT(sbi), f);
208662306a36Sopenharmony_ci	spin_unlock_irqrestore(&sbi->cp_lock, flags);
208762306a36Sopenharmony_ci}
208862306a36Sopenharmony_ci
208962306a36Sopenharmony_ci#define init_f2fs_rwsem(sem)					\
209062306a36Sopenharmony_cido {								\
209162306a36Sopenharmony_ci	static struct lock_class_key __key;			\
209262306a36Sopenharmony_ci								\
209362306a36Sopenharmony_ci	__init_f2fs_rwsem((sem), #sem, &__key);			\
209462306a36Sopenharmony_ci} while (0)
209562306a36Sopenharmony_ci
209662306a36Sopenharmony_cistatic inline void __init_f2fs_rwsem(struct f2fs_rwsem *sem,
209762306a36Sopenharmony_ci		const char *sem_name, struct lock_class_key *key)
209862306a36Sopenharmony_ci{
209962306a36Sopenharmony_ci	__init_rwsem(&sem->internal_rwsem, sem_name, key);
210062306a36Sopenharmony_ci#ifdef CONFIG_F2FS_UNFAIR_RWSEM
210162306a36Sopenharmony_ci	init_waitqueue_head(&sem->read_waiters);
210262306a36Sopenharmony_ci#endif
210362306a36Sopenharmony_ci}
210462306a36Sopenharmony_ci
210562306a36Sopenharmony_cistatic inline int f2fs_rwsem_is_locked(struct f2fs_rwsem *sem)
210662306a36Sopenharmony_ci{
210762306a36Sopenharmony_ci	return rwsem_is_locked(&sem->internal_rwsem);
210862306a36Sopenharmony_ci}
210962306a36Sopenharmony_ci
211062306a36Sopenharmony_cistatic inline int f2fs_rwsem_is_contended(struct f2fs_rwsem *sem)
211162306a36Sopenharmony_ci{
211262306a36Sopenharmony_ci	return rwsem_is_contended(&sem->internal_rwsem);
211362306a36Sopenharmony_ci}
211462306a36Sopenharmony_ci
211562306a36Sopenharmony_cistatic inline void f2fs_down_read(struct f2fs_rwsem *sem)
211662306a36Sopenharmony_ci{
211762306a36Sopenharmony_ci#ifdef CONFIG_F2FS_UNFAIR_RWSEM
211862306a36Sopenharmony_ci	wait_event(sem->read_waiters, down_read_trylock(&sem->internal_rwsem));
211962306a36Sopenharmony_ci#else
212062306a36Sopenharmony_ci	down_read(&sem->internal_rwsem);
212162306a36Sopenharmony_ci#endif
212262306a36Sopenharmony_ci}
212362306a36Sopenharmony_ci
212462306a36Sopenharmony_cistatic inline int f2fs_down_read_trylock(struct f2fs_rwsem *sem)
212562306a36Sopenharmony_ci{
212662306a36Sopenharmony_ci	return down_read_trylock(&sem->internal_rwsem);
212762306a36Sopenharmony_ci}
212862306a36Sopenharmony_ci
212962306a36Sopenharmony_cistatic inline void f2fs_up_read(struct f2fs_rwsem *sem)
213062306a36Sopenharmony_ci{
213162306a36Sopenharmony_ci	up_read(&sem->internal_rwsem);
213262306a36Sopenharmony_ci}
213362306a36Sopenharmony_ci
213462306a36Sopenharmony_cistatic inline void f2fs_down_write(struct f2fs_rwsem *sem)
213562306a36Sopenharmony_ci{
213662306a36Sopenharmony_ci	down_write(&sem->internal_rwsem);
213762306a36Sopenharmony_ci}
213862306a36Sopenharmony_ci
213962306a36Sopenharmony_ci#ifdef CONFIG_DEBUG_LOCK_ALLOC
214062306a36Sopenharmony_cistatic inline void f2fs_down_read_nested(struct f2fs_rwsem *sem, int subclass)
214162306a36Sopenharmony_ci{
214262306a36Sopenharmony_ci	down_read_nested(&sem->internal_rwsem, subclass);
214362306a36Sopenharmony_ci}
214462306a36Sopenharmony_ci
214562306a36Sopenharmony_cistatic inline void f2fs_down_write_nested(struct f2fs_rwsem *sem, int subclass)
214662306a36Sopenharmony_ci{
214762306a36Sopenharmony_ci	down_write_nested(&sem->internal_rwsem, subclass);
214862306a36Sopenharmony_ci}
214962306a36Sopenharmony_ci#else
215062306a36Sopenharmony_ci#define f2fs_down_read_nested(sem, subclass) f2fs_down_read(sem)
215162306a36Sopenharmony_ci#define f2fs_down_write_nested(sem, subclass) f2fs_down_write(sem)
215262306a36Sopenharmony_ci#endif
215362306a36Sopenharmony_ci
215462306a36Sopenharmony_cistatic inline int f2fs_down_write_trylock(struct f2fs_rwsem *sem)
215562306a36Sopenharmony_ci{
215662306a36Sopenharmony_ci	return down_write_trylock(&sem->internal_rwsem);
215762306a36Sopenharmony_ci}
215862306a36Sopenharmony_ci
215962306a36Sopenharmony_cistatic inline void f2fs_up_write(struct f2fs_rwsem *sem)
216062306a36Sopenharmony_ci{
216162306a36Sopenharmony_ci	up_write(&sem->internal_rwsem);
216262306a36Sopenharmony_ci#ifdef CONFIG_F2FS_UNFAIR_RWSEM
216362306a36Sopenharmony_ci	wake_up_all(&sem->read_waiters);
216462306a36Sopenharmony_ci#endif
216562306a36Sopenharmony_ci}
216662306a36Sopenharmony_ci
216762306a36Sopenharmony_cistatic inline void f2fs_lock_op(struct f2fs_sb_info *sbi)
216862306a36Sopenharmony_ci{
216962306a36Sopenharmony_ci	f2fs_down_read(&sbi->cp_rwsem);
217062306a36Sopenharmony_ci}
217162306a36Sopenharmony_ci
217262306a36Sopenharmony_cistatic inline int f2fs_trylock_op(struct f2fs_sb_info *sbi)
217362306a36Sopenharmony_ci{
217462306a36Sopenharmony_ci	if (time_to_inject(sbi, FAULT_LOCK_OP))
217562306a36Sopenharmony_ci		return 0;
217662306a36Sopenharmony_ci	return f2fs_down_read_trylock(&sbi->cp_rwsem);
217762306a36Sopenharmony_ci}
217862306a36Sopenharmony_ci
217962306a36Sopenharmony_cistatic inline void f2fs_unlock_op(struct f2fs_sb_info *sbi)
218062306a36Sopenharmony_ci{
218162306a36Sopenharmony_ci	f2fs_up_read(&sbi->cp_rwsem);
218262306a36Sopenharmony_ci}
218362306a36Sopenharmony_ci
218462306a36Sopenharmony_cistatic inline void f2fs_lock_all(struct f2fs_sb_info *sbi)
218562306a36Sopenharmony_ci{
218662306a36Sopenharmony_ci	f2fs_down_write(&sbi->cp_rwsem);
218762306a36Sopenharmony_ci}
218862306a36Sopenharmony_ci
218962306a36Sopenharmony_cistatic inline void f2fs_unlock_all(struct f2fs_sb_info *sbi)
219062306a36Sopenharmony_ci{
219162306a36Sopenharmony_ci	f2fs_up_write(&sbi->cp_rwsem);
219262306a36Sopenharmony_ci}
219362306a36Sopenharmony_ci
219462306a36Sopenharmony_cistatic inline int __get_cp_reason(struct f2fs_sb_info *sbi)
219562306a36Sopenharmony_ci{
219662306a36Sopenharmony_ci	int reason = CP_SYNC;
219762306a36Sopenharmony_ci
219862306a36Sopenharmony_ci	if (test_opt(sbi, FASTBOOT))
219962306a36Sopenharmony_ci		reason = CP_FASTBOOT;
220062306a36Sopenharmony_ci	if (is_sbi_flag_set(sbi, SBI_IS_CLOSE))
220162306a36Sopenharmony_ci		reason = CP_UMOUNT;
220262306a36Sopenharmony_ci	return reason;
220362306a36Sopenharmony_ci}
220462306a36Sopenharmony_ci
220562306a36Sopenharmony_cistatic inline bool __remain_node_summaries(int reason)
220662306a36Sopenharmony_ci{
220762306a36Sopenharmony_ci	return (reason & (CP_UMOUNT | CP_FASTBOOT));
220862306a36Sopenharmony_ci}
220962306a36Sopenharmony_ci
221062306a36Sopenharmony_cistatic inline bool __exist_node_summaries(struct f2fs_sb_info *sbi)
221162306a36Sopenharmony_ci{
221262306a36Sopenharmony_ci	return (is_set_ckpt_flags(sbi, CP_UMOUNT_FLAG) ||
221362306a36Sopenharmony_ci			is_set_ckpt_flags(sbi, CP_FASTBOOT_FLAG));
221462306a36Sopenharmony_ci}
221562306a36Sopenharmony_ci
221662306a36Sopenharmony_ci/*
221762306a36Sopenharmony_ci * Check whether the inode has blocks or not
221862306a36Sopenharmony_ci */
221962306a36Sopenharmony_cistatic inline int F2FS_HAS_BLOCKS(struct inode *inode)
222062306a36Sopenharmony_ci{
222162306a36Sopenharmony_ci	block_t xattr_block = F2FS_I(inode)->i_xattr_nid ? 1 : 0;
222262306a36Sopenharmony_ci
222362306a36Sopenharmony_ci	return (inode->i_blocks >> F2FS_LOG_SECTORS_PER_BLOCK) > xattr_block;
222462306a36Sopenharmony_ci}
222562306a36Sopenharmony_ci
222662306a36Sopenharmony_cistatic inline bool f2fs_has_xattr_block(unsigned int ofs)
222762306a36Sopenharmony_ci{
222862306a36Sopenharmony_ci	return ofs == XATTR_NODE_OFFSET;
222962306a36Sopenharmony_ci}
223062306a36Sopenharmony_ci
223162306a36Sopenharmony_cistatic inline bool __allow_reserved_blocks(struct f2fs_sb_info *sbi,
223262306a36Sopenharmony_ci					struct inode *inode, bool cap)
223362306a36Sopenharmony_ci{
223462306a36Sopenharmony_ci	if (!inode)
223562306a36Sopenharmony_ci		return true;
223662306a36Sopenharmony_ci	if (!test_opt(sbi, RESERVE_ROOT))
223762306a36Sopenharmony_ci		return false;
223862306a36Sopenharmony_ci	if (IS_NOQUOTA(inode))
223962306a36Sopenharmony_ci		return true;
224062306a36Sopenharmony_ci	if (uid_eq(F2FS_OPTION(sbi).s_resuid, current_fsuid()))
224162306a36Sopenharmony_ci		return true;
224262306a36Sopenharmony_ci	if (!gid_eq(F2FS_OPTION(sbi).s_resgid, GLOBAL_ROOT_GID) &&
224362306a36Sopenharmony_ci					in_group_p(F2FS_OPTION(sbi).s_resgid))
224462306a36Sopenharmony_ci		return true;
224562306a36Sopenharmony_ci	if (cap && capable(CAP_SYS_RESOURCE))
224662306a36Sopenharmony_ci		return true;
224762306a36Sopenharmony_ci	return false;
224862306a36Sopenharmony_ci}
224962306a36Sopenharmony_ci
225062306a36Sopenharmony_cistatic inline void f2fs_i_blocks_write(struct inode *, block_t, bool, bool);
225162306a36Sopenharmony_cistatic inline int inc_valid_block_count(struct f2fs_sb_info *sbi,
225262306a36Sopenharmony_ci				 struct inode *inode, blkcnt_t *count, bool partial)
225362306a36Sopenharmony_ci{
225462306a36Sopenharmony_ci	blkcnt_t diff = 0, release = 0;
225562306a36Sopenharmony_ci	block_t avail_user_block_count;
225662306a36Sopenharmony_ci	int ret;
225762306a36Sopenharmony_ci
225862306a36Sopenharmony_ci	ret = dquot_reserve_block(inode, *count);
225962306a36Sopenharmony_ci	if (ret)
226062306a36Sopenharmony_ci		return ret;
226162306a36Sopenharmony_ci
226262306a36Sopenharmony_ci	if (time_to_inject(sbi, FAULT_BLOCK)) {
226362306a36Sopenharmony_ci		release = *count;
226462306a36Sopenharmony_ci		goto release_quota;
226562306a36Sopenharmony_ci	}
226662306a36Sopenharmony_ci
226762306a36Sopenharmony_ci	/*
226862306a36Sopenharmony_ci	 * let's increase this in prior to actual block count change in order
226962306a36Sopenharmony_ci	 * for f2fs_sync_file to avoid data races when deciding checkpoint.
227062306a36Sopenharmony_ci	 */
227162306a36Sopenharmony_ci	percpu_counter_add(&sbi->alloc_valid_block_count, (*count));
227262306a36Sopenharmony_ci
227362306a36Sopenharmony_ci	spin_lock(&sbi->stat_lock);
227462306a36Sopenharmony_ci	sbi->total_valid_block_count += (block_t)(*count);
227562306a36Sopenharmony_ci	avail_user_block_count = sbi->user_block_count -
227662306a36Sopenharmony_ci					sbi->current_reserved_blocks;
227762306a36Sopenharmony_ci
227862306a36Sopenharmony_ci	if (!__allow_reserved_blocks(sbi, inode, true))
227962306a36Sopenharmony_ci		avail_user_block_count -= F2FS_OPTION(sbi).root_reserved_blocks;
228062306a36Sopenharmony_ci
228162306a36Sopenharmony_ci	if (F2FS_IO_ALIGNED(sbi))
228262306a36Sopenharmony_ci		avail_user_block_count -= sbi->blocks_per_seg *
228362306a36Sopenharmony_ci				SM_I(sbi)->additional_reserved_segments;
228462306a36Sopenharmony_ci
228562306a36Sopenharmony_ci	if (unlikely(is_sbi_flag_set(sbi, SBI_CP_DISABLED))) {
228662306a36Sopenharmony_ci		if (avail_user_block_count > sbi->unusable_block_count)
228762306a36Sopenharmony_ci			avail_user_block_count -= sbi->unusable_block_count;
228862306a36Sopenharmony_ci		else
228962306a36Sopenharmony_ci			avail_user_block_count = 0;
229062306a36Sopenharmony_ci	}
229162306a36Sopenharmony_ci	if (unlikely(sbi->total_valid_block_count > avail_user_block_count)) {
229262306a36Sopenharmony_ci		if (!partial) {
229362306a36Sopenharmony_ci			spin_unlock(&sbi->stat_lock);
229462306a36Sopenharmony_ci			goto enospc;
229562306a36Sopenharmony_ci		}
229662306a36Sopenharmony_ci
229762306a36Sopenharmony_ci		diff = sbi->total_valid_block_count - avail_user_block_count;
229862306a36Sopenharmony_ci		if (diff > *count)
229962306a36Sopenharmony_ci			diff = *count;
230062306a36Sopenharmony_ci		*count -= diff;
230162306a36Sopenharmony_ci		release = diff;
230262306a36Sopenharmony_ci		sbi->total_valid_block_count -= diff;
230362306a36Sopenharmony_ci		if (!*count) {
230462306a36Sopenharmony_ci			spin_unlock(&sbi->stat_lock);
230562306a36Sopenharmony_ci			goto enospc;
230662306a36Sopenharmony_ci		}
230762306a36Sopenharmony_ci	}
230862306a36Sopenharmony_ci	spin_unlock(&sbi->stat_lock);
230962306a36Sopenharmony_ci
231062306a36Sopenharmony_ci	if (unlikely(release)) {
231162306a36Sopenharmony_ci		percpu_counter_sub(&sbi->alloc_valid_block_count, release);
231262306a36Sopenharmony_ci		dquot_release_reservation_block(inode, release);
231362306a36Sopenharmony_ci	}
231462306a36Sopenharmony_ci	f2fs_i_blocks_write(inode, *count, true, true);
231562306a36Sopenharmony_ci	return 0;
231662306a36Sopenharmony_ci
231762306a36Sopenharmony_cienospc:
231862306a36Sopenharmony_ci	percpu_counter_sub(&sbi->alloc_valid_block_count, release);
231962306a36Sopenharmony_cirelease_quota:
232062306a36Sopenharmony_ci	dquot_release_reservation_block(inode, release);
232162306a36Sopenharmony_ci	return -ENOSPC;
232262306a36Sopenharmony_ci}
232362306a36Sopenharmony_ci
232462306a36Sopenharmony_ci__printf(2, 3)
232562306a36Sopenharmony_civoid f2fs_printk(struct f2fs_sb_info *sbi, const char *fmt, ...);
232662306a36Sopenharmony_ci
232762306a36Sopenharmony_ci#define f2fs_err(sbi, fmt, ...)						\
232862306a36Sopenharmony_ci	f2fs_printk(sbi, KERN_ERR fmt, ##__VA_ARGS__)
232962306a36Sopenharmony_ci#define f2fs_warn(sbi, fmt, ...)					\
233062306a36Sopenharmony_ci	f2fs_printk(sbi, KERN_WARNING fmt, ##__VA_ARGS__)
233162306a36Sopenharmony_ci#define f2fs_notice(sbi, fmt, ...)					\
233262306a36Sopenharmony_ci	f2fs_printk(sbi, KERN_NOTICE fmt, ##__VA_ARGS__)
233362306a36Sopenharmony_ci#define f2fs_info(sbi, fmt, ...)					\
233462306a36Sopenharmony_ci	f2fs_printk(sbi, KERN_INFO fmt, ##__VA_ARGS__)
233562306a36Sopenharmony_ci#define f2fs_debug(sbi, fmt, ...)					\
233662306a36Sopenharmony_ci	f2fs_printk(sbi, KERN_DEBUG fmt, ##__VA_ARGS__)
233762306a36Sopenharmony_ci
233862306a36Sopenharmony_ci#define PAGE_PRIVATE_GET_FUNC(name, flagname) \
233962306a36Sopenharmony_cistatic inline bool page_private_##name(struct page *page) \
234062306a36Sopenharmony_ci{ \
234162306a36Sopenharmony_ci	return PagePrivate(page) && \
234262306a36Sopenharmony_ci		test_bit(PAGE_PRIVATE_NOT_POINTER, &page_private(page)) && \
234362306a36Sopenharmony_ci		test_bit(PAGE_PRIVATE_##flagname, &page_private(page)); \
234462306a36Sopenharmony_ci}
234562306a36Sopenharmony_ci
234662306a36Sopenharmony_ci#define PAGE_PRIVATE_SET_FUNC(name, flagname) \
234762306a36Sopenharmony_cistatic inline void set_page_private_##name(struct page *page) \
234862306a36Sopenharmony_ci{ \
234962306a36Sopenharmony_ci	if (!PagePrivate(page)) \
235062306a36Sopenharmony_ci		attach_page_private(page, (void *)0); \
235162306a36Sopenharmony_ci	set_bit(PAGE_PRIVATE_NOT_POINTER, &page_private(page)); \
235262306a36Sopenharmony_ci	set_bit(PAGE_PRIVATE_##flagname, &page_private(page)); \
235362306a36Sopenharmony_ci}
235462306a36Sopenharmony_ci
235562306a36Sopenharmony_ci#define PAGE_PRIVATE_CLEAR_FUNC(name, flagname) \
235662306a36Sopenharmony_cistatic inline void clear_page_private_##name(struct page *page) \
235762306a36Sopenharmony_ci{ \
235862306a36Sopenharmony_ci	clear_bit(PAGE_PRIVATE_##flagname, &page_private(page)); \
235962306a36Sopenharmony_ci	if (page_private(page) == BIT(PAGE_PRIVATE_NOT_POINTER)) \
236062306a36Sopenharmony_ci		detach_page_private(page); \
236162306a36Sopenharmony_ci}
236262306a36Sopenharmony_ci
236362306a36Sopenharmony_ciPAGE_PRIVATE_GET_FUNC(nonpointer, NOT_POINTER);
236462306a36Sopenharmony_ciPAGE_PRIVATE_GET_FUNC(inline, INLINE_INODE);
236562306a36Sopenharmony_ciPAGE_PRIVATE_GET_FUNC(gcing, ONGOING_MIGRATION);
236662306a36Sopenharmony_ciPAGE_PRIVATE_GET_FUNC(dummy, DUMMY_WRITE);
236762306a36Sopenharmony_ci
236862306a36Sopenharmony_ciPAGE_PRIVATE_SET_FUNC(reference, REF_RESOURCE);
236962306a36Sopenharmony_ciPAGE_PRIVATE_SET_FUNC(inline, INLINE_INODE);
237062306a36Sopenharmony_ciPAGE_PRIVATE_SET_FUNC(gcing, ONGOING_MIGRATION);
237162306a36Sopenharmony_ciPAGE_PRIVATE_SET_FUNC(dummy, DUMMY_WRITE);
237262306a36Sopenharmony_ci
237362306a36Sopenharmony_ciPAGE_PRIVATE_CLEAR_FUNC(reference, REF_RESOURCE);
237462306a36Sopenharmony_ciPAGE_PRIVATE_CLEAR_FUNC(inline, INLINE_INODE);
237562306a36Sopenharmony_ciPAGE_PRIVATE_CLEAR_FUNC(gcing, ONGOING_MIGRATION);
237662306a36Sopenharmony_ciPAGE_PRIVATE_CLEAR_FUNC(dummy, DUMMY_WRITE);
237762306a36Sopenharmony_ci
237862306a36Sopenharmony_cistatic inline unsigned long get_page_private_data(struct page *page)
237962306a36Sopenharmony_ci{
238062306a36Sopenharmony_ci	unsigned long data = page_private(page);
238162306a36Sopenharmony_ci
238262306a36Sopenharmony_ci	if (!test_bit(PAGE_PRIVATE_NOT_POINTER, &data))
238362306a36Sopenharmony_ci		return 0;
238462306a36Sopenharmony_ci	return data >> PAGE_PRIVATE_MAX;
238562306a36Sopenharmony_ci}
238662306a36Sopenharmony_ci
238762306a36Sopenharmony_cistatic inline void set_page_private_data(struct page *page, unsigned long data)
238862306a36Sopenharmony_ci{
238962306a36Sopenharmony_ci	if (!PagePrivate(page))
239062306a36Sopenharmony_ci		attach_page_private(page, (void *)0);
239162306a36Sopenharmony_ci	set_bit(PAGE_PRIVATE_NOT_POINTER, &page_private(page));
239262306a36Sopenharmony_ci	page_private(page) |= data << PAGE_PRIVATE_MAX;
239362306a36Sopenharmony_ci}
239462306a36Sopenharmony_ci
239562306a36Sopenharmony_cistatic inline void clear_page_private_data(struct page *page)
239662306a36Sopenharmony_ci{
239762306a36Sopenharmony_ci	page_private(page) &= GENMASK(PAGE_PRIVATE_MAX - 1, 0);
239862306a36Sopenharmony_ci	if (page_private(page) == BIT(PAGE_PRIVATE_NOT_POINTER))
239962306a36Sopenharmony_ci		detach_page_private(page);
240062306a36Sopenharmony_ci}
240162306a36Sopenharmony_ci
240262306a36Sopenharmony_cistatic inline void clear_page_private_all(struct page *page)
240362306a36Sopenharmony_ci{
240462306a36Sopenharmony_ci	clear_page_private_data(page);
240562306a36Sopenharmony_ci	clear_page_private_reference(page);
240662306a36Sopenharmony_ci	clear_page_private_gcing(page);
240762306a36Sopenharmony_ci	clear_page_private_inline(page);
240862306a36Sopenharmony_ci
240962306a36Sopenharmony_ci	f2fs_bug_on(F2FS_P_SB(page), page_private(page));
241062306a36Sopenharmony_ci}
241162306a36Sopenharmony_ci
241262306a36Sopenharmony_cistatic inline void dec_valid_block_count(struct f2fs_sb_info *sbi,
241362306a36Sopenharmony_ci						struct inode *inode,
241462306a36Sopenharmony_ci						block_t count)
241562306a36Sopenharmony_ci{
241662306a36Sopenharmony_ci	blkcnt_t sectors = count << F2FS_LOG_SECTORS_PER_BLOCK;
241762306a36Sopenharmony_ci
241862306a36Sopenharmony_ci	spin_lock(&sbi->stat_lock);
241962306a36Sopenharmony_ci	f2fs_bug_on(sbi, sbi->total_valid_block_count < (block_t) count);
242062306a36Sopenharmony_ci	sbi->total_valid_block_count -= (block_t)count;
242162306a36Sopenharmony_ci	if (sbi->reserved_blocks &&
242262306a36Sopenharmony_ci		sbi->current_reserved_blocks < sbi->reserved_blocks)
242362306a36Sopenharmony_ci		sbi->current_reserved_blocks = min(sbi->reserved_blocks,
242462306a36Sopenharmony_ci					sbi->current_reserved_blocks + count);
242562306a36Sopenharmony_ci	spin_unlock(&sbi->stat_lock);
242662306a36Sopenharmony_ci	if (unlikely(inode->i_blocks < sectors)) {
242762306a36Sopenharmony_ci		f2fs_warn(sbi, "Inconsistent i_blocks, ino:%lu, iblocks:%llu, sectors:%llu",
242862306a36Sopenharmony_ci			  inode->i_ino,
242962306a36Sopenharmony_ci			  (unsigned long long)inode->i_blocks,
243062306a36Sopenharmony_ci			  (unsigned long long)sectors);
243162306a36Sopenharmony_ci		set_sbi_flag(sbi, SBI_NEED_FSCK);
243262306a36Sopenharmony_ci		return;
243362306a36Sopenharmony_ci	}
243462306a36Sopenharmony_ci	f2fs_i_blocks_write(inode, count, false, true);
243562306a36Sopenharmony_ci}
243662306a36Sopenharmony_ci
243762306a36Sopenharmony_cistatic inline void inc_page_count(struct f2fs_sb_info *sbi, int count_type)
243862306a36Sopenharmony_ci{
243962306a36Sopenharmony_ci	atomic_inc(&sbi->nr_pages[count_type]);
244062306a36Sopenharmony_ci
244162306a36Sopenharmony_ci	if (count_type == F2FS_DIRTY_DENTS ||
244262306a36Sopenharmony_ci			count_type == F2FS_DIRTY_NODES ||
244362306a36Sopenharmony_ci			count_type == F2FS_DIRTY_META ||
244462306a36Sopenharmony_ci			count_type == F2FS_DIRTY_QDATA ||
244562306a36Sopenharmony_ci			count_type == F2FS_DIRTY_IMETA)
244662306a36Sopenharmony_ci		set_sbi_flag(sbi, SBI_IS_DIRTY);
244762306a36Sopenharmony_ci}
244862306a36Sopenharmony_ci
244962306a36Sopenharmony_cistatic inline void inode_inc_dirty_pages(struct inode *inode)
245062306a36Sopenharmony_ci{
245162306a36Sopenharmony_ci	atomic_inc(&F2FS_I(inode)->dirty_pages);
245262306a36Sopenharmony_ci	inc_page_count(F2FS_I_SB(inode), S_ISDIR(inode->i_mode) ?
245362306a36Sopenharmony_ci				F2FS_DIRTY_DENTS : F2FS_DIRTY_DATA);
245462306a36Sopenharmony_ci	if (IS_NOQUOTA(inode))
245562306a36Sopenharmony_ci		inc_page_count(F2FS_I_SB(inode), F2FS_DIRTY_QDATA);
245662306a36Sopenharmony_ci}
245762306a36Sopenharmony_ci
245862306a36Sopenharmony_cistatic inline void dec_page_count(struct f2fs_sb_info *sbi, int count_type)
245962306a36Sopenharmony_ci{
246062306a36Sopenharmony_ci	atomic_dec(&sbi->nr_pages[count_type]);
246162306a36Sopenharmony_ci}
246262306a36Sopenharmony_ci
246362306a36Sopenharmony_cistatic inline void inode_dec_dirty_pages(struct inode *inode)
246462306a36Sopenharmony_ci{
246562306a36Sopenharmony_ci	if (!S_ISDIR(inode->i_mode) && !S_ISREG(inode->i_mode) &&
246662306a36Sopenharmony_ci			!S_ISLNK(inode->i_mode))
246762306a36Sopenharmony_ci		return;
246862306a36Sopenharmony_ci
246962306a36Sopenharmony_ci	atomic_dec(&F2FS_I(inode)->dirty_pages);
247062306a36Sopenharmony_ci	dec_page_count(F2FS_I_SB(inode), S_ISDIR(inode->i_mode) ?
247162306a36Sopenharmony_ci				F2FS_DIRTY_DENTS : F2FS_DIRTY_DATA);
247262306a36Sopenharmony_ci	if (IS_NOQUOTA(inode))
247362306a36Sopenharmony_ci		dec_page_count(F2FS_I_SB(inode), F2FS_DIRTY_QDATA);
247462306a36Sopenharmony_ci}
247562306a36Sopenharmony_ci
247662306a36Sopenharmony_cistatic inline void inc_atomic_write_cnt(struct inode *inode)
247762306a36Sopenharmony_ci{
247862306a36Sopenharmony_ci	struct f2fs_sb_info *sbi = F2FS_I_SB(inode);
247962306a36Sopenharmony_ci	struct f2fs_inode_info *fi = F2FS_I(inode);
248062306a36Sopenharmony_ci	u64 current_write;
248162306a36Sopenharmony_ci
248262306a36Sopenharmony_ci	fi->atomic_write_cnt++;
248362306a36Sopenharmony_ci	atomic64_inc(&sbi->current_atomic_write);
248462306a36Sopenharmony_ci	current_write = atomic64_read(&sbi->current_atomic_write);
248562306a36Sopenharmony_ci	if (current_write > sbi->peak_atomic_write)
248662306a36Sopenharmony_ci		sbi->peak_atomic_write = current_write;
248762306a36Sopenharmony_ci}
248862306a36Sopenharmony_ci
248962306a36Sopenharmony_cistatic inline void release_atomic_write_cnt(struct inode *inode)
249062306a36Sopenharmony_ci{
249162306a36Sopenharmony_ci	struct f2fs_sb_info *sbi = F2FS_I_SB(inode);
249262306a36Sopenharmony_ci	struct f2fs_inode_info *fi = F2FS_I(inode);
249362306a36Sopenharmony_ci
249462306a36Sopenharmony_ci	atomic64_sub(fi->atomic_write_cnt, &sbi->current_atomic_write);
249562306a36Sopenharmony_ci	fi->atomic_write_cnt = 0;
249662306a36Sopenharmony_ci}
249762306a36Sopenharmony_ci
249862306a36Sopenharmony_cistatic inline s64 get_pages(struct f2fs_sb_info *sbi, int count_type)
249962306a36Sopenharmony_ci{
250062306a36Sopenharmony_ci	return atomic_read(&sbi->nr_pages[count_type]);
250162306a36Sopenharmony_ci}
250262306a36Sopenharmony_ci
250362306a36Sopenharmony_cistatic inline int get_dirty_pages(struct inode *inode)
250462306a36Sopenharmony_ci{
250562306a36Sopenharmony_ci	return atomic_read(&F2FS_I(inode)->dirty_pages);
250662306a36Sopenharmony_ci}
250762306a36Sopenharmony_ci
250862306a36Sopenharmony_cistatic inline int get_blocktype_secs(struct f2fs_sb_info *sbi, int block_type)
250962306a36Sopenharmony_ci{
251062306a36Sopenharmony_ci	unsigned int pages_per_sec = sbi->segs_per_sec * sbi->blocks_per_seg;
251162306a36Sopenharmony_ci	unsigned int segs = (get_pages(sbi, block_type) + pages_per_sec - 1) >>
251262306a36Sopenharmony_ci						sbi->log_blocks_per_seg;
251362306a36Sopenharmony_ci
251462306a36Sopenharmony_ci	return segs / sbi->segs_per_sec;
251562306a36Sopenharmony_ci}
251662306a36Sopenharmony_ci
251762306a36Sopenharmony_cistatic inline block_t valid_user_blocks(struct f2fs_sb_info *sbi)
251862306a36Sopenharmony_ci{
251962306a36Sopenharmony_ci	return sbi->total_valid_block_count;
252062306a36Sopenharmony_ci}
252162306a36Sopenharmony_ci
252262306a36Sopenharmony_cistatic inline block_t discard_blocks(struct f2fs_sb_info *sbi)
252362306a36Sopenharmony_ci{
252462306a36Sopenharmony_ci	return sbi->discard_blks;
252562306a36Sopenharmony_ci}
252662306a36Sopenharmony_ci
252762306a36Sopenharmony_cistatic inline unsigned long __bitmap_size(struct f2fs_sb_info *sbi, int flag)
252862306a36Sopenharmony_ci{
252962306a36Sopenharmony_ci	struct f2fs_checkpoint *ckpt = F2FS_CKPT(sbi);
253062306a36Sopenharmony_ci
253162306a36Sopenharmony_ci	/* return NAT or SIT bitmap */
253262306a36Sopenharmony_ci	if (flag == NAT_BITMAP)
253362306a36Sopenharmony_ci		return le32_to_cpu(ckpt->nat_ver_bitmap_bytesize);
253462306a36Sopenharmony_ci	else if (flag == SIT_BITMAP)
253562306a36Sopenharmony_ci		return le32_to_cpu(ckpt->sit_ver_bitmap_bytesize);
253662306a36Sopenharmony_ci
253762306a36Sopenharmony_ci	return 0;
253862306a36Sopenharmony_ci}
253962306a36Sopenharmony_ci
254062306a36Sopenharmony_cistatic inline block_t __cp_payload(struct f2fs_sb_info *sbi)
254162306a36Sopenharmony_ci{
254262306a36Sopenharmony_ci	return le32_to_cpu(F2FS_RAW_SUPER(sbi)->cp_payload);
254362306a36Sopenharmony_ci}
254462306a36Sopenharmony_ci
254562306a36Sopenharmony_cistatic inline void *__bitmap_ptr(struct f2fs_sb_info *sbi, int flag)
254662306a36Sopenharmony_ci{
254762306a36Sopenharmony_ci	struct f2fs_checkpoint *ckpt = F2FS_CKPT(sbi);
254862306a36Sopenharmony_ci	void *tmp_ptr = &ckpt->sit_nat_version_bitmap;
254962306a36Sopenharmony_ci	int offset;
255062306a36Sopenharmony_ci
255162306a36Sopenharmony_ci	if (is_set_ckpt_flags(sbi, CP_LARGE_NAT_BITMAP_FLAG)) {
255262306a36Sopenharmony_ci		offset = (flag == SIT_BITMAP) ?
255362306a36Sopenharmony_ci			le32_to_cpu(ckpt->nat_ver_bitmap_bytesize) : 0;
255462306a36Sopenharmony_ci		/*
255562306a36Sopenharmony_ci		 * if large_nat_bitmap feature is enabled, leave checksum
255662306a36Sopenharmony_ci		 * protection for all nat/sit bitmaps.
255762306a36Sopenharmony_ci		 */
255862306a36Sopenharmony_ci		return tmp_ptr + offset + sizeof(__le32);
255962306a36Sopenharmony_ci	}
256062306a36Sopenharmony_ci
256162306a36Sopenharmony_ci	if (__cp_payload(sbi) > 0) {
256262306a36Sopenharmony_ci		if (flag == NAT_BITMAP)
256362306a36Sopenharmony_ci			return tmp_ptr;
256462306a36Sopenharmony_ci		else
256562306a36Sopenharmony_ci			return (unsigned char *)ckpt + F2FS_BLKSIZE;
256662306a36Sopenharmony_ci	} else {
256762306a36Sopenharmony_ci		offset = (flag == NAT_BITMAP) ?
256862306a36Sopenharmony_ci			le32_to_cpu(ckpt->sit_ver_bitmap_bytesize) : 0;
256962306a36Sopenharmony_ci		return tmp_ptr + offset;
257062306a36Sopenharmony_ci	}
257162306a36Sopenharmony_ci}
257262306a36Sopenharmony_ci
257362306a36Sopenharmony_cistatic inline block_t __start_cp_addr(struct f2fs_sb_info *sbi)
257462306a36Sopenharmony_ci{
257562306a36Sopenharmony_ci	block_t start_addr = le32_to_cpu(F2FS_RAW_SUPER(sbi)->cp_blkaddr);
257662306a36Sopenharmony_ci
257762306a36Sopenharmony_ci	if (sbi->cur_cp_pack == 2)
257862306a36Sopenharmony_ci		start_addr += sbi->blocks_per_seg;
257962306a36Sopenharmony_ci	return start_addr;
258062306a36Sopenharmony_ci}
258162306a36Sopenharmony_ci
258262306a36Sopenharmony_cistatic inline block_t __start_cp_next_addr(struct f2fs_sb_info *sbi)
258362306a36Sopenharmony_ci{
258462306a36Sopenharmony_ci	block_t start_addr = le32_to_cpu(F2FS_RAW_SUPER(sbi)->cp_blkaddr);
258562306a36Sopenharmony_ci
258662306a36Sopenharmony_ci	if (sbi->cur_cp_pack == 1)
258762306a36Sopenharmony_ci		start_addr += sbi->blocks_per_seg;
258862306a36Sopenharmony_ci	return start_addr;
258962306a36Sopenharmony_ci}
259062306a36Sopenharmony_ci
259162306a36Sopenharmony_cistatic inline void __set_cp_next_pack(struct f2fs_sb_info *sbi)
259262306a36Sopenharmony_ci{
259362306a36Sopenharmony_ci	sbi->cur_cp_pack = (sbi->cur_cp_pack == 1) ? 2 : 1;
259462306a36Sopenharmony_ci}
259562306a36Sopenharmony_ci
259662306a36Sopenharmony_cistatic inline block_t __start_sum_addr(struct f2fs_sb_info *sbi)
259762306a36Sopenharmony_ci{
259862306a36Sopenharmony_ci	return le32_to_cpu(F2FS_CKPT(sbi)->cp_pack_start_sum);
259962306a36Sopenharmony_ci}
260062306a36Sopenharmony_ci
260162306a36Sopenharmony_ciextern void f2fs_mark_inode_dirty_sync(struct inode *inode, bool sync);
260262306a36Sopenharmony_cistatic inline int inc_valid_node_count(struct f2fs_sb_info *sbi,
260362306a36Sopenharmony_ci					struct inode *inode, bool is_inode)
260462306a36Sopenharmony_ci{
260562306a36Sopenharmony_ci	block_t	valid_block_count;
260662306a36Sopenharmony_ci	unsigned int valid_node_count, user_block_count;
260762306a36Sopenharmony_ci	int err;
260862306a36Sopenharmony_ci
260962306a36Sopenharmony_ci	if (is_inode) {
261062306a36Sopenharmony_ci		if (inode) {
261162306a36Sopenharmony_ci			err = dquot_alloc_inode(inode);
261262306a36Sopenharmony_ci			if (err)
261362306a36Sopenharmony_ci				return err;
261462306a36Sopenharmony_ci		}
261562306a36Sopenharmony_ci	} else {
261662306a36Sopenharmony_ci		err = dquot_reserve_block(inode, 1);
261762306a36Sopenharmony_ci		if (err)
261862306a36Sopenharmony_ci			return err;
261962306a36Sopenharmony_ci	}
262062306a36Sopenharmony_ci
262162306a36Sopenharmony_ci	if (time_to_inject(sbi, FAULT_BLOCK))
262262306a36Sopenharmony_ci		goto enospc;
262362306a36Sopenharmony_ci
262462306a36Sopenharmony_ci	spin_lock(&sbi->stat_lock);
262562306a36Sopenharmony_ci
262662306a36Sopenharmony_ci	valid_block_count = sbi->total_valid_block_count +
262762306a36Sopenharmony_ci					sbi->current_reserved_blocks + 1;
262862306a36Sopenharmony_ci
262962306a36Sopenharmony_ci	if (!__allow_reserved_blocks(sbi, inode, false))
263062306a36Sopenharmony_ci		valid_block_count += F2FS_OPTION(sbi).root_reserved_blocks;
263162306a36Sopenharmony_ci
263262306a36Sopenharmony_ci	if (F2FS_IO_ALIGNED(sbi))
263362306a36Sopenharmony_ci		valid_block_count += sbi->blocks_per_seg *
263462306a36Sopenharmony_ci				SM_I(sbi)->additional_reserved_segments;
263562306a36Sopenharmony_ci
263662306a36Sopenharmony_ci	user_block_count = sbi->user_block_count;
263762306a36Sopenharmony_ci	if (unlikely(is_sbi_flag_set(sbi, SBI_CP_DISABLED)))
263862306a36Sopenharmony_ci		user_block_count -= sbi->unusable_block_count;
263962306a36Sopenharmony_ci
264062306a36Sopenharmony_ci	if (unlikely(valid_block_count > user_block_count)) {
264162306a36Sopenharmony_ci		spin_unlock(&sbi->stat_lock);
264262306a36Sopenharmony_ci		goto enospc;
264362306a36Sopenharmony_ci	}
264462306a36Sopenharmony_ci
264562306a36Sopenharmony_ci	valid_node_count = sbi->total_valid_node_count + 1;
264662306a36Sopenharmony_ci	if (unlikely(valid_node_count > sbi->total_node_count)) {
264762306a36Sopenharmony_ci		spin_unlock(&sbi->stat_lock);
264862306a36Sopenharmony_ci		goto enospc;
264962306a36Sopenharmony_ci	}
265062306a36Sopenharmony_ci
265162306a36Sopenharmony_ci	sbi->total_valid_node_count++;
265262306a36Sopenharmony_ci	sbi->total_valid_block_count++;
265362306a36Sopenharmony_ci	spin_unlock(&sbi->stat_lock);
265462306a36Sopenharmony_ci
265562306a36Sopenharmony_ci	if (inode) {
265662306a36Sopenharmony_ci		if (is_inode)
265762306a36Sopenharmony_ci			f2fs_mark_inode_dirty_sync(inode, true);
265862306a36Sopenharmony_ci		else
265962306a36Sopenharmony_ci			f2fs_i_blocks_write(inode, 1, true, true);
266062306a36Sopenharmony_ci	}
266162306a36Sopenharmony_ci
266262306a36Sopenharmony_ci	percpu_counter_inc(&sbi->alloc_valid_block_count);
266362306a36Sopenharmony_ci	return 0;
266462306a36Sopenharmony_ci
266562306a36Sopenharmony_cienospc:
266662306a36Sopenharmony_ci	if (is_inode) {
266762306a36Sopenharmony_ci		if (inode)
266862306a36Sopenharmony_ci			dquot_free_inode(inode);
266962306a36Sopenharmony_ci	} else {
267062306a36Sopenharmony_ci		dquot_release_reservation_block(inode, 1);
267162306a36Sopenharmony_ci	}
267262306a36Sopenharmony_ci	return -ENOSPC;
267362306a36Sopenharmony_ci}
267462306a36Sopenharmony_ci
267562306a36Sopenharmony_cistatic inline void dec_valid_node_count(struct f2fs_sb_info *sbi,
267662306a36Sopenharmony_ci					struct inode *inode, bool is_inode)
267762306a36Sopenharmony_ci{
267862306a36Sopenharmony_ci	spin_lock(&sbi->stat_lock);
267962306a36Sopenharmony_ci
268062306a36Sopenharmony_ci	if (unlikely(!sbi->total_valid_block_count ||
268162306a36Sopenharmony_ci			!sbi->total_valid_node_count)) {
268262306a36Sopenharmony_ci		f2fs_warn(sbi, "dec_valid_node_count: inconsistent block counts, total_valid_block:%u, total_valid_node:%u",
268362306a36Sopenharmony_ci			  sbi->total_valid_block_count,
268462306a36Sopenharmony_ci			  sbi->total_valid_node_count);
268562306a36Sopenharmony_ci		set_sbi_flag(sbi, SBI_NEED_FSCK);
268662306a36Sopenharmony_ci	} else {
268762306a36Sopenharmony_ci		sbi->total_valid_block_count--;
268862306a36Sopenharmony_ci		sbi->total_valid_node_count--;
268962306a36Sopenharmony_ci	}
269062306a36Sopenharmony_ci
269162306a36Sopenharmony_ci	if (sbi->reserved_blocks &&
269262306a36Sopenharmony_ci		sbi->current_reserved_blocks < sbi->reserved_blocks)
269362306a36Sopenharmony_ci		sbi->current_reserved_blocks++;
269462306a36Sopenharmony_ci
269562306a36Sopenharmony_ci	spin_unlock(&sbi->stat_lock);
269662306a36Sopenharmony_ci
269762306a36Sopenharmony_ci	if (is_inode) {
269862306a36Sopenharmony_ci		dquot_free_inode(inode);
269962306a36Sopenharmony_ci	} else {
270062306a36Sopenharmony_ci		if (unlikely(inode->i_blocks == 0)) {
270162306a36Sopenharmony_ci			f2fs_warn(sbi, "dec_valid_node_count: inconsistent i_blocks, ino:%lu, iblocks:%llu",
270262306a36Sopenharmony_ci				  inode->i_ino,
270362306a36Sopenharmony_ci				  (unsigned long long)inode->i_blocks);
270462306a36Sopenharmony_ci			set_sbi_flag(sbi, SBI_NEED_FSCK);
270562306a36Sopenharmony_ci			return;
270662306a36Sopenharmony_ci		}
270762306a36Sopenharmony_ci		f2fs_i_blocks_write(inode, 1, false, true);
270862306a36Sopenharmony_ci	}
270962306a36Sopenharmony_ci}
271062306a36Sopenharmony_ci
271162306a36Sopenharmony_cistatic inline unsigned int valid_node_count(struct f2fs_sb_info *sbi)
271262306a36Sopenharmony_ci{
271362306a36Sopenharmony_ci	return sbi->total_valid_node_count;
271462306a36Sopenharmony_ci}
271562306a36Sopenharmony_ci
271662306a36Sopenharmony_cistatic inline void inc_valid_inode_count(struct f2fs_sb_info *sbi)
271762306a36Sopenharmony_ci{
271862306a36Sopenharmony_ci	percpu_counter_inc(&sbi->total_valid_inode_count);
271962306a36Sopenharmony_ci}
272062306a36Sopenharmony_ci
272162306a36Sopenharmony_cistatic inline void dec_valid_inode_count(struct f2fs_sb_info *sbi)
272262306a36Sopenharmony_ci{
272362306a36Sopenharmony_ci	percpu_counter_dec(&sbi->total_valid_inode_count);
272462306a36Sopenharmony_ci}
272562306a36Sopenharmony_ci
272662306a36Sopenharmony_cistatic inline s64 valid_inode_count(struct f2fs_sb_info *sbi)
272762306a36Sopenharmony_ci{
272862306a36Sopenharmony_ci	return percpu_counter_sum_positive(&sbi->total_valid_inode_count);
272962306a36Sopenharmony_ci}
273062306a36Sopenharmony_ci
273162306a36Sopenharmony_cistatic inline struct page *f2fs_grab_cache_page(struct address_space *mapping,
273262306a36Sopenharmony_ci						pgoff_t index, bool for_write)
273362306a36Sopenharmony_ci{
273462306a36Sopenharmony_ci	struct page *page;
273562306a36Sopenharmony_ci	unsigned int flags;
273662306a36Sopenharmony_ci
273762306a36Sopenharmony_ci	if (IS_ENABLED(CONFIG_F2FS_FAULT_INJECTION)) {
273862306a36Sopenharmony_ci		if (!for_write)
273962306a36Sopenharmony_ci			page = find_get_page_flags(mapping, index,
274062306a36Sopenharmony_ci							FGP_LOCK | FGP_ACCESSED);
274162306a36Sopenharmony_ci		else
274262306a36Sopenharmony_ci			page = find_lock_page(mapping, index);
274362306a36Sopenharmony_ci		if (page)
274462306a36Sopenharmony_ci			return page;
274562306a36Sopenharmony_ci
274662306a36Sopenharmony_ci		if (time_to_inject(F2FS_M_SB(mapping), FAULT_PAGE_ALLOC))
274762306a36Sopenharmony_ci			return NULL;
274862306a36Sopenharmony_ci	}
274962306a36Sopenharmony_ci
275062306a36Sopenharmony_ci	if (!for_write)
275162306a36Sopenharmony_ci		return grab_cache_page(mapping, index);
275262306a36Sopenharmony_ci
275362306a36Sopenharmony_ci	flags = memalloc_nofs_save();
275462306a36Sopenharmony_ci	page = grab_cache_page_write_begin(mapping, index);
275562306a36Sopenharmony_ci	memalloc_nofs_restore(flags);
275662306a36Sopenharmony_ci
275762306a36Sopenharmony_ci	return page;
275862306a36Sopenharmony_ci}
275962306a36Sopenharmony_ci
276062306a36Sopenharmony_cistatic inline struct page *f2fs_pagecache_get_page(
276162306a36Sopenharmony_ci				struct address_space *mapping, pgoff_t index,
276262306a36Sopenharmony_ci				fgf_t fgp_flags, gfp_t gfp_mask)
276362306a36Sopenharmony_ci{
276462306a36Sopenharmony_ci	if (time_to_inject(F2FS_M_SB(mapping), FAULT_PAGE_GET))
276562306a36Sopenharmony_ci		return NULL;
276662306a36Sopenharmony_ci
276762306a36Sopenharmony_ci	return pagecache_get_page(mapping, index, fgp_flags, gfp_mask);
276862306a36Sopenharmony_ci}
276962306a36Sopenharmony_ci
277062306a36Sopenharmony_cistatic inline void f2fs_put_page(struct page *page, int unlock)
277162306a36Sopenharmony_ci{
277262306a36Sopenharmony_ci	if (!page)
277362306a36Sopenharmony_ci		return;
277462306a36Sopenharmony_ci
277562306a36Sopenharmony_ci	if (unlock) {
277662306a36Sopenharmony_ci		f2fs_bug_on(F2FS_P_SB(page), !PageLocked(page));
277762306a36Sopenharmony_ci		unlock_page(page);
277862306a36Sopenharmony_ci	}
277962306a36Sopenharmony_ci	put_page(page);
278062306a36Sopenharmony_ci}
278162306a36Sopenharmony_ci
278262306a36Sopenharmony_cistatic inline void f2fs_put_dnode(struct dnode_of_data *dn)
278362306a36Sopenharmony_ci{
278462306a36Sopenharmony_ci	if (dn->node_page)
278562306a36Sopenharmony_ci		f2fs_put_page(dn->node_page, 1);
278662306a36Sopenharmony_ci	if (dn->inode_page && dn->node_page != dn->inode_page)
278762306a36Sopenharmony_ci		f2fs_put_page(dn->inode_page, 0);
278862306a36Sopenharmony_ci	dn->node_page = NULL;
278962306a36Sopenharmony_ci	dn->inode_page = NULL;
279062306a36Sopenharmony_ci}
279162306a36Sopenharmony_ci
279262306a36Sopenharmony_cistatic inline struct kmem_cache *f2fs_kmem_cache_create(const char *name,
279362306a36Sopenharmony_ci					size_t size)
279462306a36Sopenharmony_ci{
279562306a36Sopenharmony_ci	return kmem_cache_create(name, size, 0, SLAB_RECLAIM_ACCOUNT, NULL);
279662306a36Sopenharmony_ci}
279762306a36Sopenharmony_ci
279862306a36Sopenharmony_cistatic inline void *f2fs_kmem_cache_alloc_nofail(struct kmem_cache *cachep,
279962306a36Sopenharmony_ci						gfp_t flags)
280062306a36Sopenharmony_ci{
280162306a36Sopenharmony_ci	void *entry;
280262306a36Sopenharmony_ci
280362306a36Sopenharmony_ci	entry = kmem_cache_alloc(cachep, flags);
280462306a36Sopenharmony_ci	if (!entry)
280562306a36Sopenharmony_ci		entry = kmem_cache_alloc(cachep, flags | __GFP_NOFAIL);
280662306a36Sopenharmony_ci	return entry;
280762306a36Sopenharmony_ci}
280862306a36Sopenharmony_ci
280962306a36Sopenharmony_cistatic inline void *f2fs_kmem_cache_alloc(struct kmem_cache *cachep,
281062306a36Sopenharmony_ci			gfp_t flags, bool nofail, struct f2fs_sb_info *sbi)
281162306a36Sopenharmony_ci{
281262306a36Sopenharmony_ci	if (nofail)
281362306a36Sopenharmony_ci		return f2fs_kmem_cache_alloc_nofail(cachep, flags);
281462306a36Sopenharmony_ci
281562306a36Sopenharmony_ci	if (time_to_inject(sbi, FAULT_SLAB_ALLOC))
281662306a36Sopenharmony_ci		return NULL;
281762306a36Sopenharmony_ci
281862306a36Sopenharmony_ci	return kmem_cache_alloc(cachep, flags);
281962306a36Sopenharmony_ci}
282062306a36Sopenharmony_ci
282162306a36Sopenharmony_cistatic inline bool is_inflight_io(struct f2fs_sb_info *sbi, int type)
282262306a36Sopenharmony_ci{
282362306a36Sopenharmony_ci	if (get_pages(sbi, F2FS_RD_DATA) || get_pages(sbi, F2FS_RD_NODE) ||
282462306a36Sopenharmony_ci		get_pages(sbi, F2FS_RD_META) || get_pages(sbi, F2FS_WB_DATA) ||
282562306a36Sopenharmony_ci		get_pages(sbi, F2FS_WB_CP_DATA) ||
282662306a36Sopenharmony_ci		get_pages(sbi, F2FS_DIO_READ) ||
282762306a36Sopenharmony_ci		get_pages(sbi, F2FS_DIO_WRITE))
282862306a36Sopenharmony_ci		return true;
282962306a36Sopenharmony_ci
283062306a36Sopenharmony_ci	if (type != DISCARD_TIME && SM_I(sbi) && SM_I(sbi)->dcc_info &&
283162306a36Sopenharmony_ci			atomic_read(&SM_I(sbi)->dcc_info->queued_discard))
283262306a36Sopenharmony_ci		return true;
283362306a36Sopenharmony_ci
283462306a36Sopenharmony_ci	if (SM_I(sbi) && SM_I(sbi)->fcc_info &&
283562306a36Sopenharmony_ci			atomic_read(&SM_I(sbi)->fcc_info->queued_flush))
283662306a36Sopenharmony_ci		return true;
283762306a36Sopenharmony_ci	return false;
283862306a36Sopenharmony_ci}
283962306a36Sopenharmony_ci
284062306a36Sopenharmony_cistatic inline bool is_idle(struct f2fs_sb_info *sbi, int type)
284162306a36Sopenharmony_ci{
284262306a36Sopenharmony_ci	if (sbi->gc_mode == GC_URGENT_HIGH)
284362306a36Sopenharmony_ci		return true;
284462306a36Sopenharmony_ci
284562306a36Sopenharmony_ci	if (is_inflight_io(sbi, type))
284662306a36Sopenharmony_ci		return false;
284762306a36Sopenharmony_ci
284862306a36Sopenharmony_ci	if (sbi->gc_mode == GC_URGENT_MID)
284962306a36Sopenharmony_ci		return true;
285062306a36Sopenharmony_ci
285162306a36Sopenharmony_ci	if (sbi->gc_mode == GC_URGENT_LOW &&
285262306a36Sopenharmony_ci			(type == DISCARD_TIME || type == GC_TIME))
285362306a36Sopenharmony_ci		return true;
285462306a36Sopenharmony_ci
285562306a36Sopenharmony_ci	return f2fs_time_over(sbi, type);
285662306a36Sopenharmony_ci}
285762306a36Sopenharmony_ci
285862306a36Sopenharmony_cistatic inline void f2fs_radix_tree_insert(struct radix_tree_root *root,
285962306a36Sopenharmony_ci				unsigned long index, void *item)
286062306a36Sopenharmony_ci{
286162306a36Sopenharmony_ci	while (radix_tree_insert(root, index, item))
286262306a36Sopenharmony_ci		cond_resched();
286362306a36Sopenharmony_ci}
286462306a36Sopenharmony_ci
286562306a36Sopenharmony_ci#define RAW_IS_INODE(p)	((p)->footer.nid == (p)->footer.ino)
286662306a36Sopenharmony_ci
286762306a36Sopenharmony_cistatic inline bool IS_INODE(struct page *page)
286862306a36Sopenharmony_ci{
286962306a36Sopenharmony_ci	struct f2fs_node *p = F2FS_NODE(page);
287062306a36Sopenharmony_ci
287162306a36Sopenharmony_ci	return RAW_IS_INODE(p);
287262306a36Sopenharmony_ci}
287362306a36Sopenharmony_ci
287462306a36Sopenharmony_cistatic inline int offset_in_addr(struct f2fs_inode *i)
287562306a36Sopenharmony_ci{
287662306a36Sopenharmony_ci	return (i->i_inline & F2FS_EXTRA_ATTR) ?
287762306a36Sopenharmony_ci			(le16_to_cpu(i->i_extra_isize) / sizeof(__le32)) : 0;
287862306a36Sopenharmony_ci}
287962306a36Sopenharmony_ci
288062306a36Sopenharmony_cistatic inline __le32 *blkaddr_in_node(struct f2fs_node *node)
288162306a36Sopenharmony_ci{
288262306a36Sopenharmony_ci	return RAW_IS_INODE(node) ? node->i.i_addr : node->dn.addr;
288362306a36Sopenharmony_ci}
288462306a36Sopenharmony_ci
288562306a36Sopenharmony_cistatic inline int f2fs_has_extra_attr(struct inode *inode);
288662306a36Sopenharmony_cistatic inline block_t data_blkaddr(struct inode *inode,
288762306a36Sopenharmony_ci			struct page *node_page, unsigned int offset)
288862306a36Sopenharmony_ci{
288962306a36Sopenharmony_ci	struct f2fs_node *raw_node;
289062306a36Sopenharmony_ci	__le32 *addr_array;
289162306a36Sopenharmony_ci	int base = 0;
289262306a36Sopenharmony_ci	bool is_inode = IS_INODE(node_page);
289362306a36Sopenharmony_ci
289462306a36Sopenharmony_ci	raw_node = F2FS_NODE(node_page);
289562306a36Sopenharmony_ci
289662306a36Sopenharmony_ci	if (is_inode) {
289762306a36Sopenharmony_ci		if (!inode)
289862306a36Sopenharmony_ci			/* from GC path only */
289962306a36Sopenharmony_ci			base = offset_in_addr(&raw_node->i);
290062306a36Sopenharmony_ci		else if (f2fs_has_extra_attr(inode))
290162306a36Sopenharmony_ci			base = get_extra_isize(inode);
290262306a36Sopenharmony_ci	}
290362306a36Sopenharmony_ci
290462306a36Sopenharmony_ci	addr_array = blkaddr_in_node(raw_node);
290562306a36Sopenharmony_ci	return le32_to_cpu(addr_array[base + offset]);
290662306a36Sopenharmony_ci}
290762306a36Sopenharmony_ci
290862306a36Sopenharmony_cistatic inline block_t f2fs_data_blkaddr(struct dnode_of_data *dn)
290962306a36Sopenharmony_ci{
291062306a36Sopenharmony_ci	return data_blkaddr(dn->inode, dn->node_page, dn->ofs_in_node);
291162306a36Sopenharmony_ci}
291262306a36Sopenharmony_ci
291362306a36Sopenharmony_cistatic inline int f2fs_test_bit(unsigned int nr, char *addr)
291462306a36Sopenharmony_ci{
291562306a36Sopenharmony_ci	int mask;
291662306a36Sopenharmony_ci
291762306a36Sopenharmony_ci	addr += (nr >> 3);
291862306a36Sopenharmony_ci	mask = BIT(7 - (nr & 0x07));
291962306a36Sopenharmony_ci	return mask & *addr;
292062306a36Sopenharmony_ci}
292162306a36Sopenharmony_ci
292262306a36Sopenharmony_cistatic inline void f2fs_set_bit(unsigned int nr, char *addr)
292362306a36Sopenharmony_ci{
292462306a36Sopenharmony_ci	int mask;
292562306a36Sopenharmony_ci
292662306a36Sopenharmony_ci	addr += (nr >> 3);
292762306a36Sopenharmony_ci	mask = BIT(7 - (nr & 0x07));
292862306a36Sopenharmony_ci	*addr |= mask;
292962306a36Sopenharmony_ci}
293062306a36Sopenharmony_ci
293162306a36Sopenharmony_cistatic inline void f2fs_clear_bit(unsigned int nr, char *addr)
293262306a36Sopenharmony_ci{
293362306a36Sopenharmony_ci	int mask;
293462306a36Sopenharmony_ci
293562306a36Sopenharmony_ci	addr += (nr >> 3);
293662306a36Sopenharmony_ci	mask = BIT(7 - (nr & 0x07));
293762306a36Sopenharmony_ci	*addr &= ~mask;
293862306a36Sopenharmony_ci}
293962306a36Sopenharmony_ci
294062306a36Sopenharmony_cistatic inline int f2fs_test_and_set_bit(unsigned int nr, char *addr)
294162306a36Sopenharmony_ci{
294262306a36Sopenharmony_ci	int mask;
294362306a36Sopenharmony_ci	int ret;
294462306a36Sopenharmony_ci
294562306a36Sopenharmony_ci	addr += (nr >> 3);
294662306a36Sopenharmony_ci	mask = BIT(7 - (nr & 0x07));
294762306a36Sopenharmony_ci	ret = mask & *addr;
294862306a36Sopenharmony_ci	*addr |= mask;
294962306a36Sopenharmony_ci	return ret;
295062306a36Sopenharmony_ci}
295162306a36Sopenharmony_ci
295262306a36Sopenharmony_cistatic inline int f2fs_test_and_clear_bit(unsigned int nr, char *addr)
295362306a36Sopenharmony_ci{
295462306a36Sopenharmony_ci	int mask;
295562306a36Sopenharmony_ci	int ret;
295662306a36Sopenharmony_ci
295762306a36Sopenharmony_ci	addr += (nr >> 3);
295862306a36Sopenharmony_ci	mask = BIT(7 - (nr & 0x07));
295962306a36Sopenharmony_ci	ret = mask & *addr;
296062306a36Sopenharmony_ci	*addr &= ~mask;
296162306a36Sopenharmony_ci	return ret;
296262306a36Sopenharmony_ci}
296362306a36Sopenharmony_ci
296462306a36Sopenharmony_cistatic inline void f2fs_change_bit(unsigned int nr, char *addr)
296562306a36Sopenharmony_ci{
296662306a36Sopenharmony_ci	int mask;
296762306a36Sopenharmony_ci
296862306a36Sopenharmony_ci	addr += (nr >> 3);
296962306a36Sopenharmony_ci	mask = BIT(7 - (nr & 0x07));
297062306a36Sopenharmony_ci	*addr ^= mask;
297162306a36Sopenharmony_ci}
297262306a36Sopenharmony_ci
297362306a36Sopenharmony_ci/*
297462306a36Sopenharmony_ci * On-disk inode flags (f2fs_inode::i_flags)
297562306a36Sopenharmony_ci */
297662306a36Sopenharmony_ci#define F2FS_COMPR_FL			0x00000004 /* Compress file */
297762306a36Sopenharmony_ci#define F2FS_SYNC_FL			0x00000008 /* Synchronous updates */
297862306a36Sopenharmony_ci#define F2FS_IMMUTABLE_FL		0x00000010 /* Immutable file */
297962306a36Sopenharmony_ci#define F2FS_APPEND_FL			0x00000020 /* writes to file may only append */
298062306a36Sopenharmony_ci#define F2FS_NODUMP_FL			0x00000040 /* do not dump file */
298162306a36Sopenharmony_ci#define F2FS_NOATIME_FL			0x00000080 /* do not update atime */
298262306a36Sopenharmony_ci#define F2FS_NOCOMP_FL			0x00000400 /* Don't compress */
298362306a36Sopenharmony_ci#define F2FS_INDEX_FL			0x00001000 /* hash-indexed directory */
298462306a36Sopenharmony_ci#define F2FS_DIRSYNC_FL			0x00010000 /* dirsync behaviour (directories only) */
298562306a36Sopenharmony_ci#define F2FS_PROJINHERIT_FL		0x20000000 /* Create with parents projid */
298662306a36Sopenharmony_ci#define F2FS_CASEFOLD_FL		0x40000000 /* Casefolded file */
298762306a36Sopenharmony_ci
298862306a36Sopenharmony_ci#define F2FS_QUOTA_DEFAULT_FL		(F2FS_NOATIME_FL | F2FS_IMMUTABLE_FL)
298962306a36Sopenharmony_ci
299062306a36Sopenharmony_ci/* Flags that should be inherited by new inodes from their parent. */
299162306a36Sopenharmony_ci#define F2FS_FL_INHERITED (F2FS_SYNC_FL | F2FS_NODUMP_FL | F2FS_NOATIME_FL | \
299262306a36Sopenharmony_ci			   F2FS_DIRSYNC_FL | F2FS_PROJINHERIT_FL | \
299362306a36Sopenharmony_ci			   F2FS_CASEFOLD_FL)
299462306a36Sopenharmony_ci
299562306a36Sopenharmony_ci/* Flags that are appropriate for regular files (all but dir-specific ones). */
299662306a36Sopenharmony_ci#define F2FS_REG_FLMASK		(~(F2FS_DIRSYNC_FL | F2FS_PROJINHERIT_FL | \
299762306a36Sopenharmony_ci				F2FS_CASEFOLD_FL))
299862306a36Sopenharmony_ci
299962306a36Sopenharmony_ci/* Flags that are appropriate for non-directories/regular files. */
300062306a36Sopenharmony_ci#define F2FS_OTHER_FLMASK	(F2FS_NODUMP_FL | F2FS_NOATIME_FL)
300162306a36Sopenharmony_ci
300262306a36Sopenharmony_cistatic inline __u32 f2fs_mask_flags(umode_t mode, __u32 flags)
300362306a36Sopenharmony_ci{
300462306a36Sopenharmony_ci	if (S_ISDIR(mode))
300562306a36Sopenharmony_ci		return flags;
300662306a36Sopenharmony_ci	else if (S_ISREG(mode))
300762306a36Sopenharmony_ci		return flags & F2FS_REG_FLMASK;
300862306a36Sopenharmony_ci	else
300962306a36Sopenharmony_ci		return flags & F2FS_OTHER_FLMASK;
301062306a36Sopenharmony_ci}
301162306a36Sopenharmony_ci
301262306a36Sopenharmony_cistatic inline void __mark_inode_dirty_flag(struct inode *inode,
301362306a36Sopenharmony_ci						int flag, bool set)
301462306a36Sopenharmony_ci{
301562306a36Sopenharmony_ci	switch (flag) {
301662306a36Sopenharmony_ci	case FI_INLINE_XATTR:
301762306a36Sopenharmony_ci	case FI_INLINE_DATA:
301862306a36Sopenharmony_ci	case FI_INLINE_DENTRY:
301962306a36Sopenharmony_ci	case FI_NEW_INODE:
302062306a36Sopenharmony_ci		if (set)
302162306a36Sopenharmony_ci			return;
302262306a36Sopenharmony_ci		fallthrough;
302362306a36Sopenharmony_ci	case FI_DATA_EXIST:
302462306a36Sopenharmony_ci	case FI_INLINE_DOTS:
302562306a36Sopenharmony_ci	case FI_PIN_FILE:
302662306a36Sopenharmony_ci	case FI_COMPRESS_RELEASED:
302762306a36Sopenharmony_ci		f2fs_mark_inode_dirty_sync(inode, true);
302862306a36Sopenharmony_ci	}
302962306a36Sopenharmony_ci}
303062306a36Sopenharmony_ci
303162306a36Sopenharmony_cistatic inline void set_inode_flag(struct inode *inode, int flag)
303262306a36Sopenharmony_ci{
303362306a36Sopenharmony_ci	set_bit(flag, F2FS_I(inode)->flags);
303462306a36Sopenharmony_ci	__mark_inode_dirty_flag(inode, flag, true);
303562306a36Sopenharmony_ci}
303662306a36Sopenharmony_ci
303762306a36Sopenharmony_cistatic inline int is_inode_flag_set(struct inode *inode, int flag)
303862306a36Sopenharmony_ci{
303962306a36Sopenharmony_ci	return test_bit(flag, F2FS_I(inode)->flags);
304062306a36Sopenharmony_ci}
304162306a36Sopenharmony_ci
304262306a36Sopenharmony_cistatic inline void clear_inode_flag(struct inode *inode, int flag)
304362306a36Sopenharmony_ci{
304462306a36Sopenharmony_ci	clear_bit(flag, F2FS_I(inode)->flags);
304562306a36Sopenharmony_ci	__mark_inode_dirty_flag(inode, flag, false);
304662306a36Sopenharmony_ci}
304762306a36Sopenharmony_ci
304862306a36Sopenharmony_cistatic inline bool f2fs_verity_in_progress(struct inode *inode)
304962306a36Sopenharmony_ci{
305062306a36Sopenharmony_ci	return IS_ENABLED(CONFIG_FS_VERITY) &&
305162306a36Sopenharmony_ci	       is_inode_flag_set(inode, FI_VERITY_IN_PROGRESS);
305262306a36Sopenharmony_ci}
305362306a36Sopenharmony_ci
305462306a36Sopenharmony_cistatic inline void set_acl_inode(struct inode *inode, umode_t mode)
305562306a36Sopenharmony_ci{
305662306a36Sopenharmony_ci	F2FS_I(inode)->i_acl_mode = mode;
305762306a36Sopenharmony_ci	set_inode_flag(inode, FI_ACL_MODE);
305862306a36Sopenharmony_ci	f2fs_mark_inode_dirty_sync(inode, false);
305962306a36Sopenharmony_ci}
306062306a36Sopenharmony_ci
306162306a36Sopenharmony_cistatic inline void f2fs_i_links_write(struct inode *inode, bool inc)
306262306a36Sopenharmony_ci{
306362306a36Sopenharmony_ci	if (inc)
306462306a36Sopenharmony_ci		inc_nlink(inode);
306562306a36Sopenharmony_ci	else
306662306a36Sopenharmony_ci		drop_nlink(inode);
306762306a36Sopenharmony_ci	f2fs_mark_inode_dirty_sync(inode, true);
306862306a36Sopenharmony_ci}
306962306a36Sopenharmony_ci
307062306a36Sopenharmony_cistatic inline void f2fs_i_blocks_write(struct inode *inode,
307162306a36Sopenharmony_ci					block_t diff, bool add, bool claim)
307262306a36Sopenharmony_ci{
307362306a36Sopenharmony_ci	bool clean = !is_inode_flag_set(inode, FI_DIRTY_INODE);
307462306a36Sopenharmony_ci	bool recover = is_inode_flag_set(inode, FI_AUTO_RECOVER);
307562306a36Sopenharmony_ci
307662306a36Sopenharmony_ci	/* add = 1, claim = 1 should be dquot_reserve_block in pair */
307762306a36Sopenharmony_ci	if (add) {
307862306a36Sopenharmony_ci		if (claim)
307962306a36Sopenharmony_ci			dquot_claim_block(inode, diff);
308062306a36Sopenharmony_ci		else
308162306a36Sopenharmony_ci			dquot_alloc_block_nofail(inode, diff);
308262306a36Sopenharmony_ci	} else {
308362306a36Sopenharmony_ci		dquot_free_block(inode, diff);
308462306a36Sopenharmony_ci	}
308562306a36Sopenharmony_ci
308662306a36Sopenharmony_ci	f2fs_mark_inode_dirty_sync(inode, true);
308762306a36Sopenharmony_ci	if (clean || recover)
308862306a36Sopenharmony_ci		set_inode_flag(inode, FI_AUTO_RECOVER);
308962306a36Sopenharmony_ci}
309062306a36Sopenharmony_ci
309162306a36Sopenharmony_cistatic inline bool f2fs_is_atomic_file(struct inode *inode);
309262306a36Sopenharmony_ci
309362306a36Sopenharmony_cistatic inline void f2fs_i_size_write(struct inode *inode, loff_t i_size)
309462306a36Sopenharmony_ci{
309562306a36Sopenharmony_ci	bool clean = !is_inode_flag_set(inode, FI_DIRTY_INODE);
309662306a36Sopenharmony_ci	bool recover = is_inode_flag_set(inode, FI_AUTO_RECOVER);
309762306a36Sopenharmony_ci
309862306a36Sopenharmony_ci	if (i_size_read(inode) == i_size)
309962306a36Sopenharmony_ci		return;
310062306a36Sopenharmony_ci
310162306a36Sopenharmony_ci	i_size_write(inode, i_size);
310262306a36Sopenharmony_ci
310362306a36Sopenharmony_ci	if (f2fs_is_atomic_file(inode))
310462306a36Sopenharmony_ci		return;
310562306a36Sopenharmony_ci
310662306a36Sopenharmony_ci	f2fs_mark_inode_dirty_sync(inode, true);
310762306a36Sopenharmony_ci	if (clean || recover)
310862306a36Sopenharmony_ci		set_inode_flag(inode, FI_AUTO_RECOVER);
310962306a36Sopenharmony_ci}
311062306a36Sopenharmony_ci
311162306a36Sopenharmony_cistatic inline void f2fs_i_depth_write(struct inode *inode, unsigned int depth)
311262306a36Sopenharmony_ci{
311362306a36Sopenharmony_ci	F2FS_I(inode)->i_current_depth = depth;
311462306a36Sopenharmony_ci	f2fs_mark_inode_dirty_sync(inode, true);
311562306a36Sopenharmony_ci}
311662306a36Sopenharmony_ci
311762306a36Sopenharmony_cistatic inline void f2fs_i_gc_failures_write(struct inode *inode,
311862306a36Sopenharmony_ci					unsigned int count)
311962306a36Sopenharmony_ci{
312062306a36Sopenharmony_ci	F2FS_I(inode)->i_gc_failures[GC_FAILURE_PIN] = count;
312162306a36Sopenharmony_ci	f2fs_mark_inode_dirty_sync(inode, true);
312262306a36Sopenharmony_ci}
312362306a36Sopenharmony_ci
312462306a36Sopenharmony_cistatic inline void f2fs_i_xnid_write(struct inode *inode, nid_t xnid)
312562306a36Sopenharmony_ci{
312662306a36Sopenharmony_ci	F2FS_I(inode)->i_xattr_nid = xnid;
312762306a36Sopenharmony_ci	f2fs_mark_inode_dirty_sync(inode, true);
312862306a36Sopenharmony_ci}
312962306a36Sopenharmony_ci
313062306a36Sopenharmony_cistatic inline void f2fs_i_pino_write(struct inode *inode, nid_t pino)
313162306a36Sopenharmony_ci{
313262306a36Sopenharmony_ci	F2FS_I(inode)->i_pino = pino;
313362306a36Sopenharmony_ci	f2fs_mark_inode_dirty_sync(inode, true);
313462306a36Sopenharmony_ci}
313562306a36Sopenharmony_ci
313662306a36Sopenharmony_cistatic inline void get_inline_info(struct inode *inode, struct f2fs_inode *ri)
313762306a36Sopenharmony_ci{
313862306a36Sopenharmony_ci	struct f2fs_inode_info *fi = F2FS_I(inode);
313962306a36Sopenharmony_ci
314062306a36Sopenharmony_ci	if (ri->i_inline & F2FS_INLINE_XATTR)
314162306a36Sopenharmony_ci		set_bit(FI_INLINE_XATTR, fi->flags);
314262306a36Sopenharmony_ci	if (ri->i_inline & F2FS_INLINE_DATA)
314362306a36Sopenharmony_ci		set_bit(FI_INLINE_DATA, fi->flags);
314462306a36Sopenharmony_ci	if (ri->i_inline & F2FS_INLINE_DENTRY)
314562306a36Sopenharmony_ci		set_bit(FI_INLINE_DENTRY, fi->flags);
314662306a36Sopenharmony_ci	if (ri->i_inline & F2FS_DATA_EXIST)
314762306a36Sopenharmony_ci		set_bit(FI_DATA_EXIST, fi->flags);
314862306a36Sopenharmony_ci	if (ri->i_inline & F2FS_INLINE_DOTS)
314962306a36Sopenharmony_ci		set_bit(FI_INLINE_DOTS, fi->flags);
315062306a36Sopenharmony_ci	if (ri->i_inline & F2FS_EXTRA_ATTR)
315162306a36Sopenharmony_ci		set_bit(FI_EXTRA_ATTR, fi->flags);
315262306a36Sopenharmony_ci	if (ri->i_inline & F2FS_PIN_FILE)
315362306a36Sopenharmony_ci		set_bit(FI_PIN_FILE, fi->flags);
315462306a36Sopenharmony_ci	if (ri->i_inline & F2FS_COMPRESS_RELEASED)
315562306a36Sopenharmony_ci		set_bit(FI_COMPRESS_RELEASED, fi->flags);
315662306a36Sopenharmony_ci}
315762306a36Sopenharmony_ci
315862306a36Sopenharmony_cistatic inline void set_raw_inline(struct inode *inode, struct f2fs_inode *ri)
315962306a36Sopenharmony_ci{
316062306a36Sopenharmony_ci	ri->i_inline = 0;
316162306a36Sopenharmony_ci
316262306a36Sopenharmony_ci	if (is_inode_flag_set(inode, FI_INLINE_XATTR))
316362306a36Sopenharmony_ci		ri->i_inline |= F2FS_INLINE_XATTR;
316462306a36Sopenharmony_ci	if (is_inode_flag_set(inode, FI_INLINE_DATA))
316562306a36Sopenharmony_ci		ri->i_inline |= F2FS_INLINE_DATA;
316662306a36Sopenharmony_ci	if (is_inode_flag_set(inode, FI_INLINE_DENTRY))
316762306a36Sopenharmony_ci		ri->i_inline |= F2FS_INLINE_DENTRY;
316862306a36Sopenharmony_ci	if (is_inode_flag_set(inode, FI_DATA_EXIST))
316962306a36Sopenharmony_ci		ri->i_inline |= F2FS_DATA_EXIST;
317062306a36Sopenharmony_ci	if (is_inode_flag_set(inode, FI_INLINE_DOTS))
317162306a36Sopenharmony_ci		ri->i_inline |= F2FS_INLINE_DOTS;
317262306a36Sopenharmony_ci	if (is_inode_flag_set(inode, FI_EXTRA_ATTR))
317362306a36Sopenharmony_ci		ri->i_inline |= F2FS_EXTRA_ATTR;
317462306a36Sopenharmony_ci	if (is_inode_flag_set(inode, FI_PIN_FILE))
317562306a36Sopenharmony_ci		ri->i_inline |= F2FS_PIN_FILE;
317662306a36Sopenharmony_ci	if (is_inode_flag_set(inode, FI_COMPRESS_RELEASED))
317762306a36Sopenharmony_ci		ri->i_inline |= F2FS_COMPRESS_RELEASED;
317862306a36Sopenharmony_ci}
317962306a36Sopenharmony_ci
318062306a36Sopenharmony_cistatic inline int f2fs_has_extra_attr(struct inode *inode)
318162306a36Sopenharmony_ci{
318262306a36Sopenharmony_ci	return is_inode_flag_set(inode, FI_EXTRA_ATTR);
318362306a36Sopenharmony_ci}
318462306a36Sopenharmony_ci
318562306a36Sopenharmony_cistatic inline int f2fs_has_inline_xattr(struct inode *inode)
318662306a36Sopenharmony_ci{
318762306a36Sopenharmony_ci	return is_inode_flag_set(inode, FI_INLINE_XATTR);
318862306a36Sopenharmony_ci}
318962306a36Sopenharmony_ci
319062306a36Sopenharmony_cistatic inline int f2fs_compressed_file(struct inode *inode)
319162306a36Sopenharmony_ci{
319262306a36Sopenharmony_ci	return S_ISREG(inode->i_mode) &&
319362306a36Sopenharmony_ci		is_inode_flag_set(inode, FI_COMPRESSED_FILE);
319462306a36Sopenharmony_ci}
319562306a36Sopenharmony_ci
319662306a36Sopenharmony_cistatic inline bool f2fs_need_compress_data(struct inode *inode)
319762306a36Sopenharmony_ci{
319862306a36Sopenharmony_ci	int compress_mode = F2FS_OPTION(F2FS_I_SB(inode)).compress_mode;
319962306a36Sopenharmony_ci
320062306a36Sopenharmony_ci	if (!f2fs_compressed_file(inode))
320162306a36Sopenharmony_ci		return false;
320262306a36Sopenharmony_ci
320362306a36Sopenharmony_ci	if (compress_mode == COMPR_MODE_FS)
320462306a36Sopenharmony_ci		return true;
320562306a36Sopenharmony_ci	else if (compress_mode == COMPR_MODE_USER &&
320662306a36Sopenharmony_ci			is_inode_flag_set(inode, FI_ENABLE_COMPRESS))
320762306a36Sopenharmony_ci		return true;
320862306a36Sopenharmony_ci
320962306a36Sopenharmony_ci	return false;
321062306a36Sopenharmony_ci}
321162306a36Sopenharmony_ci
321262306a36Sopenharmony_cistatic inline unsigned int addrs_per_inode(struct inode *inode)
321362306a36Sopenharmony_ci{
321462306a36Sopenharmony_ci	unsigned int addrs = CUR_ADDRS_PER_INODE(inode) -
321562306a36Sopenharmony_ci				get_inline_xattr_addrs(inode);
321662306a36Sopenharmony_ci
321762306a36Sopenharmony_ci	if (!f2fs_compressed_file(inode))
321862306a36Sopenharmony_ci		return addrs;
321962306a36Sopenharmony_ci	return ALIGN_DOWN(addrs, F2FS_I(inode)->i_cluster_size);
322062306a36Sopenharmony_ci}
322162306a36Sopenharmony_ci
322262306a36Sopenharmony_cistatic inline unsigned int addrs_per_block(struct inode *inode)
322362306a36Sopenharmony_ci{
322462306a36Sopenharmony_ci	if (!f2fs_compressed_file(inode))
322562306a36Sopenharmony_ci		return DEF_ADDRS_PER_BLOCK;
322662306a36Sopenharmony_ci	return ALIGN_DOWN(DEF_ADDRS_PER_BLOCK, F2FS_I(inode)->i_cluster_size);
322762306a36Sopenharmony_ci}
322862306a36Sopenharmony_ci
322962306a36Sopenharmony_cistatic inline void *inline_xattr_addr(struct inode *inode, struct page *page)
323062306a36Sopenharmony_ci{
323162306a36Sopenharmony_ci	struct f2fs_inode *ri = F2FS_INODE(page);
323262306a36Sopenharmony_ci
323362306a36Sopenharmony_ci	return (void *)&(ri->i_addr[DEF_ADDRS_PER_INODE -
323462306a36Sopenharmony_ci					get_inline_xattr_addrs(inode)]);
323562306a36Sopenharmony_ci}
323662306a36Sopenharmony_ci
323762306a36Sopenharmony_cistatic inline int inline_xattr_size(struct inode *inode)
323862306a36Sopenharmony_ci{
323962306a36Sopenharmony_ci	if (f2fs_has_inline_xattr(inode))
324062306a36Sopenharmony_ci		return get_inline_xattr_addrs(inode) * sizeof(__le32);
324162306a36Sopenharmony_ci	return 0;
324262306a36Sopenharmony_ci}
324362306a36Sopenharmony_ci
324462306a36Sopenharmony_ci/*
324562306a36Sopenharmony_ci * Notice: check inline_data flag without inode page lock is unsafe.
324662306a36Sopenharmony_ci * It could change at any time by f2fs_convert_inline_page().
324762306a36Sopenharmony_ci */
324862306a36Sopenharmony_cistatic inline int f2fs_has_inline_data(struct inode *inode)
324962306a36Sopenharmony_ci{
325062306a36Sopenharmony_ci	return is_inode_flag_set(inode, FI_INLINE_DATA);
325162306a36Sopenharmony_ci}
325262306a36Sopenharmony_ci
325362306a36Sopenharmony_cistatic inline int f2fs_exist_data(struct inode *inode)
325462306a36Sopenharmony_ci{
325562306a36Sopenharmony_ci	return is_inode_flag_set(inode, FI_DATA_EXIST);
325662306a36Sopenharmony_ci}
325762306a36Sopenharmony_ci
325862306a36Sopenharmony_cistatic inline int f2fs_has_inline_dots(struct inode *inode)
325962306a36Sopenharmony_ci{
326062306a36Sopenharmony_ci	return is_inode_flag_set(inode, FI_INLINE_DOTS);
326162306a36Sopenharmony_ci}
326262306a36Sopenharmony_ci
326362306a36Sopenharmony_cistatic inline int f2fs_is_mmap_file(struct inode *inode)
326462306a36Sopenharmony_ci{
326562306a36Sopenharmony_ci	return is_inode_flag_set(inode, FI_MMAP_FILE);
326662306a36Sopenharmony_ci}
326762306a36Sopenharmony_ci
326862306a36Sopenharmony_cistatic inline bool f2fs_is_pinned_file(struct inode *inode)
326962306a36Sopenharmony_ci{
327062306a36Sopenharmony_ci	return is_inode_flag_set(inode, FI_PIN_FILE);
327162306a36Sopenharmony_ci}
327262306a36Sopenharmony_ci
327362306a36Sopenharmony_cistatic inline bool f2fs_is_atomic_file(struct inode *inode)
327462306a36Sopenharmony_ci{
327562306a36Sopenharmony_ci	return is_inode_flag_set(inode, FI_ATOMIC_FILE);
327662306a36Sopenharmony_ci}
327762306a36Sopenharmony_ci
327862306a36Sopenharmony_cistatic inline bool f2fs_is_cow_file(struct inode *inode)
327962306a36Sopenharmony_ci{
328062306a36Sopenharmony_ci	return is_inode_flag_set(inode, FI_COW_FILE);
328162306a36Sopenharmony_ci}
328262306a36Sopenharmony_ci
328362306a36Sopenharmony_cistatic inline __le32 *get_dnode_addr(struct inode *inode,
328462306a36Sopenharmony_ci					struct page *node_page);
328562306a36Sopenharmony_cistatic inline void *inline_data_addr(struct inode *inode, struct page *page)
328662306a36Sopenharmony_ci{
328762306a36Sopenharmony_ci	__le32 *addr = get_dnode_addr(inode, page);
328862306a36Sopenharmony_ci
328962306a36Sopenharmony_ci	return (void *)(addr + DEF_INLINE_RESERVED_SIZE);
329062306a36Sopenharmony_ci}
329162306a36Sopenharmony_ci
329262306a36Sopenharmony_cistatic inline int f2fs_has_inline_dentry(struct inode *inode)
329362306a36Sopenharmony_ci{
329462306a36Sopenharmony_ci	return is_inode_flag_set(inode, FI_INLINE_DENTRY);
329562306a36Sopenharmony_ci}
329662306a36Sopenharmony_ci
329762306a36Sopenharmony_cistatic inline int is_file(struct inode *inode, int type)
329862306a36Sopenharmony_ci{
329962306a36Sopenharmony_ci	return F2FS_I(inode)->i_advise & type;
330062306a36Sopenharmony_ci}
330162306a36Sopenharmony_ci
330262306a36Sopenharmony_cistatic inline void set_file(struct inode *inode, int type)
330362306a36Sopenharmony_ci{
330462306a36Sopenharmony_ci	if (is_file(inode, type))
330562306a36Sopenharmony_ci		return;
330662306a36Sopenharmony_ci	F2FS_I(inode)->i_advise |= type;
330762306a36Sopenharmony_ci	f2fs_mark_inode_dirty_sync(inode, true);
330862306a36Sopenharmony_ci}
330962306a36Sopenharmony_ci
331062306a36Sopenharmony_cistatic inline void clear_file(struct inode *inode, int type)
331162306a36Sopenharmony_ci{
331262306a36Sopenharmony_ci	if (!is_file(inode, type))
331362306a36Sopenharmony_ci		return;
331462306a36Sopenharmony_ci	F2FS_I(inode)->i_advise &= ~type;
331562306a36Sopenharmony_ci	f2fs_mark_inode_dirty_sync(inode, true);
331662306a36Sopenharmony_ci}
331762306a36Sopenharmony_ci
331862306a36Sopenharmony_cistatic inline bool f2fs_is_time_consistent(struct inode *inode)
331962306a36Sopenharmony_ci{
332062306a36Sopenharmony_ci	struct timespec64 ctime = inode_get_ctime(inode);
332162306a36Sopenharmony_ci
332262306a36Sopenharmony_ci	if (!timespec64_equal(F2FS_I(inode)->i_disk_time, &inode->i_atime))
332362306a36Sopenharmony_ci		return false;
332462306a36Sopenharmony_ci	if (!timespec64_equal(F2FS_I(inode)->i_disk_time + 1, &ctime))
332562306a36Sopenharmony_ci		return false;
332662306a36Sopenharmony_ci	if (!timespec64_equal(F2FS_I(inode)->i_disk_time + 2, &inode->i_mtime))
332762306a36Sopenharmony_ci		return false;
332862306a36Sopenharmony_ci	return true;
332962306a36Sopenharmony_ci}
333062306a36Sopenharmony_ci
333162306a36Sopenharmony_cistatic inline bool f2fs_skip_inode_update(struct inode *inode, int dsync)
333262306a36Sopenharmony_ci{
333362306a36Sopenharmony_ci	bool ret;
333462306a36Sopenharmony_ci
333562306a36Sopenharmony_ci	if (dsync) {
333662306a36Sopenharmony_ci		struct f2fs_sb_info *sbi = F2FS_I_SB(inode);
333762306a36Sopenharmony_ci
333862306a36Sopenharmony_ci		spin_lock(&sbi->inode_lock[DIRTY_META]);
333962306a36Sopenharmony_ci		ret = list_empty(&F2FS_I(inode)->gdirty_list);
334062306a36Sopenharmony_ci		spin_unlock(&sbi->inode_lock[DIRTY_META]);
334162306a36Sopenharmony_ci		return ret;
334262306a36Sopenharmony_ci	}
334362306a36Sopenharmony_ci	if (!is_inode_flag_set(inode, FI_AUTO_RECOVER) ||
334462306a36Sopenharmony_ci			file_keep_isize(inode) ||
334562306a36Sopenharmony_ci			i_size_read(inode) & ~PAGE_MASK)
334662306a36Sopenharmony_ci		return false;
334762306a36Sopenharmony_ci
334862306a36Sopenharmony_ci	if (!f2fs_is_time_consistent(inode))
334962306a36Sopenharmony_ci		return false;
335062306a36Sopenharmony_ci
335162306a36Sopenharmony_ci	spin_lock(&F2FS_I(inode)->i_size_lock);
335262306a36Sopenharmony_ci	ret = F2FS_I(inode)->last_disk_size == i_size_read(inode);
335362306a36Sopenharmony_ci	spin_unlock(&F2FS_I(inode)->i_size_lock);
335462306a36Sopenharmony_ci
335562306a36Sopenharmony_ci	return ret;
335662306a36Sopenharmony_ci}
335762306a36Sopenharmony_ci
335862306a36Sopenharmony_cistatic inline bool f2fs_readonly(struct super_block *sb)
335962306a36Sopenharmony_ci{
336062306a36Sopenharmony_ci	return sb_rdonly(sb);
336162306a36Sopenharmony_ci}
336262306a36Sopenharmony_ci
336362306a36Sopenharmony_cistatic inline bool f2fs_cp_error(struct f2fs_sb_info *sbi)
336462306a36Sopenharmony_ci{
336562306a36Sopenharmony_ci	return is_set_ckpt_flags(sbi, CP_ERROR_FLAG);
336662306a36Sopenharmony_ci}
336762306a36Sopenharmony_ci
336862306a36Sopenharmony_cistatic inline bool is_dot_dotdot(const u8 *name, size_t len)
336962306a36Sopenharmony_ci{
337062306a36Sopenharmony_ci	if (len == 1 && name[0] == '.')
337162306a36Sopenharmony_ci		return true;
337262306a36Sopenharmony_ci
337362306a36Sopenharmony_ci	if (len == 2 && name[0] == '.' && name[1] == '.')
337462306a36Sopenharmony_ci		return true;
337562306a36Sopenharmony_ci
337662306a36Sopenharmony_ci	return false;
337762306a36Sopenharmony_ci}
337862306a36Sopenharmony_ci
337962306a36Sopenharmony_cistatic inline void *f2fs_kmalloc(struct f2fs_sb_info *sbi,
338062306a36Sopenharmony_ci					size_t size, gfp_t flags)
338162306a36Sopenharmony_ci{
338262306a36Sopenharmony_ci	if (time_to_inject(sbi, FAULT_KMALLOC))
338362306a36Sopenharmony_ci		return NULL;
338462306a36Sopenharmony_ci
338562306a36Sopenharmony_ci	return kmalloc(size, flags);
338662306a36Sopenharmony_ci}
338762306a36Sopenharmony_ci
338862306a36Sopenharmony_cistatic inline void *f2fs_getname(struct f2fs_sb_info *sbi)
338962306a36Sopenharmony_ci{
339062306a36Sopenharmony_ci	if (time_to_inject(sbi, FAULT_KMALLOC))
339162306a36Sopenharmony_ci		return NULL;
339262306a36Sopenharmony_ci
339362306a36Sopenharmony_ci	return __getname();
339462306a36Sopenharmony_ci}
339562306a36Sopenharmony_ci
339662306a36Sopenharmony_cistatic inline void f2fs_putname(char *buf)
339762306a36Sopenharmony_ci{
339862306a36Sopenharmony_ci	__putname(buf);
339962306a36Sopenharmony_ci}
340062306a36Sopenharmony_ci
340162306a36Sopenharmony_cistatic inline void *f2fs_kzalloc(struct f2fs_sb_info *sbi,
340262306a36Sopenharmony_ci					size_t size, gfp_t flags)
340362306a36Sopenharmony_ci{
340462306a36Sopenharmony_ci	return f2fs_kmalloc(sbi, size, flags | __GFP_ZERO);
340562306a36Sopenharmony_ci}
340662306a36Sopenharmony_ci
340762306a36Sopenharmony_cistatic inline void *f2fs_kvmalloc(struct f2fs_sb_info *sbi,
340862306a36Sopenharmony_ci					size_t size, gfp_t flags)
340962306a36Sopenharmony_ci{
341062306a36Sopenharmony_ci	if (time_to_inject(sbi, FAULT_KVMALLOC))
341162306a36Sopenharmony_ci		return NULL;
341262306a36Sopenharmony_ci
341362306a36Sopenharmony_ci	return kvmalloc(size, flags);
341462306a36Sopenharmony_ci}
341562306a36Sopenharmony_ci
341662306a36Sopenharmony_cistatic inline void *f2fs_kvzalloc(struct f2fs_sb_info *sbi,
341762306a36Sopenharmony_ci					size_t size, gfp_t flags)
341862306a36Sopenharmony_ci{
341962306a36Sopenharmony_ci	return f2fs_kvmalloc(sbi, size, flags | __GFP_ZERO);
342062306a36Sopenharmony_ci}
342162306a36Sopenharmony_ci
342262306a36Sopenharmony_cistatic inline int get_extra_isize(struct inode *inode)
342362306a36Sopenharmony_ci{
342462306a36Sopenharmony_ci	return F2FS_I(inode)->i_extra_isize / sizeof(__le32);
342562306a36Sopenharmony_ci}
342662306a36Sopenharmony_ci
342762306a36Sopenharmony_cistatic inline int get_inline_xattr_addrs(struct inode *inode)
342862306a36Sopenharmony_ci{
342962306a36Sopenharmony_ci	return F2FS_I(inode)->i_inline_xattr_size;
343062306a36Sopenharmony_ci}
343162306a36Sopenharmony_ci
343262306a36Sopenharmony_cistatic inline __le32 *get_dnode_addr(struct inode *inode,
343362306a36Sopenharmony_ci					struct page *node_page)
343462306a36Sopenharmony_ci{
343562306a36Sopenharmony_ci	int base = 0;
343662306a36Sopenharmony_ci
343762306a36Sopenharmony_ci	if (IS_INODE(node_page) && f2fs_has_extra_attr(inode))
343862306a36Sopenharmony_ci		base = get_extra_isize(inode);
343962306a36Sopenharmony_ci
344062306a36Sopenharmony_ci	return blkaddr_in_node(F2FS_NODE(node_page)) + base;
344162306a36Sopenharmony_ci}
344262306a36Sopenharmony_ci
344362306a36Sopenharmony_ci#define f2fs_get_inode_mode(i) \
344462306a36Sopenharmony_ci	((is_inode_flag_set(i, FI_ACL_MODE)) ? \
344562306a36Sopenharmony_ci	 (F2FS_I(i)->i_acl_mode) : ((i)->i_mode))
344662306a36Sopenharmony_ci
344762306a36Sopenharmony_ci#define F2FS_MIN_EXTRA_ATTR_SIZE		(sizeof(__le32))
344862306a36Sopenharmony_ci
344962306a36Sopenharmony_ci#define F2FS_TOTAL_EXTRA_ATTR_SIZE			\
345062306a36Sopenharmony_ci	(offsetof(struct f2fs_inode, i_extra_end) -	\
345162306a36Sopenharmony_ci	offsetof(struct f2fs_inode, i_extra_isize))	\
345262306a36Sopenharmony_ci
345362306a36Sopenharmony_ci#define F2FS_OLD_ATTRIBUTE_SIZE	(offsetof(struct f2fs_inode, i_addr))
345462306a36Sopenharmony_ci#define F2FS_FITS_IN_INODE(f2fs_inode, extra_isize, field)		\
345562306a36Sopenharmony_ci		((offsetof(typeof(*(f2fs_inode)), field) +	\
345662306a36Sopenharmony_ci		sizeof((f2fs_inode)->field))			\
345762306a36Sopenharmony_ci		<= (F2FS_OLD_ATTRIBUTE_SIZE + (extra_isize)))	\
345862306a36Sopenharmony_ci
345962306a36Sopenharmony_ci#define __is_large_section(sbi)		((sbi)->segs_per_sec > 1)
346062306a36Sopenharmony_ci
346162306a36Sopenharmony_ci#define __is_meta_io(fio) (PAGE_TYPE_OF_BIO((fio)->type) == META)
346262306a36Sopenharmony_ci
346362306a36Sopenharmony_cibool f2fs_is_valid_blkaddr(struct f2fs_sb_info *sbi,
346462306a36Sopenharmony_ci					block_t blkaddr, int type);
346562306a36Sopenharmony_cistatic inline void verify_blkaddr(struct f2fs_sb_info *sbi,
346662306a36Sopenharmony_ci					block_t blkaddr, int type)
346762306a36Sopenharmony_ci{
346862306a36Sopenharmony_ci	if (!f2fs_is_valid_blkaddr(sbi, blkaddr, type))
346962306a36Sopenharmony_ci		f2fs_err(sbi, "invalid blkaddr: %u, type: %d, run fsck to fix.",
347062306a36Sopenharmony_ci			 blkaddr, type);
347162306a36Sopenharmony_ci}
347262306a36Sopenharmony_ci
347362306a36Sopenharmony_cistatic inline bool __is_valid_data_blkaddr(block_t blkaddr)
347462306a36Sopenharmony_ci{
347562306a36Sopenharmony_ci	if (blkaddr == NEW_ADDR || blkaddr == NULL_ADDR ||
347662306a36Sopenharmony_ci			blkaddr == COMPRESS_ADDR)
347762306a36Sopenharmony_ci		return false;
347862306a36Sopenharmony_ci	return true;
347962306a36Sopenharmony_ci}
348062306a36Sopenharmony_ci
348162306a36Sopenharmony_ci/*
348262306a36Sopenharmony_ci * file.c
348362306a36Sopenharmony_ci */
348462306a36Sopenharmony_ciint f2fs_sync_file(struct file *file, loff_t start, loff_t end, int datasync);
348562306a36Sopenharmony_ciint f2fs_do_truncate_blocks(struct inode *inode, u64 from, bool lock);
348662306a36Sopenharmony_ciint f2fs_truncate_blocks(struct inode *inode, u64 from, bool lock);
348762306a36Sopenharmony_ciint f2fs_truncate(struct inode *inode);
348862306a36Sopenharmony_ciint f2fs_getattr(struct mnt_idmap *idmap, const struct path *path,
348962306a36Sopenharmony_ci		 struct kstat *stat, u32 request_mask, unsigned int flags);
349062306a36Sopenharmony_ciint f2fs_setattr(struct mnt_idmap *idmap, struct dentry *dentry,
349162306a36Sopenharmony_ci		 struct iattr *attr);
349262306a36Sopenharmony_ciint f2fs_truncate_hole(struct inode *inode, pgoff_t pg_start, pgoff_t pg_end);
349362306a36Sopenharmony_civoid f2fs_truncate_data_blocks_range(struct dnode_of_data *dn, int count);
349462306a36Sopenharmony_ciint f2fs_precache_extents(struct inode *inode);
349562306a36Sopenharmony_ciint f2fs_fileattr_get(struct dentry *dentry, struct fileattr *fa);
349662306a36Sopenharmony_ciint f2fs_fileattr_set(struct mnt_idmap *idmap,
349762306a36Sopenharmony_ci		      struct dentry *dentry, struct fileattr *fa);
349862306a36Sopenharmony_cilong f2fs_ioctl(struct file *filp, unsigned int cmd, unsigned long arg);
349962306a36Sopenharmony_cilong f2fs_compat_ioctl(struct file *file, unsigned int cmd, unsigned long arg);
350062306a36Sopenharmony_ciint f2fs_transfer_project_quota(struct inode *inode, kprojid_t kprojid);
350162306a36Sopenharmony_ciint f2fs_pin_file_control(struct inode *inode, bool inc);
350262306a36Sopenharmony_ci
350362306a36Sopenharmony_ci/*
350462306a36Sopenharmony_ci * inode.c
350562306a36Sopenharmony_ci */
350662306a36Sopenharmony_civoid f2fs_set_inode_flags(struct inode *inode);
350762306a36Sopenharmony_cibool f2fs_inode_chksum_verify(struct f2fs_sb_info *sbi, struct page *page);
350862306a36Sopenharmony_civoid f2fs_inode_chksum_set(struct f2fs_sb_info *sbi, struct page *page);
350962306a36Sopenharmony_cistruct inode *f2fs_iget(struct super_block *sb, unsigned long ino);
351062306a36Sopenharmony_cistruct inode *f2fs_iget_retry(struct super_block *sb, unsigned long ino);
351162306a36Sopenharmony_ciint f2fs_try_to_free_nats(struct f2fs_sb_info *sbi, int nr_shrink);
351262306a36Sopenharmony_civoid f2fs_update_inode(struct inode *inode, struct page *node_page);
351362306a36Sopenharmony_civoid f2fs_update_inode_page(struct inode *inode);
351462306a36Sopenharmony_ciint f2fs_write_inode(struct inode *inode, struct writeback_control *wbc);
351562306a36Sopenharmony_civoid f2fs_evict_inode(struct inode *inode);
351662306a36Sopenharmony_civoid f2fs_handle_failed_inode(struct inode *inode);
351762306a36Sopenharmony_ci
351862306a36Sopenharmony_ci/*
351962306a36Sopenharmony_ci * namei.c
352062306a36Sopenharmony_ci */
352162306a36Sopenharmony_ciint f2fs_update_extension_list(struct f2fs_sb_info *sbi, const char *name,
352262306a36Sopenharmony_ci							bool hot, bool set);
352362306a36Sopenharmony_cistruct dentry *f2fs_get_parent(struct dentry *child);
352462306a36Sopenharmony_ciint f2fs_get_tmpfile(struct mnt_idmap *idmap, struct inode *dir,
352562306a36Sopenharmony_ci		     struct inode **new_inode);
352662306a36Sopenharmony_ci
352762306a36Sopenharmony_ci/*
352862306a36Sopenharmony_ci * dir.c
352962306a36Sopenharmony_ci */
353062306a36Sopenharmony_ciint f2fs_init_casefolded_name(const struct inode *dir,
353162306a36Sopenharmony_ci			      struct f2fs_filename *fname);
353262306a36Sopenharmony_ciint f2fs_setup_filename(struct inode *dir, const struct qstr *iname,
353362306a36Sopenharmony_ci			int lookup, struct f2fs_filename *fname);
353462306a36Sopenharmony_ciint f2fs_prepare_lookup(struct inode *dir, struct dentry *dentry,
353562306a36Sopenharmony_ci			struct f2fs_filename *fname);
353662306a36Sopenharmony_civoid f2fs_free_filename(struct f2fs_filename *fname);
353762306a36Sopenharmony_cistruct f2fs_dir_entry *f2fs_find_target_dentry(const struct f2fs_dentry_ptr *d,
353862306a36Sopenharmony_ci			const struct f2fs_filename *fname, int *max_slots);
353962306a36Sopenharmony_ciint f2fs_fill_dentries(struct dir_context *ctx, struct f2fs_dentry_ptr *d,
354062306a36Sopenharmony_ci			unsigned int start_pos, struct fscrypt_str *fstr);
354162306a36Sopenharmony_civoid f2fs_do_make_empty_dir(struct inode *inode, struct inode *parent,
354262306a36Sopenharmony_ci			struct f2fs_dentry_ptr *d);
354362306a36Sopenharmony_cistruct page *f2fs_init_inode_metadata(struct inode *inode, struct inode *dir,
354462306a36Sopenharmony_ci			const struct f2fs_filename *fname, struct page *dpage);
354562306a36Sopenharmony_civoid f2fs_update_parent_metadata(struct inode *dir, struct inode *inode,
354662306a36Sopenharmony_ci			unsigned int current_depth);
354762306a36Sopenharmony_ciint f2fs_room_for_filename(const void *bitmap, int slots, int max_slots);
354862306a36Sopenharmony_civoid f2fs_drop_nlink(struct inode *dir, struct inode *inode);
354962306a36Sopenharmony_cistruct f2fs_dir_entry *__f2fs_find_entry(struct inode *dir,
355062306a36Sopenharmony_ci					 const struct f2fs_filename *fname,
355162306a36Sopenharmony_ci					 struct page **res_page);
355262306a36Sopenharmony_cistruct f2fs_dir_entry *f2fs_find_entry(struct inode *dir,
355362306a36Sopenharmony_ci			const struct qstr *child, struct page **res_page);
355462306a36Sopenharmony_cistruct f2fs_dir_entry *f2fs_parent_dir(struct inode *dir, struct page **p);
355562306a36Sopenharmony_ciino_t f2fs_inode_by_name(struct inode *dir, const struct qstr *qstr,
355662306a36Sopenharmony_ci			struct page **page);
355762306a36Sopenharmony_civoid f2fs_set_link(struct inode *dir, struct f2fs_dir_entry *de,
355862306a36Sopenharmony_ci			struct page *page, struct inode *inode);
355962306a36Sopenharmony_cibool f2fs_has_enough_room(struct inode *dir, struct page *ipage,
356062306a36Sopenharmony_ci			  const struct f2fs_filename *fname);
356162306a36Sopenharmony_civoid f2fs_update_dentry(nid_t ino, umode_t mode, struct f2fs_dentry_ptr *d,
356262306a36Sopenharmony_ci			const struct fscrypt_str *name, f2fs_hash_t name_hash,
356362306a36Sopenharmony_ci			unsigned int bit_pos);
356462306a36Sopenharmony_ciint f2fs_add_regular_entry(struct inode *dir, const struct f2fs_filename *fname,
356562306a36Sopenharmony_ci			struct inode *inode, nid_t ino, umode_t mode);
356662306a36Sopenharmony_ciint f2fs_add_dentry(struct inode *dir, const struct f2fs_filename *fname,
356762306a36Sopenharmony_ci			struct inode *inode, nid_t ino, umode_t mode);
356862306a36Sopenharmony_ciint f2fs_do_add_link(struct inode *dir, const struct qstr *name,
356962306a36Sopenharmony_ci			struct inode *inode, nid_t ino, umode_t mode);
357062306a36Sopenharmony_civoid f2fs_delete_entry(struct f2fs_dir_entry *dentry, struct page *page,
357162306a36Sopenharmony_ci			struct inode *dir, struct inode *inode);
357262306a36Sopenharmony_ciint f2fs_do_tmpfile(struct inode *inode, struct inode *dir,
357362306a36Sopenharmony_ci					struct f2fs_filename *fname);
357462306a36Sopenharmony_cibool f2fs_empty_dir(struct inode *dir);
357562306a36Sopenharmony_ci
357662306a36Sopenharmony_cistatic inline int f2fs_add_link(struct dentry *dentry, struct inode *inode)
357762306a36Sopenharmony_ci{
357862306a36Sopenharmony_ci	if (fscrypt_is_nokey_name(dentry))
357962306a36Sopenharmony_ci		return -ENOKEY;
358062306a36Sopenharmony_ci	return f2fs_do_add_link(d_inode(dentry->d_parent), &dentry->d_name,
358162306a36Sopenharmony_ci				inode, inode->i_ino, inode->i_mode);
358262306a36Sopenharmony_ci}
358362306a36Sopenharmony_ci
358462306a36Sopenharmony_ci/*
358562306a36Sopenharmony_ci * super.c
358662306a36Sopenharmony_ci */
358762306a36Sopenharmony_ciint f2fs_inode_dirtied(struct inode *inode, bool sync);
358862306a36Sopenharmony_civoid f2fs_inode_synced(struct inode *inode);
358962306a36Sopenharmony_ciint f2fs_dquot_initialize(struct inode *inode);
359062306a36Sopenharmony_ciint f2fs_enable_quota_files(struct f2fs_sb_info *sbi, bool rdonly);
359162306a36Sopenharmony_ciint f2fs_quota_sync(struct super_block *sb, int type);
359262306a36Sopenharmony_ciloff_t max_file_blocks(struct inode *inode);
359362306a36Sopenharmony_civoid f2fs_quota_off_umount(struct super_block *sb);
359462306a36Sopenharmony_civoid f2fs_save_errors(struct f2fs_sb_info *sbi, unsigned char flag);
359562306a36Sopenharmony_civoid f2fs_handle_critical_error(struct f2fs_sb_info *sbi, unsigned char reason,
359662306a36Sopenharmony_ci							bool irq_context);
359762306a36Sopenharmony_civoid f2fs_handle_error(struct f2fs_sb_info *sbi, unsigned char error);
359862306a36Sopenharmony_civoid f2fs_handle_error_async(struct f2fs_sb_info *sbi, unsigned char error);
359962306a36Sopenharmony_ciint f2fs_commit_super(struct f2fs_sb_info *sbi, bool recover);
360062306a36Sopenharmony_ciint f2fs_sync_fs(struct super_block *sb, int sync);
360162306a36Sopenharmony_ciint f2fs_sanity_check_ckpt(struct f2fs_sb_info *sbi);
360262306a36Sopenharmony_ci
360362306a36Sopenharmony_ci/*
360462306a36Sopenharmony_ci * hash.c
360562306a36Sopenharmony_ci */
360662306a36Sopenharmony_civoid f2fs_hash_filename(const struct inode *dir, struct f2fs_filename *fname);
360762306a36Sopenharmony_ci
360862306a36Sopenharmony_ci/*
360962306a36Sopenharmony_ci * node.c
361062306a36Sopenharmony_ci */
361162306a36Sopenharmony_cistruct node_info;
361262306a36Sopenharmony_ci
361362306a36Sopenharmony_ciint f2fs_check_nid_range(struct f2fs_sb_info *sbi, nid_t nid);
361462306a36Sopenharmony_cibool f2fs_available_free_memory(struct f2fs_sb_info *sbi, int type);
361562306a36Sopenharmony_cibool f2fs_in_warm_node_list(struct f2fs_sb_info *sbi, struct page *page);
361662306a36Sopenharmony_civoid f2fs_init_fsync_node_info(struct f2fs_sb_info *sbi);
361762306a36Sopenharmony_civoid f2fs_del_fsync_node_entry(struct f2fs_sb_info *sbi, struct page *page);
361862306a36Sopenharmony_civoid f2fs_reset_fsync_node_info(struct f2fs_sb_info *sbi);
361962306a36Sopenharmony_ciint f2fs_need_dentry_mark(struct f2fs_sb_info *sbi, nid_t nid);
362062306a36Sopenharmony_cibool f2fs_is_checkpointed_node(struct f2fs_sb_info *sbi, nid_t nid);
362162306a36Sopenharmony_cibool f2fs_need_inode_block_update(struct f2fs_sb_info *sbi, nid_t ino);
362262306a36Sopenharmony_ciint f2fs_get_node_info(struct f2fs_sb_info *sbi, nid_t nid,
362362306a36Sopenharmony_ci				struct node_info *ni, bool checkpoint_context);
362462306a36Sopenharmony_cipgoff_t f2fs_get_next_page_offset(struct dnode_of_data *dn, pgoff_t pgofs);
362562306a36Sopenharmony_ciint f2fs_get_dnode_of_data(struct dnode_of_data *dn, pgoff_t index, int mode);
362662306a36Sopenharmony_ciint f2fs_truncate_inode_blocks(struct inode *inode, pgoff_t from);
362762306a36Sopenharmony_ciint f2fs_truncate_xattr_node(struct inode *inode);
362862306a36Sopenharmony_ciint f2fs_wait_on_node_pages_writeback(struct f2fs_sb_info *sbi,
362962306a36Sopenharmony_ci					unsigned int seq_id);
363062306a36Sopenharmony_cibool f2fs_nat_bitmap_enabled(struct f2fs_sb_info *sbi);
363162306a36Sopenharmony_ciint f2fs_remove_inode_page(struct inode *inode);
363262306a36Sopenharmony_cistruct page *f2fs_new_inode_page(struct inode *inode);
363362306a36Sopenharmony_cistruct page *f2fs_new_node_page(struct dnode_of_data *dn, unsigned int ofs);
363462306a36Sopenharmony_civoid f2fs_ra_node_page(struct f2fs_sb_info *sbi, nid_t nid);
363562306a36Sopenharmony_cistruct page *f2fs_get_node_page(struct f2fs_sb_info *sbi, pgoff_t nid);
363662306a36Sopenharmony_cistruct page *f2fs_get_node_page_ra(struct page *parent, int start);
363762306a36Sopenharmony_ciint f2fs_move_node_page(struct page *node_page, int gc_type);
363862306a36Sopenharmony_civoid f2fs_flush_inline_data(struct f2fs_sb_info *sbi);
363962306a36Sopenharmony_ciint f2fs_fsync_node_pages(struct f2fs_sb_info *sbi, struct inode *inode,
364062306a36Sopenharmony_ci			struct writeback_control *wbc, bool atomic,
364162306a36Sopenharmony_ci			unsigned int *seq_id);
364262306a36Sopenharmony_ciint f2fs_sync_node_pages(struct f2fs_sb_info *sbi,
364362306a36Sopenharmony_ci			struct writeback_control *wbc,
364462306a36Sopenharmony_ci			bool do_balance, enum iostat_type io_type);
364562306a36Sopenharmony_ciint f2fs_build_free_nids(struct f2fs_sb_info *sbi, bool sync, bool mount);
364662306a36Sopenharmony_cibool f2fs_alloc_nid(struct f2fs_sb_info *sbi, nid_t *nid);
364762306a36Sopenharmony_civoid f2fs_alloc_nid_done(struct f2fs_sb_info *sbi, nid_t nid);
364862306a36Sopenharmony_civoid f2fs_alloc_nid_failed(struct f2fs_sb_info *sbi, nid_t nid);
364962306a36Sopenharmony_ciint f2fs_try_to_free_nids(struct f2fs_sb_info *sbi, int nr_shrink);
365062306a36Sopenharmony_ciint f2fs_recover_inline_xattr(struct inode *inode, struct page *page);
365162306a36Sopenharmony_ciint f2fs_recover_xattr_data(struct inode *inode, struct page *page);
365262306a36Sopenharmony_ciint f2fs_recover_inode_page(struct f2fs_sb_info *sbi, struct page *page);
365362306a36Sopenharmony_ciint f2fs_restore_node_summary(struct f2fs_sb_info *sbi,
365462306a36Sopenharmony_ci			unsigned int segno, struct f2fs_summary_block *sum);
365562306a36Sopenharmony_civoid f2fs_enable_nat_bits(struct f2fs_sb_info *sbi);
365662306a36Sopenharmony_ciint f2fs_flush_nat_entries(struct f2fs_sb_info *sbi, struct cp_control *cpc);
365762306a36Sopenharmony_ciint f2fs_build_node_manager(struct f2fs_sb_info *sbi);
365862306a36Sopenharmony_civoid f2fs_destroy_node_manager(struct f2fs_sb_info *sbi);
365962306a36Sopenharmony_ciint __init f2fs_create_node_manager_caches(void);
366062306a36Sopenharmony_civoid f2fs_destroy_node_manager_caches(void);
366162306a36Sopenharmony_ci
366262306a36Sopenharmony_ci/*
366362306a36Sopenharmony_ci * segment.c
366462306a36Sopenharmony_ci */
366562306a36Sopenharmony_cibool f2fs_need_SSR(struct f2fs_sb_info *sbi);
366662306a36Sopenharmony_ciint f2fs_commit_atomic_write(struct inode *inode);
366762306a36Sopenharmony_civoid f2fs_abort_atomic_write(struct inode *inode, bool clean);
366862306a36Sopenharmony_civoid f2fs_balance_fs(struct f2fs_sb_info *sbi, bool need);
366962306a36Sopenharmony_civoid f2fs_balance_fs_bg(struct f2fs_sb_info *sbi, bool from_bg);
367062306a36Sopenharmony_ciint f2fs_issue_flush(struct f2fs_sb_info *sbi, nid_t ino);
367162306a36Sopenharmony_ciint f2fs_create_flush_cmd_control(struct f2fs_sb_info *sbi);
367262306a36Sopenharmony_ciint f2fs_flush_device_cache(struct f2fs_sb_info *sbi);
367362306a36Sopenharmony_civoid f2fs_destroy_flush_cmd_control(struct f2fs_sb_info *sbi, bool free);
367462306a36Sopenharmony_civoid f2fs_invalidate_blocks(struct f2fs_sb_info *sbi, block_t addr);
367562306a36Sopenharmony_cibool f2fs_is_checkpointed_data(struct f2fs_sb_info *sbi, block_t blkaddr);
367662306a36Sopenharmony_ciint f2fs_start_discard_thread(struct f2fs_sb_info *sbi);
367762306a36Sopenharmony_civoid f2fs_drop_discard_cmd(struct f2fs_sb_info *sbi);
367862306a36Sopenharmony_civoid f2fs_stop_discard_thread(struct f2fs_sb_info *sbi);
367962306a36Sopenharmony_cibool f2fs_issue_discard_timeout(struct f2fs_sb_info *sbi);
368062306a36Sopenharmony_civoid f2fs_clear_prefree_segments(struct f2fs_sb_info *sbi,
368162306a36Sopenharmony_ci					struct cp_control *cpc);
368262306a36Sopenharmony_civoid f2fs_dirty_to_prefree(struct f2fs_sb_info *sbi);
368362306a36Sopenharmony_ciblock_t f2fs_get_unusable_blocks(struct f2fs_sb_info *sbi);
368462306a36Sopenharmony_ciint f2fs_disable_cp_again(struct f2fs_sb_info *sbi, block_t unusable);
368562306a36Sopenharmony_civoid f2fs_release_discard_addrs(struct f2fs_sb_info *sbi);
368662306a36Sopenharmony_ciint f2fs_npages_for_summary_flush(struct f2fs_sb_info *sbi, bool for_ra);
368762306a36Sopenharmony_cibool f2fs_segment_has_free_slot(struct f2fs_sb_info *sbi, int segno);
368862306a36Sopenharmony_civoid f2fs_init_inmem_curseg(struct f2fs_sb_info *sbi);
368962306a36Sopenharmony_civoid f2fs_save_inmem_curseg(struct f2fs_sb_info *sbi);
369062306a36Sopenharmony_civoid f2fs_restore_inmem_curseg(struct f2fs_sb_info *sbi);
369162306a36Sopenharmony_civoid f2fs_get_new_segment(struct f2fs_sb_info *sbi,
369262306a36Sopenharmony_ci			unsigned int *newseg, bool new_sec, int dir);
369362306a36Sopenharmony_civoid f2fs_allocate_segment_for_resize(struct f2fs_sb_info *sbi, int type,
369462306a36Sopenharmony_ci					unsigned int start, unsigned int end);
369562306a36Sopenharmony_civoid f2fs_allocate_new_section(struct f2fs_sb_info *sbi, int type, bool force);
369662306a36Sopenharmony_civoid f2fs_allocate_new_segments(struct f2fs_sb_info *sbi);
369762306a36Sopenharmony_ciint f2fs_trim_fs(struct f2fs_sb_info *sbi, struct fstrim_range *range);
369862306a36Sopenharmony_cibool f2fs_exist_trim_candidates(struct f2fs_sb_info *sbi,
369962306a36Sopenharmony_ci					struct cp_control *cpc);
370062306a36Sopenharmony_cistruct page *f2fs_get_sum_page(struct f2fs_sb_info *sbi, unsigned int segno);
370162306a36Sopenharmony_civoid f2fs_update_meta_page(struct f2fs_sb_info *sbi, void *src,
370262306a36Sopenharmony_ci					block_t blk_addr);
370362306a36Sopenharmony_civoid f2fs_do_write_meta_page(struct f2fs_sb_info *sbi, struct page *page,
370462306a36Sopenharmony_ci						enum iostat_type io_type);
370562306a36Sopenharmony_civoid f2fs_do_write_node_page(unsigned int nid, struct f2fs_io_info *fio);
370662306a36Sopenharmony_civoid f2fs_outplace_write_data(struct dnode_of_data *dn,
370762306a36Sopenharmony_ci			struct f2fs_io_info *fio);
370862306a36Sopenharmony_ciint f2fs_inplace_write_data(struct f2fs_io_info *fio);
370962306a36Sopenharmony_civoid f2fs_do_replace_block(struct f2fs_sb_info *sbi, struct f2fs_summary *sum,
371062306a36Sopenharmony_ci			block_t old_blkaddr, block_t new_blkaddr,
371162306a36Sopenharmony_ci			bool recover_curseg, bool recover_newaddr,
371262306a36Sopenharmony_ci			bool from_gc);
371362306a36Sopenharmony_civoid f2fs_replace_block(struct f2fs_sb_info *sbi, struct dnode_of_data *dn,
371462306a36Sopenharmony_ci			block_t old_addr, block_t new_addr,
371562306a36Sopenharmony_ci			unsigned char version, bool recover_curseg,
371662306a36Sopenharmony_ci			bool recover_newaddr);
371762306a36Sopenharmony_civoid f2fs_allocate_data_block(struct f2fs_sb_info *sbi, struct page *page,
371862306a36Sopenharmony_ci			block_t old_blkaddr, block_t *new_blkaddr,
371962306a36Sopenharmony_ci			struct f2fs_summary *sum, int type,
372062306a36Sopenharmony_ci			struct f2fs_io_info *fio);
372162306a36Sopenharmony_civoid f2fs_update_device_state(struct f2fs_sb_info *sbi, nid_t ino,
372262306a36Sopenharmony_ci					block_t blkaddr, unsigned int blkcnt);
372362306a36Sopenharmony_civoid f2fs_wait_on_page_writeback(struct page *page,
372462306a36Sopenharmony_ci			enum page_type type, bool ordered, bool locked);
372562306a36Sopenharmony_civoid f2fs_wait_on_block_writeback(struct inode *inode, block_t blkaddr);
372662306a36Sopenharmony_civoid f2fs_wait_on_block_writeback_range(struct inode *inode, block_t blkaddr,
372762306a36Sopenharmony_ci								block_t len);
372862306a36Sopenharmony_civoid f2fs_write_data_summaries(struct f2fs_sb_info *sbi, block_t start_blk);
372962306a36Sopenharmony_civoid f2fs_write_node_summaries(struct f2fs_sb_info *sbi, block_t start_blk);
373062306a36Sopenharmony_ciint f2fs_lookup_journal_in_cursum(struct f2fs_journal *journal, int type,
373162306a36Sopenharmony_ci			unsigned int val, int alloc);
373262306a36Sopenharmony_civoid f2fs_flush_sit_entries(struct f2fs_sb_info *sbi, struct cp_control *cpc);
373362306a36Sopenharmony_ciint f2fs_fix_curseg_write_pointer(struct f2fs_sb_info *sbi);
373462306a36Sopenharmony_ciint f2fs_check_write_pointer(struct f2fs_sb_info *sbi);
373562306a36Sopenharmony_ciint f2fs_build_segment_manager(struct f2fs_sb_info *sbi);
373662306a36Sopenharmony_civoid f2fs_destroy_segment_manager(struct f2fs_sb_info *sbi);
373762306a36Sopenharmony_ciint __init f2fs_create_segment_manager_caches(void);
373862306a36Sopenharmony_civoid f2fs_destroy_segment_manager_caches(void);
373962306a36Sopenharmony_ciint f2fs_rw_hint_to_seg_type(enum rw_hint hint);
374062306a36Sopenharmony_ciunsigned int f2fs_usable_segs_in_sec(struct f2fs_sb_info *sbi,
374162306a36Sopenharmony_ci			unsigned int segno);
374262306a36Sopenharmony_ciunsigned int f2fs_usable_blks_in_seg(struct f2fs_sb_info *sbi,
374362306a36Sopenharmony_ci			unsigned int segno);
374462306a36Sopenharmony_ci
374562306a36Sopenharmony_ci#define DEF_FRAGMENT_SIZE	4
374662306a36Sopenharmony_ci#define MIN_FRAGMENT_SIZE	1
374762306a36Sopenharmony_ci#define MAX_FRAGMENT_SIZE	512
374862306a36Sopenharmony_ci
374962306a36Sopenharmony_cistatic inline bool f2fs_need_rand_seg(struct f2fs_sb_info *sbi)
375062306a36Sopenharmony_ci{
375162306a36Sopenharmony_ci	return F2FS_OPTION(sbi).fs_mode == FS_MODE_FRAGMENT_SEG ||
375262306a36Sopenharmony_ci		F2FS_OPTION(sbi).fs_mode == FS_MODE_FRAGMENT_BLK;
375362306a36Sopenharmony_ci}
375462306a36Sopenharmony_ci
375562306a36Sopenharmony_ci/*
375662306a36Sopenharmony_ci * checkpoint.c
375762306a36Sopenharmony_ci */
375862306a36Sopenharmony_civoid f2fs_stop_checkpoint(struct f2fs_sb_info *sbi, bool end_io,
375962306a36Sopenharmony_ci							unsigned char reason);
376062306a36Sopenharmony_civoid f2fs_flush_ckpt_thread(struct f2fs_sb_info *sbi);
376162306a36Sopenharmony_cistruct page *f2fs_grab_meta_page(struct f2fs_sb_info *sbi, pgoff_t index);
376262306a36Sopenharmony_cistruct page *f2fs_get_meta_page(struct f2fs_sb_info *sbi, pgoff_t index);
376362306a36Sopenharmony_cistruct page *f2fs_get_meta_page_retry(struct f2fs_sb_info *sbi, pgoff_t index);
376462306a36Sopenharmony_cistruct page *f2fs_get_tmp_page(struct f2fs_sb_info *sbi, pgoff_t index);
376562306a36Sopenharmony_cibool f2fs_is_valid_blkaddr(struct f2fs_sb_info *sbi,
376662306a36Sopenharmony_ci					block_t blkaddr, int type);
376762306a36Sopenharmony_ciint f2fs_ra_meta_pages(struct f2fs_sb_info *sbi, block_t start, int nrpages,
376862306a36Sopenharmony_ci			int type, bool sync);
376962306a36Sopenharmony_civoid f2fs_ra_meta_pages_cond(struct f2fs_sb_info *sbi, pgoff_t index,
377062306a36Sopenharmony_ci							unsigned int ra_blocks);
377162306a36Sopenharmony_cilong f2fs_sync_meta_pages(struct f2fs_sb_info *sbi, enum page_type type,
377262306a36Sopenharmony_ci			long nr_to_write, enum iostat_type io_type);
377362306a36Sopenharmony_civoid f2fs_add_ino_entry(struct f2fs_sb_info *sbi, nid_t ino, int type);
377462306a36Sopenharmony_civoid f2fs_remove_ino_entry(struct f2fs_sb_info *sbi, nid_t ino, int type);
377562306a36Sopenharmony_civoid f2fs_release_ino_entry(struct f2fs_sb_info *sbi, bool all);
377662306a36Sopenharmony_cibool f2fs_exist_written_data(struct f2fs_sb_info *sbi, nid_t ino, int mode);
377762306a36Sopenharmony_civoid f2fs_set_dirty_device(struct f2fs_sb_info *sbi, nid_t ino,
377862306a36Sopenharmony_ci					unsigned int devidx, int type);
377962306a36Sopenharmony_cibool f2fs_is_dirty_device(struct f2fs_sb_info *sbi, nid_t ino,
378062306a36Sopenharmony_ci					unsigned int devidx, int type);
378162306a36Sopenharmony_ciint f2fs_acquire_orphan_inode(struct f2fs_sb_info *sbi);
378262306a36Sopenharmony_civoid f2fs_release_orphan_inode(struct f2fs_sb_info *sbi);
378362306a36Sopenharmony_civoid f2fs_add_orphan_inode(struct inode *inode);
378462306a36Sopenharmony_civoid f2fs_remove_orphan_inode(struct f2fs_sb_info *sbi, nid_t ino);
378562306a36Sopenharmony_ciint f2fs_recover_orphan_inodes(struct f2fs_sb_info *sbi);
378662306a36Sopenharmony_ciint f2fs_get_valid_checkpoint(struct f2fs_sb_info *sbi);
378762306a36Sopenharmony_civoid f2fs_update_dirty_folio(struct inode *inode, struct folio *folio);
378862306a36Sopenharmony_civoid f2fs_remove_dirty_inode(struct inode *inode);
378962306a36Sopenharmony_ciint f2fs_sync_dirty_inodes(struct f2fs_sb_info *sbi, enum inode_type type,
379062306a36Sopenharmony_ci								bool from_cp);
379162306a36Sopenharmony_civoid f2fs_wait_on_all_pages(struct f2fs_sb_info *sbi, int type);
379262306a36Sopenharmony_ciu64 f2fs_get_sectors_written(struct f2fs_sb_info *sbi);
379362306a36Sopenharmony_ciint f2fs_write_checkpoint(struct f2fs_sb_info *sbi, struct cp_control *cpc);
379462306a36Sopenharmony_civoid f2fs_init_ino_entry_info(struct f2fs_sb_info *sbi);
379562306a36Sopenharmony_ciint __init f2fs_create_checkpoint_caches(void);
379662306a36Sopenharmony_civoid f2fs_destroy_checkpoint_caches(void);
379762306a36Sopenharmony_ciint f2fs_issue_checkpoint(struct f2fs_sb_info *sbi);
379862306a36Sopenharmony_ciint f2fs_start_ckpt_thread(struct f2fs_sb_info *sbi);
379962306a36Sopenharmony_civoid f2fs_stop_ckpt_thread(struct f2fs_sb_info *sbi);
380062306a36Sopenharmony_civoid f2fs_init_ckpt_req_control(struct f2fs_sb_info *sbi);
380162306a36Sopenharmony_ci
380262306a36Sopenharmony_ci/*
380362306a36Sopenharmony_ci * data.c
380462306a36Sopenharmony_ci */
380562306a36Sopenharmony_ciint __init f2fs_init_bioset(void);
380662306a36Sopenharmony_civoid f2fs_destroy_bioset(void);
380762306a36Sopenharmony_cibool f2fs_is_cp_guaranteed(struct page *page);
380862306a36Sopenharmony_ciint f2fs_init_bio_entry_cache(void);
380962306a36Sopenharmony_civoid f2fs_destroy_bio_entry_cache(void);
381062306a36Sopenharmony_civoid f2fs_submit_read_bio(struct f2fs_sb_info *sbi, struct bio *bio,
381162306a36Sopenharmony_ci			  enum page_type type);
381262306a36Sopenharmony_ciint f2fs_init_write_merge_io(struct f2fs_sb_info *sbi);
381362306a36Sopenharmony_civoid f2fs_submit_merged_write(struct f2fs_sb_info *sbi, enum page_type type);
381462306a36Sopenharmony_civoid f2fs_submit_merged_write_cond(struct f2fs_sb_info *sbi,
381562306a36Sopenharmony_ci				struct inode *inode, struct page *page,
381662306a36Sopenharmony_ci				nid_t ino, enum page_type type);
381762306a36Sopenharmony_civoid f2fs_submit_merged_ipu_write(struct f2fs_sb_info *sbi,
381862306a36Sopenharmony_ci					struct bio **bio, struct page *page);
381962306a36Sopenharmony_civoid f2fs_flush_merged_writes(struct f2fs_sb_info *sbi);
382062306a36Sopenharmony_ciint f2fs_submit_page_bio(struct f2fs_io_info *fio);
382162306a36Sopenharmony_ciint f2fs_merge_page_bio(struct f2fs_io_info *fio);
382262306a36Sopenharmony_civoid f2fs_submit_page_write(struct f2fs_io_info *fio);
382362306a36Sopenharmony_cistruct block_device *f2fs_target_device(struct f2fs_sb_info *sbi,
382462306a36Sopenharmony_ci		block_t blk_addr, sector_t *sector);
382562306a36Sopenharmony_ciint f2fs_target_device_index(struct f2fs_sb_info *sbi, block_t blkaddr);
382662306a36Sopenharmony_civoid f2fs_set_data_blkaddr(struct dnode_of_data *dn, block_t blkaddr);
382762306a36Sopenharmony_civoid f2fs_update_data_blkaddr(struct dnode_of_data *dn, block_t blkaddr);
382862306a36Sopenharmony_ciint f2fs_reserve_new_blocks(struct dnode_of_data *dn, blkcnt_t count);
382962306a36Sopenharmony_ciint f2fs_reserve_new_block(struct dnode_of_data *dn);
383062306a36Sopenharmony_ciint f2fs_get_block_locked(struct dnode_of_data *dn, pgoff_t index);
383162306a36Sopenharmony_ciint f2fs_reserve_block(struct dnode_of_data *dn, pgoff_t index);
383262306a36Sopenharmony_cistruct page *f2fs_get_read_data_page(struct inode *inode, pgoff_t index,
383362306a36Sopenharmony_ci			blk_opf_t op_flags, bool for_write, pgoff_t *next_pgofs);
383462306a36Sopenharmony_cistruct page *f2fs_find_data_page(struct inode *inode, pgoff_t index,
383562306a36Sopenharmony_ci							pgoff_t *next_pgofs);
383662306a36Sopenharmony_cistruct page *f2fs_get_lock_data_page(struct inode *inode, pgoff_t index,
383762306a36Sopenharmony_ci			bool for_write);
383862306a36Sopenharmony_cistruct page *f2fs_get_new_data_page(struct inode *inode,
383962306a36Sopenharmony_ci			struct page *ipage, pgoff_t index, bool new_i_size);
384062306a36Sopenharmony_ciint f2fs_do_write_data_page(struct f2fs_io_info *fio);
384162306a36Sopenharmony_ciint f2fs_map_blocks(struct inode *inode, struct f2fs_map_blocks *map, int flag);
384262306a36Sopenharmony_ciint f2fs_fiemap(struct inode *inode, struct fiemap_extent_info *fieinfo,
384362306a36Sopenharmony_ci			u64 start, u64 len);
384462306a36Sopenharmony_ciint f2fs_encrypt_one_page(struct f2fs_io_info *fio);
384562306a36Sopenharmony_cibool f2fs_should_update_inplace(struct inode *inode, struct f2fs_io_info *fio);
384662306a36Sopenharmony_cibool f2fs_should_update_outplace(struct inode *inode, struct f2fs_io_info *fio);
384762306a36Sopenharmony_ciint f2fs_write_single_data_page(struct page *page, int *submitted,
384862306a36Sopenharmony_ci				struct bio **bio, sector_t *last_block,
384962306a36Sopenharmony_ci				struct writeback_control *wbc,
385062306a36Sopenharmony_ci				enum iostat_type io_type,
385162306a36Sopenharmony_ci				int compr_blocks, bool allow_balance);
385262306a36Sopenharmony_civoid f2fs_write_failed(struct inode *inode, loff_t to);
385362306a36Sopenharmony_civoid f2fs_invalidate_folio(struct folio *folio, size_t offset, size_t length);
385462306a36Sopenharmony_cibool f2fs_release_folio(struct folio *folio, gfp_t wait);
385562306a36Sopenharmony_cibool f2fs_overwrite_io(struct inode *inode, loff_t pos, size_t len);
385662306a36Sopenharmony_civoid f2fs_clear_page_cache_dirty_tag(struct page *page);
385762306a36Sopenharmony_ciint f2fs_init_post_read_processing(void);
385862306a36Sopenharmony_civoid f2fs_destroy_post_read_processing(void);
385962306a36Sopenharmony_ciint f2fs_init_post_read_wq(struct f2fs_sb_info *sbi);
386062306a36Sopenharmony_civoid f2fs_destroy_post_read_wq(struct f2fs_sb_info *sbi);
386162306a36Sopenharmony_ciextern const struct iomap_ops f2fs_iomap_ops;
386262306a36Sopenharmony_ci
386362306a36Sopenharmony_ci/*
386462306a36Sopenharmony_ci * gc.c
386562306a36Sopenharmony_ci */
386662306a36Sopenharmony_ciint f2fs_start_gc_thread(struct f2fs_sb_info *sbi);
386762306a36Sopenharmony_civoid f2fs_stop_gc_thread(struct f2fs_sb_info *sbi);
386862306a36Sopenharmony_ciblock_t f2fs_start_bidx_of_node(unsigned int node_ofs, struct inode *inode);
386962306a36Sopenharmony_ciint f2fs_gc(struct f2fs_sb_info *sbi, struct f2fs_gc_control *gc_control);
387062306a36Sopenharmony_civoid f2fs_build_gc_manager(struct f2fs_sb_info *sbi);
387162306a36Sopenharmony_ciint f2fs_resize_fs(struct file *filp, __u64 block_count);
387262306a36Sopenharmony_ciint __init f2fs_create_garbage_collection_cache(void);
387362306a36Sopenharmony_civoid f2fs_destroy_garbage_collection_cache(void);
387462306a36Sopenharmony_ci/* victim selection function for cleaning and SSR */
387562306a36Sopenharmony_ciint f2fs_get_victim(struct f2fs_sb_info *sbi, unsigned int *result,
387662306a36Sopenharmony_ci			int gc_type, int type, char alloc_mode,
387762306a36Sopenharmony_ci			unsigned long long age);
387862306a36Sopenharmony_ci
387962306a36Sopenharmony_ci/*
388062306a36Sopenharmony_ci * recovery.c
388162306a36Sopenharmony_ci */
388262306a36Sopenharmony_ciint f2fs_recover_fsync_data(struct f2fs_sb_info *sbi, bool check_only);
388362306a36Sopenharmony_cibool f2fs_space_for_roll_forward(struct f2fs_sb_info *sbi);
388462306a36Sopenharmony_ciint __init f2fs_create_recovery_cache(void);
388562306a36Sopenharmony_civoid f2fs_destroy_recovery_cache(void);
388662306a36Sopenharmony_ci
388762306a36Sopenharmony_ci/*
388862306a36Sopenharmony_ci * debug.c
388962306a36Sopenharmony_ci */
389062306a36Sopenharmony_ci#ifdef CONFIG_F2FS_STAT_FS
389162306a36Sopenharmony_cistruct f2fs_stat_info {
389262306a36Sopenharmony_ci	struct list_head stat_list;
389362306a36Sopenharmony_ci	struct f2fs_sb_info *sbi;
389462306a36Sopenharmony_ci	int all_area_segs, sit_area_segs, nat_area_segs, ssa_area_segs;
389562306a36Sopenharmony_ci	int main_area_segs, main_area_sections, main_area_zones;
389662306a36Sopenharmony_ci	unsigned long long hit_cached[NR_EXTENT_CACHES];
389762306a36Sopenharmony_ci	unsigned long long hit_rbtree[NR_EXTENT_CACHES];
389862306a36Sopenharmony_ci	unsigned long long total_ext[NR_EXTENT_CACHES];
389962306a36Sopenharmony_ci	unsigned long long hit_total[NR_EXTENT_CACHES];
390062306a36Sopenharmony_ci	int ext_tree[NR_EXTENT_CACHES];
390162306a36Sopenharmony_ci	int zombie_tree[NR_EXTENT_CACHES];
390262306a36Sopenharmony_ci	int ext_node[NR_EXTENT_CACHES];
390362306a36Sopenharmony_ci	/* to count memory footprint */
390462306a36Sopenharmony_ci	unsigned long long ext_mem[NR_EXTENT_CACHES];
390562306a36Sopenharmony_ci	/* for read extent cache */
390662306a36Sopenharmony_ci	unsigned long long hit_largest;
390762306a36Sopenharmony_ci	/* for block age extent cache */
390862306a36Sopenharmony_ci	unsigned long long allocated_data_blocks;
390962306a36Sopenharmony_ci	int ndirty_node, ndirty_dent, ndirty_meta, ndirty_imeta;
391062306a36Sopenharmony_ci	int ndirty_data, ndirty_qdata;
391162306a36Sopenharmony_ci	unsigned int ndirty_dirs, ndirty_files, nquota_files, ndirty_all;
391262306a36Sopenharmony_ci	int nats, dirty_nats, sits, dirty_sits;
391362306a36Sopenharmony_ci	int free_nids, avail_nids, alloc_nids;
391462306a36Sopenharmony_ci	int total_count, utilization;
391562306a36Sopenharmony_ci	int nr_wb_cp_data, nr_wb_data;
391662306a36Sopenharmony_ci	int nr_rd_data, nr_rd_node, nr_rd_meta;
391762306a36Sopenharmony_ci	int nr_dio_read, nr_dio_write;
391862306a36Sopenharmony_ci	unsigned int io_skip_bggc, other_skip_bggc;
391962306a36Sopenharmony_ci	int nr_flushing, nr_flushed, flush_list_empty;
392062306a36Sopenharmony_ci	int nr_discarding, nr_discarded;
392162306a36Sopenharmony_ci	int nr_discard_cmd;
392262306a36Sopenharmony_ci	unsigned int undiscard_blks;
392362306a36Sopenharmony_ci	int nr_issued_ckpt, nr_total_ckpt, nr_queued_ckpt;
392462306a36Sopenharmony_ci	unsigned int cur_ckpt_time, peak_ckpt_time;
392562306a36Sopenharmony_ci	int inline_xattr, inline_inode, inline_dir, append, update, orphans;
392662306a36Sopenharmony_ci	int compr_inode, swapfile_inode;
392762306a36Sopenharmony_ci	unsigned long long compr_blocks;
392862306a36Sopenharmony_ci	int aw_cnt, max_aw_cnt;
392962306a36Sopenharmony_ci	unsigned int valid_count, valid_node_count, valid_inode_count, discard_blks;
393062306a36Sopenharmony_ci	unsigned int bimodal, avg_vblocks;
393162306a36Sopenharmony_ci	int util_free, util_valid, util_invalid;
393262306a36Sopenharmony_ci	int rsvd_segs, overp_segs;
393362306a36Sopenharmony_ci	int dirty_count, node_pages, meta_pages, compress_pages;
393462306a36Sopenharmony_ci	int compress_page_hit;
393562306a36Sopenharmony_ci	int prefree_count, free_segs, free_secs;
393662306a36Sopenharmony_ci	int cp_call_count[MAX_CALL_TYPE], cp_count;
393762306a36Sopenharmony_ci	int gc_call_count[MAX_CALL_TYPE];
393862306a36Sopenharmony_ci	int gc_segs[2][2];
393962306a36Sopenharmony_ci	int gc_secs[2][2];
394062306a36Sopenharmony_ci	int tot_blks, data_blks, node_blks;
394162306a36Sopenharmony_ci	int bg_data_blks, bg_node_blks;
394262306a36Sopenharmony_ci	int curseg[NR_CURSEG_TYPE];
394362306a36Sopenharmony_ci	int cursec[NR_CURSEG_TYPE];
394462306a36Sopenharmony_ci	int curzone[NR_CURSEG_TYPE];
394562306a36Sopenharmony_ci	unsigned int dirty_seg[NR_CURSEG_TYPE];
394662306a36Sopenharmony_ci	unsigned int full_seg[NR_CURSEG_TYPE];
394762306a36Sopenharmony_ci	unsigned int valid_blks[NR_CURSEG_TYPE];
394862306a36Sopenharmony_ci
394962306a36Sopenharmony_ci	unsigned int meta_count[META_MAX];
395062306a36Sopenharmony_ci	unsigned int segment_count[2];
395162306a36Sopenharmony_ci	unsigned int block_count[2];
395262306a36Sopenharmony_ci	unsigned int inplace_count;
395362306a36Sopenharmony_ci	unsigned long long base_mem, cache_mem, page_mem;
395462306a36Sopenharmony_ci};
395562306a36Sopenharmony_ci
395662306a36Sopenharmony_cistatic inline struct f2fs_stat_info *F2FS_STAT(struct f2fs_sb_info *sbi)
395762306a36Sopenharmony_ci{
395862306a36Sopenharmony_ci	return (struct f2fs_stat_info *)sbi->stat_info;
395962306a36Sopenharmony_ci}
396062306a36Sopenharmony_ci
396162306a36Sopenharmony_ci#define stat_inc_cp_call_count(sbi, foreground)				\
396262306a36Sopenharmony_ci		atomic_inc(&sbi->cp_call_count[(foreground)])
396362306a36Sopenharmony_ci#define stat_inc_cp_count(si)		(F2FS_STAT(sbi)->cp_count++)
396462306a36Sopenharmony_ci#define stat_io_skip_bggc_count(sbi)	((sbi)->io_skip_bggc++)
396562306a36Sopenharmony_ci#define stat_other_skip_bggc_count(sbi)	((sbi)->other_skip_bggc++)
396662306a36Sopenharmony_ci#define stat_inc_dirty_inode(sbi, type)	((sbi)->ndirty_inode[type]++)
396762306a36Sopenharmony_ci#define stat_dec_dirty_inode(sbi, type)	((sbi)->ndirty_inode[type]--)
396862306a36Sopenharmony_ci#define stat_inc_total_hit(sbi, type)		(atomic64_inc(&(sbi)->total_hit_ext[type]))
396962306a36Sopenharmony_ci#define stat_inc_rbtree_node_hit(sbi, type)	(atomic64_inc(&(sbi)->read_hit_rbtree[type]))
397062306a36Sopenharmony_ci#define stat_inc_largest_node_hit(sbi)	(atomic64_inc(&(sbi)->read_hit_largest))
397162306a36Sopenharmony_ci#define stat_inc_cached_node_hit(sbi, type)	(atomic64_inc(&(sbi)->read_hit_cached[type]))
397262306a36Sopenharmony_ci#define stat_inc_inline_xattr(inode)					\
397362306a36Sopenharmony_ci	do {								\
397462306a36Sopenharmony_ci		if (f2fs_has_inline_xattr(inode))			\
397562306a36Sopenharmony_ci			(atomic_inc(&F2FS_I_SB(inode)->inline_xattr));	\
397662306a36Sopenharmony_ci	} while (0)
397762306a36Sopenharmony_ci#define stat_dec_inline_xattr(inode)					\
397862306a36Sopenharmony_ci	do {								\
397962306a36Sopenharmony_ci		if (f2fs_has_inline_xattr(inode))			\
398062306a36Sopenharmony_ci			(atomic_dec(&F2FS_I_SB(inode)->inline_xattr));	\
398162306a36Sopenharmony_ci	} while (0)
398262306a36Sopenharmony_ci#define stat_inc_inline_inode(inode)					\
398362306a36Sopenharmony_ci	do {								\
398462306a36Sopenharmony_ci		if (f2fs_has_inline_data(inode))			\
398562306a36Sopenharmony_ci			(atomic_inc(&F2FS_I_SB(inode)->inline_inode));	\
398662306a36Sopenharmony_ci	} while (0)
398762306a36Sopenharmony_ci#define stat_dec_inline_inode(inode)					\
398862306a36Sopenharmony_ci	do {								\
398962306a36Sopenharmony_ci		if (f2fs_has_inline_data(inode))			\
399062306a36Sopenharmony_ci			(atomic_dec(&F2FS_I_SB(inode)->inline_inode));	\
399162306a36Sopenharmony_ci	} while (0)
399262306a36Sopenharmony_ci#define stat_inc_inline_dir(inode)					\
399362306a36Sopenharmony_ci	do {								\
399462306a36Sopenharmony_ci		if (f2fs_has_inline_dentry(inode))			\
399562306a36Sopenharmony_ci			(atomic_inc(&F2FS_I_SB(inode)->inline_dir));	\
399662306a36Sopenharmony_ci	} while (0)
399762306a36Sopenharmony_ci#define stat_dec_inline_dir(inode)					\
399862306a36Sopenharmony_ci	do {								\
399962306a36Sopenharmony_ci		if (f2fs_has_inline_dentry(inode))			\
400062306a36Sopenharmony_ci			(atomic_dec(&F2FS_I_SB(inode)->inline_dir));	\
400162306a36Sopenharmony_ci	} while (0)
400262306a36Sopenharmony_ci#define stat_inc_compr_inode(inode)					\
400362306a36Sopenharmony_ci	do {								\
400462306a36Sopenharmony_ci		if (f2fs_compressed_file(inode))			\
400562306a36Sopenharmony_ci			(atomic_inc(&F2FS_I_SB(inode)->compr_inode));	\
400662306a36Sopenharmony_ci	} while (0)
400762306a36Sopenharmony_ci#define stat_dec_compr_inode(inode)					\
400862306a36Sopenharmony_ci	do {								\
400962306a36Sopenharmony_ci		if (f2fs_compressed_file(inode))			\
401062306a36Sopenharmony_ci			(atomic_dec(&F2FS_I_SB(inode)->compr_inode));	\
401162306a36Sopenharmony_ci	} while (0)
401262306a36Sopenharmony_ci#define stat_add_compr_blocks(inode, blocks)				\
401362306a36Sopenharmony_ci		(atomic64_add(blocks, &F2FS_I_SB(inode)->compr_blocks))
401462306a36Sopenharmony_ci#define stat_sub_compr_blocks(inode, blocks)				\
401562306a36Sopenharmony_ci		(atomic64_sub(blocks, &F2FS_I_SB(inode)->compr_blocks))
401662306a36Sopenharmony_ci#define stat_inc_swapfile_inode(inode)					\
401762306a36Sopenharmony_ci		(atomic_inc(&F2FS_I_SB(inode)->swapfile_inode))
401862306a36Sopenharmony_ci#define stat_dec_swapfile_inode(inode)					\
401962306a36Sopenharmony_ci		(atomic_dec(&F2FS_I_SB(inode)->swapfile_inode))
402062306a36Sopenharmony_ci#define stat_inc_atomic_inode(inode)					\
402162306a36Sopenharmony_ci			(atomic_inc(&F2FS_I_SB(inode)->atomic_files))
402262306a36Sopenharmony_ci#define stat_dec_atomic_inode(inode)					\
402362306a36Sopenharmony_ci			(atomic_dec(&F2FS_I_SB(inode)->atomic_files))
402462306a36Sopenharmony_ci#define stat_inc_meta_count(sbi, blkaddr)				\
402562306a36Sopenharmony_ci	do {								\
402662306a36Sopenharmony_ci		if (blkaddr < SIT_I(sbi)->sit_base_addr)		\
402762306a36Sopenharmony_ci			atomic_inc(&(sbi)->meta_count[META_CP]);	\
402862306a36Sopenharmony_ci		else if (blkaddr < NM_I(sbi)->nat_blkaddr)		\
402962306a36Sopenharmony_ci			atomic_inc(&(sbi)->meta_count[META_SIT]);	\
403062306a36Sopenharmony_ci		else if (blkaddr < SM_I(sbi)->ssa_blkaddr)		\
403162306a36Sopenharmony_ci			atomic_inc(&(sbi)->meta_count[META_NAT]);	\
403262306a36Sopenharmony_ci		else if (blkaddr < SM_I(sbi)->main_blkaddr)		\
403362306a36Sopenharmony_ci			atomic_inc(&(sbi)->meta_count[META_SSA]);	\
403462306a36Sopenharmony_ci	} while (0)
403562306a36Sopenharmony_ci#define stat_inc_seg_type(sbi, curseg)					\
403662306a36Sopenharmony_ci		((sbi)->segment_count[(curseg)->alloc_type]++)
403762306a36Sopenharmony_ci#define stat_inc_block_count(sbi, curseg)				\
403862306a36Sopenharmony_ci		((sbi)->block_count[(curseg)->alloc_type]++)
403962306a36Sopenharmony_ci#define stat_inc_inplace_blocks(sbi)					\
404062306a36Sopenharmony_ci		(atomic_inc(&(sbi)->inplace_count))
404162306a36Sopenharmony_ci#define stat_update_max_atomic_write(inode)				\
404262306a36Sopenharmony_ci	do {								\
404362306a36Sopenharmony_ci		int cur = atomic_read(&F2FS_I_SB(inode)->atomic_files);	\
404462306a36Sopenharmony_ci		int max = atomic_read(&F2FS_I_SB(inode)->max_aw_cnt);	\
404562306a36Sopenharmony_ci		if (cur > max)						\
404662306a36Sopenharmony_ci			atomic_set(&F2FS_I_SB(inode)->max_aw_cnt, cur);	\
404762306a36Sopenharmony_ci	} while (0)
404862306a36Sopenharmony_ci#define stat_inc_gc_call_count(sbi, foreground)				\
404962306a36Sopenharmony_ci		(F2FS_STAT(sbi)->gc_call_count[(foreground)]++)
405062306a36Sopenharmony_ci#define stat_inc_gc_sec_count(sbi, type, gc_type)			\
405162306a36Sopenharmony_ci		(F2FS_STAT(sbi)->gc_secs[(type)][(gc_type)]++)
405262306a36Sopenharmony_ci#define stat_inc_gc_seg_count(sbi, type, gc_type)			\
405362306a36Sopenharmony_ci		(F2FS_STAT(sbi)->gc_segs[(type)][(gc_type)]++)
405462306a36Sopenharmony_ci
405562306a36Sopenharmony_ci#define stat_inc_tot_blk_count(si, blks)				\
405662306a36Sopenharmony_ci	((si)->tot_blks += (blks))
405762306a36Sopenharmony_ci
405862306a36Sopenharmony_ci#define stat_inc_data_blk_count(sbi, blks, gc_type)			\
405962306a36Sopenharmony_ci	do {								\
406062306a36Sopenharmony_ci		struct f2fs_stat_info *si = F2FS_STAT(sbi);		\
406162306a36Sopenharmony_ci		stat_inc_tot_blk_count(si, blks);			\
406262306a36Sopenharmony_ci		si->data_blks += (blks);				\
406362306a36Sopenharmony_ci		si->bg_data_blks += ((gc_type) == BG_GC) ? (blks) : 0;	\
406462306a36Sopenharmony_ci	} while (0)
406562306a36Sopenharmony_ci
406662306a36Sopenharmony_ci#define stat_inc_node_blk_count(sbi, blks, gc_type)			\
406762306a36Sopenharmony_ci	do {								\
406862306a36Sopenharmony_ci		struct f2fs_stat_info *si = F2FS_STAT(sbi);		\
406962306a36Sopenharmony_ci		stat_inc_tot_blk_count(si, blks);			\
407062306a36Sopenharmony_ci		si->node_blks += (blks);				\
407162306a36Sopenharmony_ci		si->bg_node_blks += ((gc_type) == BG_GC) ? (blks) : 0;	\
407262306a36Sopenharmony_ci	} while (0)
407362306a36Sopenharmony_ci
407462306a36Sopenharmony_ciint f2fs_build_stats(struct f2fs_sb_info *sbi);
407562306a36Sopenharmony_civoid f2fs_destroy_stats(struct f2fs_sb_info *sbi);
407662306a36Sopenharmony_civoid __init f2fs_create_root_stats(void);
407762306a36Sopenharmony_civoid f2fs_destroy_root_stats(void);
407862306a36Sopenharmony_civoid f2fs_update_sit_info(struct f2fs_sb_info *sbi);
407962306a36Sopenharmony_ci#else
408062306a36Sopenharmony_ci#define stat_inc_cp_call_count(sbi, foreground)		do { } while (0)
408162306a36Sopenharmony_ci#define stat_inc_cp_count(sbi)				do { } while (0)
408262306a36Sopenharmony_ci#define stat_io_skip_bggc_count(sbi)			do { } while (0)
408362306a36Sopenharmony_ci#define stat_other_skip_bggc_count(sbi)			do { } while (0)
408462306a36Sopenharmony_ci#define stat_inc_dirty_inode(sbi, type)			do { } while (0)
408562306a36Sopenharmony_ci#define stat_dec_dirty_inode(sbi, type)			do { } while (0)
408662306a36Sopenharmony_ci#define stat_inc_total_hit(sbi, type)			do { } while (0)
408762306a36Sopenharmony_ci#define stat_inc_rbtree_node_hit(sbi, type)		do { } while (0)
408862306a36Sopenharmony_ci#define stat_inc_largest_node_hit(sbi)			do { } while (0)
408962306a36Sopenharmony_ci#define stat_inc_cached_node_hit(sbi, type)		do { } while (0)
409062306a36Sopenharmony_ci#define stat_inc_inline_xattr(inode)			do { } while (0)
409162306a36Sopenharmony_ci#define stat_dec_inline_xattr(inode)			do { } while (0)
409262306a36Sopenharmony_ci#define stat_inc_inline_inode(inode)			do { } while (0)
409362306a36Sopenharmony_ci#define stat_dec_inline_inode(inode)			do { } while (0)
409462306a36Sopenharmony_ci#define stat_inc_inline_dir(inode)			do { } while (0)
409562306a36Sopenharmony_ci#define stat_dec_inline_dir(inode)			do { } while (0)
409662306a36Sopenharmony_ci#define stat_inc_compr_inode(inode)			do { } while (0)
409762306a36Sopenharmony_ci#define stat_dec_compr_inode(inode)			do { } while (0)
409862306a36Sopenharmony_ci#define stat_add_compr_blocks(inode, blocks)		do { } while (0)
409962306a36Sopenharmony_ci#define stat_sub_compr_blocks(inode, blocks)		do { } while (0)
410062306a36Sopenharmony_ci#define stat_inc_swapfile_inode(inode)			do { } while (0)
410162306a36Sopenharmony_ci#define stat_dec_swapfile_inode(inode)			do { } while (0)
410262306a36Sopenharmony_ci#define stat_inc_atomic_inode(inode)			do { } while (0)
410362306a36Sopenharmony_ci#define stat_dec_atomic_inode(inode)			do { } while (0)
410462306a36Sopenharmony_ci#define stat_update_max_atomic_write(inode)		do { } while (0)
410562306a36Sopenharmony_ci#define stat_inc_meta_count(sbi, blkaddr)		do { } while (0)
410662306a36Sopenharmony_ci#define stat_inc_seg_type(sbi, curseg)			do { } while (0)
410762306a36Sopenharmony_ci#define stat_inc_block_count(sbi, curseg)		do { } while (0)
410862306a36Sopenharmony_ci#define stat_inc_inplace_blocks(sbi)			do { } while (0)
410962306a36Sopenharmony_ci#define stat_inc_gc_call_count(sbi, foreground)		do { } while (0)
411062306a36Sopenharmony_ci#define stat_inc_gc_sec_count(sbi, type, gc_type)	do { } while (0)
411162306a36Sopenharmony_ci#define stat_inc_gc_seg_count(sbi, type, gc_type)	do { } while (0)
411262306a36Sopenharmony_ci#define stat_inc_tot_blk_count(si, blks)		do { } while (0)
411362306a36Sopenharmony_ci#define stat_inc_data_blk_count(sbi, blks, gc_type)	do { } while (0)
411462306a36Sopenharmony_ci#define stat_inc_node_blk_count(sbi, blks, gc_type)	do { } while (0)
411562306a36Sopenharmony_ci
411662306a36Sopenharmony_cistatic inline int f2fs_build_stats(struct f2fs_sb_info *sbi) { return 0; }
411762306a36Sopenharmony_cistatic inline void f2fs_destroy_stats(struct f2fs_sb_info *sbi) { }
411862306a36Sopenharmony_cistatic inline void __init f2fs_create_root_stats(void) { }
411962306a36Sopenharmony_cistatic inline void f2fs_destroy_root_stats(void) { }
412062306a36Sopenharmony_cistatic inline void f2fs_update_sit_info(struct f2fs_sb_info *sbi) {}
412162306a36Sopenharmony_ci#endif
412262306a36Sopenharmony_ci
412362306a36Sopenharmony_ciextern const struct file_operations f2fs_dir_operations;
412462306a36Sopenharmony_ciextern const struct file_operations f2fs_file_operations;
412562306a36Sopenharmony_ciextern const struct inode_operations f2fs_file_inode_operations;
412662306a36Sopenharmony_ciextern const struct address_space_operations f2fs_dblock_aops;
412762306a36Sopenharmony_ciextern const struct address_space_operations f2fs_node_aops;
412862306a36Sopenharmony_ciextern const struct address_space_operations f2fs_meta_aops;
412962306a36Sopenharmony_ciextern const struct inode_operations f2fs_dir_inode_operations;
413062306a36Sopenharmony_ciextern const struct inode_operations f2fs_symlink_inode_operations;
413162306a36Sopenharmony_ciextern const struct inode_operations f2fs_encrypted_symlink_inode_operations;
413262306a36Sopenharmony_ciextern const struct inode_operations f2fs_special_inode_operations;
413362306a36Sopenharmony_ciextern struct kmem_cache *f2fs_inode_entry_slab;
413462306a36Sopenharmony_ci
413562306a36Sopenharmony_ci/*
413662306a36Sopenharmony_ci * inline.c
413762306a36Sopenharmony_ci */
413862306a36Sopenharmony_cibool f2fs_may_inline_data(struct inode *inode);
413962306a36Sopenharmony_cibool f2fs_sanity_check_inline_data(struct inode *inode);
414062306a36Sopenharmony_cibool f2fs_may_inline_dentry(struct inode *inode);
414162306a36Sopenharmony_civoid f2fs_do_read_inline_data(struct page *page, struct page *ipage);
414262306a36Sopenharmony_civoid f2fs_truncate_inline_inode(struct inode *inode,
414362306a36Sopenharmony_ci						struct page *ipage, u64 from);
414462306a36Sopenharmony_ciint f2fs_read_inline_data(struct inode *inode, struct page *page);
414562306a36Sopenharmony_ciint f2fs_convert_inline_page(struct dnode_of_data *dn, struct page *page);
414662306a36Sopenharmony_ciint f2fs_convert_inline_inode(struct inode *inode);
414762306a36Sopenharmony_ciint f2fs_try_convert_inline_dir(struct inode *dir, struct dentry *dentry);
414862306a36Sopenharmony_ciint f2fs_write_inline_data(struct inode *inode, struct page *page);
414962306a36Sopenharmony_ciint f2fs_recover_inline_data(struct inode *inode, struct page *npage);
415062306a36Sopenharmony_cistruct f2fs_dir_entry *f2fs_find_in_inline_dir(struct inode *dir,
415162306a36Sopenharmony_ci					const struct f2fs_filename *fname,
415262306a36Sopenharmony_ci					struct page **res_page);
415362306a36Sopenharmony_ciint f2fs_make_empty_inline_dir(struct inode *inode, struct inode *parent,
415462306a36Sopenharmony_ci			struct page *ipage);
415562306a36Sopenharmony_ciint f2fs_add_inline_entry(struct inode *dir, const struct f2fs_filename *fname,
415662306a36Sopenharmony_ci			struct inode *inode, nid_t ino, umode_t mode);
415762306a36Sopenharmony_civoid f2fs_delete_inline_entry(struct f2fs_dir_entry *dentry,
415862306a36Sopenharmony_ci				struct page *page, struct inode *dir,
415962306a36Sopenharmony_ci				struct inode *inode);
416062306a36Sopenharmony_cibool f2fs_empty_inline_dir(struct inode *dir);
416162306a36Sopenharmony_ciint f2fs_read_inline_dir(struct file *file, struct dir_context *ctx,
416262306a36Sopenharmony_ci			struct fscrypt_str *fstr);
416362306a36Sopenharmony_ciint f2fs_inline_data_fiemap(struct inode *inode,
416462306a36Sopenharmony_ci			struct fiemap_extent_info *fieinfo,
416562306a36Sopenharmony_ci			__u64 start, __u64 len);
416662306a36Sopenharmony_ci
416762306a36Sopenharmony_ci/*
416862306a36Sopenharmony_ci * shrinker.c
416962306a36Sopenharmony_ci */
417062306a36Sopenharmony_ciunsigned long f2fs_shrink_count(struct shrinker *shrink,
417162306a36Sopenharmony_ci			struct shrink_control *sc);
417262306a36Sopenharmony_ciunsigned long f2fs_shrink_scan(struct shrinker *shrink,
417362306a36Sopenharmony_ci			struct shrink_control *sc);
417462306a36Sopenharmony_civoid f2fs_join_shrinker(struct f2fs_sb_info *sbi);
417562306a36Sopenharmony_civoid f2fs_leave_shrinker(struct f2fs_sb_info *sbi);
417662306a36Sopenharmony_ci
417762306a36Sopenharmony_ci/*
417862306a36Sopenharmony_ci * extent_cache.c
417962306a36Sopenharmony_ci */
418062306a36Sopenharmony_cibool sanity_check_extent_cache(struct inode *inode);
418162306a36Sopenharmony_civoid f2fs_init_extent_tree(struct inode *inode);
418262306a36Sopenharmony_civoid f2fs_drop_extent_tree(struct inode *inode);
418362306a36Sopenharmony_civoid f2fs_destroy_extent_node(struct inode *inode);
418462306a36Sopenharmony_civoid f2fs_destroy_extent_tree(struct inode *inode);
418562306a36Sopenharmony_civoid f2fs_init_extent_cache_info(struct f2fs_sb_info *sbi);
418662306a36Sopenharmony_ciint __init f2fs_create_extent_cache(void);
418762306a36Sopenharmony_civoid f2fs_destroy_extent_cache(void);
418862306a36Sopenharmony_ci
418962306a36Sopenharmony_ci/* read extent cache ops */
419062306a36Sopenharmony_civoid f2fs_init_read_extent_tree(struct inode *inode, struct page *ipage);
419162306a36Sopenharmony_cibool f2fs_lookup_read_extent_cache(struct inode *inode, pgoff_t pgofs,
419262306a36Sopenharmony_ci			struct extent_info *ei);
419362306a36Sopenharmony_cibool f2fs_lookup_read_extent_cache_block(struct inode *inode, pgoff_t index,
419462306a36Sopenharmony_ci			block_t *blkaddr);
419562306a36Sopenharmony_civoid f2fs_update_read_extent_cache(struct dnode_of_data *dn);
419662306a36Sopenharmony_civoid f2fs_update_read_extent_cache_range(struct dnode_of_data *dn,
419762306a36Sopenharmony_ci			pgoff_t fofs, block_t blkaddr, unsigned int len);
419862306a36Sopenharmony_ciunsigned int f2fs_shrink_read_extent_tree(struct f2fs_sb_info *sbi,
419962306a36Sopenharmony_ci			int nr_shrink);
420062306a36Sopenharmony_ci
420162306a36Sopenharmony_ci/* block age extent cache ops */
420262306a36Sopenharmony_civoid f2fs_init_age_extent_tree(struct inode *inode);
420362306a36Sopenharmony_cibool f2fs_lookup_age_extent_cache(struct inode *inode, pgoff_t pgofs,
420462306a36Sopenharmony_ci			struct extent_info *ei);
420562306a36Sopenharmony_civoid f2fs_update_age_extent_cache(struct dnode_of_data *dn);
420662306a36Sopenharmony_civoid f2fs_update_age_extent_cache_range(struct dnode_of_data *dn,
420762306a36Sopenharmony_ci			pgoff_t fofs, unsigned int len);
420862306a36Sopenharmony_ciunsigned int f2fs_shrink_age_extent_tree(struct f2fs_sb_info *sbi,
420962306a36Sopenharmony_ci			int nr_shrink);
421062306a36Sopenharmony_ci
421162306a36Sopenharmony_ci/*
421262306a36Sopenharmony_ci * sysfs.c
421362306a36Sopenharmony_ci */
421462306a36Sopenharmony_ci#define MIN_RA_MUL	2
421562306a36Sopenharmony_ci#define MAX_RA_MUL	256
421662306a36Sopenharmony_ci
421762306a36Sopenharmony_ciint __init f2fs_init_sysfs(void);
421862306a36Sopenharmony_civoid f2fs_exit_sysfs(void);
421962306a36Sopenharmony_ciint f2fs_register_sysfs(struct f2fs_sb_info *sbi);
422062306a36Sopenharmony_civoid f2fs_unregister_sysfs(struct f2fs_sb_info *sbi);
422162306a36Sopenharmony_ci
422262306a36Sopenharmony_ci/* verity.c */
422362306a36Sopenharmony_ciextern const struct fsverity_operations f2fs_verityops;
422462306a36Sopenharmony_ci
422562306a36Sopenharmony_ci/*
422662306a36Sopenharmony_ci * crypto support
422762306a36Sopenharmony_ci */
422862306a36Sopenharmony_cistatic inline bool f2fs_encrypted_file(struct inode *inode)
422962306a36Sopenharmony_ci{
423062306a36Sopenharmony_ci	return IS_ENCRYPTED(inode) && S_ISREG(inode->i_mode);
423162306a36Sopenharmony_ci}
423262306a36Sopenharmony_ci
423362306a36Sopenharmony_cistatic inline void f2fs_set_encrypted_inode(struct inode *inode)
423462306a36Sopenharmony_ci{
423562306a36Sopenharmony_ci#ifdef CONFIG_FS_ENCRYPTION
423662306a36Sopenharmony_ci	file_set_encrypt(inode);
423762306a36Sopenharmony_ci	f2fs_set_inode_flags(inode);
423862306a36Sopenharmony_ci#endif
423962306a36Sopenharmony_ci}
424062306a36Sopenharmony_ci
424162306a36Sopenharmony_ci/*
424262306a36Sopenharmony_ci * Returns true if the reads of the inode's data need to undergo some
424362306a36Sopenharmony_ci * postprocessing step, like decryption or authenticity verification.
424462306a36Sopenharmony_ci */
424562306a36Sopenharmony_cistatic inline bool f2fs_post_read_required(struct inode *inode)
424662306a36Sopenharmony_ci{
424762306a36Sopenharmony_ci	return f2fs_encrypted_file(inode) || fsverity_active(inode) ||
424862306a36Sopenharmony_ci		f2fs_compressed_file(inode);
424962306a36Sopenharmony_ci}
425062306a36Sopenharmony_ci
425162306a36Sopenharmony_ci/*
425262306a36Sopenharmony_ci * compress.c
425362306a36Sopenharmony_ci */
425462306a36Sopenharmony_ci#ifdef CONFIG_F2FS_FS_COMPRESSION
425562306a36Sopenharmony_cibool f2fs_is_compressed_page(struct page *page);
425662306a36Sopenharmony_cistruct page *f2fs_compress_control_page(struct page *page);
425762306a36Sopenharmony_ciint f2fs_prepare_compress_overwrite(struct inode *inode,
425862306a36Sopenharmony_ci			struct page **pagep, pgoff_t index, void **fsdata);
425962306a36Sopenharmony_cibool f2fs_compress_write_end(struct inode *inode, void *fsdata,
426062306a36Sopenharmony_ci					pgoff_t index, unsigned copied);
426162306a36Sopenharmony_ciint f2fs_truncate_partial_cluster(struct inode *inode, u64 from, bool lock);
426262306a36Sopenharmony_civoid f2fs_compress_write_end_io(struct bio *bio, struct page *page);
426362306a36Sopenharmony_cibool f2fs_is_compress_backend_ready(struct inode *inode);
426462306a36Sopenharmony_cibool f2fs_is_compress_level_valid(int alg, int lvl);
426562306a36Sopenharmony_ciint __init f2fs_init_compress_mempool(void);
426662306a36Sopenharmony_civoid f2fs_destroy_compress_mempool(void);
426762306a36Sopenharmony_civoid f2fs_decompress_cluster(struct decompress_io_ctx *dic, bool in_task);
426862306a36Sopenharmony_civoid f2fs_end_read_compressed_page(struct page *page, bool failed,
426962306a36Sopenharmony_ci				block_t blkaddr, bool in_task);
427062306a36Sopenharmony_cibool f2fs_cluster_is_empty(struct compress_ctx *cc);
427162306a36Sopenharmony_cibool f2fs_cluster_can_merge_page(struct compress_ctx *cc, pgoff_t index);
427262306a36Sopenharmony_cibool f2fs_all_cluster_page_ready(struct compress_ctx *cc, struct page **pages,
427362306a36Sopenharmony_ci				int index, int nr_pages, bool uptodate);
427462306a36Sopenharmony_cibool f2fs_sanity_check_cluster(struct dnode_of_data *dn);
427562306a36Sopenharmony_civoid f2fs_compress_ctx_add_page(struct compress_ctx *cc, struct page *page);
427662306a36Sopenharmony_ciint f2fs_write_multi_pages(struct compress_ctx *cc,
427762306a36Sopenharmony_ci						int *submitted,
427862306a36Sopenharmony_ci						struct writeback_control *wbc,
427962306a36Sopenharmony_ci						enum iostat_type io_type);
428062306a36Sopenharmony_ciint f2fs_is_compressed_cluster(struct inode *inode, pgoff_t index);
428162306a36Sopenharmony_civoid f2fs_update_read_extent_tree_range_compressed(struct inode *inode,
428262306a36Sopenharmony_ci				pgoff_t fofs, block_t blkaddr,
428362306a36Sopenharmony_ci				unsigned int llen, unsigned int c_len);
428462306a36Sopenharmony_ciint f2fs_read_multi_pages(struct compress_ctx *cc, struct bio **bio_ret,
428562306a36Sopenharmony_ci				unsigned nr_pages, sector_t *last_block_in_bio,
428662306a36Sopenharmony_ci				bool is_readahead, bool for_write);
428762306a36Sopenharmony_cistruct decompress_io_ctx *f2fs_alloc_dic(struct compress_ctx *cc);
428862306a36Sopenharmony_civoid f2fs_decompress_end_io(struct decompress_io_ctx *dic, bool failed,
428962306a36Sopenharmony_ci				bool in_task);
429062306a36Sopenharmony_civoid f2fs_put_page_dic(struct page *page, bool in_task);
429162306a36Sopenharmony_ciunsigned int f2fs_cluster_blocks_are_contiguous(struct dnode_of_data *dn,
429262306a36Sopenharmony_ci						unsigned int ofs_in_node);
429362306a36Sopenharmony_ciint f2fs_init_compress_ctx(struct compress_ctx *cc);
429462306a36Sopenharmony_civoid f2fs_destroy_compress_ctx(struct compress_ctx *cc, bool reuse);
429562306a36Sopenharmony_civoid f2fs_init_compress_info(struct f2fs_sb_info *sbi);
429662306a36Sopenharmony_ciint f2fs_init_compress_inode(struct f2fs_sb_info *sbi);
429762306a36Sopenharmony_civoid f2fs_destroy_compress_inode(struct f2fs_sb_info *sbi);
429862306a36Sopenharmony_ciint f2fs_init_page_array_cache(struct f2fs_sb_info *sbi);
429962306a36Sopenharmony_civoid f2fs_destroy_page_array_cache(struct f2fs_sb_info *sbi);
430062306a36Sopenharmony_ciint __init f2fs_init_compress_cache(void);
430162306a36Sopenharmony_civoid f2fs_destroy_compress_cache(void);
430262306a36Sopenharmony_cistruct address_space *COMPRESS_MAPPING(struct f2fs_sb_info *sbi);
430362306a36Sopenharmony_civoid f2fs_invalidate_compress_page(struct f2fs_sb_info *sbi, block_t blkaddr);
430462306a36Sopenharmony_civoid f2fs_cache_compressed_page(struct f2fs_sb_info *sbi, struct page *page,
430562306a36Sopenharmony_ci						nid_t ino, block_t blkaddr);
430662306a36Sopenharmony_cibool f2fs_load_compressed_page(struct f2fs_sb_info *sbi, struct page *page,
430762306a36Sopenharmony_ci								block_t blkaddr);
430862306a36Sopenharmony_civoid f2fs_invalidate_compress_pages(struct f2fs_sb_info *sbi, nid_t ino);
430962306a36Sopenharmony_ci#define inc_compr_inode_stat(inode)					\
431062306a36Sopenharmony_ci	do {								\
431162306a36Sopenharmony_ci		struct f2fs_sb_info *sbi = F2FS_I_SB(inode);		\
431262306a36Sopenharmony_ci		sbi->compr_new_inode++;					\
431362306a36Sopenharmony_ci	} while (0)
431462306a36Sopenharmony_ci#define add_compr_block_stat(inode, blocks)				\
431562306a36Sopenharmony_ci	do {								\
431662306a36Sopenharmony_ci		struct f2fs_sb_info *sbi = F2FS_I_SB(inode);		\
431762306a36Sopenharmony_ci		int diff = F2FS_I(inode)->i_cluster_size - blocks;	\
431862306a36Sopenharmony_ci		sbi->compr_written_block += blocks;			\
431962306a36Sopenharmony_ci		sbi->compr_saved_block += diff;				\
432062306a36Sopenharmony_ci	} while (0)
432162306a36Sopenharmony_ci#else
432262306a36Sopenharmony_cistatic inline bool f2fs_is_compressed_page(struct page *page) { return false; }
432362306a36Sopenharmony_cistatic inline bool f2fs_is_compress_backend_ready(struct inode *inode)
432462306a36Sopenharmony_ci{
432562306a36Sopenharmony_ci	if (!f2fs_compressed_file(inode))
432662306a36Sopenharmony_ci		return true;
432762306a36Sopenharmony_ci	/* not support compression */
432862306a36Sopenharmony_ci	return false;
432962306a36Sopenharmony_ci}
433062306a36Sopenharmony_cistatic inline bool f2fs_is_compress_level_valid(int alg, int lvl) { return false; }
433162306a36Sopenharmony_cistatic inline struct page *f2fs_compress_control_page(struct page *page)
433262306a36Sopenharmony_ci{
433362306a36Sopenharmony_ci	WARN_ON_ONCE(1);
433462306a36Sopenharmony_ci	return ERR_PTR(-EINVAL);
433562306a36Sopenharmony_ci}
433662306a36Sopenharmony_cistatic inline int __init f2fs_init_compress_mempool(void) { return 0; }
433762306a36Sopenharmony_cistatic inline void f2fs_destroy_compress_mempool(void) { }
433862306a36Sopenharmony_cistatic inline void f2fs_decompress_cluster(struct decompress_io_ctx *dic,
433962306a36Sopenharmony_ci				bool in_task) { }
434062306a36Sopenharmony_cistatic inline void f2fs_end_read_compressed_page(struct page *page,
434162306a36Sopenharmony_ci				bool failed, block_t blkaddr, bool in_task)
434262306a36Sopenharmony_ci{
434362306a36Sopenharmony_ci	WARN_ON_ONCE(1);
434462306a36Sopenharmony_ci}
434562306a36Sopenharmony_cistatic inline void f2fs_put_page_dic(struct page *page, bool in_task)
434662306a36Sopenharmony_ci{
434762306a36Sopenharmony_ci	WARN_ON_ONCE(1);
434862306a36Sopenharmony_ci}
434962306a36Sopenharmony_cistatic inline unsigned int f2fs_cluster_blocks_are_contiguous(
435062306a36Sopenharmony_ci			struct dnode_of_data *dn, unsigned int ofs_in_node) { return 0; }
435162306a36Sopenharmony_cistatic inline bool f2fs_sanity_check_cluster(struct dnode_of_data *dn) { return false; }
435262306a36Sopenharmony_cistatic inline int f2fs_init_compress_inode(struct f2fs_sb_info *sbi) { return 0; }
435362306a36Sopenharmony_cistatic inline void f2fs_destroy_compress_inode(struct f2fs_sb_info *sbi) { }
435462306a36Sopenharmony_cistatic inline int f2fs_init_page_array_cache(struct f2fs_sb_info *sbi) { return 0; }
435562306a36Sopenharmony_cistatic inline void f2fs_destroy_page_array_cache(struct f2fs_sb_info *sbi) { }
435662306a36Sopenharmony_cistatic inline int __init f2fs_init_compress_cache(void) { return 0; }
435762306a36Sopenharmony_cistatic inline void f2fs_destroy_compress_cache(void) { }
435862306a36Sopenharmony_cistatic inline void f2fs_invalidate_compress_page(struct f2fs_sb_info *sbi,
435962306a36Sopenharmony_ci				block_t blkaddr) { }
436062306a36Sopenharmony_cistatic inline void f2fs_cache_compressed_page(struct f2fs_sb_info *sbi,
436162306a36Sopenharmony_ci				struct page *page, nid_t ino, block_t blkaddr) { }
436262306a36Sopenharmony_cistatic inline bool f2fs_load_compressed_page(struct f2fs_sb_info *sbi,
436362306a36Sopenharmony_ci				struct page *page, block_t blkaddr) { return false; }
436462306a36Sopenharmony_cistatic inline void f2fs_invalidate_compress_pages(struct f2fs_sb_info *sbi,
436562306a36Sopenharmony_ci							nid_t ino) { }
436662306a36Sopenharmony_ci#define inc_compr_inode_stat(inode)		do { } while (0)
436762306a36Sopenharmony_cistatic inline void f2fs_update_read_extent_tree_range_compressed(
436862306a36Sopenharmony_ci				struct inode *inode,
436962306a36Sopenharmony_ci				pgoff_t fofs, block_t blkaddr,
437062306a36Sopenharmony_ci				unsigned int llen, unsigned int c_len) { }
437162306a36Sopenharmony_ci#endif
437262306a36Sopenharmony_ci
437362306a36Sopenharmony_cistatic inline int set_compress_context(struct inode *inode)
437462306a36Sopenharmony_ci{
437562306a36Sopenharmony_ci#ifdef CONFIG_F2FS_FS_COMPRESSION
437662306a36Sopenharmony_ci	struct f2fs_sb_info *sbi = F2FS_I_SB(inode);
437762306a36Sopenharmony_ci
437862306a36Sopenharmony_ci	F2FS_I(inode)->i_compress_algorithm =
437962306a36Sopenharmony_ci			F2FS_OPTION(sbi).compress_algorithm;
438062306a36Sopenharmony_ci	F2FS_I(inode)->i_log_cluster_size =
438162306a36Sopenharmony_ci			F2FS_OPTION(sbi).compress_log_size;
438262306a36Sopenharmony_ci	F2FS_I(inode)->i_compress_flag =
438362306a36Sopenharmony_ci			F2FS_OPTION(sbi).compress_chksum ?
438462306a36Sopenharmony_ci				BIT(COMPRESS_CHKSUM) : 0;
438562306a36Sopenharmony_ci	F2FS_I(inode)->i_cluster_size =
438662306a36Sopenharmony_ci			BIT(F2FS_I(inode)->i_log_cluster_size);
438762306a36Sopenharmony_ci	if ((F2FS_I(inode)->i_compress_algorithm == COMPRESS_LZ4 ||
438862306a36Sopenharmony_ci		F2FS_I(inode)->i_compress_algorithm == COMPRESS_ZSTD) &&
438962306a36Sopenharmony_ci			F2FS_OPTION(sbi).compress_level)
439062306a36Sopenharmony_ci		F2FS_I(inode)->i_compress_level =
439162306a36Sopenharmony_ci				F2FS_OPTION(sbi).compress_level;
439262306a36Sopenharmony_ci	F2FS_I(inode)->i_flags |= F2FS_COMPR_FL;
439362306a36Sopenharmony_ci	set_inode_flag(inode, FI_COMPRESSED_FILE);
439462306a36Sopenharmony_ci	stat_inc_compr_inode(inode);
439562306a36Sopenharmony_ci	inc_compr_inode_stat(inode);
439662306a36Sopenharmony_ci	f2fs_mark_inode_dirty_sync(inode, true);
439762306a36Sopenharmony_ci	return 0;
439862306a36Sopenharmony_ci#else
439962306a36Sopenharmony_ci	return -EOPNOTSUPP;
440062306a36Sopenharmony_ci#endif
440162306a36Sopenharmony_ci}
440262306a36Sopenharmony_ci
440362306a36Sopenharmony_cistatic inline bool f2fs_disable_compressed_file(struct inode *inode)
440462306a36Sopenharmony_ci{
440562306a36Sopenharmony_ci	struct f2fs_inode_info *fi = F2FS_I(inode);
440662306a36Sopenharmony_ci
440762306a36Sopenharmony_ci	f2fs_down_write(&F2FS_I(inode)->i_sem);
440862306a36Sopenharmony_ci
440962306a36Sopenharmony_ci	if (!f2fs_compressed_file(inode)) {
441062306a36Sopenharmony_ci		f2fs_up_write(&F2FS_I(inode)->i_sem);
441162306a36Sopenharmony_ci		return true;
441262306a36Sopenharmony_ci	}
441362306a36Sopenharmony_ci	if (f2fs_is_mmap_file(inode) ||
441462306a36Sopenharmony_ci		(S_ISREG(inode->i_mode) && F2FS_HAS_BLOCKS(inode))) {
441562306a36Sopenharmony_ci		f2fs_up_write(&F2FS_I(inode)->i_sem);
441662306a36Sopenharmony_ci		return false;
441762306a36Sopenharmony_ci	}
441862306a36Sopenharmony_ci
441962306a36Sopenharmony_ci	fi->i_flags &= ~F2FS_COMPR_FL;
442062306a36Sopenharmony_ci	stat_dec_compr_inode(inode);
442162306a36Sopenharmony_ci	clear_inode_flag(inode, FI_COMPRESSED_FILE);
442262306a36Sopenharmony_ci	f2fs_mark_inode_dirty_sync(inode, true);
442362306a36Sopenharmony_ci
442462306a36Sopenharmony_ci	f2fs_up_write(&F2FS_I(inode)->i_sem);
442562306a36Sopenharmony_ci	return true;
442662306a36Sopenharmony_ci}
442762306a36Sopenharmony_ci
442862306a36Sopenharmony_ci#define F2FS_FEATURE_FUNCS(name, flagname) \
442962306a36Sopenharmony_cistatic inline bool f2fs_sb_has_##name(struct f2fs_sb_info *sbi) \
443062306a36Sopenharmony_ci{ \
443162306a36Sopenharmony_ci	return F2FS_HAS_FEATURE(sbi, F2FS_FEATURE_##flagname); \
443262306a36Sopenharmony_ci}
443362306a36Sopenharmony_ci
443462306a36Sopenharmony_ciF2FS_FEATURE_FUNCS(encrypt, ENCRYPT);
443562306a36Sopenharmony_ciF2FS_FEATURE_FUNCS(blkzoned, BLKZONED);
443662306a36Sopenharmony_ciF2FS_FEATURE_FUNCS(extra_attr, EXTRA_ATTR);
443762306a36Sopenharmony_ciF2FS_FEATURE_FUNCS(project_quota, PRJQUOTA);
443862306a36Sopenharmony_ciF2FS_FEATURE_FUNCS(inode_chksum, INODE_CHKSUM);
443962306a36Sopenharmony_ciF2FS_FEATURE_FUNCS(flexible_inline_xattr, FLEXIBLE_INLINE_XATTR);
444062306a36Sopenharmony_ciF2FS_FEATURE_FUNCS(quota_ino, QUOTA_INO);
444162306a36Sopenharmony_ciF2FS_FEATURE_FUNCS(inode_crtime, INODE_CRTIME);
444262306a36Sopenharmony_ciF2FS_FEATURE_FUNCS(lost_found, LOST_FOUND);
444362306a36Sopenharmony_ciF2FS_FEATURE_FUNCS(verity, VERITY);
444462306a36Sopenharmony_ciF2FS_FEATURE_FUNCS(sb_chksum, SB_CHKSUM);
444562306a36Sopenharmony_ciF2FS_FEATURE_FUNCS(casefold, CASEFOLD);
444662306a36Sopenharmony_ciF2FS_FEATURE_FUNCS(compression, COMPRESSION);
444762306a36Sopenharmony_ciF2FS_FEATURE_FUNCS(readonly, RO);
444862306a36Sopenharmony_ci
444962306a36Sopenharmony_ci#ifdef CONFIG_BLK_DEV_ZONED
445062306a36Sopenharmony_cistatic inline bool f2fs_blkz_is_seq(struct f2fs_sb_info *sbi, int devi,
445162306a36Sopenharmony_ci				    block_t blkaddr)
445262306a36Sopenharmony_ci{
445362306a36Sopenharmony_ci	unsigned int zno = blkaddr / sbi->blocks_per_blkz;
445462306a36Sopenharmony_ci
445562306a36Sopenharmony_ci	return test_bit(zno, FDEV(devi).blkz_seq);
445662306a36Sopenharmony_ci}
445762306a36Sopenharmony_ci#endif
445862306a36Sopenharmony_ci
445962306a36Sopenharmony_cistatic inline int f2fs_bdev_index(struct f2fs_sb_info *sbi,
446062306a36Sopenharmony_ci				  struct block_device *bdev)
446162306a36Sopenharmony_ci{
446262306a36Sopenharmony_ci	int i;
446362306a36Sopenharmony_ci
446462306a36Sopenharmony_ci	if (!f2fs_is_multi_device(sbi))
446562306a36Sopenharmony_ci		return 0;
446662306a36Sopenharmony_ci
446762306a36Sopenharmony_ci	for (i = 0; i < sbi->s_ndevs; i++)
446862306a36Sopenharmony_ci		if (FDEV(i).bdev == bdev)
446962306a36Sopenharmony_ci			return i;
447062306a36Sopenharmony_ci
447162306a36Sopenharmony_ci	WARN_ON(1);
447262306a36Sopenharmony_ci	return -1;
447362306a36Sopenharmony_ci}
447462306a36Sopenharmony_ci
447562306a36Sopenharmony_cistatic inline bool f2fs_hw_should_discard(struct f2fs_sb_info *sbi)
447662306a36Sopenharmony_ci{
447762306a36Sopenharmony_ci	return f2fs_sb_has_blkzoned(sbi);
447862306a36Sopenharmony_ci}
447962306a36Sopenharmony_ci
448062306a36Sopenharmony_cistatic inline bool f2fs_bdev_support_discard(struct block_device *bdev)
448162306a36Sopenharmony_ci{
448262306a36Sopenharmony_ci	return bdev_max_discard_sectors(bdev) || bdev_is_zoned(bdev);
448362306a36Sopenharmony_ci}
448462306a36Sopenharmony_ci
448562306a36Sopenharmony_cistatic inline bool f2fs_hw_support_discard(struct f2fs_sb_info *sbi)
448662306a36Sopenharmony_ci{
448762306a36Sopenharmony_ci	int i;
448862306a36Sopenharmony_ci
448962306a36Sopenharmony_ci	if (!f2fs_is_multi_device(sbi))
449062306a36Sopenharmony_ci		return f2fs_bdev_support_discard(sbi->sb->s_bdev);
449162306a36Sopenharmony_ci
449262306a36Sopenharmony_ci	for (i = 0; i < sbi->s_ndevs; i++)
449362306a36Sopenharmony_ci		if (f2fs_bdev_support_discard(FDEV(i).bdev))
449462306a36Sopenharmony_ci			return true;
449562306a36Sopenharmony_ci	return false;
449662306a36Sopenharmony_ci}
449762306a36Sopenharmony_ci
449862306a36Sopenharmony_cistatic inline bool f2fs_realtime_discard_enable(struct f2fs_sb_info *sbi)
449962306a36Sopenharmony_ci{
450062306a36Sopenharmony_ci	return (test_opt(sbi, DISCARD) && f2fs_hw_support_discard(sbi)) ||
450162306a36Sopenharmony_ci					f2fs_hw_should_discard(sbi);
450262306a36Sopenharmony_ci}
450362306a36Sopenharmony_ci
450462306a36Sopenharmony_cistatic inline bool f2fs_hw_is_readonly(struct f2fs_sb_info *sbi)
450562306a36Sopenharmony_ci{
450662306a36Sopenharmony_ci	int i;
450762306a36Sopenharmony_ci
450862306a36Sopenharmony_ci	if (!f2fs_is_multi_device(sbi))
450962306a36Sopenharmony_ci		return bdev_read_only(sbi->sb->s_bdev);
451062306a36Sopenharmony_ci
451162306a36Sopenharmony_ci	for (i = 0; i < sbi->s_ndevs; i++)
451262306a36Sopenharmony_ci		if (bdev_read_only(FDEV(i).bdev))
451362306a36Sopenharmony_ci			return true;
451462306a36Sopenharmony_ci	return false;
451562306a36Sopenharmony_ci}
451662306a36Sopenharmony_ci
451762306a36Sopenharmony_cistatic inline bool f2fs_dev_is_readonly(struct f2fs_sb_info *sbi)
451862306a36Sopenharmony_ci{
451962306a36Sopenharmony_ci	return f2fs_sb_has_readonly(sbi) || f2fs_hw_is_readonly(sbi);
452062306a36Sopenharmony_ci}
452162306a36Sopenharmony_ci
452262306a36Sopenharmony_cistatic inline bool f2fs_lfs_mode(struct f2fs_sb_info *sbi)
452362306a36Sopenharmony_ci{
452462306a36Sopenharmony_ci	return F2FS_OPTION(sbi).fs_mode == FS_MODE_LFS;
452562306a36Sopenharmony_ci}
452662306a36Sopenharmony_ci
452762306a36Sopenharmony_cistatic inline bool f2fs_low_mem_mode(struct f2fs_sb_info *sbi)
452862306a36Sopenharmony_ci{
452962306a36Sopenharmony_ci	return F2FS_OPTION(sbi).memory_mode == MEMORY_MODE_LOW;
453062306a36Sopenharmony_ci}
453162306a36Sopenharmony_ci
453262306a36Sopenharmony_cistatic inline bool f2fs_may_compress(struct inode *inode)
453362306a36Sopenharmony_ci{
453462306a36Sopenharmony_ci	if (IS_SWAPFILE(inode) || f2fs_is_pinned_file(inode) ||
453562306a36Sopenharmony_ci		f2fs_is_atomic_file(inode) || f2fs_has_inline_data(inode) ||
453662306a36Sopenharmony_ci		f2fs_is_mmap_file(inode))
453762306a36Sopenharmony_ci		return false;
453862306a36Sopenharmony_ci	return S_ISREG(inode->i_mode) || S_ISDIR(inode->i_mode);
453962306a36Sopenharmony_ci}
454062306a36Sopenharmony_ci
454162306a36Sopenharmony_cistatic inline void f2fs_i_compr_blocks_update(struct inode *inode,
454262306a36Sopenharmony_ci						u64 blocks, bool add)
454362306a36Sopenharmony_ci{
454462306a36Sopenharmony_ci	struct f2fs_inode_info *fi = F2FS_I(inode);
454562306a36Sopenharmony_ci	int diff = fi->i_cluster_size - blocks;
454662306a36Sopenharmony_ci
454762306a36Sopenharmony_ci	/* don't update i_compr_blocks if saved blocks were released */
454862306a36Sopenharmony_ci	if (!add && !atomic_read(&fi->i_compr_blocks))
454962306a36Sopenharmony_ci		return;
455062306a36Sopenharmony_ci
455162306a36Sopenharmony_ci	if (add) {
455262306a36Sopenharmony_ci		atomic_add(diff, &fi->i_compr_blocks);
455362306a36Sopenharmony_ci		stat_add_compr_blocks(inode, diff);
455462306a36Sopenharmony_ci	} else {
455562306a36Sopenharmony_ci		atomic_sub(diff, &fi->i_compr_blocks);
455662306a36Sopenharmony_ci		stat_sub_compr_blocks(inode, diff);
455762306a36Sopenharmony_ci	}
455862306a36Sopenharmony_ci	f2fs_mark_inode_dirty_sync(inode, true);
455962306a36Sopenharmony_ci}
456062306a36Sopenharmony_ci
456162306a36Sopenharmony_cistatic inline bool f2fs_allow_multi_device_dio(struct f2fs_sb_info *sbi,
456262306a36Sopenharmony_ci								int flag)
456362306a36Sopenharmony_ci{
456462306a36Sopenharmony_ci	if (!f2fs_is_multi_device(sbi))
456562306a36Sopenharmony_ci		return false;
456662306a36Sopenharmony_ci	if (flag != F2FS_GET_BLOCK_DIO)
456762306a36Sopenharmony_ci		return false;
456862306a36Sopenharmony_ci	return sbi->aligned_blksize;
456962306a36Sopenharmony_ci}
457062306a36Sopenharmony_ci
457162306a36Sopenharmony_cistatic inline bool f2fs_need_verity(const struct inode *inode, pgoff_t idx)
457262306a36Sopenharmony_ci{
457362306a36Sopenharmony_ci	return fsverity_active(inode) && (idx <
457462306a36Sopenharmony_ci		DIV_ROUND_UP(fsverity_get_verified_data_size(inode), PAGE_SIZE));
457562306a36Sopenharmony_ci}
457662306a36Sopenharmony_ci
457762306a36Sopenharmony_ci#ifdef CONFIG_F2FS_FAULT_INJECTION
457862306a36Sopenharmony_ciextern void f2fs_build_fault_attr(struct f2fs_sb_info *sbi, unsigned int rate,
457962306a36Sopenharmony_ci							unsigned int type);
458062306a36Sopenharmony_ci#else
458162306a36Sopenharmony_ci#define f2fs_build_fault_attr(sbi, rate, type)		do { } while (0)
458262306a36Sopenharmony_ci#endif
458362306a36Sopenharmony_ci
458462306a36Sopenharmony_cistatic inline bool is_journalled_quota(struct f2fs_sb_info *sbi)
458562306a36Sopenharmony_ci{
458662306a36Sopenharmony_ci#ifdef CONFIG_QUOTA
458762306a36Sopenharmony_ci	if (f2fs_sb_has_quota_ino(sbi))
458862306a36Sopenharmony_ci		return true;
458962306a36Sopenharmony_ci	if (F2FS_OPTION(sbi).s_qf_names[USRQUOTA] ||
459062306a36Sopenharmony_ci		F2FS_OPTION(sbi).s_qf_names[GRPQUOTA] ||
459162306a36Sopenharmony_ci		F2FS_OPTION(sbi).s_qf_names[PRJQUOTA])
459262306a36Sopenharmony_ci		return true;
459362306a36Sopenharmony_ci#endif
459462306a36Sopenharmony_ci	return false;
459562306a36Sopenharmony_ci}
459662306a36Sopenharmony_ci
459762306a36Sopenharmony_cistatic inline bool f2fs_block_unit_discard(struct f2fs_sb_info *sbi)
459862306a36Sopenharmony_ci{
459962306a36Sopenharmony_ci	return F2FS_OPTION(sbi).discard_unit == DISCARD_UNIT_BLOCK;
460062306a36Sopenharmony_ci}
460162306a36Sopenharmony_ci
460262306a36Sopenharmony_cistatic inline void f2fs_io_schedule_timeout(long timeout)
460362306a36Sopenharmony_ci{
460462306a36Sopenharmony_ci	set_current_state(TASK_UNINTERRUPTIBLE);
460562306a36Sopenharmony_ci	io_schedule_timeout(timeout);
460662306a36Sopenharmony_ci}
460762306a36Sopenharmony_ci
460862306a36Sopenharmony_cistatic inline void f2fs_handle_page_eio(struct f2fs_sb_info *sbi, pgoff_t ofs,
460962306a36Sopenharmony_ci					enum page_type type)
461062306a36Sopenharmony_ci{
461162306a36Sopenharmony_ci	if (unlikely(f2fs_cp_error(sbi)))
461262306a36Sopenharmony_ci		return;
461362306a36Sopenharmony_ci
461462306a36Sopenharmony_ci	if (ofs == sbi->page_eio_ofs[type]) {
461562306a36Sopenharmony_ci		if (sbi->page_eio_cnt[type]++ == MAX_RETRY_PAGE_EIO)
461662306a36Sopenharmony_ci			set_ckpt_flags(sbi, CP_ERROR_FLAG);
461762306a36Sopenharmony_ci	} else {
461862306a36Sopenharmony_ci		sbi->page_eio_ofs[type] = ofs;
461962306a36Sopenharmony_ci		sbi->page_eio_cnt[type] = 0;
462062306a36Sopenharmony_ci	}
462162306a36Sopenharmony_ci}
462262306a36Sopenharmony_ci
462362306a36Sopenharmony_cistatic inline bool f2fs_is_readonly(struct f2fs_sb_info *sbi)
462462306a36Sopenharmony_ci{
462562306a36Sopenharmony_ci	return f2fs_sb_has_readonly(sbi) || f2fs_readonly(sbi->sb);
462662306a36Sopenharmony_ci}
462762306a36Sopenharmony_ci
462862306a36Sopenharmony_cistatic inline void f2fs_truncate_meta_inode_pages(struct f2fs_sb_info *sbi,
462962306a36Sopenharmony_ci					block_t blkaddr, unsigned int cnt)
463062306a36Sopenharmony_ci{
463162306a36Sopenharmony_ci	bool need_submit = false;
463262306a36Sopenharmony_ci	int i = 0;
463362306a36Sopenharmony_ci
463462306a36Sopenharmony_ci	do {
463562306a36Sopenharmony_ci		struct page *page;
463662306a36Sopenharmony_ci
463762306a36Sopenharmony_ci		page = find_get_page(META_MAPPING(sbi), blkaddr + i);
463862306a36Sopenharmony_ci		if (page) {
463962306a36Sopenharmony_ci			if (PageWriteback(page))
464062306a36Sopenharmony_ci				need_submit = true;
464162306a36Sopenharmony_ci			f2fs_put_page(page, 0);
464262306a36Sopenharmony_ci		}
464362306a36Sopenharmony_ci	} while (++i < cnt && !need_submit);
464462306a36Sopenharmony_ci
464562306a36Sopenharmony_ci	if (need_submit)
464662306a36Sopenharmony_ci		f2fs_submit_merged_write_cond(sbi, sbi->meta_inode,
464762306a36Sopenharmony_ci							NULL, 0, DATA);
464862306a36Sopenharmony_ci
464962306a36Sopenharmony_ci	truncate_inode_pages_range(META_MAPPING(sbi),
465062306a36Sopenharmony_ci			F2FS_BLK_TO_BYTES((loff_t)blkaddr),
465162306a36Sopenharmony_ci			F2FS_BLK_END_BYTES((loff_t)(blkaddr + cnt - 1)));
465262306a36Sopenharmony_ci}
465362306a36Sopenharmony_ci
465462306a36Sopenharmony_cistatic inline void f2fs_invalidate_internal_cache(struct f2fs_sb_info *sbi,
465562306a36Sopenharmony_ci								block_t blkaddr)
465662306a36Sopenharmony_ci{
465762306a36Sopenharmony_ci	f2fs_truncate_meta_inode_pages(sbi, blkaddr, 1);
465862306a36Sopenharmony_ci	f2fs_invalidate_compress_page(sbi, blkaddr);
465962306a36Sopenharmony_ci}
466062306a36Sopenharmony_ci
466162306a36Sopenharmony_ci#define EFSBADCRC	EBADMSG		/* Bad CRC detected */
466262306a36Sopenharmony_ci#define EFSCORRUPTED	EUCLEAN		/* Filesystem is corrupted */
466362306a36Sopenharmony_ci
466462306a36Sopenharmony_ci#endif /* _LINUX_F2FS_H */
4665