162306a36Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0 */ 262306a36Sopenharmony_ci/* 362306a36Sopenharmony_ci * Copyright (C) 2009 Oracle. All rights reserved. 462306a36Sopenharmony_ci */ 562306a36Sopenharmony_ci 662306a36Sopenharmony_ci#ifndef BTRFS_FREE_SPACE_CACHE_H 762306a36Sopenharmony_ci#define BTRFS_FREE_SPACE_CACHE_H 862306a36Sopenharmony_ci 962306a36Sopenharmony_ci/* 1062306a36Sopenharmony_ci * This is the trim state of an extent or bitmap. 1162306a36Sopenharmony_ci * 1262306a36Sopenharmony_ci * BTRFS_TRIM_STATE_TRIMMING is special and used to maintain the state of a 1362306a36Sopenharmony_ci * bitmap as we may need several trims to fully trim a single bitmap entry. 1462306a36Sopenharmony_ci * This is reset should any free space other than trimmed space be added to the 1562306a36Sopenharmony_ci * bitmap. 1662306a36Sopenharmony_ci */ 1762306a36Sopenharmony_cienum btrfs_trim_state { 1862306a36Sopenharmony_ci BTRFS_TRIM_STATE_UNTRIMMED, 1962306a36Sopenharmony_ci BTRFS_TRIM_STATE_TRIMMED, 2062306a36Sopenharmony_ci BTRFS_TRIM_STATE_TRIMMING, 2162306a36Sopenharmony_ci}; 2262306a36Sopenharmony_ci 2362306a36Sopenharmony_cistruct btrfs_free_space { 2462306a36Sopenharmony_ci struct rb_node offset_index; 2562306a36Sopenharmony_ci struct rb_node bytes_index; 2662306a36Sopenharmony_ci u64 offset; 2762306a36Sopenharmony_ci u64 bytes; 2862306a36Sopenharmony_ci u64 max_extent_size; 2962306a36Sopenharmony_ci unsigned long *bitmap; 3062306a36Sopenharmony_ci struct list_head list; 3162306a36Sopenharmony_ci enum btrfs_trim_state trim_state; 3262306a36Sopenharmony_ci s32 bitmap_extents; 3362306a36Sopenharmony_ci}; 3462306a36Sopenharmony_ci 3562306a36Sopenharmony_cistatic inline bool btrfs_free_space_trimmed(struct btrfs_free_space *info) 3662306a36Sopenharmony_ci{ 3762306a36Sopenharmony_ci return (info->trim_state == BTRFS_TRIM_STATE_TRIMMED); 3862306a36Sopenharmony_ci} 3962306a36Sopenharmony_ci 4062306a36Sopenharmony_cistatic inline bool btrfs_free_space_trimming_bitmap( 4162306a36Sopenharmony_ci struct btrfs_free_space *info) 4262306a36Sopenharmony_ci{ 4362306a36Sopenharmony_ci return (info->trim_state == BTRFS_TRIM_STATE_TRIMMING); 4462306a36Sopenharmony_ci} 4562306a36Sopenharmony_ci 4662306a36Sopenharmony_ci/* 4762306a36Sopenharmony_ci * Deltas are an effective way to populate global statistics. Give macro names 4862306a36Sopenharmony_ci * to make it clear what we're doing. An example is discard_extents in 4962306a36Sopenharmony_ci * btrfs_free_space_ctl. 5062306a36Sopenharmony_ci */ 5162306a36Sopenharmony_cienum { 5262306a36Sopenharmony_ci BTRFS_STAT_CURR, 5362306a36Sopenharmony_ci BTRFS_STAT_PREV, 5462306a36Sopenharmony_ci BTRFS_STAT_NR_ENTRIES, 5562306a36Sopenharmony_ci}; 5662306a36Sopenharmony_ci 5762306a36Sopenharmony_cistruct btrfs_free_space_ctl { 5862306a36Sopenharmony_ci spinlock_t tree_lock; 5962306a36Sopenharmony_ci struct rb_root free_space_offset; 6062306a36Sopenharmony_ci struct rb_root_cached free_space_bytes; 6162306a36Sopenharmony_ci u64 free_space; 6262306a36Sopenharmony_ci int extents_thresh; 6362306a36Sopenharmony_ci int free_extents; 6462306a36Sopenharmony_ci int total_bitmaps; 6562306a36Sopenharmony_ci int unit; 6662306a36Sopenharmony_ci u64 start; 6762306a36Sopenharmony_ci s32 discardable_extents[BTRFS_STAT_NR_ENTRIES]; 6862306a36Sopenharmony_ci s64 discardable_bytes[BTRFS_STAT_NR_ENTRIES]; 6962306a36Sopenharmony_ci const struct btrfs_free_space_op *op; 7062306a36Sopenharmony_ci struct btrfs_block_group *block_group; 7162306a36Sopenharmony_ci struct mutex cache_writeout_mutex; 7262306a36Sopenharmony_ci struct list_head trimming_ranges; 7362306a36Sopenharmony_ci}; 7462306a36Sopenharmony_ci 7562306a36Sopenharmony_cistruct btrfs_free_space_op { 7662306a36Sopenharmony_ci bool (*use_bitmap)(struct btrfs_free_space_ctl *ctl, 7762306a36Sopenharmony_ci struct btrfs_free_space *info); 7862306a36Sopenharmony_ci}; 7962306a36Sopenharmony_ci 8062306a36Sopenharmony_cistruct btrfs_io_ctl { 8162306a36Sopenharmony_ci void *cur, *orig; 8262306a36Sopenharmony_ci struct page *page; 8362306a36Sopenharmony_ci struct page **pages; 8462306a36Sopenharmony_ci struct btrfs_fs_info *fs_info; 8562306a36Sopenharmony_ci struct inode *inode; 8662306a36Sopenharmony_ci unsigned long size; 8762306a36Sopenharmony_ci int index; 8862306a36Sopenharmony_ci int num_pages; 8962306a36Sopenharmony_ci int entries; 9062306a36Sopenharmony_ci int bitmaps; 9162306a36Sopenharmony_ci}; 9262306a36Sopenharmony_ci 9362306a36Sopenharmony_ciint __init btrfs_free_space_init(void); 9462306a36Sopenharmony_civoid __cold btrfs_free_space_exit(void); 9562306a36Sopenharmony_cistruct inode *lookup_free_space_inode(struct btrfs_block_group *block_group, 9662306a36Sopenharmony_ci struct btrfs_path *path); 9762306a36Sopenharmony_ciint create_free_space_inode(struct btrfs_trans_handle *trans, 9862306a36Sopenharmony_ci struct btrfs_block_group *block_group, 9962306a36Sopenharmony_ci struct btrfs_path *path); 10062306a36Sopenharmony_ciint btrfs_remove_free_space_inode(struct btrfs_trans_handle *trans, 10162306a36Sopenharmony_ci struct inode *inode, 10262306a36Sopenharmony_ci struct btrfs_block_group *block_group); 10362306a36Sopenharmony_ci 10462306a36Sopenharmony_ciint btrfs_truncate_free_space_cache(struct btrfs_trans_handle *trans, 10562306a36Sopenharmony_ci struct btrfs_block_group *block_group, 10662306a36Sopenharmony_ci struct inode *inode); 10762306a36Sopenharmony_ciint load_free_space_cache(struct btrfs_block_group *block_group); 10862306a36Sopenharmony_ciint btrfs_wait_cache_io(struct btrfs_trans_handle *trans, 10962306a36Sopenharmony_ci struct btrfs_block_group *block_group, 11062306a36Sopenharmony_ci struct btrfs_path *path); 11162306a36Sopenharmony_ciint btrfs_write_out_cache(struct btrfs_trans_handle *trans, 11262306a36Sopenharmony_ci struct btrfs_block_group *block_group, 11362306a36Sopenharmony_ci struct btrfs_path *path); 11462306a36Sopenharmony_ci 11562306a36Sopenharmony_civoid btrfs_init_free_space_ctl(struct btrfs_block_group *block_group, 11662306a36Sopenharmony_ci struct btrfs_free_space_ctl *ctl); 11762306a36Sopenharmony_ciint __btrfs_add_free_space(struct btrfs_block_group *block_group, u64 bytenr, 11862306a36Sopenharmony_ci u64 size, enum btrfs_trim_state trim_state); 11962306a36Sopenharmony_ciint btrfs_add_free_space(struct btrfs_block_group *block_group, 12062306a36Sopenharmony_ci u64 bytenr, u64 size); 12162306a36Sopenharmony_ciint btrfs_add_free_space_unused(struct btrfs_block_group *block_group, 12262306a36Sopenharmony_ci u64 bytenr, u64 size); 12362306a36Sopenharmony_ciint btrfs_add_free_space_async_trimmed(struct btrfs_block_group *block_group, 12462306a36Sopenharmony_ci u64 bytenr, u64 size); 12562306a36Sopenharmony_ciint btrfs_remove_free_space(struct btrfs_block_group *block_group, 12662306a36Sopenharmony_ci u64 bytenr, u64 size); 12762306a36Sopenharmony_civoid btrfs_remove_free_space_cache(struct btrfs_block_group *block_group); 12862306a36Sopenharmony_cibool btrfs_is_free_space_trimmed(struct btrfs_block_group *block_group); 12962306a36Sopenharmony_ciu64 btrfs_find_space_for_alloc(struct btrfs_block_group *block_group, 13062306a36Sopenharmony_ci u64 offset, u64 bytes, u64 empty_size, 13162306a36Sopenharmony_ci u64 *max_extent_size); 13262306a36Sopenharmony_civoid btrfs_dump_free_space(struct btrfs_block_group *block_group, 13362306a36Sopenharmony_ci u64 bytes); 13462306a36Sopenharmony_ciint btrfs_find_space_cluster(struct btrfs_block_group *block_group, 13562306a36Sopenharmony_ci struct btrfs_free_cluster *cluster, 13662306a36Sopenharmony_ci u64 offset, u64 bytes, u64 empty_size); 13762306a36Sopenharmony_civoid btrfs_init_free_cluster(struct btrfs_free_cluster *cluster); 13862306a36Sopenharmony_ciu64 btrfs_alloc_from_cluster(struct btrfs_block_group *block_group, 13962306a36Sopenharmony_ci struct btrfs_free_cluster *cluster, u64 bytes, 14062306a36Sopenharmony_ci u64 min_start, u64 *max_extent_size); 14162306a36Sopenharmony_civoid btrfs_return_cluster_to_free_space( 14262306a36Sopenharmony_ci struct btrfs_block_group *block_group, 14362306a36Sopenharmony_ci struct btrfs_free_cluster *cluster); 14462306a36Sopenharmony_ciint btrfs_trim_block_group(struct btrfs_block_group *block_group, 14562306a36Sopenharmony_ci u64 *trimmed, u64 start, u64 end, u64 minlen); 14662306a36Sopenharmony_ciint btrfs_trim_block_group_extents(struct btrfs_block_group *block_group, 14762306a36Sopenharmony_ci u64 *trimmed, u64 start, u64 end, u64 minlen, 14862306a36Sopenharmony_ci bool async); 14962306a36Sopenharmony_ciint btrfs_trim_block_group_bitmaps(struct btrfs_block_group *block_group, 15062306a36Sopenharmony_ci u64 *trimmed, u64 start, u64 end, u64 minlen, 15162306a36Sopenharmony_ci u64 maxlen, bool async); 15262306a36Sopenharmony_ci 15362306a36Sopenharmony_cibool btrfs_free_space_cache_v1_active(struct btrfs_fs_info *fs_info); 15462306a36Sopenharmony_ciint btrfs_set_free_space_cache_v1_active(struct btrfs_fs_info *fs_info, bool active); 15562306a36Sopenharmony_ci/* Support functions for running our sanity tests */ 15662306a36Sopenharmony_ci#ifdef CONFIG_BTRFS_FS_RUN_SANITY_TESTS 15762306a36Sopenharmony_ciint test_add_free_space_entry(struct btrfs_block_group *cache, 15862306a36Sopenharmony_ci u64 offset, u64 bytes, bool bitmap); 15962306a36Sopenharmony_ciint test_check_exists(struct btrfs_block_group *cache, u64 offset, u64 bytes); 16062306a36Sopenharmony_ci#endif 16162306a36Sopenharmony_ci 16262306a36Sopenharmony_ci#endif 163