#include <linux/pagemap.h>
#include <linux/sched.h>
#include <linux/sched/signal.h>
#include <linux/slab.h>
#include <linux/math64.h>
#include <linux/ratelimit.h>
#include <linux/error-injection.h>
#include <linux/sched/mm.h>
#include "ctree.h"
#include "fs.h"
#include "messages.h"
#include "misc.h"
#include "free-space-cache.h"
#include "transaction.h"
#include "disk-io.h"
#include "extent_io.h"
#include "space-info.h"
#include "block-group.h"
#include "discard.h"
#include "subpage.h"
#include "inode-item.h"
#include "accessors.h"
#include "file-item.h"
#include "file.h"
#include "super.h"
#define BITS_PER_BITMAP …
#define MAX_CACHE_BYTES_PER_GIG …
#define FORCE_EXTENT_THRESHOLD …
static struct kmem_cache *btrfs_free_space_cachep;
static struct kmem_cache *btrfs_free_space_bitmap_cachep;
struct btrfs_trim_range { … };
static int link_free_space(struct btrfs_free_space_ctl *ctl,
struct btrfs_free_space *info);
static void unlink_free_space(struct btrfs_free_space_ctl *ctl,
struct btrfs_free_space *info, bool update_stat);
static int search_bitmap(struct btrfs_free_space_ctl *ctl,
struct btrfs_free_space *bitmap_info, u64 *offset,
u64 *bytes, bool for_alloc);
static void free_bitmap(struct btrfs_free_space_ctl *ctl,
struct btrfs_free_space *bitmap_info);
static void bitmap_clear_bits(struct btrfs_free_space_ctl *ctl,
struct btrfs_free_space *info, u64 offset,
u64 bytes, bool update_stats);
static void btrfs_crc32c_final(u32 crc, u8 *result)
{ … }
static void __btrfs_remove_free_space_cache(struct btrfs_free_space_ctl *ctl)
{ … }
static struct inode *__lookup_free_space_inode(struct btrfs_root *root,
struct btrfs_path *path,
u64 offset)
{ … }
struct inode *lookup_free_space_inode(struct btrfs_block_group *block_group,
struct btrfs_path *path)
{ … }
static int __create_free_space_inode(struct btrfs_root *root,
struct btrfs_trans_handle *trans,
struct btrfs_path *path,
u64 ino, u64 offset)
{ … }
int create_free_space_inode(struct btrfs_trans_handle *trans,
struct btrfs_block_group *block_group,
struct btrfs_path *path)
{ … }
int btrfs_remove_free_space_inode(struct btrfs_trans_handle *trans,
struct inode *inode,
struct btrfs_block_group *block_group)
{ … }
int btrfs_truncate_free_space_cache(struct btrfs_trans_handle *trans,
struct btrfs_block_group *block_group,
struct inode *vfs_inode)
{ … }
static void readahead_cache(struct inode *inode)
{ … }
static int io_ctl_init(struct btrfs_io_ctl *io_ctl, struct inode *inode,
int write)
{ … }
ALLOW_ERROR_INJECTION(…);
static void io_ctl_free(struct btrfs_io_ctl *io_ctl)
{ … }
static void io_ctl_unmap_page(struct btrfs_io_ctl *io_ctl)
{ … }
static void io_ctl_map_page(struct btrfs_io_ctl *io_ctl, int clear)
{ … }
static void io_ctl_drop_pages(struct btrfs_io_ctl *io_ctl)
{ … }
static int io_ctl_prepare_pages(struct btrfs_io_ctl *io_ctl, bool uptodate)
{ … }
static void io_ctl_set_generation(struct btrfs_io_ctl *io_ctl, u64 generation)
{ … }
static int io_ctl_check_generation(struct btrfs_io_ctl *io_ctl, u64 generation)
{ … }
static void io_ctl_set_crc(struct btrfs_io_ctl *io_ctl, int index)
{ … }
static int io_ctl_check_crc(struct btrfs_io_ctl *io_ctl, int index)
{ … }
static int io_ctl_add_entry(struct btrfs_io_ctl *io_ctl, u64 offset, u64 bytes,
void *bitmap)
{ … }
static int io_ctl_add_bitmap(struct btrfs_io_ctl *io_ctl, void *bitmap)
{ … }
static void io_ctl_zero_remaining_pages(struct btrfs_io_ctl *io_ctl)
{ … }
static int io_ctl_read_entry(struct btrfs_io_ctl *io_ctl,
struct btrfs_free_space *entry, u8 *type)
{ … }
static int io_ctl_read_bitmap(struct btrfs_io_ctl *io_ctl,
struct btrfs_free_space *entry)
{ … }
static void recalculate_thresholds(struct btrfs_free_space_ctl *ctl)
{ … }
static int __load_free_space_cache(struct btrfs_root *root, struct inode *inode,
struct btrfs_free_space_ctl *ctl,
struct btrfs_path *path, u64 offset)
{ … }
static int copy_free_space_cache(struct btrfs_block_group *block_group,
struct btrfs_free_space_ctl *ctl)
{ … }
static struct lock_class_key btrfs_free_space_inode_key;
int load_free_space_cache(struct btrfs_block_group *block_group)
{ … }
static noinline_for_stack
int write_cache_extent_entries(struct btrfs_io_ctl *io_ctl,
struct btrfs_free_space_ctl *ctl,
struct btrfs_block_group *block_group,
int *entries, int *bitmaps,
struct list_head *bitmap_list)
{ … }
static noinline_for_stack int
update_cache_item(struct btrfs_trans_handle *trans,
struct btrfs_root *root,
struct inode *inode,
struct btrfs_path *path, u64 offset,
int entries, int bitmaps)
{ … }
static noinline_for_stack int write_pinned_extent_entries(
struct btrfs_trans_handle *trans,
struct btrfs_block_group *block_group,
struct btrfs_io_ctl *io_ctl,
int *entries)
{ … }
static noinline_for_stack int
write_bitmap_entries(struct btrfs_io_ctl *io_ctl, struct list_head *bitmap_list)
{ … }
static int flush_dirty_cache(struct inode *inode)
{ … }
static void noinline_for_stack
cleanup_bitmap_list(struct list_head *bitmap_list)
{ … }
static void noinline_for_stack
cleanup_write_cache_enospc(struct inode *inode,
struct btrfs_io_ctl *io_ctl,
struct extent_state **cached_state)
{ … }
static int __btrfs_wait_cache_io(struct btrfs_root *root,
struct btrfs_trans_handle *trans,
struct btrfs_block_group *block_group,
struct btrfs_io_ctl *io_ctl,
struct btrfs_path *path, u64 offset)
{ … }
int btrfs_wait_cache_io(struct btrfs_trans_handle *trans,
struct btrfs_block_group *block_group,
struct btrfs_path *path)
{ … }
static int __btrfs_write_out_cache(struct inode *inode,
struct btrfs_free_space_ctl *ctl,
struct btrfs_block_group *block_group,
struct btrfs_io_ctl *io_ctl,
struct btrfs_trans_handle *trans)
{ … }
int btrfs_write_out_cache(struct btrfs_trans_handle *trans,
struct btrfs_block_group *block_group,
struct btrfs_path *path)
{ … }
static inline unsigned long offset_to_bit(u64 bitmap_start, u32 unit,
u64 offset)
{ … }
static inline unsigned long bytes_to_bits(u64 bytes, u32 unit)
{ … }
static inline u64 offset_to_bitmap(struct btrfs_free_space_ctl *ctl,
u64 offset)
{ … }
static int tree_insert_offset(struct btrfs_free_space_ctl *ctl,
struct btrfs_free_cluster *cluster,
struct btrfs_free_space *new_entry)
{ … }
static inline u64 get_max_extent_size(const struct btrfs_free_space *entry)
{ … }
static bool entry_less(struct rb_node *node, const struct rb_node *parent)
{ … }
static struct btrfs_free_space *
tree_search_offset(struct btrfs_free_space_ctl *ctl,
u64 offset, int bitmap_only, int fuzzy)
{ … }
static inline void unlink_free_space(struct btrfs_free_space_ctl *ctl,
struct btrfs_free_space *info,
bool update_stat)
{ … }
static int link_free_space(struct btrfs_free_space_ctl *ctl,
struct btrfs_free_space *info)
{ … }
static void relink_bitmap_entry(struct btrfs_free_space_ctl *ctl,
struct btrfs_free_space *info)
{ … }
static inline void bitmap_clear_bits(struct btrfs_free_space_ctl *ctl,
struct btrfs_free_space *info,
u64 offset, u64 bytes, bool update_stat)
{ … }
static void btrfs_bitmap_set_bits(struct btrfs_free_space_ctl *ctl,
struct btrfs_free_space *info, u64 offset,
u64 bytes)
{ … }
static int search_bitmap(struct btrfs_free_space_ctl *ctl,
struct btrfs_free_space *bitmap_info, u64 *offset,
u64 *bytes, bool for_alloc)
{ … }
static struct btrfs_free_space *
find_free_space(struct btrfs_free_space_ctl *ctl, u64 *offset, u64 *bytes,
unsigned long align, u64 *max_extent_size, bool use_bytes_index)
{ … }
static void add_new_bitmap(struct btrfs_free_space_ctl *ctl,
struct btrfs_free_space *info, u64 offset)
{ … }
static void free_bitmap(struct btrfs_free_space_ctl *ctl,
struct btrfs_free_space *bitmap_info)
{ … }
static noinline int remove_from_bitmap(struct btrfs_free_space_ctl *ctl,
struct btrfs_free_space *bitmap_info,
u64 *offset, u64 *bytes)
{ … }
static u64 add_bytes_to_bitmap(struct btrfs_free_space_ctl *ctl,
struct btrfs_free_space *info, u64 offset,
u64 bytes, enum btrfs_trim_state trim_state)
{ … }
static bool use_bitmap(struct btrfs_free_space_ctl *ctl,
struct btrfs_free_space *info)
{ … }
static const struct btrfs_free_space_op free_space_op = …;
static int insert_into_bitmap(struct btrfs_free_space_ctl *ctl,
struct btrfs_free_space *info)
{ … }
static bool try_merge_free_space(struct btrfs_free_space_ctl *ctl,
struct btrfs_free_space *info, bool update_stat)
{ … }
static bool steal_from_bitmap_to_end(struct btrfs_free_space_ctl *ctl,
struct btrfs_free_space *info,
bool update_stat)
{ … }
static bool steal_from_bitmap_to_front(struct btrfs_free_space_ctl *ctl,
struct btrfs_free_space *info,
bool update_stat)
{ … }
static void steal_from_bitmap(struct btrfs_free_space_ctl *ctl,
struct btrfs_free_space *info,
bool update_stat)
{ … }
static int __btrfs_add_free_space(struct btrfs_block_group *block_group,
u64 offset, u64 bytes,
enum btrfs_trim_state trim_state)
{ … }
static int __btrfs_add_free_space_zoned(struct btrfs_block_group *block_group,
u64 bytenr, u64 size, bool used)
{ … }
int btrfs_add_free_space(struct btrfs_block_group *block_group,
u64 bytenr, u64 size)
{ … }
int btrfs_add_free_space_unused(struct btrfs_block_group *block_group,
u64 bytenr, u64 size)
{ … }
int btrfs_add_free_space_async_trimmed(struct btrfs_block_group *block_group,
u64 bytenr, u64 size)
{ … }
int btrfs_remove_free_space(struct btrfs_block_group *block_group,
u64 offset, u64 bytes)
{ … }
void btrfs_dump_free_space(struct btrfs_block_group *block_group,
u64 bytes)
{ … }
void btrfs_init_free_space_ctl(struct btrfs_block_group *block_group,
struct btrfs_free_space_ctl *ctl)
{ … }
static void __btrfs_return_cluster_to_free_space(
struct btrfs_block_group *block_group,
struct btrfs_free_cluster *cluster)
{ … }
void btrfs_remove_free_space_cache(struct btrfs_block_group *block_group)
{ … }
bool btrfs_is_free_space_trimmed(struct btrfs_block_group *block_group)
{ … }
u64 btrfs_find_space_for_alloc(struct btrfs_block_group *block_group,
u64 offset, u64 bytes, u64 empty_size,
u64 *max_extent_size)
{ … }
void btrfs_return_cluster_to_free_space(
struct btrfs_block_group *block_group,
struct btrfs_free_cluster *cluster)
{ … }
static u64 btrfs_alloc_from_bitmap(struct btrfs_block_group *block_group,
struct btrfs_free_cluster *cluster,
struct btrfs_free_space *entry,
u64 bytes, u64 min_start,
u64 *max_extent_size)
{ … }
u64 btrfs_alloc_from_cluster(struct btrfs_block_group *block_group,
struct btrfs_free_cluster *cluster, u64 bytes,
u64 min_start, u64 *max_extent_size)
{ … }
static int btrfs_bitmap_cluster(struct btrfs_block_group *block_group,
struct btrfs_free_space *entry,
struct btrfs_free_cluster *cluster,
u64 offset, u64 bytes,
u64 cont1_bytes, u64 min_bytes)
{ … }
static noinline int
setup_cluster_no_bitmap(struct btrfs_block_group *block_group,
struct btrfs_free_cluster *cluster,
struct list_head *bitmaps, u64 offset, u64 bytes,
u64 cont1_bytes, u64 min_bytes)
{ … }
static noinline int
setup_cluster_bitmap(struct btrfs_block_group *block_group,
struct btrfs_free_cluster *cluster,
struct list_head *bitmaps, u64 offset, u64 bytes,
u64 cont1_bytes, u64 min_bytes)
{ … }
int btrfs_find_space_cluster(struct btrfs_block_group *block_group,
struct btrfs_free_cluster *cluster,
u64 offset, u64 bytes, u64 empty_size)
{ … }
void btrfs_init_free_cluster(struct btrfs_free_cluster *cluster)
{ … }
static int do_trimming(struct btrfs_block_group *block_group,
u64 *total_trimmed, u64 start, u64 bytes,
u64 reserved_start, u64 reserved_bytes,
enum btrfs_trim_state reserved_trim_state,
struct btrfs_trim_range *trim_entry)
{ … }
static int trim_no_bitmap(struct btrfs_block_group *block_group,
u64 *total_trimmed, u64 start, u64 end, u64 minlen,
bool async)
{ … }
static void reset_trimming_bitmap(struct btrfs_free_space_ctl *ctl, u64 offset)
{ … }
static void end_trimming_bitmap(struct btrfs_free_space_ctl *ctl,
struct btrfs_free_space *entry)
{ … }
static int trim_bitmaps(struct btrfs_block_group *block_group,
u64 *total_trimmed, u64 start, u64 end, u64 minlen,
u64 maxlen, bool async)
{ … }
int btrfs_trim_block_group(struct btrfs_block_group *block_group,
u64 *trimmed, u64 start, u64 end, u64 minlen)
{ … }
int btrfs_trim_block_group_extents(struct btrfs_block_group *block_group,
u64 *trimmed, u64 start, u64 end, u64 minlen,
bool async)
{ … }
int btrfs_trim_block_group_bitmaps(struct btrfs_block_group *block_group,
u64 *trimmed, u64 start, u64 end, u64 minlen,
u64 maxlen, bool async)
{ … }
bool btrfs_free_space_cache_v1_active(struct btrfs_fs_info *fs_info)
{ … }
static int cleanup_free_space_cache_v1(struct btrfs_fs_info *fs_info,
struct btrfs_trans_handle *trans)
{ … }
int btrfs_set_free_space_cache_v1_active(struct btrfs_fs_info *fs_info, bool active)
{ … }
int __init btrfs_free_space_init(void)
{ … }
void __cold btrfs_free_space_exit(void)
{ … }
#ifdef CONFIG_BTRFS_FS_RUN_SANITY_TESTS
int test_add_free_space_entry(struct btrfs_block_group *cache,
u64 offset, u64 bytes, bool bitmap)
{ … }
int test_check_exists(struct btrfs_block_group *cache,
u64 offset, u64 bytes)
{ … }
#endif