18c2ecf20Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0 */ 28c2ecf20Sopenharmony_ci/* 38c2ecf20Sopenharmony_ci * Copyright (C) 2009 Oracle. All rights reserved. 48c2ecf20Sopenharmony_ci */ 58c2ecf20Sopenharmony_ci 68c2ecf20Sopenharmony_ci#ifndef BTRFS_FREE_SPACE_CACHE_H 78c2ecf20Sopenharmony_ci#define BTRFS_FREE_SPACE_CACHE_H 88c2ecf20Sopenharmony_ci 98c2ecf20Sopenharmony_ci/* 108c2ecf20Sopenharmony_ci * This is the trim state of an extent or bitmap. 118c2ecf20Sopenharmony_ci * 128c2ecf20Sopenharmony_ci * BTRFS_TRIM_STATE_TRIMMING is special and used to maintain the state of a 138c2ecf20Sopenharmony_ci * bitmap as we may need several trims to fully trim a single bitmap entry. 148c2ecf20Sopenharmony_ci * This is reset should any free space other than trimmed space be added to the 158c2ecf20Sopenharmony_ci * bitmap. 168c2ecf20Sopenharmony_ci */ 178c2ecf20Sopenharmony_cienum btrfs_trim_state { 188c2ecf20Sopenharmony_ci BTRFS_TRIM_STATE_UNTRIMMED, 198c2ecf20Sopenharmony_ci BTRFS_TRIM_STATE_TRIMMED, 208c2ecf20Sopenharmony_ci BTRFS_TRIM_STATE_TRIMMING, 218c2ecf20Sopenharmony_ci}; 228c2ecf20Sopenharmony_ci 238c2ecf20Sopenharmony_cistruct btrfs_free_space { 248c2ecf20Sopenharmony_ci struct rb_node offset_index; 258c2ecf20Sopenharmony_ci u64 offset; 268c2ecf20Sopenharmony_ci u64 bytes; 278c2ecf20Sopenharmony_ci u64 max_extent_size; 288c2ecf20Sopenharmony_ci unsigned long *bitmap; 298c2ecf20Sopenharmony_ci struct list_head list; 308c2ecf20Sopenharmony_ci enum btrfs_trim_state trim_state; 318c2ecf20Sopenharmony_ci s32 bitmap_extents; 328c2ecf20Sopenharmony_ci}; 338c2ecf20Sopenharmony_ci 348c2ecf20Sopenharmony_cistatic inline bool btrfs_free_space_trimmed(struct btrfs_free_space *info) 358c2ecf20Sopenharmony_ci{ 368c2ecf20Sopenharmony_ci return (info->trim_state == BTRFS_TRIM_STATE_TRIMMED); 378c2ecf20Sopenharmony_ci} 388c2ecf20Sopenharmony_ci 398c2ecf20Sopenharmony_cistatic inline bool btrfs_free_space_trimming_bitmap( 408c2ecf20Sopenharmony_ci struct btrfs_free_space *info) 418c2ecf20Sopenharmony_ci{ 428c2ecf20Sopenharmony_ci return (info->trim_state == BTRFS_TRIM_STATE_TRIMMING); 438c2ecf20Sopenharmony_ci} 448c2ecf20Sopenharmony_ci 458c2ecf20Sopenharmony_cistruct btrfs_free_space_ctl { 468c2ecf20Sopenharmony_ci spinlock_t tree_lock; 478c2ecf20Sopenharmony_ci struct rb_root free_space_offset; 488c2ecf20Sopenharmony_ci u64 free_space; 498c2ecf20Sopenharmony_ci int extents_thresh; 508c2ecf20Sopenharmony_ci int free_extents; 518c2ecf20Sopenharmony_ci int total_bitmaps; 528c2ecf20Sopenharmony_ci int unit; 538c2ecf20Sopenharmony_ci u64 start; 548c2ecf20Sopenharmony_ci s32 discardable_extents[BTRFS_STAT_NR_ENTRIES]; 558c2ecf20Sopenharmony_ci s64 discardable_bytes[BTRFS_STAT_NR_ENTRIES]; 568c2ecf20Sopenharmony_ci const struct btrfs_free_space_op *op; 578c2ecf20Sopenharmony_ci void *private; 588c2ecf20Sopenharmony_ci struct mutex cache_writeout_mutex; 598c2ecf20Sopenharmony_ci struct list_head trimming_ranges; 608c2ecf20Sopenharmony_ci}; 618c2ecf20Sopenharmony_ci 628c2ecf20Sopenharmony_cistruct btrfs_free_space_op { 638c2ecf20Sopenharmony_ci void (*recalc_thresholds)(struct btrfs_free_space_ctl *ctl); 648c2ecf20Sopenharmony_ci bool (*use_bitmap)(struct btrfs_free_space_ctl *ctl, 658c2ecf20Sopenharmony_ci struct btrfs_free_space *info); 668c2ecf20Sopenharmony_ci}; 678c2ecf20Sopenharmony_ci 688c2ecf20Sopenharmony_cistruct btrfs_io_ctl { 698c2ecf20Sopenharmony_ci void *cur, *orig; 708c2ecf20Sopenharmony_ci struct page *page; 718c2ecf20Sopenharmony_ci struct page **pages; 728c2ecf20Sopenharmony_ci struct btrfs_fs_info *fs_info; 738c2ecf20Sopenharmony_ci struct inode *inode; 748c2ecf20Sopenharmony_ci unsigned long size; 758c2ecf20Sopenharmony_ci int index; 768c2ecf20Sopenharmony_ci int num_pages; 778c2ecf20Sopenharmony_ci int entries; 788c2ecf20Sopenharmony_ci int bitmaps; 798c2ecf20Sopenharmony_ci unsigned check_crcs:1; 808c2ecf20Sopenharmony_ci}; 818c2ecf20Sopenharmony_ci 828c2ecf20Sopenharmony_cistruct inode *lookup_free_space_inode(struct btrfs_block_group *block_group, 838c2ecf20Sopenharmony_ci struct btrfs_path *path); 848c2ecf20Sopenharmony_ciint create_free_space_inode(struct btrfs_trans_handle *trans, 858c2ecf20Sopenharmony_ci struct btrfs_block_group *block_group, 868c2ecf20Sopenharmony_ci struct btrfs_path *path); 878c2ecf20Sopenharmony_ci 888c2ecf20Sopenharmony_ciint btrfs_check_trunc_cache_free_space(struct btrfs_fs_info *fs_info, 898c2ecf20Sopenharmony_ci struct btrfs_block_rsv *rsv); 908c2ecf20Sopenharmony_ciint btrfs_truncate_free_space_cache(struct btrfs_trans_handle *trans, 918c2ecf20Sopenharmony_ci struct btrfs_block_group *block_group, 928c2ecf20Sopenharmony_ci struct inode *inode); 938c2ecf20Sopenharmony_ciint load_free_space_cache(struct btrfs_block_group *block_group); 948c2ecf20Sopenharmony_ciint btrfs_wait_cache_io(struct btrfs_trans_handle *trans, 958c2ecf20Sopenharmony_ci struct btrfs_block_group *block_group, 968c2ecf20Sopenharmony_ci struct btrfs_path *path); 978c2ecf20Sopenharmony_ciint btrfs_write_out_cache(struct btrfs_trans_handle *trans, 988c2ecf20Sopenharmony_ci struct btrfs_block_group *block_group, 998c2ecf20Sopenharmony_ci struct btrfs_path *path); 1008c2ecf20Sopenharmony_cistruct inode *lookup_free_ino_inode(struct btrfs_root *root, 1018c2ecf20Sopenharmony_ci struct btrfs_path *path); 1028c2ecf20Sopenharmony_ciint create_free_ino_inode(struct btrfs_root *root, 1038c2ecf20Sopenharmony_ci struct btrfs_trans_handle *trans, 1048c2ecf20Sopenharmony_ci struct btrfs_path *path); 1058c2ecf20Sopenharmony_ciint load_free_ino_cache(struct btrfs_fs_info *fs_info, 1068c2ecf20Sopenharmony_ci struct btrfs_root *root); 1078c2ecf20Sopenharmony_ciint btrfs_write_out_ino_cache(struct btrfs_root *root, 1088c2ecf20Sopenharmony_ci struct btrfs_trans_handle *trans, 1098c2ecf20Sopenharmony_ci struct btrfs_path *path, 1108c2ecf20Sopenharmony_ci struct inode *inode); 1118c2ecf20Sopenharmony_ci 1128c2ecf20Sopenharmony_civoid btrfs_init_free_space_ctl(struct btrfs_block_group *block_group); 1138c2ecf20Sopenharmony_ciint __btrfs_add_free_space(struct btrfs_fs_info *fs_info, 1148c2ecf20Sopenharmony_ci struct btrfs_free_space_ctl *ctl, 1158c2ecf20Sopenharmony_ci u64 bytenr, u64 size, 1168c2ecf20Sopenharmony_ci enum btrfs_trim_state trim_state); 1178c2ecf20Sopenharmony_ciint btrfs_add_free_space(struct btrfs_block_group *block_group, 1188c2ecf20Sopenharmony_ci u64 bytenr, u64 size); 1198c2ecf20Sopenharmony_ciint btrfs_add_free_space_async_trimmed(struct btrfs_block_group *block_group, 1208c2ecf20Sopenharmony_ci u64 bytenr, u64 size); 1218c2ecf20Sopenharmony_ciint btrfs_remove_free_space(struct btrfs_block_group *block_group, 1228c2ecf20Sopenharmony_ci u64 bytenr, u64 size); 1238c2ecf20Sopenharmony_civoid __btrfs_remove_free_space_cache(struct btrfs_free_space_ctl *ctl); 1248c2ecf20Sopenharmony_civoid btrfs_remove_free_space_cache(struct btrfs_block_group *block_group); 1258c2ecf20Sopenharmony_cibool btrfs_is_free_space_trimmed(struct btrfs_block_group *block_group); 1268c2ecf20Sopenharmony_ciu64 btrfs_find_space_for_alloc(struct btrfs_block_group *block_group, 1278c2ecf20Sopenharmony_ci u64 offset, u64 bytes, u64 empty_size, 1288c2ecf20Sopenharmony_ci u64 *max_extent_size); 1298c2ecf20Sopenharmony_ciu64 btrfs_find_ino_for_alloc(struct btrfs_root *fs_root); 1308c2ecf20Sopenharmony_civoid btrfs_dump_free_space(struct btrfs_block_group *block_group, 1318c2ecf20Sopenharmony_ci u64 bytes); 1328c2ecf20Sopenharmony_ciint btrfs_find_space_cluster(struct btrfs_block_group *block_group, 1338c2ecf20Sopenharmony_ci struct btrfs_free_cluster *cluster, 1348c2ecf20Sopenharmony_ci u64 offset, u64 bytes, u64 empty_size); 1358c2ecf20Sopenharmony_civoid btrfs_init_free_cluster(struct btrfs_free_cluster *cluster); 1368c2ecf20Sopenharmony_ciu64 btrfs_alloc_from_cluster(struct btrfs_block_group *block_group, 1378c2ecf20Sopenharmony_ci struct btrfs_free_cluster *cluster, u64 bytes, 1388c2ecf20Sopenharmony_ci u64 min_start, u64 *max_extent_size); 1398c2ecf20Sopenharmony_civoid btrfs_return_cluster_to_free_space( 1408c2ecf20Sopenharmony_ci struct btrfs_block_group *block_group, 1418c2ecf20Sopenharmony_ci struct btrfs_free_cluster *cluster); 1428c2ecf20Sopenharmony_ciint btrfs_trim_block_group(struct btrfs_block_group *block_group, 1438c2ecf20Sopenharmony_ci u64 *trimmed, u64 start, u64 end, u64 minlen); 1448c2ecf20Sopenharmony_ciint btrfs_trim_block_group_extents(struct btrfs_block_group *block_group, 1458c2ecf20Sopenharmony_ci u64 *trimmed, u64 start, u64 end, u64 minlen, 1468c2ecf20Sopenharmony_ci bool async); 1478c2ecf20Sopenharmony_ciint btrfs_trim_block_group_bitmaps(struct btrfs_block_group *block_group, 1488c2ecf20Sopenharmony_ci u64 *trimmed, u64 start, u64 end, u64 minlen, 1498c2ecf20Sopenharmony_ci u64 maxlen, bool async); 1508c2ecf20Sopenharmony_ci 1518c2ecf20Sopenharmony_ci/* Support functions for running our sanity tests */ 1528c2ecf20Sopenharmony_ci#ifdef CONFIG_BTRFS_FS_RUN_SANITY_TESTS 1538c2ecf20Sopenharmony_ciint test_add_free_space_entry(struct btrfs_block_group *cache, 1548c2ecf20Sopenharmony_ci u64 offset, u64 bytes, bool bitmap); 1558c2ecf20Sopenharmony_ciint test_check_exists(struct btrfs_block_group *cache, u64 offset, u64 bytes); 1568c2ecf20Sopenharmony_ci#endif 1578c2ecf20Sopenharmony_ci 1588c2ecf20Sopenharmony_ci#endif 159