162306a36Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0 */
262306a36Sopenharmony_ci/*
362306a36Sopenharmony_ci * Copyright (C) 2007 Oracle.  All rights reserved.
462306a36Sopenharmony_ci */
562306a36Sopenharmony_ci
662306a36Sopenharmony_ci#ifndef BTRFS_ORDERED_DATA_H
762306a36Sopenharmony_ci#define BTRFS_ORDERED_DATA_H
862306a36Sopenharmony_ci
962306a36Sopenharmony_ci/* one of these per inode */
1062306a36Sopenharmony_cistruct btrfs_ordered_inode_tree {
1162306a36Sopenharmony_ci	spinlock_t lock;
1262306a36Sopenharmony_ci	struct rb_root tree;
1362306a36Sopenharmony_ci	struct rb_node *last;
1462306a36Sopenharmony_ci};
1562306a36Sopenharmony_ci
1662306a36Sopenharmony_cistruct btrfs_ordered_sum {
1762306a36Sopenharmony_ci	/*
1862306a36Sopenharmony_ci	 * Logical start address and length for of the blocks covered by
1962306a36Sopenharmony_ci	 * the sums array.
2062306a36Sopenharmony_ci	 */
2162306a36Sopenharmony_ci	u64 logical;
2262306a36Sopenharmony_ci	u32 len;
2362306a36Sopenharmony_ci
2462306a36Sopenharmony_ci	struct list_head list;
2562306a36Sopenharmony_ci	/* last field is a variable length array of csums */
2662306a36Sopenharmony_ci	u8 sums[];
2762306a36Sopenharmony_ci};
2862306a36Sopenharmony_ci
2962306a36Sopenharmony_ci/*
3062306a36Sopenharmony_ci * Bits for btrfs_ordered_extent::flags.
3162306a36Sopenharmony_ci *
3262306a36Sopenharmony_ci * BTRFS_ORDERED_IO_DONE is set when all of the blocks are written.
3362306a36Sopenharmony_ci * It is used to make sure metadata is inserted into the tree only once
3462306a36Sopenharmony_ci * per extent.
3562306a36Sopenharmony_ci *
3662306a36Sopenharmony_ci * BTRFS_ORDERED_COMPLETE is set when the extent is removed from the
3762306a36Sopenharmony_ci * rbtree, just before waking any waiters.  It is used to indicate the
3862306a36Sopenharmony_ci * IO is done and any metadata is inserted into the tree.
3962306a36Sopenharmony_ci */
4062306a36Sopenharmony_cienum {
4162306a36Sopenharmony_ci	/*
4262306a36Sopenharmony_ci	 * Different types for ordered extents, one and only one of the 4 types
4362306a36Sopenharmony_ci	 * need to be set when creating ordered extent.
4462306a36Sopenharmony_ci	 *
4562306a36Sopenharmony_ci	 * REGULAR:	For regular non-compressed COW write
4662306a36Sopenharmony_ci	 * NOCOW:	For NOCOW write into existing non-hole extent
4762306a36Sopenharmony_ci	 * PREALLOC:	For NOCOW write into preallocated extent
4862306a36Sopenharmony_ci	 * COMPRESSED:	For compressed COW write
4962306a36Sopenharmony_ci	 */
5062306a36Sopenharmony_ci	BTRFS_ORDERED_REGULAR,
5162306a36Sopenharmony_ci	BTRFS_ORDERED_NOCOW,
5262306a36Sopenharmony_ci	BTRFS_ORDERED_PREALLOC,
5362306a36Sopenharmony_ci	BTRFS_ORDERED_COMPRESSED,
5462306a36Sopenharmony_ci
5562306a36Sopenharmony_ci	/*
5662306a36Sopenharmony_ci	 * Extra bit for direct io, can only be set for
5762306a36Sopenharmony_ci	 * REGULAR/NOCOW/PREALLOC. No direct io for compressed extent.
5862306a36Sopenharmony_ci	 */
5962306a36Sopenharmony_ci	BTRFS_ORDERED_DIRECT,
6062306a36Sopenharmony_ci
6162306a36Sopenharmony_ci	/* Extra status bits for ordered extents */
6262306a36Sopenharmony_ci
6362306a36Sopenharmony_ci	/* set when all the pages are written */
6462306a36Sopenharmony_ci	BTRFS_ORDERED_IO_DONE,
6562306a36Sopenharmony_ci	/* set when removed from the tree */
6662306a36Sopenharmony_ci	BTRFS_ORDERED_COMPLETE,
6762306a36Sopenharmony_ci	/* We had an io error when writing this out */
6862306a36Sopenharmony_ci	BTRFS_ORDERED_IOERR,
6962306a36Sopenharmony_ci	/* Set when we have to truncate an extent */
7062306a36Sopenharmony_ci	BTRFS_ORDERED_TRUNCATED,
7162306a36Sopenharmony_ci	/* Used during fsync to track already logged extents */
7262306a36Sopenharmony_ci	BTRFS_ORDERED_LOGGED,
7362306a36Sopenharmony_ci	/* We have already logged all the csums of the ordered extent */
7462306a36Sopenharmony_ci	BTRFS_ORDERED_LOGGED_CSUM,
7562306a36Sopenharmony_ci	/* We wait for this extent to complete in the current transaction */
7662306a36Sopenharmony_ci	BTRFS_ORDERED_PENDING,
7762306a36Sopenharmony_ci	/* BTRFS_IOC_ENCODED_WRITE */
7862306a36Sopenharmony_ci	BTRFS_ORDERED_ENCODED,
7962306a36Sopenharmony_ci};
8062306a36Sopenharmony_ci
8162306a36Sopenharmony_ci/* BTRFS_ORDERED_* flags that specify the type of the extent. */
8262306a36Sopenharmony_ci#define BTRFS_ORDERED_TYPE_FLAGS ((1UL << BTRFS_ORDERED_REGULAR) |	\
8362306a36Sopenharmony_ci				  (1UL << BTRFS_ORDERED_NOCOW) |	\
8462306a36Sopenharmony_ci				  (1UL << BTRFS_ORDERED_PREALLOC) |	\
8562306a36Sopenharmony_ci				  (1UL << BTRFS_ORDERED_COMPRESSED) |	\
8662306a36Sopenharmony_ci				  (1UL << BTRFS_ORDERED_DIRECT) |	\
8762306a36Sopenharmony_ci				  (1UL << BTRFS_ORDERED_ENCODED))
8862306a36Sopenharmony_ci
8962306a36Sopenharmony_cistruct btrfs_ordered_extent {
9062306a36Sopenharmony_ci	/* logical offset in the file */
9162306a36Sopenharmony_ci	u64 file_offset;
9262306a36Sopenharmony_ci
9362306a36Sopenharmony_ci	/*
9462306a36Sopenharmony_ci	 * These fields directly correspond to the same fields in
9562306a36Sopenharmony_ci	 * btrfs_file_extent_item.
9662306a36Sopenharmony_ci	 */
9762306a36Sopenharmony_ci	u64 num_bytes;
9862306a36Sopenharmony_ci	u64 ram_bytes;
9962306a36Sopenharmony_ci	u64 disk_bytenr;
10062306a36Sopenharmony_ci	u64 disk_num_bytes;
10162306a36Sopenharmony_ci	u64 offset;
10262306a36Sopenharmony_ci
10362306a36Sopenharmony_ci	/* number of bytes that still need writing */
10462306a36Sopenharmony_ci	u64 bytes_left;
10562306a36Sopenharmony_ci
10662306a36Sopenharmony_ci	/*
10762306a36Sopenharmony_ci	 * the end of the ordered extent which is behind it but
10862306a36Sopenharmony_ci	 * didn't update disk_i_size. Please see the comment of
10962306a36Sopenharmony_ci	 * btrfs_ordered_update_i_size();
11062306a36Sopenharmony_ci	 */
11162306a36Sopenharmony_ci	u64 outstanding_isize;
11262306a36Sopenharmony_ci
11362306a36Sopenharmony_ci	/*
11462306a36Sopenharmony_ci	 * If we get truncated we need to adjust the file extent we enter for
11562306a36Sopenharmony_ci	 * this ordered extent so that we do not expose stale data.
11662306a36Sopenharmony_ci	 */
11762306a36Sopenharmony_ci	u64 truncated_len;
11862306a36Sopenharmony_ci
11962306a36Sopenharmony_ci	/* flags (described above) */
12062306a36Sopenharmony_ci	unsigned long flags;
12162306a36Sopenharmony_ci
12262306a36Sopenharmony_ci	/* compression algorithm */
12362306a36Sopenharmony_ci	int compress_type;
12462306a36Sopenharmony_ci
12562306a36Sopenharmony_ci	/* Qgroup reserved space */
12662306a36Sopenharmony_ci	int qgroup_rsv;
12762306a36Sopenharmony_ci
12862306a36Sopenharmony_ci	/* reference count */
12962306a36Sopenharmony_ci	refcount_t refs;
13062306a36Sopenharmony_ci
13162306a36Sopenharmony_ci	/* the inode we belong to */
13262306a36Sopenharmony_ci	struct inode *inode;
13362306a36Sopenharmony_ci
13462306a36Sopenharmony_ci	/* list of checksums for insertion when the extent io is done */
13562306a36Sopenharmony_ci	struct list_head list;
13662306a36Sopenharmony_ci
13762306a36Sopenharmony_ci	/* used for fast fsyncs */
13862306a36Sopenharmony_ci	struct list_head log_list;
13962306a36Sopenharmony_ci
14062306a36Sopenharmony_ci	/* used to wait for the BTRFS_ORDERED_COMPLETE bit */
14162306a36Sopenharmony_ci	wait_queue_head_t wait;
14262306a36Sopenharmony_ci
14362306a36Sopenharmony_ci	/* our friendly rbtree entry */
14462306a36Sopenharmony_ci	struct rb_node rb_node;
14562306a36Sopenharmony_ci
14662306a36Sopenharmony_ci	/* a per root list of all the pending ordered extents */
14762306a36Sopenharmony_ci	struct list_head root_extent_list;
14862306a36Sopenharmony_ci
14962306a36Sopenharmony_ci	struct btrfs_work work;
15062306a36Sopenharmony_ci
15162306a36Sopenharmony_ci	struct completion completion;
15262306a36Sopenharmony_ci	struct btrfs_work flush_work;
15362306a36Sopenharmony_ci	struct list_head work_list;
15462306a36Sopenharmony_ci};
15562306a36Sopenharmony_ci
15662306a36Sopenharmony_cistatic inline void
15762306a36Sopenharmony_cibtrfs_ordered_inode_tree_init(struct btrfs_ordered_inode_tree *t)
15862306a36Sopenharmony_ci{
15962306a36Sopenharmony_ci	spin_lock_init(&t->lock);
16062306a36Sopenharmony_ci	t->tree = RB_ROOT;
16162306a36Sopenharmony_ci	t->last = NULL;
16262306a36Sopenharmony_ci}
16362306a36Sopenharmony_ci
16462306a36Sopenharmony_ciint btrfs_finish_one_ordered(struct btrfs_ordered_extent *ordered_extent);
16562306a36Sopenharmony_ciint btrfs_finish_ordered_io(struct btrfs_ordered_extent *ordered_extent);
16662306a36Sopenharmony_ci
16762306a36Sopenharmony_civoid btrfs_put_ordered_extent(struct btrfs_ordered_extent *entry);
16862306a36Sopenharmony_civoid btrfs_remove_ordered_extent(struct btrfs_inode *btrfs_inode,
16962306a36Sopenharmony_ci				struct btrfs_ordered_extent *entry);
17062306a36Sopenharmony_cibool btrfs_finish_ordered_extent(struct btrfs_ordered_extent *ordered,
17162306a36Sopenharmony_ci				 struct page *page, u64 file_offset, u64 len,
17262306a36Sopenharmony_ci				 bool uptodate);
17362306a36Sopenharmony_civoid btrfs_mark_ordered_io_finished(struct btrfs_inode *inode,
17462306a36Sopenharmony_ci				struct page *page, u64 file_offset,
17562306a36Sopenharmony_ci				u64 num_bytes, bool uptodate);
17662306a36Sopenharmony_cibool btrfs_dec_test_ordered_pending(struct btrfs_inode *inode,
17762306a36Sopenharmony_ci				    struct btrfs_ordered_extent **cached,
17862306a36Sopenharmony_ci				    u64 file_offset, u64 io_size);
17962306a36Sopenharmony_cistruct btrfs_ordered_extent *btrfs_alloc_ordered_extent(
18062306a36Sopenharmony_ci			struct btrfs_inode *inode, u64 file_offset,
18162306a36Sopenharmony_ci			u64 num_bytes, u64 ram_bytes, u64 disk_bytenr,
18262306a36Sopenharmony_ci			u64 disk_num_bytes, u64 offset, unsigned long flags,
18362306a36Sopenharmony_ci			int compress_type);
18462306a36Sopenharmony_civoid btrfs_add_ordered_sum(struct btrfs_ordered_extent *entry,
18562306a36Sopenharmony_ci			   struct btrfs_ordered_sum *sum);
18662306a36Sopenharmony_cistruct btrfs_ordered_extent *btrfs_lookup_ordered_extent(struct btrfs_inode *inode,
18762306a36Sopenharmony_ci							 u64 file_offset);
18862306a36Sopenharmony_civoid btrfs_start_ordered_extent(struct btrfs_ordered_extent *entry);
18962306a36Sopenharmony_ciint btrfs_wait_ordered_range(struct inode *inode, u64 start, u64 len);
19062306a36Sopenharmony_cistruct btrfs_ordered_extent *
19162306a36Sopenharmony_cibtrfs_lookup_first_ordered_extent(struct btrfs_inode *inode, u64 file_offset);
19262306a36Sopenharmony_cistruct btrfs_ordered_extent *btrfs_lookup_first_ordered_range(
19362306a36Sopenharmony_ci			struct btrfs_inode *inode, u64 file_offset, u64 len);
19462306a36Sopenharmony_cistruct btrfs_ordered_extent *btrfs_lookup_ordered_range(
19562306a36Sopenharmony_ci		struct btrfs_inode *inode,
19662306a36Sopenharmony_ci		u64 file_offset,
19762306a36Sopenharmony_ci		u64 len);
19862306a36Sopenharmony_civoid btrfs_get_ordered_extents_for_logging(struct btrfs_inode *inode,
19962306a36Sopenharmony_ci					   struct list_head *list);
20062306a36Sopenharmony_ciu64 btrfs_wait_ordered_extents(struct btrfs_root *root, u64 nr,
20162306a36Sopenharmony_ci			       const u64 range_start, const u64 range_len);
20262306a36Sopenharmony_civoid btrfs_wait_ordered_roots(struct btrfs_fs_info *fs_info, u64 nr,
20362306a36Sopenharmony_ci			      const u64 range_start, const u64 range_len);
20462306a36Sopenharmony_civoid btrfs_lock_and_flush_ordered_range(struct btrfs_inode *inode, u64 start,
20562306a36Sopenharmony_ci					u64 end,
20662306a36Sopenharmony_ci					struct extent_state **cached_state);
20762306a36Sopenharmony_cibool btrfs_try_lock_ordered_range(struct btrfs_inode *inode, u64 start, u64 end,
20862306a36Sopenharmony_ci				  struct extent_state **cached_state);
20962306a36Sopenharmony_cistruct btrfs_ordered_extent *btrfs_split_ordered_extent(
21062306a36Sopenharmony_ci			struct btrfs_ordered_extent *ordered, u64 len);
21162306a36Sopenharmony_ciint __init ordered_data_init(void);
21262306a36Sopenharmony_civoid __cold ordered_data_exit(void);
21362306a36Sopenharmony_ci
21462306a36Sopenharmony_ci#endif
215