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