#include <linux/sched.h>
#include <linux/bio.h>
#include <linux/slab.h>
#include <linux/blkdev.h>
#include <linux/raid/pq.h>
#include <linux/hash.h>
#include <linux/list_sort.h>
#include <linux/raid/xor.h>
#include <linux/mm.h>
#include "messages.h"
#include "ctree.h"
#include "disk-io.h"
#include "volumes.h"
#include "raid56.h"
#include "async-thread.h"
#include "file-item.h"
#include "btrfs_inode.h"
#define RBIO_RMW_LOCKED_BIT …
#define RBIO_CACHE_BIT …
#define RBIO_CACHE_READY_BIT …
#define RBIO_CACHE_SIZE …
#define BTRFS_STRIPE_HASH_TABLE_BITS …
static void dump_bioc(const struct btrfs_fs_info *fs_info, const struct btrfs_io_context *bioc)
{ … }
static void btrfs_dump_rbio(const struct btrfs_fs_info *fs_info,
const struct btrfs_raid_bio *rbio)
{ … }
#define ASSERT_RBIO(expr, rbio) …
#define ASSERT_RBIO_STRIPE(expr, rbio, stripe_nr) …
#define ASSERT_RBIO_SECTOR(expr, rbio, sector_nr) …
#define ASSERT_RBIO_LOGICAL(expr, rbio, logical) …
struct btrfs_stripe_hash { … };
struct btrfs_stripe_hash_table { … };
struct sector_ptr { … };
static void rmw_rbio_work(struct work_struct *work);
static void rmw_rbio_work_locked(struct work_struct *work);
static void index_rbio_pages(struct btrfs_raid_bio *rbio);
static int alloc_rbio_pages(struct btrfs_raid_bio *rbio);
static int finish_parity_scrub(struct btrfs_raid_bio *rbio);
static void scrub_rbio_work_locked(struct work_struct *work);
static void free_raid_bio_pointers(struct btrfs_raid_bio *rbio)
{ … }
static void free_raid_bio(struct btrfs_raid_bio *rbio)
{ … }
static void start_async_work(struct btrfs_raid_bio *rbio, work_func_t work_func)
{ … }
int btrfs_alloc_stripe_hash_table(struct btrfs_fs_info *info)
{ … }
static void cache_rbio_pages(struct btrfs_raid_bio *rbio)
{ … }
static int rbio_bucket(struct btrfs_raid_bio *rbio)
{ … }
static bool full_page_sectors_uptodate(struct btrfs_raid_bio *rbio,
unsigned int page_nr)
{ … }
static void index_stripe_sectors(struct btrfs_raid_bio *rbio)
{ … }
static void steal_rbio_page(struct btrfs_raid_bio *src,
struct btrfs_raid_bio *dest, int page_nr)
{ … }
static bool is_data_stripe_page(struct btrfs_raid_bio *rbio, int page_nr)
{ … }
static void steal_rbio(struct btrfs_raid_bio *src, struct btrfs_raid_bio *dest)
{ … }
static void merge_rbio(struct btrfs_raid_bio *dest,
struct btrfs_raid_bio *victim)
{ … }
static void __remove_rbio_from_cache(struct btrfs_raid_bio *rbio)
{ … }
static void remove_rbio_from_cache(struct btrfs_raid_bio *rbio)
{ … }
static void btrfs_clear_rbio_cache(struct btrfs_fs_info *info)
{ … }
void btrfs_free_stripe_hash_table(struct btrfs_fs_info *info)
{ … }
static void cache_rbio(struct btrfs_raid_bio *rbio)
{ … }
static void run_xor(void **pages, int src_cnt, ssize_t len)
{ … }
static int rbio_is_full(struct btrfs_raid_bio *rbio)
{ … }
static int rbio_can_merge(struct btrfs_raid_bio *last,
struct btrfs_raid_bio *cur)
{ … }
static unsigned int rbio_stripe_sector_index(const struct btrfs_raid_bio *rbio,
unsigned int stripe_nr,
unsigned int sector_nr)
{ … }
static struct sector_ptr *rbio_stripe_sector(const struct btrfs_raid_bio *rbio,
unsigned int stripe_nr,
unsigned int sector_nr)
{ … }
static struct sector_ptr *rbio_pstripe_sector(const struct btrfs_raid_bio *rbio,
unsigned int sector_nr)
{ … }
static struct sector_ptr *rbio_qstripe_sector(const struct btrfs_raid_bio *rbio,
unsigned int sector_nr)
{ … }
static noinline int lock_stripe_add(struct btrfs_raid_bio *rbio)
{ … }
static void recover_rbio_work_locked(struct work_struct *work);
static noinline void unlock_stripe(struct btrfs_raid_bio *rbio)
{ … }
static void rbio_endio_bio_list(struct bio *cur, blk_status_t err)
{ … }
static void rbio_orig_end_io(struct btrfs_raid_bio *rbio, blk_status_t err)
{ … }
static struct sector_ptr *sector_in_rbio(struct btrfs_raid_bio *rbio,
int stripe_nr, int sector_nr,
bool bio_list_only)
{ … }
static struct btrfs_raid_bio *alloc_rbio(struct btrfs_fs_info *fs_info,
struct btrfs_io_context *bioc)
{ … }
static int alloc_rbio_pages(struct btrfs_raid_bio *rbio)
{ … }
static int alloc_rbio_parity_pages(struct btrfs_raid_bio *rbio)
{ … }
static int get_rbio_veritical_errors(struct btrfs_raid_bio *rbio, int sector_nr,
int *faila, int *failb)
{ … }
static int rbio_add_io_sector(struct btrfs_raid_bio *rbio,
struct bio_list *bio_list,
struct sector_ptr *sector,
unsigned int stripe_nr,
unsigned int sector_nr,
enum req_op op)
{ … }
static void index_one_bio(struct btrfs_raid_bio *rbio, struct bio *bio)
{ … }
static void index_rbio_pages(struct btrfs_raid_bio *rbio)
{ … }
static void bio_get_trace_info(struct btrfs_raid_bio *rbio, struct bio *bio,
struct raid56_bio_trace_info *trace_info)
{ … }
static inline void bio_list_put(struct bio_list *bio_list)
{ … }
static void assert_rbio(struct btrfs_raid_bio *rbio)
{ … }
static void generate_pq_vertical(struct btrfs_raid_bio *rbio, int sectornr)
{ … }
static int rmw_assemble_write_bios(struct btrfs_raid_bio *rbio,
struct bio_list *bio_list)
{ … }
static void set_rbio_range_error(struct btrfs_raid_bio *rbio, struct bio *bio)
{ … }
static struct sector_ptr *find_stripe_sector(struct btrfs_raid_bio *rbio,
struct page *page,
unsigned int pgoff)
{ … }
static void set_bio_pages_uptodate(struct btrfs_raid_bio *rbio, struct bio *bio)
{ … }
static int get_bio_sector_nr(struct btrfs_raid_bio *rbio, struct bio *bio)
{ … }
static void rbio_update_error_bitmap(struct btrfs_raid_bio *rbio, struct bio *bio)
{ … }
static void verify_bio_data_sectors(struct btrfs_raid_bio *rbio,
struct bio *bio)
{ … }
static void raid_wait_read_end_io(struct bio *bio)
{ … }
static void submit_read_wait_bio_list(struct btrfs_raid_bio *rbio,
struct bio_list *bio_list)
{ … }
static int alloc_rbio_data_pages(struct btrfs_raid_bio *rbio)
{ … }
struct btrfs_plug_cb { … };
static int plug_cmp(void *priv, const struct list_head *a,
const struct list_head *b)
{ … }
static void raid_unplug(struct blk_plug_cb *cb, bool from_schedule)
{ … }
static void rbio_add_bio(struct btrfs_raid_bio *rbio, struct bio *orig_bio)
{ … }
void raid56_parity_write(struct bio *bio, struct btrfs_io_context *bioc)
{ … }
static int verify_one_sector(struct btrfs_raid_bio *rbio,
int stripe_nr, int sector_nr)
{ … }
static int recover_vertical(struct btrfs_raid_bio *rbio, int sector_nr,
void **pointers, void **unmap_array)
{ … }
static int recover_sectors(struct btrfs_raid_bio *rbio)
{ … }
static void recover_rbio(struct btrfs_raid_bio *rbio)
{ … }
static void recover_rbio_work(struct work_struct *work)
{ … }
static void recover_rbio_work_locked(struct work_struct *work)
{ … }
static void set_rbio_raid6_extra_error(struct btrfs_raid_bio *rbio, int mirror_num)
{ … }
void raid56_parity_recover(struct bio *bio, struct btrfs_io_context *bioc,
int mirror_num)
{ … }
static void fill_data_csums(struct btrfs_raid_bio *rbio)
{ … }
static int rmw_read_wait_recover(struct btrfs_raid_bio *rbio)
{ … }
static void raid_wait_write_end_io(struct bio *bio)
{ … }
static void submit_write_bios(struct btrfs_raid_bio *rbio,
struct bio_list *bio_list)
{ … }
static bool need_read_stripe_sectors(struct btrfs_raid_bio *rbio)
{ … }
static void rmw_rbio(struct btrfs_raid_bio *rbio)
{ … }
static void rmw_rbio_work(struct work_struct *work)
{ … }
static void rmw_rbio_work_locked(struct work_struct *work)
{ … }
struct btrfs_raid_bio *raid56_parity_alloc_scrub_rbio(struct bio *bio,
struct btrfs_io_context *bioc,
struct btrfs_device *scrub_dev,
unsigned long *dbitmap, int stripe_nsectors)
{ … }
static int alloc_rbio_essential_pages(struct btrfs_raid_bio *rbio)
{ … }
static int finish_parity_scrub(struct btrfs_raid_bio *rbio)
{ … }
static inline int is_data_stripe(struct btrfs_raid_bio *rbio, int stripe)
{ … }
static int recover_scrub_rbio(struct btrfs_raid_bio *rbio)
{ … }
static int scrub_assemble_read_bios(struct btrfs_raid_bio *rbio)
{ … }
static void scrub_rbio(struct btrfs_raid_bio *rbio)
{ … }
static void scrub_rbio_work_locked(struct work_struct *work)
{ … }
void raid56_parity_submit_scrub_rbio(struct btrfs_raid_bio *rbio)
{ … }
void raid56_parity_cache_data_pages(struct btrfs_raid_bio *rbio,
struct page **data_pages, u64 data_logical)
{ … }