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