#include <linux/sched.h>
#include <linux/pagemap.h>
#include <linux/writeback.h>
#include <linux/blkdev.h>
#include <linux/rbtree.h>
#include <linux/slab.h>
#include <linux/error-injection.h>
#include "ctree.h"
#include "disk-io.h"
#include "transaction.h"
#include "volumes.h"
#include "locking.h"
#include "btrfs_inode.h"
#include "async-thread.h"
#include "free-space-cache.h"
#include "qgroup.h"
#include "print-tree.h"
#include "delalloc-space.h"
#include "block-group.h"
#include "backref.h"
#include "misc.h"
#include "subpage.h"
#include "zoned.h"
#include "inode-item.h"
#include "space-info.h"
#include "fs.h"
#include "accessors.h"
#include "extent-tree.h"
#include "root-tree.h"
#include "file-item.h"
#include "relocation.h"
#include "super.h"
#include "tree-checker.h"
#define RELOCATION_RESERVED_NODES …
struct mapping_node { … };
struct mapping_tree { … };
struct tree_block { … };
#define MAX_EXTENTS …
struct file_extent_cluster { … };
enum reloc_stage { … };
struct reloc_control { … };
static void mark_block_processed(struct reloc_control *rc,
struct btrfs_backref_node *node)
{ … }
static struct btrfs_backref_node *walk_up_backref(
struct btrfs_backref_node *node,
struct btrfs_backref_edge *edges[], int *index)
{ … }
static struct btrfs_backref_node *walk_down_backref(
struct btrfs_backref_edge *edges[], int *index)
{ … }
static void update_backref_node(struct btrfs_backref_cache *cache,
struct btrfs_backref_node *node, u64 bytenr)
{ … }
static int update_backref_cache(struct btrfs_trans_handle *trans,
struct btrfs_backref_cache *cache)
{ … }
static bool reloc_root_is_dead(const struct btrfs_root *root)
{ … }
static bool have_reloc_root(const struct btrfs_root *root)
{ … }
bool btrfs_should_ignore_reloc_root(const struct btrfs_root *root)
{ … }
struct btrfs_root *find_reloc_root(struct btrfs_fs_info *fs_info, u64 bytenr)
{ … }
static bool handle_useless_nodes(struct reloc_control *rc,
struct btrfs_backref_node *node)
{ … }
static noinline_for_stack struct btrfs_backref_node *build_backref_tree(
struct btrfs_trans_handle *trans,
struct reloc_control *rc, struct btrfs_key *node_key,
int level, u64 bytenr)
{ … }
static int clone_backref_node(struct btrfs_trans_handle *trans,
struct reloc_control *rc,
const struct btrfs_root *src,
struct btrfs_root *dest)
{ … }
static int __add_reloc_root(struct btrfs_root *root)
{ … }
static void __del_reloc_root(struct btrfs_root *root)
{ … }
static int __update_reloc_root(struct btrfs_root *root)
{ … }
static struct btrfs_root *create_reloc_root(struct btrfs_trans_handle *trans,
struct btrfs_root *root, u64 objectid)
{ … }
int btrfs_init_reloc_root(struct btrfs_trans_handle *trans,
struct btrfs_root *root)
{ … }
int btrfs_update_reloc_root(struct btrfs_trans_handle *trans,
struct btrfs_root *root)
{ … }
static int get_new_location(struct inode *reloc_inode, u64 *new_bytenr,
u64 bytenr, u64 num_bytes)
{ … }
static noinline_for_stack
int replace_file_extents(struct btrfs_trans_handle *trans,
struct reloc_control *rc,
struct btrfs_root *root,
struct extent_buffer *leaf)
{ … }
static noinline_for_stack int memcmp_node_keys(const struct extent_buffer *eb,
int slot, const struct btrfs_path *path,
int level)
{ … }
static noinline_for_stack
int replace_path(struct btrfs_trans_handle *trans, struct reloc_control *rc,
struct btrfs_root *dest, struct btrfs_root *src,
struct btrfs_path *path, struct btrfs_key *next_key,
int lowest_level, int max_level)
{ … }
static noinline_for_stack
int walk_up_reloc_tree(struct btrfs_root *root, struct btrfs_path *path,
int *level)
{ … }
static noinline_for_stack
int walk_down_reloc_tree(struct btrfs_root *root, struct btrfs_path *path,
int *level)
{ … }
static int invalidate_extent_cache(struct btrfs_root *root,
const struct btrfs_key *min_key,
const struct btrfs_key *max_key)
{ … }
static int find_next_key(struct btrfs_path *path, int level,
struct btrfs_key *key)
{ … }
static int insert_dirty_subvol(struct btrfs_trans_handle *trans,
struct reloc_control *rc,
struct btrfs_root *root)
{ … }
static int clean_dirty_subvols(struct reloc_control *rc)
{ … }
static noinline_for_stack int merge_reloc_root(struct reloc_control *rc,
struct btrfs_root *root)
{ … }
static noinline_for_stack
int prepare_to_merge(struct reloc_control *rc, int err)
{ … }
static noinline_for_stack
void free_reloc_roots(struct list_head *list)
{ … }
static noinline_for_stack
void merge_reloc_roots(struct reloc_control *rc)
{ … }
static void free_block_list(struct rb_root *blocks)
{ … }
static int record_reloc_root_in_trans(struct btrfs_trans_handle *trans,
struct btrfs_root *reloc_root)
{ … }
static noinline_for_stack
struct btrfs_root *select_reloc_root(struct btrfs_trans_handle *trans,
struct reloc_control *rc,
struct btrfs_backref_node *node,
struct btrfs_backref_edge *edges[])
{ … }
static noinline_for_stack
struct btrfs_root *select_one_root(struct btrfs_backref_node *node)
{ … }
static noinline_for_stack u64 calcu_metadata_size(struct reloc_control *rc,
struct btrfs_backref_node *node)
{ … }
static int reserve_metadata_space(struct btrfs_trans_handle *trans,
struct reloc_control *rc,
struct btrfs_backref_node *node)
{ … }
static int do_relocation(struct btrfs_trans_handle *trans,
struct reloc_control *rc,
struct btrfs_backref_node *node,
struct btrfs_key *key,
struct btrfs_path *path, int lowest)
{ … }
static int link_to_upper(struct btrfs_trans_handle *trans,
struct reloc_control *rc,
struct btrfs_backref_node *node,
struct btrfs_path *path)
{ … }
static int finish_pending_nodes(struct btrfs_trans_handle *trans,
struct reloc_control *rc,
struct btrfs_path *path, int err)
{ … }
static void update_processed_blocks(struct reloc_control *rc,
struct btrfs_backref_node *node)
{ … }
static int tree_block_processed(u64 bytenr, struct reloc_control *rc)
{ … }
static int get_tree_block_key(struct btrfs_fs_info *fs_info,
struct tree_block *block)
{ … }
static int relocate_tree_block(struct btrfs_trans_handle *trans,
struct reloc_control *rc,
struct btrfs_backref_node *node,
struct btrfs_key *key,
struct btrfs_path *path)
{ … }
static noinline_for_stack
int relocate_tree_blocks(struct btrfs_trans_handle *trans,
struct reloc_control *rc, struct rb_root *blocks)
{ … }
static noinline_for_stack int prealloc_file_extent_cluster(struct reloc_control *rc)
{ … }
static noinline_for_stack int setup_relocation_extent_mapping(struct reloc_control *rc)
{ … }
noinline int btrfs_should_cancel_balance(const struct btrfs_fs_info *fs_info)
{ … }
ALLOW_ERROR_INJECTION(…);
static u64 get_cluster_boundary_end(const struct file_extent_cluster *cluster,
int cluster_nr)
{ … }
static int relocate_one_folio(struct reloc_control *rc,
struct file_ra_state *ra,
int *cluster_nr, unsigned long index)
{ … }
static int relocate_file_extent_cluster(struct reloc_control *rc)
{ … }
static noinline_for_stack int relocate_data_extent(struct reloc_control *rc,
const struct btrfs_key *extent_key)
{ … }
static int add_tree_block(struct reloc_control *rc,
const struct btrfs_key *extent_key,
struct btrfs_path *path,
struct rb_root *blocks)
{ … }
static int __add_tree_block(struct reloc_control *rc,
u64 bytenr, u32 blocksize,
struct rb_root *blocks)
{ … }
static int delete_block_group_cache(struct btrfs_fs_info *fs_info,
struct btrfs_block_group *block_group,
struct inode *inode,
u64 ino)
{ … }
static int delete_v1_space_cache(struct extent_buffer *leaf,
struct btrfs_block_group *block_group,
u64 data_bytenr)
{ … }
static noinline_for_stack int add_data_references(struct reloc_control *rc,
const struct btrfs_key *extent_key,
struct btrfs_path *path,
struct rb_root *blocks)
{ … }
static noinline_for_stack
int find_next_extent(struct reloc_control *rc, struct btrfs_path *path,
struct btrfs_key *extent_key)
{ … }
static void set_reloc_control(struct reloc_control *rc)
{ … }
static void unset_reloc_control(struct reloc_control *rc)
{ … }
static noinline_for_stack
int prepare_to_relocate(struct reloc_control *rc)
{ … }
static noinline_for_stack int relocate_block_group(struct reloc_control *rc)
{ … }
static int __insert_orphan_inode(struct btrfs_trans_handle *trans,
struct btrfs_root *root, u64 objectid)
{ … }
static void delete_orphan_inode(struct btrfs_trans_handle *trans,
struct btrfs_root *root, u64 objectid)
{ … }
static noinline_for_stack struct inode *create_reloc_inode(
struct btrfs_fs_info *fs_info,
const struct btrfs_block_group *group)
{ … }
static int reloc_chunk_start(struct btrfs_fs_info *fs_info)
{ … }
static void reloc_chunk_end(struct btrfs_fs_info *fs_info)
{ … }
static struct reloc_control *alloc_reloc_control(struct btrfs_fs_info *fs_info)
{ … }
static void free_reloc_control(struct reloc_control *rc)
{ … }
static void describe_relocation(struct btrfs_block_group *block_group)
{ … }
static const char *stage_to_string(enum reloc_stage stage)
{ … }
int btrfs_relocate_block_group(struct btrfs_fs_info *fs_info, u64 group_start)
{ … }
static noinline_for_stack int mark_garbage_root(struct btrfs_root *root)
{ … }
int btrfs_recover_relocation(struct btrfs_fs_info *fs_info)
{ … }
int btrfs_reloc_clone_csums(struct btrfs_ordered_extent *ordered)
{ … }
int btrfs_reloc_cow_block(struct btrfs_trans_handle *trans,
struct btrfs_root *root,
const struct extent_buffer *buf,
struct extent_buffer *cow)
{ … }
void btrfs_reloc_pre_snapshot(struct btrfs_pending_snapshot *pending,
u64 *bytes_to_reserve)
{ … }
int btrfs_reloc_post_snapshot(struct btrfs_trans_handle *trans,
struct btrfs_pending_snapshot *pending)
{ … }
u64 btrfs_get_reloc_bg_bytenr(const struct btrfs_fs_info *fs_info)
{ … }