18c2ecf20Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0 */
28c2ecf20Sopenharmony_ci
38c2ecf20Sopenharmony_ci#ifndef BTRFS_EXTENT_IO_TREE_H
48c2ecf20Sopenharmony_ci#define BTRFS_EXTENT_IO_TREE_H
58c2ecf20Sopenharmony_ci
68c2ecf20Sopenharmony_cistruct extent_changeset;
78c2ecf20Sopenharmony_cistruct io_failure_record;
88c2ecf20Sopenharmony_ci
98c2ecf20Sopenharmony_ci/* Bits for the extent state */
108c2ecf20Sopenharmony_ci#define EXTENT_DIRTY		(1U << 0)
118c2ecf20Sopenharmony_ci#define EXTENT_UPTODATE		(1U << 1)
128c2ecf20Sopenharmony_ci#define EXTENT_LOCKED		(1U << 2)
138c2ecf20Sopenharmony_ci#define EXTENT_NEW		(1U << 3)
148c2ecf20Sopenharmony_ci#define EXTENT_DELALLOC		(1U << 4)
158c2ecf20Sopenharmony_ci#define EXTENT_DEFRAG		(1U << 5)
168c2ecf20Sopenharmony_ci#define EXTENT_BOUNDARY		(1U << 6)
178c2ecf20Sopenharmony_ci#define EXTENT_NODATASUM	(1U << 7)
188c2ecf20Sopenharmony_ci#define EXTENT_CLEAR_META_RESV	(1U << 8)
198c2ecf20Sopenharmony_ci#define EXTENT_NEED_WAIT	(1U << 9)
208c2ecf20Sopenharmony_ci#define EXTENT_DAMAGED		(1U << 10)
218c2ecf20Sopenharmony_ci#define EXTENT_NORESERVE	(1U << 11)
228c2ecf20Sopenharmony_ci#define EXTENT_QGROUP_RESERVED	(1U << 12)
238c2ecf20Sopenharmony_ci#define EXTENT_CLEAR_DATA_RESV	(1U << 13)
248c2ecf20Sopenharmony_ci#define EXTENT_DELALLOC_NEW	(1U << 14)
258c2ecf20Sopenharmony_ci#define EXTENT_DO_ACCOUNTING    (EXTENT_CLEAR_META_RESV | \
268c2ecf20Sopenharmony_ci				 EXTENT_CLEAR_DATA_RESV)
278c2ecf20Sopenharmony_ci#define EXTENT_CTLBITS		(EXTENT_DO_ACCOUNTING)
288c2ecf20Sopenharmony_ci
298c2ecf20Sopenharmony_ci/*
308c2ecf20Sopenharmony_ci * Redefined bits above which are used only in the device allocation tree,
318c2ecf20Sopenharmony_ci * shouldn't be using EXTENT_LOCKED / EXTENT_BOUNDARY / EXTENT_CLEAR_META_RESV
328c2ecf20Sopenharmony_ci * / EXTENT_CLEAR_DATA_RESV because they have special meaning to the bit
338c2ecf20Sopenharmony_ci * manipulation functions
348c2ecf20Sopenharmony_ci */
358c2ecf20Sopenharmony_ci#define CHUNK_ALLOCATED				EXTENT_DIRTY
368c2ecf20Sopenharmony_ci#define CHUNK_TRIMMED				EXTENT_DEFRAG
378c2ecf20Sopenharmony_ci#define CHUNK_STATE_MASK			(CHUNK_ALLOCATED |		\
388c2ecf20Sopenharmony_ci						 CHUNK_TRIMMED)
398c2ecf20Sopenharmony_ci
408c2ecf20Sopenharmony_cienum {
418c2ecf20Sopenharmony_ci	IO_TREE_FS_PINNED_EXTENTS,
428c2ecf20Sopenharmony_ci	IO_TREE_FS_EXCLUDED_EXTENTS,
438c2ecf20Sopenharmony_ci	IO_TREE_BTREE_INODE_IO,
448c2ecf20Sopenharmony_ci	IO_TREE_INODE_IO,
458c2ecf20Sopenharmony_ci	IO_TREE_INODE_IO_FAILURE,
468c2ecf20Sopenharmony_ci	IO_TREE_RELOC_BLOCKS,
478c2ecf20Sopenharmony_ci	IO_TREE_TRANS_DIRTY_PAGES,
488c2ecf20Sopenharmony_ci	IO_TREE_ROOT_DIRTY_LOG_PAGES,
498c2ecf20Sopenharmony_ci	IO_TREE_INODE_FILE_EXTENT,
508c2ecf20Sopenharmony_ci	IO_TREE_LOG_CSUM_RANGE,
518c2ecf20Sopenharmony_ci	IO_TREE_SELFTEST,
528c2ecf20Sopenharmony_ci	IO_TREE_DEVICE_ALLOC_STATE,
538c2ecf20Sopenharmony_ci};
548c2ecf20Sopenharmony_ci
558c2ecf20Sopenharmony_cistruct extent_io_tree {
568c2ecf20Sopenharmony_ci	struct rb_root state;
578c2ecf20Sopenharmony_ci	struct btrfs_fs_info *fs_info;
588c2ecf20Sopenharmony_ci	void *private_data;
598c2ecf20Sopenharmony_ci	u64 dirty_bytes;
608c2ecf20Sopenharmony_ci	bool track_uptodate;
618c2ecf20Sopenharmony_ci
628c2ecf20Sopenharmony_ci	/* Who owns this io tree, should be one of IO_TREE_* */
638c2ecf20Sopenharmony_ci	u8 owner;
648c2ecf20Sopenharmony_ci
658c2ecf20Sopenharmony_ci	spinlock_t lock;
668c2ecf20Sopenharmony_ci};
678c2ecf20Sopenharmony_ci
688c2ecf20Sopenharmony_cistruct extent_state {
698c2ecf20Sopenharmony_ci	u64 start;
708c2ecf20Sopenharmony_ci	u64 end; /* inclusive */
718c2ecf20Sopenharmony_ci	struct rb_node rb_node;
728c2ecf20Sopenharmony_ci
738c2ecf20Sopenharmony_ci	/* ADD NEW ELEMENTS AFTER THIS */
748c2ecf20Sopenharmony_ci	wait_queue_head_t wq;
758c2ecf20Sopenharmony_ci	refcount_t refs;
768c2ecf20Sopenharmony_ci	unsigned state;
778c2ecf20Sopenharmony_ci
788c2ecf20Sopenharmony_ci	struct io_failure_record *failrec;
798c2ecf20Sopenharmony_ci
808c2ecf20Sopenharmony_ci#ifdef CONFIG_BTRFS_DEBUG
818c2ecf20Sopenharmony_ci	struct list_head leak_list;
828c2ecf20Sopenharmony_ci#endif
838c2ecf20Sopenharmony_ci};
848c2ecf20Sopenharmony_ci
858c2ecf20Sopenharmony_ciint __init extent_state_cache_init(void);
868c2ecf20Sopenharmony_civoid __cold extent_state_cache_exit(void);
878c2ecf20Sopenharmony_ci
888c2ecf20Sopenharmony_civoid extent_io_tree_init(struct btrfs_fs_info *fs_info,
898c2ecf20Sopenharmony_ci			 struct extent_io_tree *tree, unsigned int owner,
908c2ecf20Sopenharmony_ci			 void *private_data);
918c2ecf20Sopenharmony_civoid extent_io_tree_release(struct extent_io_tree *tree);
928c2ecf20Sopenharmony_ci
938c2ecf20Sopenharmony_ciint lock_extent_bits(struct extent_io_tree *tree, u64 start, u64 end,
948c2ecf20Sopenharmony_ci		     struct extent_state **cached);
958c2ecf20Sopenharmony_ci
968c2ecf20Sopenharmony_cistatic inline int lock_extent(struct extent_io_tree *tree, u64 start, u64 end)
978c2ecf20Sopenharmony_ci{
988c2ecf20Sopenharmony_ci	return lock_extent_bits(tree, start, end, NULL);
998c2ecf20Sopenharmony_ci}
1008c2ecf20Sopenharmony_ci
1018c2ecf20Sopenharmony_ciint try_lock_extent(struct extent_io_tree *tree, u64 start, u64 end);
1028c2ecf20Sopenharmony_ci
1038c2ecf20Sopenharmony_ciint __init extent_io_init(void);
1048c2ecf20Sopenharmony_civoid __cold extent_io_exit(void);
1058c2ecf20Sopenharmony_ci
1068c2ecf20Sopenharmony_ciu64 count_range_bits(struct extent_io_tree *tree,
1078c2ecf20Sopenharmony_ci		     u64 *start, u64 search_end,
1088c2ecf20Sopenharmony_ci		     u64 max_bytes, unsigned bits, int contig);
1098c2ecf20Sopenharmony_ci
1108c2ecf20Sopenharmony_civoid free_extent_state(struct extent_state *state);
1118c2ecf20Sopenharmony_ciint test_range_bit(struct extent_io_tree *tree, u64 start, u64 end,
1128c2ecf20Sopenharmony_ci		   unsigned bits, int filled,
1138c2ecf20Sopenharmony_ci		   struct extent_state *cached_state);
1148c2ecf20Sopenharmony_ciint clear_record_extent_bits(struct extent_io_tree *tree, u64 start, u64 end,
1158c2ecf20Sopenharmony_ci		unsigned bits, struct extent_changeset *changeset);
1168c2ecf20Sopenharmony_ciint clear_extent_bit(struct extent_io_tree *tree, u64 start, u64 end,
1178c2ecf20Sopenharmony_ci		     unsigned bits, int wake, int delete,
1188c2ecf20Sopenharmony_ci		     struct extent_state **cached);
1198c2ecf20Sopenharmony_ciint __clear_extent_bit(struct extent_io_tree *tree, u64 start, u64 end,
1208c2ecf20Sopenharmony_ci		     unsigned bits, int wake, int delete,
1218c2ecf20Sopenharmony_ci		     struct extent_state **cached, gfp_t mask,
1228c2ecf20Sopenharmony_ci		     struct extent_changeset *changeset);
1238c2ecf20Sopenharmony_ci
1248c2ecf20Sopenharmony_cistatic inline int unlock_extent(struct extent_io_tree *tree, u64 start, u64 end)
1258c2ecf20Sopenharmony_ci{
1268c2ecf20Sopenharmony_ci	return clear_extent_bit(tree, start, end, EXTENT_LOCKED, 1, 0, NULL);
1278c2ecf20Sopenharmony_ci}
1288c2ecf20Sopenharmony_ci
1298c2ecf20Sopenharmony_cistatic inline int unlock_extent_cached(struct extent_io_tree *tree, u64 start,
1308c2ecf20Sopenharmony_ci		u64 end, struct extent_state **cached)
1318c2ecf20Sopenharmony_ci{
1328c2ecf20Sopenharmony_ci	return __clear_extent_bit(tree, start, end, EXTENT_LOCKED, 1, 0, cached,
1338c2ecf20Sopenharmony_ci				GFP_NOFS, NULL);
1348c2ecf20Sopenharmony_ci}
1358c2ecf20Sopenharmony_ci
1368c2ecf20Sopenharmony_cistatic inline int unlock_extent_cached_atomic(struct extent_io_tree *tree,
1378c2ecf20Sopenharmony_ci		u64 start, u64 end, struct extent_state **cached)
1388c2ecf20Sopenharmony_ci{
1398c2ecf20Sopenharmony_ci	return __clear_extent_bit(tree, start, end, EXTENT_LOCKED, 1, 0, cached,
1408c2ecf20Sopenharmony_ci				GFP_ATOMIC, NULL);
1418c2ecf20Sopenharmony_ci}
1428c2ecf20Sopenharmony_ci
1438c2ecf20Sopenharmony_cistatic inline int clear_extent_bits(struct extent_io_tree *tree, u64 start,
1448c2ecf20Sopenharmony_ci		u64 end, unsigned bits)
1458c2ecf20Sopenharmony_ci{
1468c2ecf20Sopenharmony_ci	int wake = 0;
1478c2ecf20Sopenharmony_ci
1488c2ecf20Sopenharmony_ci	if (bits & EXTENT_LOCKED)
1498c2ecf20Sopenharmony_ci		wake = 1;
1508c2ecf20Sopenharmony_ci
1518c2ecf20Sopenharmony_ci	return clear_extent_bit(tree, start, end, bits, wake, 0, NULL);
1528c2ecf20Sopenharmony_ci}
1538c2ecf20Sopenharmony_ci
1548c2ecf20Sopenharmony_ciint set_record_extent_bits(struct extent_io_tree *tree, u64 start, u64 end,
1558c2ecf20Sopenharmony_ci			   unsigned bits, struct extent_changeset *changeset);
1568c2ecf20Sopenharmony_ciint set_extent_bit(struct extent_io_tree *tree, u64 start, u64 end,
1578c2ecf20Sopenharmony_ci		   unsigned bits, u64 *failed_start,
1588c2ecf20Sopenharmony_ci		   struct extent_state **cached_state, gfp_t mask);
1598c2ecf20Sopenharmony_ciint set_extent_bits_nowait(struct extent_io_tree *tree, u64 start, u64 end,
1608c2ecf20Sopenharmony_ci			   unsigned bits);
1618c2ecf20Sopenharmony_ci
1628c2ecf20Sopenharmony_cistatic inline int set_extent_bits(struct extent_io_tree *tree, u64 start,
1638c2ecf20Sopenharmony_ci		u64 end, unsigned bits)
1648c2ecf20Sopenharmony_ci{
1658c2ecf20Sopenharmony_ci	return set_extent_bit(tree, start, end, bits, NULL, NULL, GFP_NOFS);
1668c2ecf20Sopenharmony_ci}
1678c2ecf20Sopenharmony_ci
1688c2ecf20Sopenharmony_cistatic inline int clear_extent_uptodate(struct extent_io_tree *tree, u64 start,
1698c2ecf20Sopenharmony_ci		u64 end, struct extent_state **cached_state)
1708c2ecf20Sopenharmony_ci{
1718c2ecf20Sopenharmony_ci	return __clear_extent_bit(tree, start, end, EXTENT_UPTODATE, 0, 0,
1728c2ecf20Sopenharmony_ci				cached_state, GFP_NOFS, NULL);
1738c2ecf20Sopenharmony_ci}
1748c2ecf20Sopenharmony_ci
1758c2ecf20Sopenharmony_cistatic inline int set_extent_dirty(struct extent_io_tree *tree, u64 start,
1768c2ecf20Sopenharmony_ci		u64 end, gfp_t mask)
1778c2ecf20Sopenharmony_ci{
1788c2ecf20Sopenharmony_ci	return set_extent_bit(tree, start, end, EXTENT_DIRTY, NULL,
1798c2ecf20Sopenharmony_ci			      NULL, mask);
1808c2ecf20Sopenharmony_ci}
1818c2ecf20Sopenharmony_ci
1828c2ecf20Sopenharmony_cistatic inline int clear_extent_dirty(struct extent_io_tree *tree, u64 start,
1838c2ecf20Sopenharmony_ci				     u64 end, struct extent_state **cached)
1848c2ecf20Sopenharmony_ci{
1858c2ecf20Sopenharmony_ci	return clear_extent_bit(tree, start, end,
1868c2ecf20Sopenharmony_ci				EXTENT_DIRTY | EXTENT_DELALLOC |
1878c2ecf20Sopenharmony_ci				EXTENT_DO_ACCOUNTING, 0, 0, cached);
1888c2ecf20Sopenharmony_ci}
1898c2ecf20Sopenharmony_ci
1908c2ecf20Sopenharmony_ciint convert_extent_bit(struct extent_io_tree *tree, u64 start, u64 end,
1918c2ecf20Sopenharmony_ci		       unsigned bits, unsigned clear_bits,
1928c2ecf20Sopenharmony_ci		       struct extent_state **cached_state);
1938c2ecf20Sopenharmony_ci
1948c2ecf20Sopenharmony_cistatic inline int set_extent_delalloc(struct extent_io_tree *tree, u64 start,
1958c2ecf20Sopenharmony_ci				      u64 end, unsigned int extra_bits,
1968c2ecf20Sopenharmony_ci				      struct extent_state **cached_state)
1978c2ecf20Sopenharmony_ci{
1988c2ecf20Sopenharmony_ci	return set_extent_bit(tree, start, end,
1998c2ecf20Sopenharmony_ci			      EXTENT_DELALLOC | EXTENT_UPTODATE | extra_bits,
2008c2ecf20Sopenharmony_ci			      NULL, cached_state, GFP_NOFS);
2018c2ecf20Sopenharmony_ci}
2028c2ecf20Sopenharmony_ci
2038c2ecf20Sopenharmony_cistatic inline int set_extent_defrag(struct extent_io_tree *tree, u64 start,
2048c2ecf20Sopenharmony_ci		u64 end, struct extent_state **cached_state)
2058c2ecf20Sopenharmony_ci{
2068c2ecf20Sopenharmony_ci	return set_extent_bit(tree, start, end,
2078c2ecf20Sopenharmony_ci			      EXTENT_DELALLOC | EXTENT_UPTODATE | EXTENT_DEFRAG,
2088c2ecf20Sopenharmony_ci			      NULL, cached_state, GFP_NOFS);
2098c2ecf20Sopenharmony_ci}
2108c2ecf20Sopenharmony_ci
2118c2ecf20Sopenharmony_cistatic inline int set_extent_new(struct extent_io_tree *tree, u64 start,
2128c2ecf20Sopenharmony_ci		u64 end)
2138c2ecf20Sopenharmony_ci{
2148c2ecf20Sopenharmony_ci	return set_extent_bit(tree, start, end, EXTENT_NEW, NULL, NULL,
2158c2ecf20Sopenharmony_ci			GFP_NOFS);
2168c2ecf20Sopenharmony_ci}
2178c2ecf20Sopenharmony_ci
2188c2ecf20Sopenharmony_cistatic inline int set_extent_uptodate(struct extent_io_tree *tree, u64 start,
2198c2ecf20Sopenharmony_ci		u64 end, struct extent_state **cached_state, gfp_t mask)
2208c2ecf20Sopenharmony_ci{
2218c2ecf20Sopenharmony_ci	return set_extent_bit(tree, start, end, EXTENT_UPTODATE, NULL,
2228c2ecf20Sopenharmony_ci			      cached_state, mask);
2238c2ecf20Sopenharmony_ci}
2248c2ecf20Sopenharmony_ci
2258c2ecf20Sopenharmony_ciint find_first_extent_bit(struct extent_io_tree *tree, u64 start,
2268c2ecf20Sopenharmony_ci			  u64 *start_ret, u64 *end_ret, unsigned bits,
2278c2ecf20Sopenharmony_ci			  struct extent_state **cached_state);
2288c2ecf20Sopenharmony_civoid find_first_clear_extent_bit(struct extent_io_tree *tree, u64 start,
2298c2ecf20Sopenharmony_ci				 u64 *start_ret, u64 *end_ret, unsigned bits);
2308c2ecf20Sopenharmony_ciint find_contiguous_extent_bit(struct extent_io_tree *tree, u64 start,
2318c2ecf20Sopenharmony_ci			       u64 *start_ret, u64 *end_ret, unsigned bits);
2328c2ecf20Sopenharmony_ciint extent_invalidatepage(struct extent_io_tree *tree,
2338c2ecf20Sopenharmony_ci			  struct page *page, unsigned long offset);
2348c2ecf20Sopenharmony_cibool btrfs_find_delalloc_range(struct extent_io_tree *tree, u64 *start,
2358c2ecf20Sopenharmony_ci			       u64 *end, u64 max_bytes,
2368c2ecf20Sopenharmony_ci			       struct extent_state **cached_state);
2378c2ecf20Sopenharmony_ci
2388c2ecf20Sopenharmony_ci/* This should be reworked in the future and put elsewhere. */
2398c2ecf20Sopenharmony_cistruct io_failure_record *get_state_failrec(struct extent_io_tree *tree, u64 start);
2408c2ecf20Sopenharmony_ciint set_state_failrec(struct extent_io_tree *tree, u64 start,
2418c2ecf20Sopenharmony_ci		      struct io_failure_record *failrec);
2428c2ecf20Sopenharmony_civoid btrfs_free_io_failure_record(struct btrfs_inode *inode, u64 start,
2438c2ecf20Sopenharmony_ci		u64 end);
2448c2ecf20Sopenharmony_ciint free_io_failure(struct extent_io_tree *failure_tree,
2458c2ecf20Sopenharmony_ci		    struct extent_io_tree *io_tree,
2468c2ecf20Sopenharmony_ci		    struct io_failure_record *rec);
2478c2ecf20Sopenharmony_ciint clean_io_failure(struct btrfs_fs_info *fs_info,
2488c2ecf20Sopenharmony_ci		     struct extent_io_tree *failure_tree,
2498c2ecf20Sopenharmony_ci		     struct extent_io_tree *io_tree, u64 start,
2508c2ecf20Sopenharmony_ci		     struct page *page, u64 ino, unsigned int pg_offset);
2518c2ecf20Sopenharmony_ci
2528c2ecf20Sopenharmony_ci#endif /* BTRFS_EXTENT_IO_TREE_H */
253