#include <linux/bitops.h>
#include <linux/slab.h>
#include <linux/bio.h>
#include <linux/mm.h>
#include <linux/pagemap.h>
#include <linux/page-flags.h>
#include <linux/sched/mm.h>
#include <linux/spinlock.h>
#include <linux/blkdev.h>
#include <linux/swap.h>
#include <linux/writeback.h>
#include <linux/pagevec.h>
#include <linux/prefetch.h>
#include <linux/fsverity.h>
#include "extent_io.h"
#include "extent-io-tree.h"
#include "extent_map.h"
#include "ctree.h"
#include "btrfs_inode.h"
#include "bio.h"
#include "locking.h"
#include "backref.h"
#include "disk-io.h"
#include "subpage.h"
#include "zoned.h"
#include "block-group.h"
#include "compression.h"
#include "fs.h"
#include "accessors.h"
#include "file-item.h"
#include "file.h"
#include "dev-replace.h"
#include "super.h"
#include "transaction.h"
static struct kmem_cache *extent_buffer_cache;
#ifdef CONFIG_BTRFS_DEBUG
static inline void btrfs_leak_debug_add_eb(struct extent_buffer *eb)
{ … }
static inline void btrfs_leak_debug_del_eb(struct extent_buffer *eb)
{ … }
void btrfs_extent_buffer_leak_debug_check(struct btrfs_fs_info *fs_info)
{ … }
#else
#define btrfs_leak_debug_add_eb …
#define btrfs_leak_debug_del_eb …
#endif
struct btrfs_bio_ctrl { … };
static void submit_one_bio(struct btrfs_bio_ctrl *bio_ctrl)
{ … }
static void submit_write_bio(struct btrfs_bio_ctrl *bio_ctrl, int ret)
{ … }
int __init extent_buffer_init_cachep(void)
{ … }
void __cold extent_buffer_free_cachep(void)
{ … }
static void process_one_page(struct btrfs_fs_info *fs_info,
struct page *page, const struct page *locked_page,
unsigned long page_ops, u64 start, u64 end)
{ … }
static void __process_pages_contig(struct address_space *mapping,
const struct page *locked_page, u64 start, u64 end,
unsigned long page_ops)
{ … }
static noinline void __unlock_for_delalloc(const struct inode *inode,
const struct page *locked_page,
u64 start, u64 end)
{ … }
static noinline int lock_delalloc_pages(struct inode *inode,
const struct page *locked_page,
u64 start,
u64 end)
{ … }
EXPORT_FOR_TESTS
noinline_for_stack bool find_lock_delalloc_range(struct inode *inode,
struct page *locked_page, u64 *start,
u64 *end)
{ … }
void extent_clear_unlock_delalloc(struct btrfs_inode *inode, u64 start, u64 end,
const struct page *locked_page,
struct extent_state **cached,
u32 clear_bits, unsigned long page_ops)
{ … }
static bool btrfs_verify_page(struct page *page, u64 start)
{ … }
static void end_page_read(struct page *page, bool uptodate, u64 start, u32 len)
{ … }
static void end_bbio_data_write(struct btrfs_bio *bbio)
{ … }
struct processed_extent { … };
static void endio_readpage_release_extent(struct processed_extent *processed,
struct btrfs_inode *inode, u64 start, u64 end,
bool uptodate)
{ … }
static void begin_page_read(struct btrfs_fs_info *fs_info, struct page *page)
{ … }
static void end_bbio_data_read(struct btrfs_bio *bbio)
{ … }
int btrfs_alloc_folio_array(unsigned int nr_folios, struct folio **folio_array)
{ … }
int btrfs_alloc_page_array(unsigned int nr_pages, struct page **page_array,
bool nofail)
{ … }
static int alloc_eb_folio_array(struct extent_buffer *eb, bool nofail)
{ … }
static bool btrfs_bio_is_contig(struct btrfs_bio_ctrl *bio_ctrl,
struct page *page, u64 disk_bytenr,
unsigned int pg_offset)
{ … }
static void alloc_new_bio(struct btrfs_inode *inode,
struct btrfs_bio_ctrl *bio_ctrl,
u64 disk_bytenr, u64 file_offset)
{ … }
static void submit_extent_page(struct btrfs_bio_ctrl *bio_ctrl,
u64 disk_bytenr, struct page *page,
size_t size, unsigned long pg_offset)
{ … }
static int attach_extent_buffer_folio(struct extent_buffer *eb,
struct folio *folio,
struct btrfs_subpage *prealloc)
{ … }
int set_page_extent_mapped(struct page *page)
{ … }
int set_folio_extent_mapped(struct folio *folio)
{ … }
void clear_page_extent_mapped(struct page *page)
{ … }
static struct extent_map *__get_extent_map(struct inode *inode, struct page *page,
u64 start, u64 len, struct extent_map **em_cached)
{ … }
static int btrfs_do_readpage(struct page *page, struct extent_map **em_cached,
struct btrfs_bio_ctrl *bio_ctrl, u64 *prev_em_start)
{ … }
int btrfs_read_folio(struct file *file, struct folio *folio)
{ … }
static inline void contiguous_readpages(struct page *pages[], int nr_pages,
u64 start, u64 end,
struct extent_map **em_cached,
struct btrfs_bio_ctrl *bio_ctrl,
u64 *prev_em_start)
{ … }
static noinline_for_stack int writepage_delalloc(struct btrfs_inode *inode,
struct page *page, struct writeback_control *wbc)
{ … }
static void find_next_dirty_byte(const struct btrfs_fs_info *fs_info,
struct page *page, u64 *start, u64 *end)
{ … }
static noinline_for_stack int __extent_writepage_io(struct btrfs_inode *inode,
struct page *page, u64 start, u32 len,
struct btrfs_bio_ctrl *bio_ctrl,
loff_t i_size,
int *nr_ret)
{ … }
static int __extent_writepage(struct page *page, struct btrfs_bio_ctrl *bio_ctrl)
{ … }
void wait_on_extent_buffer_writeback(struct extent_buffer *eb)
{ … }
static noinline_for_stack bool lock_extent_buffer_for_io(struct extent_buffer *eb,
struct writeback_control *wbc)
{ … }
static void set_btree_ioerr(struct extent_buffer *eb)
{ … }
static struct extent_buffer *find_extent_buffer_nolock(
const struct btrfs_fs_info *fs_info, u64 start)
{ … }
static void end_bbio_meta_write(struct btrfs_bio *bbio)
{ … }
static void prepare_eb_write(struct extent_buffer *eb)
{ … }
static noinline_for_stack void write_one_eb(struct extent_buffer *eb,
struct writeback_control *wbc)
{ … }
static int submit_eb_subpage(struct page *page, struct writeback_control *wbc)
{ … }
static int submit_eb_page(struct page *page, struct btrfs_eb_write_context *ctx)
{ … }
int btree_write_cache_pages(struct address_space *mapping,
struct writeback_control *wbc)
{ … }
static int extent_write_cache_pages(struct address_space *mapping,
struct btrfs_bio_ctrl *bio_ctrl)
{ … }
void extent_write_locked_range(struct inode *inode, const struct page *locked_page,
u64 start, u64 end, struct writeback_control *wbc,
bool pages_dirty)
{ … }
int btrfs_writepages(struct address_space *mapping, struct writeback_control *wbc)
{ … }
void btrfs_readahead(struct readahead_control *rac)
{ … }
int extent_invalidate_folio(struct extent_io_tree *tree,
struct folio *folio, size_t offset)
{ … }
static bool try_release_extent_state(struct extent_io_tree *tree,
struct page *page, gfp_t mask)
{ … }
bool try_release_extent_mapping(struct page *page, gfp_t mask)
{ … }
static void __free_extent_buffer(struct extent_buffer *eb)
{ … }
static int extent_buffer_under_io(const struct extent_buffer *eb)
{ … }
static bool folio_range_has_eb(struct btrfs_fs_info *fs_info, struct folio *folio)
{ … }
static void detach_extent_buffer_folio(const struct extent_buffer *eb, struct folio *folio)
{ … }
static void btrfs_release_extent_buffer_pages(const struct extent_buffer *eb)
{ … }
static inline void btrfs_release_extent_buffer(struct extent_buffer *eb)
{ … }
static struct extent_buffer *
__alloc_extent_buffer(struct btrfs_fs_info *fs_info, u64 start,
unsigned long len)
{ … }
struct extent_buffer *btrfs_clone_extent_buffer(const struct extent_buffer *src)
{ … }
struct extent_buffer *__alloc_dummy_extent_buffer(struct btrfs_fs_info *fs_info,
u64 start, unsigned long len)
{ … }
struct extent_buffer *alloc_dummy_extent_buffer(struct btrfs_fs_info *fs_info,
u64 start)
{ … }
static void check_buffer_tree_ref(struct extent_buffer *eb)
{ … }
static void mark_extent_buffer_accessed(struct extent_buffer *eb)
{ … }
struct extent_buffer *find_extent_buffer(struct btrfs_fs_info *fs_info,
u64 start)
{ … }
#ifdef CONFIG_BTRFS_FS_RUN_SANITY_TESTS
struct extent_buffer *alloc_test_extent_buffer(struct btrfs_fs_info *fs_info,
u64 start)
{ … }
#endif
static struct extent_buffer *grab_extent_buffer(
struct btrfs_fs_info *fs_info, struct page *page)
{ … }
static int check_eb_alignment(struct btrfs_fs_info *fs_info, u64 start)
{ … }
static int attach_eb_folio_to_filemap(struct extent_buffer *eb, int i,
struct btrfs_subpage *prealloc,
struct extent_buffer **found_eb_ret)
{ … }
struct extent_buffer *alloc_extent_buffer(struct btrfs_fs_info *fs_info,
u64 start, u64 owner_root, int level)
{ … }
static inline void btrfs_release_extent_buffer_rcu(struct rcu_head *head)
{ … }
static int release_extent_buffer(struct extent_buffer *eb)
__releases(&eb->refs_lock)
{ … }
void free_extent_buffer(struct extent_buffer *eb)
{ … }
void free_extent_buffer_stale(struct extent_buffer *eb)
{ … }
static void btree_clear_folio_dirty(struct folio *folio)
{ … }
static void clear_subpage_extent_buffer_dirty(const struct extent_buffer *eb)
{ … }
void btrfs_clear_buffer_dirty(struct btrfs_trans_handle *trans,
struct extent_buffer *eb)
{ … }
void set_extent_buffer_dirty(struct extent_buffer *eb)
{ … }
void clear_extent_buffer_uptodate(struct extent_buffer *eb)
{ … }
void set_extent_buffer_uptodate(struct extent_buffer *eb)
{ … }
static void clear_extent_buffer_reading(struct extent_buffer *eb)
{ … }
static void end_bbio_meta_read(struct btrfs_bio *bbio)
{ … }
int read_extent_buffer_pages(struct extent_buffer *eb, int wait, int mirror_num,
const struct btrfs_tree_parent_check *check)
{ … }
static bool report_eb_range(const struct extent_buffer *eb, unsigned long start,
unsigned long len)
{ … }
static inline int check_eb_range(const struct extent_buffer *eb,
unsigned long start, unsigned long len)
{ … }
void read_extent_buffer(const struct extent_buffer *eb, void *dstv,
unsigned long start, unsigned long len)
{ … }
int read_extent_buffer_to_user_nofault(const struct extent_buffer *eb,
void __user *dstv,
unsigned long start, unsigned long len)
{ … }
int memcmp_extent_buffer(const struct extent_buffer *eb, const void *ptrv,
unsigned long start, unsigned long len)
{ … }
static void assert_eb_folio_uptodate(const struct extent_buffer *eb, int i)
{ … }
static void __write_extent_buffer(const struct extent_buffer *eb,
const void *srcv, unsigned long start,
unsigned long len, bool use_memmove)
{ … }
void write_extent_buffer(const struct extent_buffer *eb, const void *srcv,
unsigned long start, unsigned long len)
{ … }
static void memset_extent_buffer(const struct extent_buffer *eb, int c,
unsigned long start, unsigned long len)
{ … }
void memzero_extent_buffer(const struct extent_buffer *eb, unsigned long start,
unsigned long len)
{ … }
void copy_extent_buffer_full(const struct extent_buffer *dst,
const struct extent_buffer *src)
{ … }
void copy_extent_buffer(const struct extent_buffer *dst,
const struct extent_buffer *src,
unsigned long dst_offset, unsigned long src_offset,
unsigned long len)
{ … }
static inline void eb_bitmap_offset(const struct extent_buffer *eb,
unsigned long start, unsigned long nr,
unsigned long *folio_index,
size_t *folio_offset)
{ … }
int extent_buffer_test_bit(const struct extent_buffer *eb, unsigned long start,
unsigned long nr)
{ … }
static u8 *extent_buffer_get_byte(const struct extent_buffer *eb, unsigned long bytenr)
{ … }
void extent_buffer_bitmap_set(const struct extent_buffer *eb, unsigned long start,
unsigned long pos, unsigned long len)
{ … }
void extent_buffer_bitmap_clear(const struct extent_buffer *eb,
unsigned long start, unsigned long pos,
unsigned long len)
{ … }
static inline bool areas_overlap(unsigned long src, unsigned long dst, unsigned long len)
{ … }
void memcpy_extent_buffer(const struct extent_buffer *dst,
unsigned long dst_offset, unsigned long src_offset,
unsigned long len)
{ … }
void memmove_extent_buffer(const struct extent_buffer *dst,
unsigned long dst_offset, unsigned long src_offset,
unsigned long len)
{ … }
#define GANG_LOOKUP_SIZE …
static struct extent_buffer *get_next_extent_buffer(
const struct btrfs_fs_info *fs_info, struct page *page, u64 bytenr)
{ … }
static int try_release_subpage_extent_buffer(struct page *page)
{ … }
int try_release_extent_buffer(struct page *page)
{ … }
void btrfs_readahead_tree_block(struct btrfs_fs_info *fs_info,
u64 bytenr, u64 owner_root, u64 gen, int level)
{ … }
void btrfs_readahead_node_child(struct extent_buffer *node, int slot)
{ … }